资讯动态

百亿Token语料实战:手搓一个可落地的LLM投资决策Agent

发布时间:2026/10/13 16:31:03 来源:尧图企业网站定制
我前阵子刚把团队里那个投资决策agent跑通到“持续稳定压准风险指标”的阶段憋了很久想把这个项目彻底拆开聊聊。因为市面上聊投资agent的文章不少但你真去看大部分要么停在调API的玩具层要么把系统说得神乎其神却给不出工程细节。尤其是我这次把语料规模直接干到了百亿token的量级过程中踩过的坑、推翻过好几次的设计决策我觉得很值得沉淀成一篇能给同行参考的实战笔记。这篇文章会完整讲清楚它的数据管线、检索增强方式、多智能体协作机制、回测与上线保护设计内容涉及大量真实操作层面的取舍和教训适合已经有一定NLP、大数据或量化基础、想认真做LLM金融落地的朋友。先说清楚这个agent的定位它不是一个替你一键下单的自动炒股机器人而是一个“投研决策增强系统”。它帮助研究员和基金经理完成信息收集、标的初筛、事件解读、风险预警这些环节最终给出结构化的分析和建议由人来拍板。我觉得这个定位很重要——如果一上来就追求全自动交易那风险和工程复杂度都不可控而且责任归属也很麻烦。下面我从架构聊起把整个系统的运转逻辑掰开揉碎地讲。1. 为什么我会选择“手搓”一个投资agent别误会这里说的“手搓”不是连分词器都自己写而是说整个应用层、数据层和调度框架都是基于自己的业务需求搭起来的没有直接套某个现成的“大模型应用开发框架”。做这个选择是在对比了好几条路线之后才定的我来说说当时的思考过程。第一通用RAG框架解决不了金融场景的时间敏感问题。普通问答型的RAG用户问一个问题系统检索相关文档拼进上下文然后吐一个答案这个链路对“今天涨了为什么”这种问题还行。但投资场景里的真实需求是跨时间窗口、跨多数据源的信息整合比如“最近三个交易日该标的基本面有没有发生边际变化”“这条新闻对哪些关联标的影响最大”这需要数据按时间片对齐、事件级别关联而不是简单地把一堆文档塞进Prompt。第二我们要面对的是百亿token级别的语料。这个量级意味着你不可能一次全塞进上下文哪怕模型上下文窗口做到几百万token也不现实。你真正需要的是把语料做好索引、切好分块、设计好召回策略让每次调用模型时只取其中最有价值的几十条片段。这其实是经典的“索引检索生成”架构问题而不是单纯靠模型能力就能绕过去的。第三也是最重要的一点金融场景必须可解释、可审计。模型根据什么数据得出这个结论这条结论对应的原文出处是什么在时间线上是否属于未来信息前视偏差这些都需要整个链路能回溯。用现成框架就像用黑盒出了问题你根本不知道是检索丢了数据还是模型自己编了个理由排查成本极高。自己控制链路每一步都能加日志、加校验、加人工检查点。所以最终决定大模型本身还是用成熟的开源底座但围绕它的数据加工、检索、多智能体调度、回测风控全部自己写。这样做的成本确实高但换来的是对系统每一环的绝对掌控后面排错和迭代都会轻松不少。2. 整体架构设计与关键取舍整个系统可以拆成六个核心模块数据采集与血缘管理、清洗与时间对齐、索引与存储、检索与重排、多智能体推理调度、回测与风控。这六个模块的依赖关系是单向递进的理解起来比较清晰。2.1 模块总览与核心依赖模块职责关键依赖数据采集与血缘管理对接行情、财报、公告、新闻、研报等数据流记录数据来源与版本数据提供商、抓取调度清洗与时间对齐去重、去噪、实体归一化、统一时区对齐到交易日历上一级原始库索引与存储分区存储原始数据同时产出倒排索引、向量索引、时序索引清洗结果检索与重排按检索条件从多索引中召回候选片段并用排序模型压缩数量索引层多智能体推理调度多个角色共享检索结果与中间结论最终生成决策建议检索层、大模型回测与风控检验决策逻辑的历史表现上线后持续监控异常时熔断全链路数据这里面最容易被人忽视的其实是血缘管理。你可能觉得“数据从哪来的有什么好管的”但在百亿token的工程里数据源升级、字段调整、质量修复都会导致你重新灌一遍语料没有版本管理你根本不知道当前线上跑的是哪一批数据回测结果也无法复现。2.2 多智能体的角色划分依据为什么这个系统不直接用一个Agent大包办我试过效果很差。因为投资决策链路里每个环节对能力的要求不一样有人需要严格的计算纪律有人需要广泛的语言理解有人需要保守的风险判断。把这些诉求塞进一个System Prompt里模型会在不同任务间互相干扰表现极不稳定。我最终把链路拆成了五个角色数据采集Agent负责监听新数据源事件发现新入库的公告、新闻、行情快照触发下游任务。因子计算Agent负责计算技术面、基本面相关指标对数据做严格数学处理输出标准化因子表。新闻解读Agent负责把一条新闻放到更长的时间上下文里解读判断情绪倾向、事件类型和对相关标的的潜在影响。风控Agent负责检查信号是否触碰了回撤限制、持仓集中度限制、波动率限制输出拒绝或警告。决策Agent负责汇总以上所有输出按权重和规则生成最终结构化决策建议供人类审核。每个角色用不同的System Prompt甚至可以用不同的模型规模和推理参数。因子计算Agent我甚至不用大模型直接用规则脚本替代因为数学计算用大模型属于自找麻烦。所以“多智能体”不等于“多个大模型聊天”准确说是“多个专业模块共享推理语境”其中有些模块是大模型有些则是传统程序。这是很多人误解的地方。2.3 为什么非要“检索增强”不可有朋友问我既然模型已经训练了那么多知识为什么不直接让它基于自己的记忆分析非要加检索我反问他你敢让一个研究员凭记忆报三年前的财报数据吗大概率数字是编的。大模型也存在同样的问题尤其是对细粒度的结构化数据它记不准也容易混淆不同年份的数据。检索增强的本质是把事实存储从模型参数中剥离出来放到一个可更新、可审计的外部数据库里。模型负责理解和推理数据库负责记忆事实。这样我们每次分析某个标的时可以直接拉取该标的最新财报、近期新闻、公告原文再让模型基于这些拉取到的内容做判断而不是让它去回忆“大概是这样”。我在实现上用的是“混合检索引用约束”的方案后面第四章会详细讲。这里先记住一个结论没有检索增强的投资agent就是空中楼阁它无法处理实时信息也无法为你提供可验证的推理依据。3. 数据基建百亿token语料是怎么从0落地的做投资agent模型选型、Prompt调优都是后话真正决定系统上限的是数据。我这次把语料推到百亿token这个量级过程中最痛苦的不是模型推理慢而是数据管道动不动就崩或者数据对不齐导致回测结果虚假得离谱。下面按环节说。3.1 多源数据接入与时间对齐系统涉及的原始数据主要分为五大类行情数据、财务报表、上市公司公告、新闻资讯、券商研报。每一类的更新频率、数据格式、时区体系都完全不同。比如行情数据是秒级甚至毫秒级公告和新闻是事件驱动发布财报则是季度级别的定期数据。最折磨人的就是时间对齐。新闻的“发布时间”和它影响的“业务时间”经常不一致。比如某公司晚上八点发公告直接影响第二天的开盘情绪那这条公告到底应该归属到哪一天如果按发布时间归属当天的行情已经收盘根本无法反映这个信息如果按下一个交易日归属那回测时就要把“信息产生时间”与“可交易时间”严格区分开。我们的做法是引入统一交易日历把所有事件都映射到一个“最早可知情时间”字段。这个字段用于回测时判定信息是否在当时已经被市场获得从而避免前视偏差。原始数据的原始时间戳也会完整保留绝不覆盖。这里我强烈建议所有做金融数据工程的朋友永远不要试图“修改”原始数据只能“新增”派生字段。因为一旦原始时间戳被污染整个数据集的审计价值归零。3.2 清洗、去重与分块策略原始数据里充斥着重复新闻、转载内容、模板化公告、无效字符。如果不清洗你检索的时候会召回几十条同一个事件的重复报道浪费宝贵的上下文窗口也让模型抓不住重点。新闻去重我用的是MinHashLSH方案先计算文本的SimHash指纹再通过局部敏感哈希把相似文本聚到一起保留最早、最完整的一篇作为主文档。这个方案对“同一条快讯被几十家媒体转载”的场景效果很好。分块策略也做了很长时间的调优。我最终的方案是按时间桶再按实体桶两级切分块大小控制在256到512 token之间相邻块之间重叠约32 token。为什么不直接按段落切因为金融文本里很多关键信息是分散在多个段落里的比如一个公告里“交易概述”在第一段“风险提示”在最后一段但两者在同一语境下。按固定窗口分块并加上少量重叠能比较好地保住局部语义的连续性。3.3 百亿token落地的分布式处理百亿token是什么概念按中文平均每token约1.5个汉字估算大概对应15亿汉字左右的语料量压缩成纯文本也有几十GB。这个量级单机处理会很尴尬分布式是必须的。我把处理流程抽成了三个Stage原始清洗、分块标准化、向量化入库。每个Stage都是独立的计算任务可以横向扩展。向量化阶段我用了一个开源的嵌入模型在8卡GPU集群上跑吞吐量大概能到每秒几百条文本。算个账你就知道为什么这个阶段要开集群如果一条文本约500 token百亿token就是200万条文档即使每秒处理300条单批也要跑接近两个小时。这还只是向量化前面还有分词、清洗、校验等多个阶段。所以整个pipeline必须支持增量处理和断点续跑否则每次新增数据都要全量重跑会崩溃的。这里有个小技巧每个文档入库时写入哈希指纹新增任务先比对指纹相同的直接跳过。这样如果某一批数据重复推送系统能自动幂等不会重复占存储。整套增量流程上线后数据延迟从原来的“全量更新需要两三天”压到了“新数据进入库到可被检索小于五分钟”。3.4 存储层选型存储层我拆成了三种索引协同工作倒排索引负责关键词精确匹配向量索引负责语义相似检索时序索引负责按时间范围聚合。你可能会问为什么不用一个全能的向量库搞定一切因为投资场景的查询经常是结构化的比如“某标的最近三天的所有公告”这种查询是纯粹的KV型过滤用向量索引去做完全是用牛刀杀鸡效率和准确率都不行。我的存储方案是原始文档放对象存储按日期和标的类型分区倒排索引单独建用于精确词匹配向量索引单独建用于语义召回元数据全部进宽表数据库用于结构化过滤。四者通过统一的文档ID关联。方案看起来笨但胜在每一层都能独立扩展且任何一个索引挂了都不影响其他模块运转。4. RAG检索系统让agent学会“有据可查”如果说数据基建是地基那检索系统就是整个agent的信息入口。检索系统做得不好模型再聪明也没用因为喂进去的上下文是脏的、偏的、过时的。这个模块我迭代的版本最多从最开始的纯关键词检索到后来的混合检索重排效果有质的提升。4.1 混合检索为什么单靠向量不够刚开始图省事只用了向量检索。测下来发现两个问题一是金融领域专有名词和缩写很多比如某个公司简称、某个行业术语在语义向量空间里经常匹配不到二是有些需要精确匹配的内容比如股票代码、报告期编号、公告编号用语义检索会召回一堆不相关的内容。后来改成“BM25倒排检索稠密向量检索”双通道两种召回结果合并后去重。为什么这个组合对金融有效因为倒排索引能确保“代码、名称、术语”这类精确信息一定被召回向量检索能兜住“语义改写、同义表达”这类模糊场景。比如用户写“盈利下滑”倒排可能搜不到什么但向量能把它和“净利润减少”“业绩不佳”等表述关联起来。双通道合并后召回数量还是太多需要做重排压缩。我用的方案是对候选片段打一个相关度分综合考量文本语义相似度、时间衰减、实体匹配度三个维度。时间衰减很重要否则一条两年前的旧新闻会跟一条昨天的快讯排在一起模型很容易被旧信息带偏。4.2 向量化模型选型与领域适配嵌入模型我对比过多个开源方案最终并没有选择参数最大的那个而是选了在中文金融语料上综合表现最稳的一个通用模型因为金融领域对“数字敏感性”要求很高纯通用模型在涉及数字比较、时间关系、否定语义的场景下容易出错的概率明显更大。测试中我专门构造了一个领域测试集包含三类问题数字比较类“某公司去年利润是否为正增长”、否定语义类“某公告是否构成业绩承诺”“某声明是否实质构成减持”、事件时序类“该增持计划是在回购之前还是之后”。前两类问题最能暴露模型和检索的缺陷。结果显示在加入检索后准确率明显提高但在否定语义上仍然有稳定比例的错误这个只能靠后续微调或者规则修正去补。百亿token语料本身就是做领域适配的好原料。我建议如果条件允许用这部分语料对嵌入模型做继续预训练或者对比学习微调效果会更好。但我们当时为了控成本选择先以通用模型垫底微调放到二期这个决定回溯来看是可以接受的——先把链路跑通再逐步优化瓶颈。4.3 引用约束与防幻觉设计防幻觉不能靠“叮嘱模型不要编”要靠约束机制。我的做法是为每一条检索结果附带一个引用ID并在Prompt里强约束模型的每一句事实性描述都必须附上引用ID没有引用支撑的内容必须明确标注为“推测”。同时生成的结果会经过一个引用校验器去核实每个引用ID是否真的存在于检索结果中如果模型用了不存在的引用ID该回复会被直接打回重写。金丝雀测试集是另一道防线。我每个季度会人工挑一批有明确答案的问题送入系统走全链路核对模型的输出是否引用了正确的数据源、是否给出了正确的结论。这项工作是纯人工的很费时间但它是整个系统质量的生命线。没有它你根本不知道系统上线后是变好了还是悄悄变坏了。5. 多智能体协作从情报到投资决策的完整链路系统最终产出的是一个结构化的决策建议这个建议不是一步到位的而是五个智能体接力协作的结果。让我具体讲讲它们之间是怎么配合的。5.1 智能体之间到底怎么沟通首先明确一点我没有让智能体之间用自然语言互相聊天。很多人一提到多智能体就想到A说一句B接一句这在投资场景里既慢又不可控。我采用的是“结构化消息共享黑板”机制。每个智能体完成后把输出写成一个JSON消息包含结构化字段、结论摘要、引用片段列表、置信度。决策Agent读取这些汇总消息而不是去读其他Agent的冗长分析原文。这样做的好处有三个第一是上下文占用低决策Agent不需要把所有分析原文都塞进来只需要读摘要第二是可调试每个Agent输出都是结构化的中间逻辑出了问题能快速定位到具体环节第三是可审计谁在什么时候得出了什么结论全部留痕。共享黑板机制则用于记录全局状态比如当前正在分析哪些标的、哪些结论已经被确认、哪些还在待复核。这样不同Agent不会重复检索相同的内容大幅节省了推理和数据查询的开销。5.2 事件驱动的主循环与任务调度系统不是“用户问一句答一句”的同步模式而是事件驱动的异步模式。核心事件循环可以简化为以下伪代码while True: event event_bus.next_event() if event.type NEW_DATA: tasks parse_data_event(event) for task in tasks: dispatcher.submit(task, roleFACTOR_WORKER) elif event.type FACTOR_DONE: res event.result if res.has_anomaly(): dispatcher.submit(res, roleNEWS_ANALYST) elif event.type ANALYSIS_DONE: dispatcher.submit(event.result, roleRISK_GUARD) elif event.type RISK_PASSED: dispatcher.submit(event.result, roleDECISION_MAKER, require_approvalTrue) elif event.type DECISION_PROPOSED: notify_human_approver(event.result)所有任务通过消息队列异步调度各角色可以并发执行。比如同时来了十条公告因子计算Agent可以并行处理多条新闻解读Agent也不必等前一条完全结束才启动。这里有个工程细节模型推理是最耗时的部分所以凡是不需要大模型的环节比如因子计算尽量走普通计算只有到新闻解读、决策汇总等真正需要语义理解的地方才调用大模型这样能省很大一笔推理成本。5.3 人工审批与权限设计再说说人工审批这个落地层面的关键设计。当决策Agent输出一个带有方向性操作信号的建议时系统并不会直接执行而是进入一个人工审批队列。审批界面展示的内容包括信号摘要、置信度、检索引用的原文列表、相关历史相似信号的回测统计结果。审批人只需要做三个动作同意、拒绝、退回补充分析。权限设计上也做了区分不同级别的信号需要不同权限审批。比如“信息提示”级别可以自动推送到研究员的仪表盘“交易建议”级别必须由具备相应权限的投资经理审批“涉及集中度突破”这样的高风险信号则需要风控负责人二次审批。这种分级机制保证了系统在高效率的同时不会因为无人把关而失控。6. 回测体系、上线监控与那些踩过的坑系统光能跑通还远远不够你必须有一个可靠的回测体系去验证它的历史表现同时有一套上线后的监控与熔断机制来保证它不会在实盘中惹出大祸。这一块可以说是整个项目中“含金量”最高的部分也是我踩坑最密集的地方。6.1 基于事件驱动回测的投资场景传统的回测框架大多以交易日为单位按收盘价/开盘价计算交易结果这在量价策略里够用。但要验证一个Agent的决策链路这种框架远远不够因为Agent的决策是事件驱动的数据什么时候到达、什么时候被处理、什么时候模型做判断这些都要精确模拟。我最终搭建了一个事件驱动回测引擎按时间顺序回放历史事件流每个事件进入系统后走和线上完全相同的处理链路然后记录决策信号及其之后一段时间的表现。回测过程中最核心的校验就是前视偏差某个信号在回测中被触发时用到的所有数据必须在该信号触发时间之前就已公开。我在这里吃过一次大亏。早期回测数据显示系统信号准确率高得惊人后来排查发现是公告数据在入库时被打上了“财报报告期”的时间戳而不是“公告发布日期”的时间戳。结果就是2024年的一季报被当成2024年一季度初就已知晓的数据参与计算相当于提前几个月“预知”了财报。那次教训让我彻底确立了“原始时间戳永久保留其他字段只能新增派生”的数据铁律。6.2 上线后的监控与熔断机制系统上线后我设置了四个关键监控指标推理延迟、检索命中率、空结果率、人工审批拒绝率。这四个指标各有意义推理延迟反映系统负载和模型推理性能检索命中率反映数据管线和检索质量命中率突降通常意味着索引挂了或者数据断更空结果率则反映检索召回量是否合理长期为0说明检索策略过于严格人工审批拒绝率是最重要的指标它直接反映模型输出与人类专家判断的偏离程度拒绝率突然飙高说明系统某个环节在恶化。熔断机制分三档软件熔断、策略熔断、人工熔断。软件熔断是当推理延迟或错误率超过阈值时系统自动减少任务并发量策略熔断是当模拟盘或小资金实盘的当日回撤超过设定阈值时系统自动进入只读模式只输出分析不再更新交易建议人工熔断则是任何一个具备权限的成员都可以一键停掉整个Agent的自动决策链路。我强烈建议任何做AI决策系统的团队都要把人工熔断放在最高优先级因为再完备的自动化也会遇到意想不到的情况最终兜底的必须是人。6.3 关于数据质量、评估指标的几点血泪经验最后再分享几个我反复踩过的坑希望后来者能一次避开。第一评估一个投资agent不要只看收益率。收益率只是结果而且受市场环境影响极大。我后来构建了一套多维评估体系信号准确率、决策稳定度、最大回撤、可解释性评分、引用正确率。这五个维度放在一起看才能比较全面地判断Agent是不是真的在“正确地工作”。第二不要试图用一个全能的评估集去覆盖所有场景。我早期把几千条历史样本混合做评测结果模型在某些类上表现好、某些类上很差但混合分数看起来还凑合。后来改成按事件类型分层评估比如“财报类”“公告类”“新闻类”“宏观类”各自单独出报告问题才暴露出来。分层评估的额外好处是你可以针对最差的部分单独做数据补充和Prompt优化。第三也是我觉得最值得强调的一点不要一头扎进全自动。我第一次搭建这个系统的目标曾经是全流程无人化结果在开发周期上付出了巨大代价。后来把目标改成“人机协同”——机器负责信息收集和初步分析人负责最终判断整个项目才真正跑通。与其追求一个完美但迟迟无法落地的“终极形态”不如先把“辅助工具”做得足够好用、足够可靠。这个投资agent做到现在我最大的体会是最重的不是模型能力而是数据质量和评估体系。大模型技术在飞速迭代但如果没有干净、可信、可追溯的数据底座再强的模型也会在真实场景里摔跤回测和上线监控不是可选的加分项而是整个系统的安全底线。如果你也想做类似的东西我的建议是别想着一步到位把单个任务助手先跑通比如只做新闻情绪分析、只做财报异常扫描再逐步扩展成多角色协同。投资决策的最终责任始终要由人来承担agent的角色是帮你把信息处理得更快、更准、更完整。这个定位想清楚了后面所有的技术取舍都会顺很多。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑