过去这一年里,我陆陆续续折腾过好几个跟LLM沾边的工具,但老实说,真正让我愿意每个周末都坐到电脑前认真迭代的,就是这个基于LLM大模型的股票基金周预测Agent。它不是那种炫技型项目,不追求实时tick级别预测,也不编造什么"超高胜率"的神话,而是老老实实做一件事:把公开的市场行情、行业新闻、宏观数据收集起来,交给大模型做一轮周度方向判断,最后输出一份结构化的预测报告,里面包含方向倾向、概率估计和风险提示。
做这个项目的最初动机很朴素。我自己体验过不少量化分析工具,它们擅长算指标、画曲线,但要把"美联储官员讲话""某行业出现突发政策""龙头公司发布超预期财报"这类非结构化信息纳入分析框架,传统规则系统几乎无能为力。而LLM恰好擅长处理文本语义,擅长做信息归纳,还具备一定的推理能力。我就想知道:如果把"行情数据计算"交给代码,把"语义理解与综合判断"交给大模型,两者结合起来,能不能做成一个每周能自动运转、输出可读分析结论的Agent?
这个项目前前后后花了我三周左右的业余时间。如果你也想做一个类似的"AI投研助理",或者正打算把大模型引入量化工作流,这篇复盘应该能让你少踩好几个坑。我会把架构设计、数据获取、提示词组织、回测方法、常见问题全部摊开来讲,包括那些网上不太会有人主动告诉你的教训。
1. 项目缘起:为什么偏偏是"周预测"而不是更疯狂的玩法
很多人听到"股票预测AI",第一反应都是:能不能每天预测涨跌?能不能跑赢市场?我跟朋友聊这个项目时,对方的第一句话几乎都是"那你赚了多少"。这种期待本身就有问题,我自己在项目启动前就先做了预期管理。
1.1 我为什么选周度频率
选周频而不是日频,是我对LLM能力边界做过认真判断之后的结果。日频预测听起来更性感,实际上对信息质量和时效性的要求非常苛刻——盘中突发消息、资金流变化、微妙的市场情绪转向,这些LLM几乎是感知不到的,尤其是免费或低成本接口,本来就有数据延迟。即使给你实时数据,模型对分钟级走势的推理能力也远不如一套成熟的统计模型。
周频则正好落在LLM的能力甜蜜区。一周内的市场信息可以被充分沉淀,新闻、财报、政策事件都有了相对完整的发酵过程,大模型能够把这些信息综合起来做偏中线的判断。这个判断不需要精确到"下周某天涨3%",而是方向性的:看多、看空或者震荡,再辅以概率估计。
用一句话概括定位:我不需要Agent告诉我"下周一开盘价是多少",我只需要它当我的初级投研助手,把杂乱的信息梳理成有条理的多空逻辑报告。
1.2 LLM做预测的原理边界
为什么"大模型能预测股票"这个想法不是完全离谱?因为预训练模型在训练过程中吸收了海量历史财经文本、市场评论和公司财报,它实际上掌握了一部分"市场常识"。就好比一个读过上万篇券商研报的实习生,你问他"某行业现在最大的风险是什么",他多少能说出一二;但你问"明天该板块哪只票会涨停",他大概率是在瞎编。
这背后的逻辑是:LLM擅长模式识别和语义归纳,但它不是预言机。预测的质量高度依赖输入信息的质量和组织方式。同样的模型,你把一堆零散新闻直接丢进去,跟把新闻先做事件抽取、按重要度排序之后再喂给它,产出的质量可能差几个量级。
1.3 这个Agent真正解决的问题
说到底,我做这个项目不是指望它成为印钞机,而是想验证一套工作流:能否用大模型构建一个半自动化的信息处理与决策辅助系统。它真正能解决的是:
- 每周花大量时间翻阅资讯、研报、公告,却难以形成结构化决策参考的难题;
- 传统量化模型无法有效利用文本信息(新闻、舆情、政策表述)的缺陷;
- 个人投资者容易受单一消息影响、做出情绪化判断的问题——Agent输出的是一份经过整理的逻辑链,而不是一条孤立的热点消息。
想清楚这三点,整个项目的设计方向就不会跑偏:不是去追求"预测准确性"这一个指标,而是要同时保证可解释性、稳定性和可维护性。
2. 整体架构与技术选型:一个能落地的LLM预测系统长什么样
项目最有意思的部分并不是"调一个模型",而是整个系统怎么组织。直接调一个API输出预测结果,那是demo;能把预测流程周度化、自动化、可回溯,才叫Agent。
2.1 系统的四层数据流
我把整个系统拆成四个模块:数据采集层、信息加工层、分析决策层、输出呈现层。每一层只负责一件事,层与层之间通过标准化的数据结构传递信息。
数据采集层负责从各种公开渠道获取行情数据(开盘、收盘、最高、最低、成交量)、财经新闻、宏观数据(如PMI、CPI等官方指标)。信息加工层做三件事:清洗异常数值、把新闻做关键事件抽取、把行情数据整理成一段结构化的趋势摘要。分析决策层是核心,把前面加工好的信息连同设计好的提示词发送给大模型,拿到结构化的JSON输出。输出呈现层再把模型输出的内容渲染成一份人类可读的周报,包括核心结论、逻辑要点、风险提示和免责声明。
这个分层设计最大的好处是:每一层都可以独立替换和测试。比如你觉得新闻抽取效果不好,单独换一个抽取策略就行,不用改动其他模块;你想换一家模型接口,分析决策层的调用逻辑也不需要推倒重来。
2.2 技术栈的具体选型
我用的技术栈不复杂,都是常见方案:
| 模块 | 技术选型 | 选型理由 |
|---|---|---|
| 开发语言 | Python 3.10 | 数据处理、AI接口支持最完善 |
| 数据存储 | SQLite | 轻量、单文件,个人项目足够 |
| 数据获取 | 行情接口 + 新闻RSS + 官方统计 | 免费稳定,不需要额外成本 |
| 信息加工 | pandas + 正则 + LLM摘要 | 结构化和非结构化数据分别处理 |
| 大模型调用 | 主流大模型API(对话类) | 不需要微调,通用能力已够用 |
| 输出解析 | 强制JSON格式 + 自动校验 | 把模型输出变成可靠的数据结构 |
我建议个人项目别一上来就上重型组件。有朋友上来就搭了一套消息队列加容器编排,结果数据量根本跑不满,白白增加维护成本。SQLite加Python脚本,跑一次分钟级完成,完全够用。
2.3 为什么采用"摘要+决策"两段式而不是一步到位
这个设计决策我认为是整个项目里最重要的一步。最初我试过直接把几十条新闻原文和行情数据一次性塞进提示词,让模型"直接给出判断",结果很糟糕——模型被大量信息淹没,输出经常缺乏重点,甚至出现前后矛盾的观点。
问题出在上下文窗口的"稀释效应"上。大模型对长上下文的注意力是有限的,内容越长,模型越容易丢失关键线索。于是我改为两段式:第一轮调用模型,让它对新闻列表进行压缩和提炼——输出几条关键事件及其影响方向(利多、利空、中性);第二轮再把提炼后的事件标签、行情技术指标摘要、历史走势特征一起送入模型,做最终的预测判断。
这两步的实际效果差异非常大。做了信息压缩之后,第二轮的决策输入只有原来的20%左右长度,而且关键信息密度大幅提高,模型给出的判断逻辑明显更聚焦,不再出现"因为A所以涨,因为B所以跌"这种自相矛盾的表述。
3. 核心模块实现:数据、提示词与输出解析
这一节是整个项目的重头戏。你会发现,真正花费最多时间的不是调模型,而是让数据干净、让提示词精准、让输出可解析。
3.1 数据获取与清洗的实用方案
数据是一切的基础,但很多人在第一步就踩坑。我的经验是:行情数据容易处理,非结构化的新闻数据才是真正的硬骨头。
行情数据部分,我会拉取目标标的过去60个交易日的日线数据,计算几个简单的技术指标:5日均线位置、20日均线位置、近期波动率、成交量变化趋势。这里不需要太复杂的指标,因为我发现LLM对"死叉金叉"这类术语的理解虽然没问题,但它更擅长处理的是"价格在近20日处于什么分位数"这类直白描述。
新闻数据部分,用RSS源加联网搜索接口来收集。收集之后要做两层清洗。第一层是去重和过滤:同一事件的重复报道只保留一篇,删除明显无关的内容。第二层是事件化压缩:把长达几百字的新闻稿压缩成"某公司发布超预期财报,净利润同比增长40%,属于利好"这样的事件描述。这一步我用的是小模型辅助完成,成本低且速度快。
关键提示:清洗时一定要做"数值白名单"校验,尤其针对新闻里的百分比数据。曾经出现过新闻原文把"下跌2%"复制成了"下跌20%",模型差点据此给出了极端看空判断。宁可丢弃可疑数据,也不要让脏数据流进决策环节。
3.2 提示词工程的核心设计思路
提示词设计是整个项目中最需要反复打磨的部分。我前前后后改了十几版,核心的进化方向只有一个:把模糊的"请分析一下"改成有约束力的"请基于给定模板输出"。
一个可参考的提示词框架长这样:
你是一名拥有十年经验的宏观策略分析师。请基于以下信息,对【某主流宽基指数】本周(周一至周五)走势给出方向判断。 【近60日行情摘要】 - 收盘价从XXX变化至XXX,区间涨跌幅X% - 当前价格处于近20日分位数的X% - 近5日成交量相对前20日均量的变化率为X% 【本周重要事件】 1. [事件描述](影响方向: 利多/利空/中性) 2. [事件描述](影响方向: 利多/利空/中性) 【宏观背景】 - [宏观经济指标简述] 请严格按以下JSON格式输出,不得输出其他内容: { "方向": "看多" | "看震荡" | "看空", "概率估计": 50-100之间的整数, "核心逻辑": "不超过150字", "关键风险": "不超过100字", "关注点位": ["数值1", "数值2"] }这套提示词的精髓在于:给模型一个明确的角色定位,提供压缩后的高质量输入,用JSON结构强制约束输出。另外我在"概率估计"字段里做了范围限制——不允许低于50,避免模型总是给出"五五开"的模糊答案,强迫它在消化信息后做出有倾向性的判断。
3.3 结构化输出的可靠解析方法
大模型的输出天然不稳定,哪怕提示词里写了"必须输出JSON",实测下来仍有不小的概率出现多余字符、注释、甚至残缺JSON。我试过好几种方案,最后跑得最稳的是这套组合:
第一步,使用JSON格式约束参数(如果你的模型API支持的话)来限制输出格式;第二步,在解析阶段用容错性好的解析库而不是标准json库,它能自动修复一些常见的JSON格式问题;第三步,做业务级校验——方向字段必须匹配三个枚举值之一,概率必须是50到100的整数,核心逻辑不能为空。
校验失败的输出会触发自动重试机制,最多重试两次。重试时我会把解析失败的原因回传给模型,让它"根据错误信息修正输出"。这个办法实测能把有效输出率从八成左右提升到接近满分。注意,重试会造成额外的接口调用成本,所以我只对关键环节开启这个功能。
4. 从回测到模拟盘:验证预测系统的真实水平
辛辛苦苦把Agent搭起来之后,最刺激也是最能泼冷水的环节来了——它到底准不准。我建议所有人都认真做验证,不要被"某次预测很准"的幸存者偏差冲昏头脑。
4.1 回测方案的设计细节
我的回测方案是在历史数据上的时间旅行模拟。用历史某一天之前的数据和新闻(只使用当时已公开的信息)来生成"历史预测",再跟真实的市场走势做对比。
这个方案看似简单,实际有一个大坑:未来函数。新闻数据和行情数据都必须是截止到预测时的历史数据,不能用后续信息做任何锚定。我最早的回测代码里不小心用了全量数据的均值做归一化,等于偷偷用了未来信息,回测胜率一度漂亮得惊人,后来发现逻辑错误之后立刻修正,数据重新变得"难看"了不少。
回测期我选择了过去12个月,每周生成一个预测,共有50多个独立样本。评估指标包括方向准确率、看对时的平均幅度、看错时的最大回撤,以及预测的"方向强度"和实际涨跌幅的相关性。
4.2 模拟盘实跑的结果怎么看
实跑两个多月的结果,我不想用"很准"来形容。准确率大概落在五成五到六成之间,看起来不算惊艳,但有很多细节值得说。
系统在震荡行情中的方向判断非常差,经常给出"看震荡"的正确废话;但在有明确趋势的行情中,一旦判断对了方向,平均幅度显著高于判断错时的幅度。这意味着,Agent的价值可能不在于每次都对,而在于它识别趋势性机会时具有实际参考意义。
我还发现一个有趣的现象:当模型的"概率估计"给出高置信度(比如超过75)时,准确率明显提升;而低置信度预测的准确率接近抛硬币。这让我意识到,系统输出的置信度本身就是一个有效信号,可以用来做仓位参考——高置信度时多关注,低置信度时干脆忽略。
4.3 评估指标与调优思路
预测量化领域最忌讳只看"准确率"这一个指标。我建立了几个小维度:
| 指标 | 计算方式 | 我的目标 |
|---|---|---|
| 方向准确率 | 判断方向与实际周涨跌幅一致的比例 | 高于55% |
| 置信度区分度 | 高置信组和低置信组的准确率差值 | 尽量拉大 |
| 信息利用率 | 输入的关键事件中有多少被模型反映在逻辑中 | 尽量接近100% |
| 逻辑一致性 | 预测逻辑中是否存在自相矛盾表述 | 为零 |
调优的过程就是围绕这几个指标做针对性改进。比如信息利用率偏低时,我意识到是新闻压缩环节把太多细节丢掉了,导致决策层的模型"看不到"关键信息。后来我在压缩提示词里特别加了一句"保留所有与市场影响直接相关的数值和主体",信息利用率就明显上升了。
5. 常见问题的排查实录:幻觉、时效性与输出漂移
做这类项目,踩坑是免不了的。这一节我把自己调试过程中最典型的几个问题整理成了速查指南,每一个都是真金白银的教训。
5.1 模型幻觉的根源与压制方法
大模型幻觉在预测场景里格外致命。最典型的表现是:模型会一本正经地引用一个根本不存在的政策文件,或者给出一串看起来合理但实际错误的宏观经济数据。我遇到过最离谱的一次,模型把一个行业自媒体的小道消息当成了正式发布,据此给出了明确的看空判断。
我压制幻觉的方法组合拳是:
- 要求模型必须引用输入材料:每一句核心观点后面加上对应的信息来源编号,没有来源编号的观点视为无效。
- 输入里明确标注"以下信息均来自给定材料,严禁引用外部知识":这句话能有效抑制模型动用预训练记忆里的过期信息。
- 给高危数据项做人工校验:模型输出的核心逻辑里提到的具体数值,系统会自动与输入数据比对,不一致就触发重写。
这一套组合拳下来,幻觉出现的频率大幅降低,但并没有完全消失。所以最终输出的报告里我保留了一行小字提示:"AI生成内容仅供参考,重要决策请核对原始信息源。"这不是免责炒作,是我吃过亏后的真实经验。
5.2 数据时效性在"周预测"场景下的特殊问题
周预测有一个容易被忽略的坑:模型预训练的知识存在截止日期,你以为它不知道某件新发生的事,但它可能把旧新闻当成了新事件。
我遇到过这样一个典型场景:某行业在2019年有过一波政策刺激行情,到了2024年出现了相似的政策表述,模型在看到当前输入后,竟然在逻辑里掺入了2019年的旧市场反应路径作为类比依据。这个类比并非毫无参考价值,但问题是2019年和当前的宏观环境差异巨大,直接套用会导致判断偏差。
解决办法是给所有输入数据打上明确的时间标签,并在提示词里加一条约束:"你只能基于时间标签标注的最新信息做判断,禁止使用模型记忆中早于输入时间窗口的类比案例。"这不算完全解决,但能显著减少错误的时间锚定。
5.3 输出漂移与上下文污染
上下文污染是指前一周的预测结论或数据残留在模型的"潜意识"里,影响本周判断。用无状态接口时这个问题相对少见,但一旦你为了节省成本开了对话缓存或历史记录功能,旧的判断就会不断干扰新预测。
我记得有一周,前一周刚"看多"过某标的,结果这一周数据明明已经转弱,模型仍然在逻辑里倾向于找利好证据,这就是典型的上下文污染。后来我彻底关闭了对话缓存,每次预测都从全新会话开始,这个问题立刻消失。宁肯多花一点点接口费用,也要保证每次预测的独立性。
这个概念延伸到更广的场景:如果你希望Agent做"持续跟踪",也不应该让模型直接记忆上周的结论,而是把上周结论作为一份独立文档,显式地告诉模型"这是上周观点,以下是本周新信息,请更新你的判断"。让模型意识到信息变化,而不是靠上下文窗口里的"残留记忆"。
5.4 常见问题速查表
| 现象 | 根因 | 处置方案 |
|---|---|---|
| 预测结果总是"看震荡" | 提示词允许模糊输出,模型偷懒回避确定性判断 | 强制方向枚举+"概率估计不能低于50"约束 |
| 核心逻辑出现幻觉数据 | 模型调用预训练记忆而非现有时效数据 | 要求附带信息源编号,高危数值与输入自动比对 |
| 同一条新闻被重复计入权重 | 新闻去重不彻底,多条同源报道都进了输入 | 基于标题+正文做simhash去重,保留第一来源 |
| 判断逻辑自相矛盾 | 输入信息过多,决策参考不集中 | 切换为"摘要+决策"两段式流程 |
| 高置信度预测依然老出错 | 模型缺少负面案例思维训练 | 提示词增加"请列举至少一个反向逻辑"要求 |
| 接口输出偶尔截断 | 输出token上限不够 | 把JSON字段压缩,或调用支持更长输出的最大token参数 |
6. 踩坑之后总结出的经验与后续扩展方向
项目做到这里,它的价值已经不只是一个预测工具。对我来说,它更像一个实验平台,在验证"大模型能不能做金融分析类Agent"这件事上,给出了足够真实的答案。
6.1 做对了哪几件事
第一件事是拒绝了一步到位的复杂架构,用简单的模块化设计先把流程跑通。有太多项目死在前期过度设计上。第二件事是把"可控输出"放在了和"预测准确率"同等重要的位置。一个输出稳定、格式规范的Agent,哪怕准确率平平,你也能持续迭代、持续改进;一个时好时坏、输出混乱的Agent,连问题出在哪里你都无法定位。第三件事是重视了置信度信号,没有盲目追随每一次预测,而是把模型的高置信度输出当作更值得关注的信号。
如果要从头再做一遍,我会在开始的时候就建立更完善的数据版本管理。我现在用的SQLite虽然简单,但历史预测和回测结果混在一张表里,做数据回溯时有各种麻烦。要是把每次运行的输入数据、模型输出、评估结果都按版本存档,后面做分析会顺手太多。
6.2 后续可以怎么扩展
我对这个Agent的未来走向有一些具体想法。首先是引入多模型投票机制——目前只用一个模型做决策,不同模型的"性格"差异其实挺大的,有的偏谨慎,有的偏激进。让三个不同风格的模型独立预测,最后对结论做一致性评估,如果出现分歧就用"少数派报告"的方式呈现。其次是增加更多数据源,比如行业内研究员公开的月报数据、专利公告密度、招聘信息趋势这类另类数据,这些对大模型做判断非常有用。
还有一个很实际的优化方向:用强化学习的思路做"预测校准"。每周末跑完预测后,把实际走势回灌给系统,生成一份"预测复盘报告",指出哪些逻辑线对了、哪些错了。坚持几周之后,这套数据本身就可以用来微调或者做模型选择的依据,形成一个持续进化的闭环。
6.3 给同类项目开发者的一点忠告
如果你也打算做类似的LLM Agent项目,我给你三个最真诚的建议。
第一,不要在预测准确率上死磕。大模型参与的预测系统,价值是"信息综合效率"和"决策参考维度",而不是一个精确的神谕。你把它当成一个每周帮你读几十篇研报、整理出多空逻辑的智能助手,心态就会摆正很多。
第二,不要忽略工程化细节。数据清洗、输出校验、异常重试这些"脏活累活",决定了你的系统能不能稳定运行,这些工作往往比调提示词更花时间、也更重要。
第三,永远对自己的Agent保持怀疑。每一次模型给出的答案,都默认它可能有错误。保留原始数据、保留推理链路、允许自己推翻它,这是所有AI辅助决策类工具能够长期使用的底线逻辑。
说白了,这个项目让我最有成就感的地方,不是某一次预测判断对了方向,而是我真正理解了一个问题:大模型做金融预测,能力边界不在模型本身,而在我们怎么设计信息流、怎么控制输出、怎么定义成功标准。这套方法论,放到任何一个垂直领域的LLM Agent上,都通用。