Multi Agent 的协作与效率

AI2 次阅读14 分钟

从 ralph-loop 聊起

2025年底,一个神奇的故事传遍了全球的 AI 圈子。一位养羊的牧场主通过一行命令,让 Claude Code 持续迭代了超过 12 个小时,并且结果可用,甚至让 Ahtropic 官方光速下场为 Claude Code 增加了名为 ralph-loop 的命令。

这个命令简单来说如下所示:

while :; do cat PROMPT.md | claude-code --continuedone

当时真实的实践上并没有这么简单,以我个人实践为例,要成功的运行一个自己的 ralph-loop大概为以下步骤:

  1. 根据你的需求拆分一个需求文件,详细的列出每一项任务,确保任务足够的小且可执行。

  2. 准备一个空的 Progress 文件,用来记录任务进度,方便每次对话开始时清晰任务进度。

  3. 在 Prompt 中要求根据需求文件和进度文件来挑选任务,每次只能完成一个任务,每个任务都要测试优先(TDD)来确保结果,当前任务完成后必须立即退出当前对话。

  4. 构建一个循环脚本,重复进入对话,并运行。

简单来说, Ralph-loop 要求你自己其实很清晰要做的每一步是什么,产物是什么,Agent 本身只是你的代行者。计划提前从脑海落入文档,中间剩下的其实是执行。由于 LLM 天然的限制,上下文长度与注意力的偏移,因此需要将任务足够的细致划分。表面上看,人退出了执行的循环,但是其实,人在一开始就定下了执行的细节。

在这个阶段, 人和 Agent 是单向的遥控关系,人为 Agent 制定详细的任务,Agent 独自执行,最终结果首先来自于任务定义是否清晰足够,其次来自于 Agent 的执行能力强弱。

Agent、Sub-Agent

接下来,我们在 Ralph-loop 上更进一步。其实不难发现,需求文件的生成和拆分,也是可以由 AI 进行拆分的。在 Claude Code 之前,Cursor 为首的 AI IDE 就有自行分步骤执行任务的情况。 Claude Code 也可以进入 Plan 模式然后制定一个多步骤的任务。

因此,只需要将任务按顺序或并行的分给新的 Agent,就可以执行任务了。这就是 Sub-Agent,将任务上下文完全的托管给一个独立的对话上下文,主 Agent 只接收来自于不同 Agent 的最终的结果。这保证了主 Agent 的上下文更加干净,可以在一次对话中执行更多的任务。

这并非全然是好事。回首 Ralph-loop,最关键的步骤并不在于如何让对话重复的跑起来,而是一个明确的需求列表,构建了应该执行哪些任务,每个任务的具体要求是什么,这才让模型在有限的上下文可以完成一个又一个的任务。

此时,人、Agent、Sub-Agent 之间,出现了一条指挥链路,人指挥 Agent, Agent 指挥 Sub-Agent, Sub-Agent 完成任务并汇报给 Agent, Agent 汇总结果给人。

好事儿发生了,看起来更有效率了。人可以同时指挥多个 Agent,每个 Agent 为了完成目的都可以调用任意的 Sub-Agent,因此操作空间成指数型上升。 Agent 无价的时候,人的注意力开始限制 Agent的发挥,在不同窗口间切换的时候,人需要先把自己脑袋中的上下文在项目之间切换。同时开多少个窗口甚至在某些时候成为了一种网络上的炫耀,仿佛自己可以掌握更大的工作空间。

实际情况其实并非如此。如果人只检查最终结果,那么就是完全将结果寄托于 Agent 本身的能力,那么当问题来临时候,人面临了更大的难题:问题出在哪里。人、Agent、Sub-Agent,这个链路变长了,因此需要分析的链路也变长了,是任务划分的错误,还是 Sub-Agent 执行的错误。如果要修复这个问题,应该如何修复。

其实这并非无解的问题,不同的 Agent 框架有不同的设计,比如 Claude Code 中,Sub-Agent的上下文接近于黑盒,只返回结果,这就导致无法检查。而 Pi 的设计让每一个 Session 都接近于明文,可以调用新的 Agent 直接查阅历史来看问题出在哪里,也可以由人工手动检查历史对话中的每个细节甚至工具调用,来找到问题所在。

毫无意义,对比单一 Agent 的 Ralph-loop,Agent/Sub-Agent 的方式下,人和 Agent 之间的协作依然是单向遥控关系,虽然人的效率被进一步的放大了,但是人也开始被自身的注意力与技术水平所限制。

Planer、Exector 与 Reviewer

如果单一 Agent 由于盲目自信,导致它对自己拆分的任务、输出的结果、无比自信,那么我们可以引入新的角色来进行制衡。 Planer、Exector、Reviewer,三个独立的 Agent,独立的负责自己对应的事情。 Planer 负责制定计划,让人/Reviewer 来审核,Exector 负责按顺序执行计划, Reviewer 负责审查计划与执行结果。

这个三角关系,其实有两种模式,其中一种是很经典的 Claude-Codex 交叉执行策略。具体来说,在 ClaudeCode 或者 Codex 执行任务结束后,通过 Skill 等方式,将它的结果交给另外一方,由另外一方对结果进行审查,然后再返回到当前会话,当前会话进行更改。在这个交替中,每个 Agent 会持有自己的对话,因此会依据上下文稳定的推进任务更新。

另外一种,我称为独立上下文模式。Exector、Reviewer 在开始执行任务/审查的时候,都会将上下文清空,也就是不保留上一次任务的执行结果或审查结果。每次都是全新的执行/审查。

第一种模式看起来更好更合理,因为历史的上下文可以帮助 Exector 在修复 Reviewer 问题的时候更好的定位问题, Reviewer 可以更清晰的知道 Exector 是否完成了问题的修复。

第二种也并非全是问题,模型非常自信也非常听话,很多时候并不会多加审查反馈的问题是否合理,也完全的相信自己改的一定正确,所以每次会话重新开始,其实是从当前的现状出发去重新执行任务,确保任务最终结果可以符合预期。

不管这两种的哪一种,其实依然藏着隐患:你必须确认 Reviewer 正确的理解你想要什么。 如果你的要求只是,代码需要有 Test Case,那么只要 Exector 提交的代码中存在 Test Case,就可以通过 Reviewer 的审查,即使 Case 中直接返回了 True。 如果你希望可以后台代码正确的部署并连接,那么 Reviewer 会帮你审查后台代码是否部署,是否可以连接,甚至可能通过工具帮你测试返回结果。 但是他并不会在意你没有要求的代码安全性。

发现了吗,Agent 们的又一个特点开始出现,我称呼他为:一根筋。任何的 Agent 都是完完全全的按照你的要求做事,你没有要求的地方他们并不会做。 Agent 没有正常开发中的基础知识,他的目的只有一个:完成当前的任务。不论以何种姿态,何种方式,完成当前的任务。

其实,在这个阶段,人和 Agent们之间的关系,已经不是单向的遥控关系了,而是将 Agent 们构建成了一个基础的工作小组,依然指挥,但是更加放任。同时,人的注意力再一次发生了移动,可以减少关注 Agent 制定的任务、Sub-Agent 执行的结果,却依然需要关注 Reviewer 的审查是否和自己的预期一样。只要守好 Reviewer 的审查工作,那么就可以确保任务的质量。

关键:如何判断结果的正确

来总结一下吧,从 Ralpha-loop 开始到 Planer-Exector-Reviewer 的三角结构,其实人的注意力一直在向后移动,越来越偏向于最终的结果。 对于最终的结果的预期越清晰,就可以越好的利用 Multi Agent,更好的使用更多的 Agent,更好的提高自身的工作效率。

但是如果人对于结果的预期并不明确,那么可能 Multi Agent 其实只是在“洗钱”。因为 Token 是需要成本的,错误是会累积的。一个 Agent 产生看起来正确的漂亮话,给到下一个 Agent,只会产生更加错误的偏差。 Planer 只制定了一个看起来正确的计划, Exector 就会按照看起来正确的进行执行, Reviewer 的审查会审查错误的方向。而人觉得他已经通过了多个 Agent 的审查,所以一定没有问题。但是其实一跑就蹦。在这样的情况下,Agent 越多,错误越大。

看起来 Multi Agent 并没有很好的提高效率,因为人似乎依然需要精细的参与每一步。但是其实并不是。人需要审查的,是 Multi Agent 的工作流中,到底哪一步更容易出现问题。是计划的制定,还是代码的实现,又或者文档生成、安全自动化审查。哪一步更容易出问题,人就更应该将精力投入到哪个节点,然后修复这个节点,这样才是 Multi Agent 提高效率的关键。

Swarm、群聊与 TeamMate

最近 Kimi Swarm 很火,宣传中从 100 个智能体进阶到了 400 个智能体。我浅薄的理解中,其实是上一种方式的进阶或变体。一个/几个 Agent 充当 Planer,剩下的分别当 Exector 和 Reviewer,然后协同工作。

难点其实可能不在 Agent 的性能,而是 Agent 的工作基建,代码并行带来的冲突合并、任务执行的依赖排序、不同 Agent 之间的通信或者 Agent 的创建和注销。人只需要合理的管理这些东西,就可以增加 Agent Team 的数量,让更多的 Agent 同时来执行任务。看起来人这一角色完成了超脱, Agent 们可以自主进化了。

这并不好,如同我在前面反复提到的内容,Coding 的难点不在于代码本身,而是在于完成后如何判断结果是正确的。

400 个 Agent 并行干活,如果出现问题,那么就是 400 个黑箱需要被打开,看看问题是不是发生在这里。如果这一步由人来完成,成本是巨大的,但是如果由新的 Agent 来完成,更像是打开了一个新的黑箱。

除此之外,另外一批人提出了一个新的方式,其中代表对象是 Slock.ai。他们把 Agent 当作同事、队友。每一个 Agent 都有记忆、工作记录,甚至是自己的责任。

Slock.ai 中,人创建 Agent,赋予他们名字,定义他们的责任,然后通过私聊/群聊的聊天框给他们发送任务。Agent 可以是 PM、Developer、Reviewer,市场运营,甚至是 HR,可以开除、聘请新的 Agent。

听起来很美好,那么效果如何呢?初期看起来井井有条,PM 可以从自己的角色出发和你详细的讨论任务的要求再分配给Developer,Developer 写完任务,会交给 Reviewer 来审查。

在这个协作模式下,一个新的视角出现了:TeamMate。 因为 Agent 有名字,因此你完全可以将 Agent 视为一个同事,因为 Agent 具有昵称、记忆、职责、工作记录。你知道 X 是负责客户端开发, Y 负责服务器运维,Z 负责完善文档。 所以当出现问题之后,你甚至知道应该找哪个 Agent 来完成这个任务。在这个模式下,Agent 彻底的成为了我们的队友,和我们一起解决问题,推动计划。尽管在整个流程中,人依然是指挥关系,但是更多的,是相互之间的协助关系。

这并非毫无根据,我们对同事的印象绝非只有一个名字,名字所代表的其实就是他的职责、任务、工作历史,甚至是否可信。名字是一个浓缩的有价值的 Token,对 Agent 来说也是一样。

所以过去人遇到了麻烦,需要同事帮帮,限制人遇到了麻烦,需要可能需要 Agent 来帮帮。

人和 Agent 处于同一个工作空间,因此协作关系进一步扩展了,人可以随意的介入任意已有的工作节点来检查内容,也可以将部分任务完全交给 Agent 来让 Agent 自由发挥,还可以随意的和 Agent 讨论并形成新的任务来推动事情的发展。

可 Agent 固有的问题依然存在:自信干活、擅长遗忘、说什么就只做什么。并且由于之前的 Multi Agent 模式中,每个 Agent 其实只知道调用 Sub-Agent、回复人。可以说没有真正的平级,身份也是从对话嵌入的,因此很容易忘记/错位自己的身份。同时每个 Agent 都需要处理更多的对话,所以 Token 也成了 Agent 效率的一部分。单位时间内, Team Mate 的 Agent 消耗的 Token 很容易比 Planer-Exector-Reviewer 这样的组合更高。