太长不看:
- multi-agents 并不会天然比单 agent 更强,很多时候只是把复杂度转移到了“协同”本身。
- 真正容易出问题的地方,不是“分工”,而是 context、memory 和状态在多个 agent 之间的传递与恢复。
- 对个人开发者而言,默认先用单 agent;只有当任务可以清晰拆分、并行执行、接口稳定时,再考虑 multi-agents。
从去年开始,关于 multi-agents/agent-team(多智能体)的讨论就没断过,到 clawdbot(现在已经更名为 OpenClaw)问世,更是将这个话题推到一个高潮。很多人都在讨论,多个 agent 协同工作,是不是比单个 agent 更强大?
我看过一些初创公司在卖力的为自家的 multi-agents 方案做营销,也见过不少自媒体号在跟风吹捧 multi-agents 的概念,“跨领域的知识融合”、“分工协作的效率提升“,听起来multi-agents 方案就是 AI agent 时代所有复杂问题的最优解。
多个 agent 协同工作,真的更强大吗?
我个人的感受并非如此。
对于普通个人开发者,如果忽视实际需求,盲目追求多个 agent 协同工作,反而可能会适得其反,轻则效率降低,重则完全失控。
原因有多个方面,既有使用者的因素,也有工具本身的现实局限性。
一方面,每个 agent 都有自己的知识面和注意力范围,如果用户没有足够详细的规则去协调它们的工作,它们很容易就会跑偏,甚至互相干扰,导致整个工作流变得混乱不堪。
另一方面,context 有限且 memory 机制不够健全仍然是 agent 自身性能的一个很大瓶颈。对于复杂任务,尤其是长生命周期的任务,如果无法保证多个 agent 之间的 context 传递和状态管理的完好性,整个系统就很容易出现问题。
这里先不讨论理想化的 A2A(Agent-to-Agent)通讯,只讨论今天普通 coding agent 更常见、也更现实的做法:memory 压缩、传递以及恢复。
即便是今天,关于 memory 机制优化的讨论仍有很大的热度。
我的意思是,memory 在被压缩和恢复之间,容易有信息损失。而这些信息损失,聚沙成塔、积少成多,很容易会使得 agent 忘记关键信息,越跑越偏。
一些失败尝试
想到几个月前有过对于组建 agent team 的尝试,不过失败了。
我的做法是,利用 CC(Claude Code)的 sub-agent 机制,让主 agent 先后孵化多个子 agent 完成不同的任务。
首先定义一系列 agent 的角色和职责,确保他们权责独立,任务清晰。
再添加一个编排者作为主 agent,负责孵化子 agent。由于 CC 的内部规则,工具不能递归调用(对于当时的版本,子 agent 还叫做 Task,作为工具的形式出现),因此每次只能由主 agent 孵化单个子 agent。
最后定义 skill,明确定义孵化规则以及不同 agent 的出场顺序,指导编排者按照规则统筹整个任务。
此外,skill 中还需要具体的定义出用来让不同子 agent 相互通讯的协议格式:前一个 agent 退出时按照协议格式记下状态信息,新 agent 入场后再按照协议格式读取并理解之前的 context。因此每个 agent 都必须深刻理解并遵守协议,不然通讯就会出现异常。
一开始,这个系统工作的还挺顺利。然而,多进行了几次任务后,就经常容易出现失败的情况。
经常出现的现象是,编排者在调用工具与孵化子 agent 间出现冲突,导致孵化失败。编排者在多次尝试无果后,对我说:“调用子 agent 失败。但是我理解整个流程,后面的流程都交给我来处理吧!”然后由主 agent 越俎代庖,独自走完全程。
现在回头看,这次失败尝试其实很适合被抽象成一个工程问题:
| 项目 | 内容 |
|---|---|
| Input | 一个主任务,以及多个预先拆分好的子任务 |
| Coordination Rules | 谁负责孵化子 agent、谁负责读写 memory、何时退出、何时交接 |
| Communication Protocol | 子 agent 退出前必须记录哪些状态,新 agent 入场后必须恢复哪些 context |
| Failure Point | 工具调用冲突、协议执行不一致、memory 恢复不完整 |
| Outcome | 编排者无法继续调度,系统退化成单 agent 硬扛全流程 |
这个例子让我意识到,multi-agents 的难点往往不在“把角色拆出来”,而在“拆出来以后,怎么稳定地交接回去”。
问题往往不在分工,而在交接
很多人一提到 multi-agents,第一反应都是“可以分工协作”。这当然没错,但分工只是第一步。
真正决定系统稳不稳定的,通常是下面这些事情:
-
上一个 agent 结束时,到底留下了什么信息
-
下一个 agent 进入时,到底恢复了多少信息
-
编排者是否真的有能力验证每个子 agent 的输出是否合格
-
一个子流程失败后,整个系统会回退、重试,还是直接失控
单 agent 的问题,很多时候只是“一个人记不住太多事”。
multi-agents 的问题则变成了“多个人之间还要反复交接,而每次交接都可能丢东西”。
如果把单 agent 看作“把所有复杂度都压在一个 context 里”,那么 multi-agents 更像是“把复杂度分散到多个 context,再额外引入一层协同复杂度”。
所以它并不是免费午餐。拆分任务本身是在降复杂度,但引入编排和通讯,又是在另一个维度上重新加复杂度。
为什么要用 multi-agents?
还不清楚失败的具体原因,但我理解大概率是 Task 和其他 CC 的内部工具调用产生冲突。若果真是工具内部问题,相信 CC 在未来的版本会解决这个问题,甚至可能推出 multi-agents 的独立接口,不过那都是后话。
回归到主题,我并不是想说 multi-agents 多么复杂、难以构建。相对的,我更想站在 multi-agents 的设立初衷,重新梳理一下为什么要用它。
multi-agents 主要是为了解决这些类型的问题:
-
任务的信息量太大,单个 agent 的 context 装不下
-
任务包含多个流程,不希望 agent “既当裁判,又当球员”
-
任何可以拆分成完全独立、能够并行的多个子任务,加速执行
如何更正确地使用 multi-agents?
如果已经确定要用 multi-agents,我现在会更倾向于遵守下面这些原则:
-
先证明单 agent 跑不动,再考虑上 multi-agents,而不是反过来
-
只拆那些边界清晰、输入输出明确、彼此独立的子任务
-
给每个 agent 规定非常具体的职责,不要让它们有大面积职责重叠
-
把交接协议写死,包括输入格式、输出格式、状态字段、失败时如何退出
-
编排者只负责调度和验收,不要既做 orchestrator,又下场干活
-
能并行的才并行;不能并行的硬拆成并行,只会额外制造同步成本
-
给整个系统设置明确的停止条件,一旦某个环节反复失败,就中断交给人
我倾向于把 multi-agents 当成一种有前提的工程手段,而不是默认配置。
它真正适合的,不是“任何复杂任务”,而是那种已经可以被拆成多个稳定子问题、并且子问题之间接口足够清晰的任务。
简言之,多个 agent 协同工作未必天然更强。对普通个人开发者而言,默认先把单 agent 用到极致,再在确有必要时引入 multi-agents,才是更稳妥的策略。