单人做 RAG 时,一个问题往往是一条链路走到底;换成多智能体,问题就变成「谁来检索、谁来写、谁来查错、谁来决定收工」。这篇不讲协议兼容和客户端怎么配,只讲工程落地:角色怎么拆、状态怎么传、什么情况下别用多智能体,以及一条从最小版跑通的顺序。
单人做 RAG,一条链路走到底是常态:问题进来,检索一次,拼上下文,模型出答案。换成多智能体,麻烦不再只是「检索准不准」,而是「谁来检索、谁来写、谁来查错、谁来决定收工」这四件事各自归谁管。管不好,延迟翻倍、排错靠猜。
这篇只讲工程落地:角色按什么边界拆、状态怎么传、循环怎么收口、成本怎么拴住,最后给一条从最小版跑通的顺序。协议兼容和客户端怎么配不在讨论范围,那是另一个话题。
先判断要不要上多智能体
很多团队一上来就画四个框连成环,结果发现原始那条单链路本来就能答对。这种情况下多智能体不会让答案变好,只会让延迟和排错成本翻倍。先花半天做减法判断,比直接开写省事得多。
| 场景特征 | 建议 |
|---|---|
| 检索一次就能命中、问题偏事实型 | 留在单链路,别拆 |
| 资料量小、主题集中,上下文塞得下 | 留在单链路,先把召回调好 |
| 步骤互相依赖且顺序不固定 | 可以考虑多智能体 |
| 需要多视角互校(一个写一个挑错) | 适合拆校验角色 |
| 单次上下文塞不下,必须分阶段交接 | 适合拆读取与整理角色 |
有个很土但有效的判断方法:把这条链路手写跑十几次。如果每次都用同一个顺序、同一套工具、同一个提示词,那它本质是工作流,用节点编排把步骤串起来就够了,不需要「多个智能体」这层壳。只有当顺序会随问题变化时,多角色调度才开始有价值。
角色怎么拆:按职责边界而不是按人名
按职责拆,不按模型拆。一个能起步的最小集合是四个角色:检索或规划、读取与整理、生成、校验。每个角色只持有自己那部分上下文,交接时传结构化字段——问题、证据片段、结论、置信度——而不是把整段对话原文塞给下一个。
- 拆分底线是「可单独测试」:每个角色都能拿一组固定输入单独跑,输出格式稳定,否则一出错只能整体重跑
- 规划角色最容易失控,给它明确步数上限和工具白名单,超出就返回兜底答案,别让它继续想
- 校验角色只干一件事:检查答案里每个断言能不能在证据里找到,别的判断交给别的角色
- 先按职责拆完,再讨论哪个角色换更便宜的模型,顺序反了会把架构锁死
如果某个角色的输出你没法写出一个稳定的结构(比如它总在自由发挥),说明这个角色边界还没切干净。这种情况别急着加提示词,先回到「它到底该负责什么」这个问题上重新切一刀。
编排与状态:循环、退出条件、共享黑板
多智能体 RAG 的骨架就是一个循环:规划、调用检索工具、生成、校验、决定重试还是收工。画得好不好看不重要,退出条件写没写死才重要。
- 写死退出条件步数上限、连续无新证据、校验连续通过次数,三者取或。任一满足就收工,别留「看情况」的分支
- 集中放共享状态用一个共享结构记录谁写的、基于哪批证据、当前结论,避免每个 Agent 各自维护一份记忆互相打架
- 把工具做成幂等可重放同一个查询重复调用应命中缓存,而不是重新打向量库,否则重试会成倍放大成本和延迟
- 日志字段先定好每步记输入摘要、调用的工具与参数、命中文档 ID、耗时、token 消耗。缺这几个字段,线上出问题只能靠猜
共享黑板这一步值得多花点时间。很多多智能体系统「越跑越乱」,根子不在模型,而在每个角色自己记了一份状态,交接时谁的是最新的说不清。集中放一份、只允许追加不允许各写各的,问题会少一大半。
入门路径:从最小版跑通再加角色
别一上来就搭四角色并行。按下面这个顺序加,每一步都能独立验证,出问题知道是哪一层。
- 第一步:单 Agent + 一个检索工具跑通「问题进、带引用答案出」。这一步不追求答得准,只要求链路通、引用格式稳定
- 第二步:拆出校验把生成和校验分成两段,校验只做一件事——检查答案里的每个断言能不能在证据里找到
- 第三步:加入规划让规划角色在多轮检索时决定下一个查询词。这一步开始才真正有「多智能体」的味道
- 第四步:再考虑并行或辩论多角色并行、互相挑错这类结构放最后。加之前先确认你能稳定复现失败案例,否则加了也不知道有没有变好
评测跟着架构一起做:准备一组固定问题加期望证据,每次改架构跑一遍,看两个指标——检索命中率、答案有没有超出证据范围。别只看答案读起来顺不顺,读起来顺但引用了不存在的证据,是最常见也最难发现的坑。跑顺之后想换更便宜的模型跑检索整理这类低难度角色,规格与价格到 /official-api 和 /models 对照当时的数字,别凭印象拍。
失败与成本:不能无限循环
多智能体天然会放大请求量:一次用户提问背后可能是多轮检索加多轮生成。不给链条扣一个总预算,它就能一直转下去。
| 失败类型 | 处理方式 |
|---|---|
| 检索超时、限流 | 退避后重试,设最多重试次数 |
| 工具参数报错 | 不可重试,直接走兜底分支 |
| 证据为空、检索无结果 | 不可重试,降级为直接作答并说明 |
| 校验连续不通过 | 到阈值就停,返回当前最优答案并标注置信度低 |
给整条链设一个总预算:总步数、总 token、总时长,任一触顶就降级成「单轮检索加直接作答」,并且在答案里明确告诉用户这是简化结果。降级路线要提前写好,别等线上触顶了才临时想。
- 区分可重试与不可重试的失败,检索超时能退避重试,参数报错重试十次也没用
- 并发上别把每个角色都当独立请求放开跑,先量出你的延迟基线,到 /tools/speed-test 测一遍再调参数
- 成本按整条链算而不是按单次调用算,估算口径参考 /tools/token-price-calculator
- 上线前把总预算、降级路径、日志字段三样写在同一个文档里,改架构时一起改
多智能体的价值不在于角色多,而在于每个角色都能被单独测试、单独替换、单独设预算。下一步把角色拆完之后,先别急着调提示词,去测一遍你的检索层基线。检索不稳,多智能体只会把误差放大。→
常见问题
多智能体 RAG 和普通 RAG 到底差在哪,值不值得多写这么多代码?
差在「谁来决定下一步查什么」和「谁来判断答得对不对」。普通 RAG 是一次检索一次生成,链路由你的代码写死;多智能体把这部分判断交给模型,代价是延迟、成本和排错难度都上升。只在任务确实需要多轮检索、或多视角互相校验时才值,其余场景先用单链路。
用 LangGraph 这类框架搭,最容易踩的坑是什么?
最常见的是把状态到处散落:每个节点各自存一份上下文,最后合不起来。建议一开始就定一个共享状态结构,明确哪些字段允许被覆盖、哪些只能追加。其次是循环没有硬性退出条件,模型说「再查一次」就一直查,必须用步数、证据增量、时间三重上限兜住。
多个 Agent 互相看不到对方的证据,答案对不上怎么办?
本质是状态没共享。做法是把证据池做成只读的公共区,所有角色引用同一批文档 ID,生成时要求答案里带上引用标记,校验时就检查标记能否对应回证据池。对不上的断言直接删掉或降级成「不确定」,不要让它留在答案里。