一直听到的都是“多 Agent 团队协作如何强”,今天我来讲一个相反的案例。我们把自己一个本来好好的单 Agent 任务拆成三个 Agent 协作,结果耗时变成原来的 32 倍,Token 消耗涨到 13 倍,最后输出质量还肉眼可见地变差了。这不是理论推演,是我们实打实跑过的一个多 Agent 团队协作反例。我会把整个过程、每个环节的 Token 变化、时间花在哪、为什么结果会更差,全部拆开来讲,顺便给出排查思路和后续改法,希望帮大家少踩这个坑。
先说明背景:这不是某个特殊场景才有的偶然现象,而是多 Agent 系统中非常典型的“协作成本失控”。你越是想让 Agent 之间互相检查、互相补全,系统就越容易陷入上下文混乱、重复劳动和无效协调。这不是说多 Agent 方案不能做,而是说很多人低估了协作本身的代价。这篇文章适合正在做 Agent 编排、正在评估要不要把一个单体任务拆成多 Agent 的人看。
1. 这个反例到底反在哪:一个看似合理的任务如何跑出 32 倍时间和 13 倍 Token
1.1 原始需求与改造动机
先说任务本身。我们有一个半结构化的数据清洗与标准化流程:输入是几十份格式不统一的文档,需要从中抽取关键字段,统一枚举值,再生成结构化表格。这个任务在改造前是单 Agent 完成的,效果其实不差,准确率大概 92%,单次跑完大约 5 到 8 分钟,Token 消耗稳定在 4 万到 6 万之间。
当时我们想优化的是两个点:第一,部分字段抽取的准确率不够稳定;第二,希望引入一个“质量检查”环节,让结果更可控。基于这两个诉求,团队做了一个很直觉的决策:把任务拆成三个角色,分别是抽取 Agent、标准化 Agent、审核 Agent。抽取 Agent 负责从原文定位原始字段,标准化 Agent 负责把措辞统一成规范枚举值,审核 Agent 负责最后把关。
这个设计听起来非常合理,分工、质检、回归闭环都有了。按常规预期,增加一个审核角色,准确率应该从 92% 提升到 96% 以上,耗时多 30% 以内,Token 多 50% 左右。但实际跑出来的结果和预期差了不止一个数量级。
1.2 改造后的实测数据对比
改造后的组合采用了典型的串联模式:抽取 Agent 输出原始抽取结果,标准化 Agent 拿到结果后做映射,审核 Agent 再对最终结果做一致性校验。为了降低单次失败的概率,每个 Agent 都配置了 retry 机制,最多重试三次,并且每一步的结果都会写回一个共享上下文,方便后续 Agent 引用。
实测五组任务的数据:
| 指标 | 单 Agent 基线 | 三 Agent 协作版 | 变化倍数 |
|---|---|---|---|
| 平均耗时 | 6.4 分钟 | 205 分钟 | 32 倍 |
| Token 消耗 | 4.8 万 | 62.4 万 | 13 倍 |
| 字段准确率 | 92% | 88% | -4% |
| 完整通过率 | 100% | 60% | -40% |
最讽刺的是准确率不升反降。我们以为加了一个审核角色可以让结果更稳,结果审核 Agent 在多个字段上误判了正确结果,导致抽取 Agent 反复重新执行,最终产出了一份“被多次修改后的妥协版本”,反而把原本正确的值改错了。
这组数据一下子把所有问题暴露出来:时间主要卡在重试和审核退回上,Token 主要烧在重复读取上下文和冗余推理上。要理解为什么多 Agent 反而不如单 Agent,先得搞明白上下文是怎么被复制和污染的。
2. 成本爆炸的四个“元凶”:从上下文复制到无效协调
2.1 共享上下文变成“每个 Agent 的完整行李箱”
多 Agent 协作最常见的实现是把一个共享上下文传给所有 Agent,每个 Agent 都能看到历史消息、其他 Agent 的中间输出、当前任务描述。单 Agent 模式下,上下文里只有原始文档和一次推理链;多 Agent 模式下,上下文被反复拼接。
举个例子,抽取 Agent 第一次输出 8000 Token 的抽取结果,标准化 Agent 读取时,输入由三部分组成:系统提示 2000 Token、原始文档 30000 Token、抽取结果 8000 Token。标准化 Agent 输出 5000 Token 后,审核 Agent 又要读前面的全部内容,此时上下文变成:系统提示 2000、原始文档 30000、抽取结果 8000、标准化结果 5000,再加上审核自己的指令,可能直接到 5 万 Token。
这还只是一轮。只要审核不通过,抽取 Agent 重跑时又要把之前所有内容载入一次。上下文呈现指数级叠加,Token 成本自然膨胀。更关键的是,每个 Agent 都会在上下文中看到其他 Agent 的中间推理,这些推理并不都是有效信息,反而占用了宝贵的上下文空间,干扰注意力。
我们在排查时做了一个统计:整个过程中,真正被最终结果用到的 Token 只占 18%,其余 82% 都是中间传递、重复摘录、纠错重新分析产生的冗余信息。你可以理解成一个团队开会,每个人发言前都把整份会议纪要念一遍,然后再说自己的观点。
2.2 “审核—重做”循环会产生雪球效应
三 Agent 串联模式最大的隐患是审核 Agent 有极大的“退回权力”。审核 Agent 一旦判断某字段不合格,就会把整个任务退回给上游 Agent。上游 Agent 收到退回后,不是只修一个字段,而是经常把全部输出重新生成一遍。
实测中,五组任务里有三组都出现过至少一轮完整退回。最极端的一组任务跑了四轮完整循环,每一轮 Token 消耗都在 12 万到 18 万之间。由于每个 Agent 重跑时会把之前的结果合并进上下文,第四轮的 Token 消耗比第一轮高出接近一倍。
这就是雪球效应:审核退回导致重跑,重跑导致上下文膨胀,上下文膨胀导致模型注意力分散,注意力分散导致更可能出错,出错又触发新一轮退回。整个系统不是收敛的,而是发散的。
我后来反思,审核 Agent 不应该直接退回并要求重跑,而应该在结果旁边标注具体修改点。但当时的设计是把“发现错误”和“修正错误”的责任都强行按在抽取 Agent 头上,导致系统形成了一种低效的返工闭环。
2.3 角色分工反而破坏了问题所有权
单 Agent 模式下,模型对整个任务有完整的所有权:它知道要抽字段、要做标准化、也要保证输出格式正确,所以会在一次推理里做出全局权衡。多 Agent 模式下,每个 Agent 只负责链条上的一个环节,反而丢失了全局视角。
问题最明显的是标准化 Agent。它在处理某些字段时,会按照自己的理解修改抽取结果,导致与原始文档产生偏差。审核 Agent 审核的是标准化后的结果,如果标准化结果本身有问题,审核 Agent 会有两种表现:一是误把错误当正确,放过去;二是发现不了问题,直接通过。但我们这个案例里更常见的是第三种:审核 Agent 察觉结果“哪里不对”,但又说不出具体怎么改,于是以“缺少必要字段”为由退回,逼迫抽取 Agent 重新执行。
这个过程中,没有一个 Agent 真正对“最终交付物的一致性”负责。每个人都在做局部优化,最终结果却全局变差。这就是角色分工的悖论:你以为明确职责能让系统更可靠,实际是一旦协作协议不完善,职责切分反而会制造责任真空地带。
2.4 无效协调和管理开销被严重低估
除了任务本身的 Agent 外,我们还在外层加了一个简单的调度器,用来决定消息路由、记录任务状态、控制重试次数。调度器本身不直接处理数据,但它每轮都要读取上下文,判断当前状态,生成下一步指令。
五个任务跑下来,调度器产生的 Token 占总消耗的 21%。这不是说调度器不能加,而是说多 Agent 架构里,协调层本身就是一个成本中心。如果你用更弱的模型做调度,可能省 Token 但容易误判状态;用强模型做调度,Token 消耗会非常可观。我们当时为了稳定,给调度器用了和任务 Agent 同级别的模型,调度器的 Token 消耗和任务 Agent 基本持平。
这还没算时间上的开销。每次 Agent 调用之间都有网络请求、排队、模型推理时间。单 Agent 一次推理只需要 30 秒左右,多 Agent 一轮串联就需要 3 到 5 分钟。尤其是审核 Agent 的推理时间比抽取 Agent 还长,因为它要处理的信息量更大。整个系统的延迟被叠加,不是简单相加,而是每条消息都要经过更多层的处理和等待。
3. 实操现场回放:一个 205 分钟的失败案例全记录
3.1 初始拆分与系统提示设计
为了让这个反例可复现,我把我们当时的关键配置列出来。三个 Agent 的系统提示分别是这样的,虽然不能贴完整原版,但核心结构一致:
- 抽取 Agent:要求从文档中定位指定字段,输出 JSON 格式的原始抽取结果。系统提示里包含了所有字段定义、格式要求、示例。提示特别强调“如果发现字段缺失,必须标注为 missing”。
- 标准化 Agent:要求把抽取结果中的字段值映射到统一枚举值,如果遇到未覆盖的值,需要添加自定义标准化结果。
- 审核 Agent:要求检查抽取结果和标准化结果是否一致、是否存在缺失字段、字段值是否符合枚举定义。一旦发现问题,需要退回给上游 Agent 修改。
调度器则维护一个任务队列,记录当前步骤、剩余重试次数,并把每一步 Agent 的输出追加到共享上下文。调度器的逻辑很简单:先抽取,再标准化,最后审核;审核不通过就回退到抽取阶段。
这个设计的问题在第一步就埋下了。抽取 Agent 和标准化 Agent 的字段定义有细微差异:抽取 Agent 的输出里有一个字段叫 report_date,标准化 Agent 期望的是 date,而且审核 Agent 同时引用了两套字段名,导致每次审核都会因为字段名不匹配而报错。
3.2 第一次失败循环:从标准化到审核再到重抽
我们看其中一组任务的时间线。任务开始时,调度器先把 30 万字符的原始文档和一些任务说明传给抽取 Agent。抽取 Agent 第一次返回结果耗时 4 分钟,输出 7600 Token,字段基本齐全,准确率按我们后来人工核验大概有 90%。
标准化 Agent 拿到抽取结果后,耗时 3 分钟,输出 5400 Token。它把大部分字段映射到了枚举值,但是 report_date 这个字段它没找到,因为抽取 Agent 输出的是 report_date,而标准化 Agent 期望的是 date。它没有直接重新映射,而是把 report_date 保留,并加了一条“需要人工确认”的备注。
审核 Agent 拿到标准化结果后,耗时 5 分钟,输出 3200 Token。它发现两个问题:第一,date 字段缺失,因为标准化 Agent 没有生成 date;第二,report_date 字段缺少标准化映射。于是审核 Agent 判定不合格,返回给调度器,调度器触发重试。
这里第一次重试时,抽取 Agent 再次读取的上下文已经包含了抽取结果、标准化结果和审核反馈。它重新执行了抽字段操作,结果它没有意识到问题只出在字段名映射上,又把所有字段重新抽了一遍,输出 8200 Token,比第一次还长。
标准化 Agent 第二次收到抽取结果后,上下文里已经有三份重复的抽取结果,它的输出也膨胀到了 7100 Token。审核 Agent 第二次审核时,发现 date 字段依旧缺失,再次退回。这个循环整整重复了三次,每次上下文都比前一次更大,Token 消耗曲线像爬楼梯一样攀升。
3.3 第四次循环后的最终结果有多离谱
第四次循环后,整个流程消耗了约 42 万 Token,耗时 149 分钟。审核 Agent 在第四次实际上已经“妥协”了,它没有再退回,而是直接通过了结果。但通过的原因不是结果达标了,而是它在超长上下文中丢失了早期检查项的注意力,认为当前版本已经涵盖了之前指出的所有问题。
我们把最终输出和单 Agent 基线结果做对比,发现两个严重问题。
第一,report_date 的值在前三次循环中本来是对的,但是标准化 Agent 在第二次循环时把格式从 2024-08-11 改成了 2024/08/11,而审核 Agent 没有发现这个改动不符合输出规范,最终结果里就带着错误的日期格式。
第二,由于多轮循环后上下文里塞满了重复的抽取结果,抽取 Agent 在后续循环里出现了幻觉现象,在最终结果里塞进来一个原文里根本不存在的字段“source_version”。人工核对时发现这个字段根本不在原始文档中。单 Agent 版本从来没出现过这种问题。
这个案例非常典型:多 Agent 不是简单地把几个模型串起来,每一步都会引入新的误差源,而且误差会在循环中放大。最终输出准确率从 92% 降到 88%,其中至少有 2 个百分点的下降就是因为这种反复修改和上下文污染造成的。
3.4 Token 到底花在了哪里
我把这组的 Token 消耗做了详细拆解,按 Agent 和轮次统计。第一轮消耗 11.2 万 Token,其中抽取 4.2 万、标准化 3.6 万、审核 2.4 万、调度器 1 万。第二轮因为上下文里多了一份完整的抽取结果和标准化结果,消耗直接跳到 15.8 万。第三轮 18.7 万。第四轮 21.3 万。
这个拆解说明一个反直觉的事实:真正的原始文档读取只占第一轮,后续几轮的大头都是重复读取之前 Agent 生成的中间结果。也就是说,系统的 Token 成本不是在读“新信息”,而是在反复搬运“历史垃圾”。
如果早一点意识到这一点,我们可以在标准化 Agent 里做一个简单处理:只要求它读取抽取结果中新增的字段映射关系,而不是读取全部上下文。但当时的实现为了方便,把所有 Agent 都接入了同一个共享上下文,这个教训非常深刻。
4. 问题排查实录:从数据中发现根因的四步法
4.1 第一步,先看“分支回退率”而不是只看最终准确率
我们刚开始排查时,只盯着准确率看,发现 88% 比基线低,但也说不清低在哪。后来我们把所有 Agent 的执行日志拿出来,统计每一步的退回比例,才发现标准化 Agent 的退回率高达 70%,审核 Agent 的退回率也有 63%。这个数据说明整个流水线基本处于“大部分时间在重跑”的状态。
建议大家在排查多 Agent 系统时,一定要记录每一步的执行状态、退回原因、重试次数。最终结果准确率只能反映结果,无法反映过程,而多 Agent 系统的病根往往出在过程上。我们后来把“退回率”作为核心监控指标,很快锁定了问题环节。
4.2 第二步,检查上下文膨胀曲线
把五组任务的上下文 Token 变化画出来,能非常清晰地看到一条上升曲线。正常系统应该在某一轮后趋于平稳,但我们的系统每一轮都比上一轮多出 30% 到 40%。这就是典型的上下文失控。
实操时可以给每个 Agent 加一个 Token 计量器,记录每次调用的输入大小和输出大小。如果连续三轮输入都显著增长,就需要考虑上下文隔离、结果摘要或者任务拆分的方式。不要等到系统跑挂了再查,因为一旦上下文膨胀到接近模型窗口上限,错误率和重试率会同步飙升。
4.3 第三步,对比单 Agent 和当前多 Agent 的逐字段准确率
我们后来做了一次逐字段的准确率对比,发现多 Agent 系统并不是在所有字段上都比单 Agent 差。它在三个字段上准确率略高,在五个字段上打平,在两个字段上明显更差。其中 report_date 和 source_version 这两个字段,单 Agent 是对的,多 Agent 反而错了。
这种逐字段对比能帮你判断一个多 Agent 拆分到底有没有价值。如果只是少数字段变差,你可以在对应 Agent 的提示词里加限制;如果整体变差,那就要考虑重新设计协作方式了。我们倾向于认为,只有当一个 Agent 的能力模型明显无法覆盖某项任务时,才需要拆出去单独处理。
4.4 第四步,单独验证每个 Agent 的独立性
最后一步,我们把三个 Agent 拆开,分别用同样的输入单独测试。结果发现抽取 Agent 单独运行时准确率 91%,标准化 Agent 单独运行时能把格式映射做到 95%,审核 Agent 单独检查错误的能力也不弱。但把它们串起来之后,整体准确率反而下降。
这说明问题不在单个 Agent 的能力,而在它们之间的接口和协作协议上。我们后来重新设计了字段映射规范,统一了字段名,并把审核 Agent 的退回条件从“看到任何差异就退回”改成“必须给出具体修改建议才可退回”,准确率才回到 93% 左右,但 Token 成本依然比单 Agent 高出一倍以上。
这也引出一个重要结论:先单独验证组件,再验证组合,不要一上来就测试完整链路。独测能帮你判断 Agent 本身是否有能力问题,联测才能暴露协作问题。两者不能混为一谈。
5. 避坑经验清单:什么时候不要用多 Agent,以及如何正确拆
5.1 四个明确“不适合”多 Agent 的信号
经过这次反例,我总结出四个不适合上多 Agent 的信号,大家在做方案选型时可以拿来对照。
第一,任务本身是线性可解的,也就是单 Agent 已经能稳定完成,准确率没有明显瓶颈。不要为了“架构感”强行拆。第二,Agent 之间需要共享大量原始上下文,而且每个 Agent 都需要读取全量信息。这种场景适合用单 Agent 或检索增强,不适合让每个 Agent 都背全量文档。第三,上游 Agent 的输出格式经常不稳定,下游 Agent 很容易因为解析失败而触发重试。第四,你对最终结果有高强度一致性要求,但这种一致性无法用显式规则描述,只能通过反复审核保证。
我们这次案例基本四个信号全中。说句实话,如果当时能拿这个清单自测一下,根本不会把三 Agent 方案上线。
5.2 如果一定要用多 Agent,我推荐的四种稳健拆法
不是说多 Agent 一无是处。我后来也做了几轮成功改造,有几个拆法被验证过是有效的,分享给大家。
第一种是并行无关拆法:一个大任务先由一个 Agent 做任务分解,分解出来的子任务互相独立,再把不同子任务交给不同 Agent 并行执行,最后用一个轻量级聚合 Agent 汇总。这种形态下,各 Agent 不需要共享大量中间上下文,Token 成本不会指数膨胀,甚至因为并行还能省时间。
第二种是受限上下文拆法:每个 Agent 只能访问它执行子任务所需的那一段数据,不能访问全量上下文。这个改造我们后来做了,Token 成本直接降了 70%。核心思路是给每个 Agent 划定信息边界,就像团队成员各看各的报表,而不是围在一张桌子前翻所有文件。
第三种是轻量协调拆法:调度器只负责发消息和收结果,不做内容判断。我们之前用强模型做调度器,后来换成一个小模型加规则路由,既便宜又稳定。其实大部分多 Agent 场景根本不需要调度器做智能判断,规则路由就够用了。
第四种是分层验收拆法:审核 Agent 不直接退回整个任务,而是输出结构化的问题列表,包括字段名、期望值、实际值、修改建议。只有问题列表清晰时,上游 Agent 才执行修改。这个改动让重试次数从三轮降到了一轮不到,时间从 205 分钟降到 42 分钟,准确率回升到 93%。
5.3 Token 成本估算公式与上限预算
最后给一个可以抄作业的成本估算公式。假设单个任务的原始文档大小是 D Token,单 Agent 完成成本约是 alpha,多 Agent 串联每轮基础成本约等于所有 Agent 的上下文读取之和与各自输出之和。如果每个 Agent 都能看到完整上下文,那么第 N 轮的成本大致是:
第 N 轮成本 ≈ 原始文档 D + 之前所有 Agent 输出总和 + 本轮所有 Agent 输出总和
这个式子最核心的点是“之前输出总和”会不断增长。如果一轮循环中有 K 个 Agent 参与,而且每个 Agent 都会输出并附加到共享上下文,那么一轮下来新增的输出就是 K 倍。假设每轮 Agent 输出大小是 O,那么 n 轮总 Token 大致是:
总 Token ≈ n × (D + n × K × O)
这是一个近似式子,因为现实里输出大小会波动,但它足够说明问题:这里的成本是 O(n²) 量级增长。如果你预估 n 已经超过 2 轮,就需要特别注意了,多 Agent 循环的 Token 膨胀不是线性的,而是平方级甚至更差。
实际操作中,我建议在方案设计阶段就设定三个预算:总 Token 预算、最大循环轮数、最长耗时预算。一旦超出预算就自动熔断,把当前上下文转给一个兜底 Agent 处理,避免系统无限烧钱。我们后来加了一个“最多 2 轮重试”的熔断规则,整体成本立刻可控了。
5.4 这次反例留给我最值钱的三个认知
每次复盘这种失败案例,我都能得到比成功案例更多的思考。这个项目让我对多 Agent 系统有了几个很深的认知。
第一,多 Agent 不是一个“性能增强插件”,它有很强的结构性损耗。每增加一个 Agent,系统里就多了一个信息传递的失真点和一个协调消耗点。不要在单 Agent 还没跑通前就引入多 Agent,先把单体方案做好,做到准确率无法通过提示词优化继续提升为止。
第二,Token 成本和时间成本不是独立的,它们会互相强化。Token 多的模型调用慢,慢会让队列积压,积压会拉长端到端时间。很多团队只盯着 Token 账单看成本,忽略了时间其实也是成本的一部分。这次 32 倍时间里有至少一半是因为 Token 膨胀导致推理变慢和重试排队。
第三,审核 Agent 是一把双刃剑。增加审核角色确实能拦住一些低级错误,但它同时会引入误判、来回拉扯和上下文污染。如果你要加审核,务必让审核 Agent 的输出是“可执行的结构化修改命令”,而不是模糊的“这里不对”。模糊的反馈只会让上游 Agent 做出更多不必要的重跑。
个人经验是,我现在做 Agent 设计时,默认第一个方案永远是单 Agent + 强提示词 + 结构化输出,只有在单 Agent 方案确实因为上下文窗口或输出格式限制搞不定时,才会考虑拆分工。而且拆分时优先选并行无关拆法,其次才考虑串联流水线。串并联之间的决策点,不是“看起来有没有必要”,而是“去掉任何一个 Agent,系统的质量会不会明显下降”。如果不会明显下降,就去掉它。
这个反例不值得高兴,但它确实是我近期做过最有价值的一个实验。它让我意识到,多 Agent 团队协作不是银弹,性能和成本不会因为“加了更多 Agent”而变好,反而会因为沟通成本爆炸而变差。希望这份拆解能让正在设计类似系统的你少跳一次火坑。