手搓百亿token投资分析Agent:数据管道与检索增强的完整实战
如果你也在做 AI 应用落地大概见过不少“大模型跑个对话就上线”的玩法。这套东西刚起步的时候即使是小白也能快速搭出聊天机器人可一旦牵扯到垂直行业尤其是投资分析这种对准确性、时效性、可追溯性要求极高的场景事情就没那么简单了。今天这篇不是讲概念而是完整复盘我一个人手搓的一套投资分析 agent它背后的语料库累计超过了百亿 token覆盖财报、研报、公告、宏观纪要、新闻信源。这个过程里踩过的坑、拆过的组件、调过的参数我都会尽量原样摊开来讲。这个 agent 能做什么呢输入一个公司或行业问题它能自动检索历史资料、拆解问题、多模块分析、核验证据最后生成带引用编号的分析结论。它适合谁参考如果你手里有大量非结构化的行业文本想用大模型把资料盘活或者想从一个纯调用 API 的“提示词工程师”变成会设计检索框架、编排任务、治理数据的 AI 应用开发者这篇内容会很有用。1. 为什么手搓一个百亿token级别的投资agent1.1 百亿token到底是个什么量级很多人看“百亿token”没什么概念。我先给个参照一份正常财报大概 3000 到 8000 token一篇深度研报大概是 10000 到 30000 token。如果把全市场主要的上市公司公告、财报、研报、宏观日报、行业纪要都收集起来按十年维度累计几百亿 token 是很正常的量级。这里面真正的难点不是存储而是整理。原始文件是 PDF、HTML、图片、扫描件、表格混在一起的格式混乱OCR 误差年报里有大量重复的附注和模板套话公告编号不一致。单纯把文本灌进模型毫无意义——模型读不懂版面结构也没法理解时间顺序更不知道什么是“对这个问题有用的段落”。当时我的目标很简单所有历史语料必须能支持秒级检索检索结果必须能够回答用户问题任何结论必须有原文出处。要达到这个目标就不能把所有文本一股脑塞进上下文窗口得先把它变成结构化的索引。1.2 现成工具解决不了什么问题现在市面上不是没有投资分析工具也不是没有大模型辅助研究的产品。但实际用下来会发现一个问题它们大多是黑盒查不到细节也没法按你的思路定制。举个例子市面上常见的“智能问答”工具你问它“某公司去年的经营现金流为什么下滑”它可能给你一段很流利的回答但你追查关键数字的时候发现它把去年三季报的某个数据和年报的数据混在一起了。这才是投资场景中最致命的问题。另一个现实问题是数据权限和合规性。很多第三方工具自带数据源但你不知道它背后的信源是什么也无法保证数据更新的准确时间点。投资分析最怕的就是用不可追溯的信息做决策。所以我的选择是“手搓”——自己掌握数据管道、检索逻辑和各模块配置把黑盒变成白盒。这才是我愿意投入这么大精力做全套系统的核心原因。提示如果你只是想快速验证想法用现成工具完全没问题。但如果你要做长期、定期、自动化的分析任务并且对输出有强溯源要求那自建数据管道和检索层基本是绕不开的。2. 整体架构数据、知识、决策三层闭环2.1 数据层从原始资料到统一语料整个系统先解决的是“把杂乱的文本变成可用的语料”。数据源包括历史财报、券商研报、上市公司公告、新闻资讯、宏观数据汇总、会议纪要等。这些数据来源的格式差异非常大。我搭了一个数据管道分下面几步格式归一化代码把所有文件转换成统一文本格式。扫描件走 OCRPDF 提取时保留标题层级和表格结构。这一步很关键如果表格被拆散后面所有财务计算都会出错。去重与正文提取一份公告在三个新闻源里重复出现只保留原始来源和唯一编号。对公告和新闻还要做正文提取去掉页眉页脚、导航栏、相关推荐等信息。元数据标注每个文本片段打上“公司代码、公告日期、公告类型、文件来源、页码”等标签。更新机制增量更新定期跑同步任务。因为投资分析对时效性敏感过期数据不能混在最新语料里。这套数据管道跑起来之后入库的文本量才勉强达到“百亿 token”这个级别。可以说没有这一步后面的知识层和决策层都无从谈起。2.2 知识层索引、向量化与检索增强知识层是连接数据和模型的中间层。如果数据层是仓库知识层就是仓库的目录系统。我用两种索引方式并存一种是传统的倒排索引用于精确匹配关键词比如公司简称、财报科目、人名、地名、产品名、代码。这种索引特别适合处理交易代码、股票简称这种不适合向量化的高频词。另一种是向量索引把文本切块后通过嵌入模型转成高维向量用于语义召回。这样一来即使查询词和原文没有完全相同的表达也能找到语义上相关的内容。最终检索采用混合模式先用关键词索引做粗筛再用向量索引做语义排序最后用一个轻量的精排模型把结果重新排序。这套模式在投资领域的普适性很高也是我在多次调优后确定下来的。2.3 决策层多模块协作与工具调用知识和数据都有了接下来是让模型“干实事”。决策层我做了四个角色模块规划器负责拆解用户问题判断需要哪些信息需要检索几次是否要多轮才能完成分析。检索助理调用知识层的接口把粗检索结果收集起来再根据任务需要补充额外数据。分析模块负责读检索结果结合推理形成观点和结论。审查模块重点核验引用编号是否真实存在于知识库结论和原文是否一致有没有明显的信息断层或过度推测。这种多模块协作的好处是职责清晰。比如“检索助理”不负责写结论“分析模块”不直接查库出了问题排查逻辑链路时很快就能定位到具体环节。如果没有这种分层只是让一个大模型自由发挥它很容易把检索到的内容和自己的记忆混在一起产生幻觉。3. 手搓过程中的关键实现细节3.1 文档切分与向量化策略把文档切成块是决定检索质量的基础。切得太短上下文不足切得太长语义被稀释粗暴按固定长度切会把财报中“营业收入”和后面的数字拆散。我采用的方案是“标题感知切分”先解析文档结构保留章节标题按章节边界切分段落特别长时再按语义段或句子组进一步切分。核心是保留上下文连续性。当时写了一个分段函数大致逻辑是这样def smart_split(text, max_chars800, min_chars200): sections split_by_heading(text) # 按 Markdown 标题级别拆分 chunks [] for section in sections: # 保护表格块先拆成“标题 表格”结构 tables extract_tables(section) if tables: for t in tables: chunks.append(header table_text(t)) else: split_paragraphs(section, max_chars, min_chars, chunks) return chunks真实实现里还会判断句子边界、表格行数、数字完整性。切块后我对每个块做了元数据校验比如某一段引用的财务数据必须能对应到同一家公司防止跨公司文本混切。这一步听起来琐碎但直接决定了后面检索的精度。3.2 混合检索与精排怎么调才能准投资领域的问题有一个特点查询词往往是实体词为主比如“某某公司”“2023年报”“ROE”“现金流”。这类词用纯向量检索容易出偏差因为模型可能在语义上匹配了“资本回报率”这句话但漏掉了精确的“ROE”缩写。用混合检索就互补。我实际用的方案是第一轮召回倒排索引做关键词匹配向量索引做语义匹配两者取并集。每类取前 50 条合计约 100 条候选。第二轮精排用重排序模型对候选结果打分这个模型要能理解“问题和文本段落的相关性”。对投资场景我会额外加上时间衰减权重同样内容越新的资料得分越高财报期刚出的快报优于一份几个月前的深度研报。调优时的经验是不要只依赖离线评测集。我每两周会人工检查 50 条检索结果看看排名靠前的片段是不是真的能回答问题。有很多问题是评测集里发现不了的比如“相关但缺乏关键数据”的片段评分很高但实际没法支撑结论。这种情况单纯调模型是解决不了的需要在数据的净化和标注上下功夫。3.3 提示词约束与引用溯源投资agent不能像普通聊天助手那样随意联想。我在分析模块的提示词里明确写了三条硬规则输出必须包含引用编号编号格式为“来源[1][2][3]”每个结论必须对应至少一个引用如果检索材料不像结论必须明确标注“数据不足”禁止在没有材料支撑的情况下推测具体公司未来业绩的绝对值唯一例外是对行业背景、宏观常识的描述即便如此也会标注“通用背景无特定来源”。为了让这条可执行审查模块会逐条把引用编号映射回知识库检查引用编号对应的文本是否真的存在再比对内容和结论的关系。如果一个结论引用了“某公司上半年营收同比增长 10%”但检索引用的文本里根本没有“10%”这个数字审查模块就会打回重写。这个环节不依赖大模型自觉而是靠后处理代码校验。可以说没有审查模块这套系统不敢投入实际使用。3.4 评估集与回归测试不靠感觉调参手搓系统的另一个麻烦是改动不可控。今天优化了切分逻辑可能明天检索质量就下降了。所以必须建评估集。我的做法是准备 200 个投资相关的问题覆盖财务指标、行业竞争、公告解读、宏观政策等类型。每个问题配一个“预期答案”和“验证点”。什么时候跑评估呢每次改完代码、更新完模型、调整完提示词都跑一遍。几个关键指标我固定统计引用通过率检索结果中的引用是否真实存在且能支撑答案事实准确性关键数字是否与原文完全一致信息完整性是否漏掉重要的财务科目或事件时效性使用了过期的文本片段会被扣分有了这套回归机制我才能放心迭代。不然就是在沙滩上盖房子今天看着没问题明天可能倒了重来。4. 运行中遇到的典型问题与排查记录4.1 数据时效性导致引用过期第一次碰到这个坑是某公司发年报前系统回答问题时仍然引用旧年报数据。原因很直接数据管道增量更新没把最新年报的解析结果替换旧的。旧文档还在检索集里新的资料虽然上传了但权重没调。解决办法是给每个检索块增加“发布时间”字段并在检索时加一个“信息截止时间”参数。用户提问时默认使用当前时间系统只检索“早于等于当前时间且距离最近”的资料。旧年报和新年报同时存在时时间权重也会把新年报排到更前面。这个策略后来还被用在了公告解读上公司出了公告旧的深度研报不会消失但它不再作为主要信源。4.2 检索召回一堆噪音怎么收敛另一个常见问题是检索结果飘。比如问“某某公司的毛利率变化”结果召回了关于行业整体毛利率的研报、竞争对手的报表分析、十年前的老新闻。召回很全但排在前面的全是噪音。我排查后发现问题出在切分块过长。一份研报几万字切分块如果包含“行业分析”“公司分析”“风险提示”等多个章节向量化的时候语义互相干扰整个块变得“什么都像什么都不像”。修复方式是细化切分粒度尽量让每个块围绕一个具体主题。同时给检索接口加重排序分阈值宁可结果少一点也不要塞进一堆无关段落。少而精比大而全重要——因为分析模块一旦看到一堆不相关内容很容易被带偏。4.3 token用量和延迟失控百亿token不可能全灌进大模型。就算能灌进来时间和钱也不允许。我一开始的设计是有状态的对话模式每轮把历史摘要和检索结果一起传给模型。跑了一段时间发现复杂问题的累计上下文很容易超过几万 token响应时间直奔几十秒成本也飙高了。后来我做了两件事第一把多轮对话压缩成“简洁的已解决问题摘要”不再保留原始消息历史。对投资分析而言历史对话的价值不大最终结论才重要。第二把一些常见问题做成预计算缓存。比如“某公司过去五年的营业收入、净利润、经营性现金流”这类统计型问题直接用数据管道生成固定格式答案。只有复杂开放性问题才走大模型分析流程。这样高峰期延迟从几十秒降到了几秒内。4.4 输出有幻觉审查环节怎么兜底幻觉是这类的系统的无解难题尤其是投资场景绝不能靠提示词洗脑。我遇到过的情况是分析模块把 A 公司的财报数据当成 B 公司的或者把三年前的数据说成最新的。这种情况即使有检索材料模型还是会生成看似合理的错误结果。真正有效的兜底是强校验。审查模块不只是检查引用编号是否存在还会做类型层面的校验如果引用的文本是“某公司 2022 年年报”就不能在结论里写“2023 年”如果原文只提到“营收同比增长”就不能扩展出“净利润增长率”如果原文没有提到具体数字结论就不能出现具体数字这些规则看起来死板但确实有效。允许模型发挥想象力的场景很多但投资分析不在其中。对我来说宁可让系统说“信息不足无法判断”也绝不让它编造。5. 成本控制、性能优化与后续扩展5.1 分批处理与缓存战略百亿token级别的处理不可能一蹴而就。我的做法是把整体语料库按时间、公司、文档类型分批处理。每晚跑增量任务错峰引入新数据。导入的时候先做低成本的文本校验再考虑是否更新向量索引没有变化的文档直接跳过不重复向量化。缓存策略也是控制成本的关键。相同公司、相同格式、类似时间范围的问题答案模式高度重复。我把这些统一用模板生成不重复调用大模型。一次完整的财报分析真正需要大模型做开放推理的部分不到总查询量的三成。省下来的费用都花在了最有价值的问题上。5.2 模型分级路由与弹性调度复杂问题用大模型简单问题用轻量模型。听起来像废话但真正做到精细化调度才是节省资源的关键。我在调度层设置了一个路由规则问题先经过分类器判断任务复杂度再分配模型。比如“提取某公司最近一期研发费用”属于信息提取型直接走轻量模型而“评估某公司竞争壁垒”属于推理分析型走更强的大模型。即便是大模型我也会根据 token 量和上下文长度动态选择不同的配置。这种弹性调度也会在高峰期做队列。如果任务量突增把低优先级任务降级为异步处理保证实时任务不排队。刚开始我以为投资分析都是实时问答后来发现很多任务是固定的日报、周报生成完全可以在深夜批跑。把在线和离线任务分开系统的稳定性和成本都会明显改善。5.3 后续可以往哪个方向扩展目前这套系统已经能稳定覆盖公司分析、行业对比、公告解读、财报复盘几类任务。我自己计划中的下一步有三个方向第一个是知识图谱的接入。目前检索结果还是文档片段如果能把实体和关系抽出来形成结构化网络分析模块在做公司间对比时会更有逻辑性。比如“供应商客户关系”“股权结构变化”“行业上下游”这些内容图谱比文本块更好用。第二个是带业务逻辑的回测管道。让 agent 在产出分析结论后自动拉到历史数据做验证比如“如果按结论事件发生后的实际走势判断当时的逻辑是否正确”。这能让系统自我迭代而不只是文本层面的报告生成。第三个是多语种支持。海外资料、英文公告、外资行研报全部纳入后语料量可能从百亿token直接翻倍。届时数据管道和检索策略都需要重新设计但这也意味着系统的覆盖面和适用场景会明显扩大。最后说几点我的真实体会这套系统从零开始到能稳定输出带引用、可核验的投资分析内容前后经历了很长的摸索期。最开始我也迷信大模型的能力觉得“只要模型够强什么都能搞定”。真正跑下来才发现在垂直领域数据治理、检索质量、校验机制和成本控制远比模型参数重要。模型只是一个聪明的同事你得给它可靠的工具和清晰的工作流程。如果让我给后来者一个建议那就是不要急于追求“大而全”。先把一小块数据治理干净跑通一个垂直场景的闭环再逐步扩大到“百亿token”的规模。每一步都要有评测指标才能避免无效迭代。另一个很有用的经验是把系统设计成“可解释”的。我保留了每一次检索的原始片段、每一次分析的时间线和最终结果的所有记录。出现错误时能回溯到具体环节效率提升很多。这种可解释性在投资这类容错率低的行业里比模型精度更重要。最后不管系统做到什么程度都要清楚一点AI 分析工具是辅助研究的手段任何结论都需要人工复核。这也是我在设计审查模块时最坚持的原则。工具可以帮助我们提升效率但决策的责任始终在人身上。