ᕕ( ᐛ )ᕗ Jimyag's Blog

多 Agent 什么时候比单 Agent 更划算

看到 Graph Engineering 的讨论后,我一直想算一笔更具体的账:多开几个 Agent 到底值不值。

我拿同一份代码审查样本跑了两组实验:

  1. 一个 Agent 独立完成综合审查。
  2. 三个 Agent 分别检查安全、并发与生命周期、I/O 与可靠性,再合并结果。

Anthropic 公布的 Research 系统数据中,多 Agent 使用的 token 大约是普通聊天的 15 倍;需要共享完整上下文或包含大量紧密依赖的任务也不适合多 Agent。1 所以这次除了看发现了多少问题,我还记录了耗时、输出 token、重复结论和误报。

结果很直白:三个 Agent 确实找得更多,但增加的主要是中风险边界,token 和去重工作也跟着上去了。

实验怎么做

审查样本

样本是一份 88 行的 Go HTTP 导出功能 diff。接口接收文件名和一组 URL,在后台下载内容、写入文件,并通过另一个接口返回任务状态。

我在样本里保留了 12 个可以从代码或 Go 官方文档确认的问题,覆盖:

  • 并发读写。
  • Request Context 生命周期。
  • 文件路径与并发写入。
  • SSRF。
  • HTTP 超时和状态码。
  • 错误处理、资源释放与容量限制。

完整的审查样本统一审查要求和实验结束后公开的答案表都放在文章目录中。Reviewer 执行时只能读取样本和审查要求,看不到答案表。

答案表中有两项直接依赖 Go 的运行语义:

  • Server Request 的 Context 会在 ServeHTTP 返回时取消。2
  • http.DefaultClient 的总 Timeout 为零,也就是没有总超时。2

普通 Go map 也不支持未同步的并发读写。3

两组 Reviewer

两组使用相同的 Agent 配置和新上下文。

单 Agent 组收到统一要求:只报告 diff 引入的具体正确性、安全、可靠性或并发问题;每条 finding 必须指出代码位置和现实失败路径。

三 Agent 组读取相同 diff 和要求,但各自增加一个审查范围:

Reviewer 负责范围
Security 文件路径、外部 URL、不可信输入、信息泄漏
Concurrency goroutine、Request 生命周期、共享状态、ID 和并发写入
Reliability HTTP 行为、I/O 错误、资源释放、超时和状态报告

三名 Reviewer 并行运行,完成后由主会话按失败原因去重。相同问题即使标题或严重程度不同,也只算一个有效发现。

统一要求之外,每个 Reviewer 只增加表中的一项职责。Anthropic 把这种做法称为 Parallelization 的 sectioning:把独立的关注点交给不同 LLM 调用,再统一聚合。4

指标口径

  • 原始 finding:Reviewer 返回的 finding 数量。
  • 有效发现:可以映射到答案表,并且失败路径成立的唯一问题。
  • 重复结论:原始 finding 减去合并后的唯一问题。
  • 误报:答案表之外、同时缺少代码支持的失败路径。
  • 漏报:答案表中没有被发现的问题。
  • 耗时:从派发到全部 Reviewer 返回的墙钟时间。

平台没有提供每个 Agent 的账单级输入、推理和工具 token。文中的 token 只采用一套可复现的文本口径:

  1. 使用 gpt-tokenizer 的 GPT-4o encoding 统计输出 token。
  2. 「可观察 token 下限」等于样本与统一 prompt 的 token,加上输出 token。
  3. 不包含 system prompt、角色补充指令、内部推理和工具调用,因此不能当作实际账单。

同一套 tokenizer 下,样本和统一 prompt 共 753 token。多 Agent 组需要至少读取三遍,所以即使还没生成结果,已经重复消耗了这部分输入。

实验结果

指标 单 Agent 三 Agent
墙钟时间 41 秒 58 秒
原始 finding 8 19
有效发现 8 11
重复结论 0 8
误报 0 0
漏报 4 1
答案表覆盖率 66.7% 91.7%
输出 token 631 1552
可观察 token 下限 1384 3811

汇总结果见 results.csv,逐项归并关系见 scoring.csv。四份未经修改的 Reviewer 输出也一并保留:

三 Agent 组比单 Agent 多用 17 秒,覆盖率从 66.7% 提升到 91.7%。它没有把耗时放大三倍,因为三个 Reviewer 是并行运行的;但输出 token 是单 Agent 的 2.46 倍,可观察 token 下限是 2.75 倍。

多出来的三个问题

三 Agent 组额外找到:

  1. io.Copy 没有大小限制,远端可以持续返回内容并耗尽磁盘。
  2. 日志记录完整 URL,签名参数或 query token 可能进入日志系统。
  3. 下载后没有检查 HTTP 状态码,404500 页面也会作为正常数据写入导出文件。

这三条都成立,但在这个样本里属于中风险边界。单 Agent 已经找到了路径穿越、SSRF、并发 map、Request Context 失效、错误状态、ID 冲突和同名文件并发写入等主要问题。三 Agent 这次补到的是长尾问题。

三个 Agent 仍然会一起漏报

两组都没有指出 http.DefaultClient 缺少总超时。Go 文档明确写明 Client 的 Timeout 为零时不设置超时,而 DefaultClient 使用 Client 零值。2

三个 Reviewer 都没兜住这条。如果「HTTP Client 必须设置超时」是团队的固定规则,交给静态检查、封装好的 Client 或 review checklist 更合适。

合并不是免费的

三名 Reviewer 一共返回 19 条 finding,合并后只剩 11 条,其中 8 条是重复项:

1
2
3
4
5
6
7
8
Request Context 取消:2 个 Reviewer 重复
并发 map:2 个 Reviewer 重复
路径穿越:2 个 Reviewer 重复
SSRF:2 个 Reviewer 重复
ID 冲突:2 个 Reviewer 重复
同名文件写冲突:2 个 Reviewer 重复
Response Body 延迟关闭:2 个 Reviewer 重复
下载大小无限制:2 个 Reviewer 重复

不做归并,这 19 条会直接变成一组重复、严重程度还不一致的 review 评论。

四个判断问题

1. 任务能否拆成真正独立的部分

安全、并发和 I/O 可以从不同视角独立阅读同一份 diff,三者不需要等待彼此的结果,因此适合并行。

如果任务是「先理解一个状态机,再修改实现,最后根据测试失败继续修」,后一步持续依赖前一步形成的完整认识。强行拆成多个 Agent 会重复建立上下文,还会增加交接损耗。这种任务通常更适合一个 Agent 连续推进。

2. Agent 是否需要频繁共享完整上下文

本次实验中,每名 Reviewer 只需要一份固定 diff,不需要交换中间状态。唯一共享点是最后的 finding 列表。

如果三个 Agent 必须不断同步当前假设、未提交修改和测试状态,并行带来的时间收益很容易被通信成本抵消。Anthropic 的多 Agent Research 文章也把「需要所有 Agent 共享同一上下文」列为不适合当前多 Agent 架构的场景。1

3. 输出是否容易合并,并且有明确验证标准

代码审查至少可以要求每条 finding 包含代码位置和现实失败路径,再通过语言文档、测试或复现判断是否成立。即使如此,本次实验仍有 8 条重复结论需要合并。

如果任务输出主要依赖审美,没有统一结构,也没有可拒绝结果的标准,多个 Agent 往往只会生成更多互相矛盾的意见。

4. 任务价值是否覆盖额外成本

在这份样本中,多 Agent 用约 2.46 倍输出 token 换来 3 条额外的中风险 finding,并把漏报从 4 条降到 1 条。

是否划算取决于失败成本:

场景 判断
高风险安全审查、事故调查、关键架构评审 长尾问题可能抵得上额外成本
普通小 PR、低风险文档修改 单 Agent 找到主要问题后通常已经足够
可以用测试或静态检查覆盖的问题 优先增加确定性检查,不要增加 Reviewer
必须在短时间内探索多个独立假设 多 Agent 并行更容易体现时间价值

我会怎么用

  1. 先让一个 Agent 完成综合审查。
  2. 根据任务风险决定是否需要第二轮。
  3. 第二轮不要重复综合 prompt,而是只补安全、并发、兼容性等明确缺口。
  4. 让各 Reviewer 使用相同的 finding 格式。
  5. 合并时按失败原因去重,不按标题去重。
  6. 能用测试、编译器、静态规则确认的问题,交给确定性工具。

Claude Code 的并行 Agent 文档也建议根据上下文、协调方式和文件冲突选择 subagent、agent team 或 worktree,并明确提醒多个会话会增加 token 使用。5

这次实验不能证明什么

这只是一次小样本实验,不能推出「三个 Agent 的覆盖率固定高 25 个百分点」。

它还有几个限制:

  1. 样本是人为构造的 88 行 Go diff,不代表大型真实 PR。
  2. 每组只运行一次,没有测量模型输出的随机波动。
  3. 多 Agent 组同时改变了 Reviewer 数量和职责 prompt,测到的是「专业分工后的团队」,不是纯粹的数量效应。
  4. 有效发现和误报由我根据答案表人工归并,仍然存在判断误差。
  5. token 只统计可见文本,不能代表平台实际计费。
  6. 墙钟时间包含调度开销,也会受当时服务负载影响。

这组数据只能用来观察成本结构,不能当作通用 benchmark。对普通代码审查,我会继续默认使用一个 Agent,确认有独立风险面需要补查时再增加专门 Reviewer。测试、静态检查和固定规则能解决的问题,仍然交给确定性工具。

参考资料

#AI Agent #Multi-Agent #代码审查 #Agent Engineering #工程实践