chapter 07 / 多 Agent 编排层
多 Agent 协作
受限子代理、消息总线与验证者:编排多个循环
一个循环不够用的时候怎么办?答案不是把循环做大,而是编排多个循环。但多 Agent 是一把双刃剑——这一章先讲清楚「什么时候值得」,再讲「怎么绑住它们」。
先泼冷水:多 Agent 不是默认选择
Anthropic 的多 Agent 研究系统是目前公开细节最多的工业案例:lead agent 把研究任务分解给多个并行 subagents,各自探索后汇总——比单 Agent 基线提升 90.2%。但同一篇文章也如实报告了代价:token 消耗成倍增长、编排与调试复杂度陡增。
How we built our multi-agent research system ↗
主 Agent 协调多个并行子代理做研究,比单 Agent 提升 90.2%;代价是 token 消耗与编排复杂度——多 Agent 是有明确适用边界的架构选择。
判断标准又回到了那条原则:先问「单 Agent + 好工具够不够」。适合多 Agent 的任务有明显特征——可并行探索(研究、对比、多路验证)、上下文天然可分(每个子任务不需要看到全局)、产出可合并。
怎么「绑」比怎么「生」更重要
派生子代理很容易,难的是不让它们互相踩踏、无限繁殖。受限子代理(Bounded Subagent)的常见约束:
- 只读模式:不能写文件、不能执行破坏性命令;
- 限定递归深度:子代理不能再生孙子代理;
- 继承沙盒与审批配置:主 Agent 的安全边界自动传递;
- 上下文隔离:子代理的过程细节不进父对话,只返回最终结论——这同时解决了上下文污染。
专职化是另一条路径:验证子代理只负责检查别人的工作(代码审查、测试执行),它与生成者角色分离,正是第 3 章 Anthropic 三 Agent Harness(Planner → Generator → Evaluator)里 Evaluator 的位置——受 GAN 启发的生成/判别分工(GAN 式多 Agent 架构)。
通信拓扑:三种协作模式
| 模式 | 机制 | 适合 | 风险 |
|---|---|---|---|
| 层级调度 | 监督者分派、汇总 | 任务可分解、结构清晰 | 监督者成瓶颈 |
| 消息总线 | 发布/订阅 + 路由器 | 事件驱动、生态持续扩编 | 事件链难 debug、路由错误静默崩溃 |
| 共享状态 | 读写同一状态存储/文件 | 松散协作、跨窗口接力 | 竞争条件、需要幂等 |
升级信号:层级调度里的 If-Else 越堆越多时,考虑换消息总线。文件也是一种共享状态通道——第 3 章讲过 Anthropic 的三 Agent 通过文件通信,持久且可审计。
源码走读:子代理即工具
多 Agent 编排听起来需要一门新的「编排语言」,openJiuwen 的实现却出奇地优雅——监督者就是一个 ReActAgent,子代理注册成它的工具:
source walkthrough
SupervisorAgent:把子代理注册成 LLM 的一个工具
openJiuwen-ai/agent-core @ 1e3a5c7a3d · openjiuwen/core/multi_agent/teams/hierarchical_msgbus/supervisor_agent.py:20-140 · 提取于 2026-07-18
多 Agent 编排最优雅的实现思路:监督者自己就是一个 ReActAgent,而每个子代理以 AgentCard 的形式注册成它的「工具」——模型在循环里调用子代理,就像调用 read_file 一样自然。
- 段 1L20–41监督者 = 通信能力 + ReAct 循环
class SupervisorAgent(CommunicableAgent, ReActAgent): """Default LLM-driven supervisor for :class:`HierarchicalTeam`. Combines :class:`CommunicableAgent` (P2P send/publish) and :class:`ReActAgent` (ReAct loop). AgentCard tool calls are routed via :class:`P2PAbilityManager`; all other ability types execute normally. """ def __init__( self, card: AgentCard, config: Optional[ReActAgentConfig] = None, max_parallel_sub_agents: int = 10, ) -> None: super().__init__(card=card) if config is not None: ReActAgent.configure(self, config) self._ability_manager = P2PAbilityManager( supervisor=self, max_parallel_sub_agents=max_parallel_sub_agents, )多重继承讲清了架构:监督者 = CommunicableAgent(会发消息)+ ReActAgent(会转循环)。它没有新发明一种「编排语言」——决策仍由第 2 章那个 ReAct 循环做,只是把 ability_manager 换成 P2PAbilityManager:模型发出的 AgentCard 类工具调用被路由成对子代理的消息分发,且并行度有上限(max_parallel_sub_agents=10,多 Agent 也要有预算)。
- 段 2L130–140注册子代理:AgentCard 变成 LLM 可见的工具
def register_sub_agent_card(self, card: AgentCard) -> None: """Expose a sub-agent card to the LLM as a callable tool. Args: card: AgentCard of the sub-agent. """ self._ability_manager.add(card) logger.debug( f"[{self.__class__.__name__}] registered sub-agent " f"'{card.name}' (id={card.id}) as LLM tool" )docstring 就是设计思想:expose a sub-agent card to the LLM as a callable tool。子代理对模型而言只是又一个带名字和描述的工具——这与 Claude Code 的 Agent 工具、Anthropic 多 Agent 研究系统里「lead agent 派生 subagents」是同一个模式。工具抽象统一了「调用函数」与「委托一个循环」。
这个模式的美妙之处:第 2 章的循环、第 5 章的工具抽象,原封不动地复用到了多 Agent 场景。模型不需要学习新概念——委托一个子代理,和调用 read_file 是同一个动作。jiuwenswarm 仓库则把这套机制扩展成完整的多 Agent 协作框架(symphony 模块:图编排、经验沉淀、指纹去重)。
本章能力在 Harness 中处于什么位置?
harness positioning
本章能力在 Harness 中处于什么位置?
编排层在最顶端:它把 N 个「循环 + 上下文 + 工具」的完整栈组织成团队。注意它复用而非重造下层——子代理即工具(工具暴露层)、上下文隔离(上下文管理层)、并行度上限(循环驱动层的预算思想)。
本章概念清单 / 点击进入概念卡片
章末测验
chapter quiz
0/4 已答
Q1受限子代理(Bounded Subagent)的核心设计问题是?
Q2openJiuwen 的 SupervisorAgent 如何调度子代理?
Q3消息总线模式最适合的场景是?
Q4Anthropic 多 Agent 研究系统的结论,多 Agent 的适用边界是?