资讯动态

企业研报Agent实战:从架构选型到知识库构建与并发治理

发布时间:2026/10/2 5:23:57 来源:尧图企业网站定制
今年上半年我一直在做企业研报分析Agent的开发目前这套系统已经在团队内部跑了几个月稳定处理了上万份研报和投研纪要。今天想把整个实战过程沉淀下来从架构选型到知识库构建再到并发治理和安全合规完整串一遍。这套方案不一定是最优解但每一步都是真金白银踩出来的希望能给正在做类似项目的同学一些参照。1. 企业研报agent的核心拆解与架构抉择1.1 研报场景的“四段式”能力拆解先说清楚企业研报Agent到底要干什么。研报这个场景和通用问答机器人有本质区别它面对的是高密度、强结构、含大量数据和结论的文档用户要的不是“帮我总结一下”而是“在1000份研报里找到所有看好某赛道的核心论点并给出证据链”。所以我没有一上来就想“做一个聪明的Agent”而是先把任务拆成了四段采集也就是接入。研报来自不同的数据源有的是PDF文件有的是网页链接有的是内部的知识库文档。解析把非结构化的PDF、表格、图表转成结构化文本。这一步是整个链路里最苦、最容易翻车的环节。推理也就是大模型发挥作用的地方包括按照给定的分析框架抽取信息、归纳观点、形成结论。输出把分析结果整理成报告、表格或者带引用的列表供投研人员直接使用。每一步对应一组独立的模块模块之间通过明确的输入输出协议衔接。这样做的好处非常直接任何一环出了问题我都能定位到具体函数而不是跟着一个“黑盒Agent”瞎猜。1.2 为什么是“串行主流程并行子任务”的混合架构架构选型上我见过很多团队一上来就搞多Agent自由对话让几个Agent互相配合、互相调用。听起来很酷实际跑起来却经常让你崩溃对话链稍长就上下文混乱A说B的活儿B又推给C最后谁也没干活。我的选择是串行主流程加并行子任务的混合架构。主流程是一条清晰的管线采集 → 解析 → 分块 → 检索 → 推理 → 输出每一步都必须等前置节点完成。但在“推理”这个节点内部可以按主题拆出多个并行子任务比如同时分析“行业趋势”“财务数据”“风险因素”三个方向各自独立跑最后再汇总。这么做有三个实在的理由成本可控。纯多Agent自由对话每轮回复都会携带大量历史上下文Token消耗成倍增长。而串行管线里每个大模型调用只接收自己需要的那一部分文本。结果稳定。研报分析是严肃任务不能容忍今天给A结论、明天给B结论。固定流程保证每次执行逻辑一致。可观测。每一步都留了运行日志和中间结果出现问题可以精确摘出来单独调试。1.3 技术栈初选我当时的技术栈选型如下供参考环节选型说明应用框架Python FastAPI团队熟悉度高异步支持好编排层LangGraph显式图结构节点可重用文档解析PyMuPDF pdfplumber文本和表格分别处理向量库Milvus支持大规模检索部署成熟嵌入模型bge-m3中文场景表现稳定大模型内部部署的Qwen系列兼顾效果和数据安全任务队列Redis Stream Celery处理异步长任务这个选型经历过一次大的调整核心决策在下一部分细说。2. 框架选型为什么最终选了基于“图编排”的方案2.1 主流Agent框架的横向对比Agent框架这个词这两年是被炒得最狠的词。我在调研阶段对比过几类主流框架一类是偏对话流的适合构建聊天Bot但在复杂工作流面前表达能力不足另一类是偏编排的可以定义工具调用和多步逻辑但写起来像在写配置文件还有一类就是基于图编排的把整个任务拆成节点和边。对比下来我倾向于图编排方案因为它和企业研报这种“流程确定性高”的场景最匹配。研报分析虽然有推理和灵活性但骨架永远是固定的先读后析、先析后报。图结构天然适合表达这种逻辑。在具体选型时我评估了LangGraph、CrewAI、AutoGen还有Java生态里的Spring AI。评价如下框架优势短板适用场景LangGraph图结构清晰支持循环、条件分支可序列化学习曲线陡峭中文资料少复杂工作流、需要精细控制的场景CrewAI上手快多角色概念好用复杂逻辑难表达自定义自由度受限中小型任务、快速原型AutoGen多Agent会话能力强群体对话容易失控调试成本高研究性质、探索性任务Spring AIJava生态衔接好Agent编排能力相对基础Java技术栈为主的企业2.2 从“流程图思维”到“状态机思维”用图编排框架之后最大的思维转变是不要再想“这个Agent下一步该干嘛”而是想“当前这个节点执行完后系统处于什么状态下一条边该通向哪里”。举一个实际例子。研报分析中常见的“表格数据抽取失败”问题。如果只有“解析”和“推理”两个节点解析失败了怎么办流程图思维会想重试解析。但状态机思维会多想几步如果重试两次还是失败是该终止任务还是降级为“保留原文供人查看”我在LangGraph里给解析节点加了条件边文本提取成功就走“结构化抽取”表格提取失败但文本OK就走“仅文本分析”两者都失败才走“人工介入”。这三分支让整个流程具备了从容的容错能力而不是一个节点出错整条管线崩溃。2.3 DSL编排与代码编排之争还有一次比较有意思的讨论是关于用DSL领域专用语言编排还是直接把流程写成代码。团队里有同事主张用声明式配置觉得非技术人员也能改流程。但我坚持用代码编排。原因很简单研报分析流程链路长、涉及分支多DSL能表达的场景有限一旦遇到“需要嵌套循环、条件组合、动态工具调用”的情况配置文件会变成比代码还难读的天书。代码编排的最大优势是你可以用任何Python库来增强逻辑比如在提取节点里写正则在重排节点里调API在输出节点里渲染模板。这个自由度在项目后期非常重要因为需求永远在变框架减负但不等同于替你决策。3. 研报解析与知识库构建从头到尾的实操记录3.1 PDF解析第一个硬骨头如果让我给这套系统里最难的部分排个序PDF解析当之无愧排第一。市面上研报大量是PDF格式排版复杂双栏、页眉页脚、表格嵌套、图片截断各种情况都有。我先说一下翻过车的方案早期直接用某个PDF转文本库一把梭数据抽出来的文本顺序错乱表格内容混在正文里模型读完直接胡说。后面改成组合方案PyMuPDF负责提取正文文本按坐标信息剔除页眉页脚再定位表格区域pdfplumber负责识别表格结构把行列坐标转成Markdown表格。这个组合方案实测能把大多数研报的文本准确率提升到95%以上。但说实话剩下5%的疑难杂症依然得靠规则兜底。我写了一个后处理函数专门扫描抽出文本中连续数字比例异常的段落自动判定为疑似表格重新走表格解析通道。实操中还有一个小细节字符编码和字体嵌入问题。有些扫描版PDF连文本层都没有怎么解析都不行。遇到这种文件我的处理是直接标注为“需人工处理”并跳过不在这个环节死磕。3.2 分块不是“按字数切”而是“按语义切”文档解析完成之后下一个关键步骤是分块。一开始我也想偷懒按固定字数比如500字、800字切成小块结果检索效果稀碎。为什么因为研报里的一个完整论点经常跨越好几个段落硬切会把“因为所以”这种逻辑链拦腰截断。后来我改成了“标题层级锚点切分法”先解析出研报的标题层级比如一级标题、二级标题、三级标题然后按标题把全文切成一棵结构化树。正文足够长时再按段落进行子切分。每个分块干这样三件事记录它在原文中的页码范围、它的标题路径、它的正文内容。分块长度我最终定在1500字左右重叠区间150字。选这个值不是因为某个算法告诉我而是因为实测下来太短500字检索到的上下文信息密度不够太长3000字调用模型时容易把不相关内容带入口。1500字大概能覆盖研报中一个完整分析模块的内容。3.3 检索增强召回与重排的具体参数知识库这一块我最终用Milvus存储向量用bge-m3做嵌入。这里要提醒一个容易忽略的点嵌入模型的中文长文档能力参差不齐。bge-m3在中文长文本场景表现算稳定但要注意它按token计算成本分块过长会明显影响检索速度。检索参数我调过一次之后就基本稳定了召回阶段取top_k20召回后加一轮重排再取top_k5作为最终上下文。为什么要加重排因为向量相似度不等于内容相关性有些语义相近但主题偏离的块在第一轮会把真正关键的内容挤掉。重排模型能结合问题和文本的细致匹配明显提升最终引用内容的准确性。针对研报场景我还加了两个特殊检索器一个是“同报告内检索”专门在某一篇研报内部做相关性召回用于回答“这篇报告里怎么说”另一个是“跨报告聚合检索”用于回答“多份报告里的共识观点是什么”。这两种检索策略对投研类问题的命中率差异很大建议大家不要只用单一检索器。4. 企业落地里绕不开的并发、记忆与安全4.1 并发治理用信号量给大模型调用“限流”Agent开发的经典戏码是本地单测跑得好好的一上生产就被并发打死。这里有两层并发要处理一是大模型API的并发二是任务执行框架的并发。对API调用我直接用了信号量Semaphore做并发上限控制。团队部署的Qwen模型推理服务实测稳定并发大约在5到8路超过就会出现排队和超时。我设定成5路并发另有令牌桶做平滑。理由并发太低喂不饱业务太高容易把推理服务打崩宁肯让任务排队也不能让服务雪崩。对任务队列我用Redis Stream加Celery实现了异步执行。研报分析是大任务单篇解析加推理动辄几十秒同步请求完全不可行。异步之后前端只需要拿到任务ID后端完成后再回调通知。重试策略用指数退避加随机抖动第一次失败等5秒重试第二次等20秒第三次等70秒最多四次。这样既不会疯狂重试打爆服务也不会在瞬时故障时直接放弃任务。另外还有一层缓存容易被忽视。大模型调用结果、文档解析结果、甚至嵌入向量都应该缓存。同一份研报不会只被分析一次命中缓存能省下一大块成本和时间。4.2 记忆管理会话记忆、任务记忆、知识记忆要分开很多人问Agent怎么做记忆我的回答是先分清你要哪种记忆。会话记忆用来记住用户在当前对话里说过什么比如用户想看的行业、关心的指标。这个短用Redis存个TTL几小时的缓存就够了。任务记忆用来记录当前这个分析任务进行到哪一步、中间结果是什么。这个结构化为JSON存在任务队列上下文中。知识记忆也就是整个知识库。它不随对话变化属于长期沉淀资产存在向量库里周期性更新。最忌讳的做法是把所有记忆都往上下文窗口里塞。有同事试过把历史对话全部拼进Prompt结果上下文窗口越撑越满Token费用飙升模型响应越来越慢甚至出现“走神”。正确做法是会话记忆只保留摘要任务记忆精确记录状态知识记忆靠检索按需取用。4.3 安全合规数据权限、内容闸门与审计日志企业级Agent和玩具Demo最大的区别就在于安全。投研数据通常属于高敏感数据不能在合规上有半分含糊。数据权限这块我在文件入库阶段就打标签哪些研报属于公开资料哪些属于内部付费数据哪些属于客户私有文档。检索阶段做权限过滤确保A部门的Agent检索不到B部门的数据。这个不能只靠向量库的collection隔离用户和租户维度必须在应用层强制校验。内容闸门是第二个关键设计。大模型输出不一定安全可靠研报又是严肃内容我在输出层加了一道过滤检测是否存在关键财务数据的幻觉表述有没有超出分析范围的断言。比如模型说“该公司Q3营收将增长30%”而原文根本没有这个数据闸门就会拦截并改为提示“原文未提供该数据”。审计日志更不能少。每个查询、每次模型调用甚至每一次检索命中都记录在案。出现合规问题时能追溯“是谁在什么时间问了什么模型答了什么引用了哪些源文档”。这套日志体系虽然平时看着没什么用真正出问题的时候能救命。5. 常见问题排查实录与避坑总结5.1 六个高频问题与排查思路对照表做了几个月系统小问题层出不穷这里把我的排查清单直接放出来遇到相似的可以照着走一遍现象核心原因排查顺序文档解析进度卡住不更新任务队列积压或解析线程卡死先看队列长度再看解析函数是否有没有设置超时的大循环Agent输出“循环”话题不停止条件边判断不收敛检查LangGraph图是否有环条件函数是否在某组参数下反复走同一条边上下文爆掉Token超限分块太大或承接太多历史检查检索阶段传入的chunk数量压缩固定系统提示词API频繁报限流错误并发设置高于服务上限查看服务端日志确认限流阈值调低信号量并发度并加缓存模型引用不存在的研报内容检索召回不准或幻觉先排除“源文档本身没有该信息”再查重排结果是否把无关内容送进上下文同一条边执行多次、结果不稳定缺少记忆或状态管理检查任务记忆是否完整节点间传参是否有默认值覆盖真实结果这些问题的共同规律是绝大多数不是大模型不行而是工程链路里某一环没做扎实。Agent开发里模型占的比例真没想象中那么高外围工程是一整套更琐碎的活儿。5.2 三个值得长期坚持的工程习惯最后分享三个我吃了亏换来的习惯。第一个习惯是每个节点都必须可重试、可跳过。研报Agent里有太多外部依赖文件服务、模型API、向量库任何一个都可能瞬时抖动。如果不设计好重试和降级策略线上任务就会像多米诺骨牌一样依次失败。第二个习惯是输出必须带证据链。企业内部用户不是来娱乐的他们需要能点击查看“你说这个观点来自哪篇研报的哪一页”。我在输出格式里强制要求每个关键结论携带引用来源没有来源的结论宁可不给。这既是增信任也是防幻觉。第三个习惯是用最小成本模型先跑通闭环再优化效果。很多团队一上来就上最贵最强的模型结果发现流程有硬伤几十万Token白白烧掉。我是先用小模型能跑通全流程卡住的地方逐个解决最后再替换成大模型微调效果。这个顺序极大节约了试错成本。企业研报Agent开发不是一个“调通模型”的活而是一个“搭建系统工程”的活。如果这篇总结对正在做类似事情的你有一点启发那我就没白写。项目还在迭代后面如果有了新的尝试比如多模态图表分析、时序预测之类的扩展我再来续这篇。

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

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

免费获取报价 →
↑