三个高性能Agent串联时,Agent间约束在Handoff环节丢失导致1/3错误率,揭示需对Agent接口层而非个体进行测试。
我搭建了一个三 agent 体系:一个 planner、一个 researcher、一个 critic,互相传递工作。我仔细给每个 agent 打了分。planner 做出漂亮的计划。researcher 正确引用了来源。critic 揪出了薄弱的论点。每个 agent 在各自测试中都得了约 0.9 分,我很满意。
但这个团队仍有大约三分之一的时候答错了。
计划是好的。研究是好的。批评是好的。但在一个 agent 和下一个 agent 之间,某个环节出了问题。planner 说"研究 scaling laws,但跳过这篇论文,用户已经有了",researcher 却在两个 turn 后引用了正是那篇论文。约束条件就这样在交接中消失了。没有任何一个独立环节的测试失败,最终答案却是错的。
那一刻我恍然大悟:我应该给 agent 之间的环节打分,而不是给各个 agent 打分。
多 agent 不是单 agent 乘以三
这里有个陷阱。单 agent 很容易分析:输入 → 处理 → 输出 → 打分。所以面对三个 agent,自然的冲动是用同样的方式给三个都打分,然后收工。
但团队不是三个独立函数。它是一条链,一个 agent 的输出成为下一个 agent 的输入。而接收方永远看不到发送方知道的一切。它只看到上一个 turn 以及传递过来的上下文。团队的成功或失败取决于这些交接在多大程度上保留了重要的东西。
算笔账。如果每个 agent 在各自环节都有 95% 的正确率,但每次交接都漏掉一个小东西,三 agent 链可能三分之一的时间都是错的,而每个个体的分数都还是绿的。失败不在 agent 身上。它们在接缝处,而按 agent 设计的测试天生对接缝视而不见。
给交接打分,而不是给 agent 打分
解决这个问题的关键转变是:把被测试的对象从"agent 的环节"改成"交接":一个 agent 把工作交给下一个的那一刻。
对于每次交接,我现在问三个简单的问题:
接收方保留了发送方说的话了吗?每一条约束、每一个决定、每一个悬而未决的问题。我的那个漏论文 bug 就出在这里。researcher 自身是干净的,但它漏掉了 planner 设下的一个约束。
每个 agent 守住了自己的车道了吗?planner 应该做计划,researcher 应该做研究,critic 应该做批评。当一个 agent 开始做别人的工作时,你拆分它们的全部理由就瓦解了。
最终答案和前面的 turn 还一致吗?turn two 中的正确事实不应该在结尾的摘要里被悄悄推翻。
同样的三个 agent,截然不同的视角。我问的不再是"这个环节好不好",而是"这个东西有没有在传到下一个 agent 的过程中活下来"。
交接破碎的三种方式
我见过的几乎所有团队失败都可以归到三个桶里。
约束被丢弃或误读。发送方说了某个具体的东西,接收方弄丢了,或者 paraphrase 时数字反转了,或者发明了根本不存在的上下文("正如我们之前同意的"指向一个从未发生过的 turn)。我那个"跳过这篇论文"的 bug 就属于这一类。
agent 角色漂移。critic 开始起草计划。researcher 开始写摘要。现在你给那个 agent 写的测试测的是一份错误的工作,而你设置的分工已经悄然崩塌。
团队自相矛盾。researcher 把引用搞对了。两个 turn 后 critic 误读了它并报告为错误。planner 围绕 critic 的错误构建了最终答案。每一个单独的 turn 看起来都没问题,而团队拼凑出了一堆看起来正确实则错误的零件,交付了一个错误答案。
从三个独立 agent 的角度看,这些问题一个都发现不了。从交接的角度看,每个都有明确的归属和明确的修复方法。
让我意外的一点:模型更新后的角色漂移
这是我无法预料的一种失败。当我升级 agent 背后的模型时,最终答案质量起初没有任何变动。变动的是角色。在更新后、更急于助人的模型上,critic 开始起草计划了——而它本来只是做批评的。
角色漂移最终成为模型变更出问题的最早预警信号,远在成本或质量变动之前。所以现在我固定模型版本,每次升级时都重新检查角色行为,而不是假设新模型和老模型行为一样。它通常并不一样。
把所有这些都藏起来的错误
只给最终答案打分。漏掉每一个没有彻底毁掉最终输出的交接问题,而那其实是大多数。
所有 agent 用同一套测试。每个 agent 有不同的工作。一套通用的 rubric 把角色特有的失败模糊成了一个毫无意义的平均分。
没有交接的记录。如果你的 trace 只显示最终对话,你就看不出是哪对 agent 出了问题。你需要发送方 turn 和接收方 turn 并排对照。
把模型升级当作无事发生。新模型先漂移角色,后漂移答案。每次版本升级都要重新跑检查。
我不断回顾的教训是:在多 agent 系统中,agent 从来不是真正的难点。难点在它们之间的空间,而我恰恰没有往那里看。
如果你想要更深入的版本——带有给每次交接打分的详细 rubric 以及如何在 trace 中捕获交接——这篇文章有完整说明。
如果你在跑多 agent 团队,我很想知道是哪个交接坏掉了。我的几乎总是 planner 给下一个 agent 的某个约束,后者悄悄忘了。