|
1 | 1 | --- |
2 | 2 | title: "协调者与蜂群模式 - 多 Agent 高级编排" |
3 | | -description: "详解 Claude Code 多 Agent 高级协作模式:Coordinator Mode 协调者模式和 Agent Swarms 蜂群模式的设计理念、调度策略和适用场景。" |
| 3 | +description: "从源码角度解析 Claude Code 多 Agent 协作:Coordinator Mode 的 System Prompt 设计、Worker 生命周期、Task 通信协议和 Swarm 蜂群的任务分配机制。" |
4 | 4 | keywords: ["协调者模式", "蜂群模式", "Agent Swarm", "多 Agent 协作", "任务编排"] |
5 | 5 | --- |
6 | 6 |
|
7 | | -{/* 本章目标:介绍 Coordinator Mode 和 Agent Swarms */} |
| 7 | +{/* 本章目标:从源码角度揭示 Coordinator Mode 和 Agent Swarms 的架构设计 */} |
8 | 8 |
|
9 | | -## 两种协作模式 |
| 9 | +## 两种协作模式的架构差异 |
10 | 10 |
|
11 | | -子 Agent 是"临时帮手"——主 Agent 派出去做一件事就回来。对于更复杂的协作需求,Claude Code 提供了两种高级模式: |
| 11 | +| 维度 | Coordinator Mode | Agent Swarms | |
| 12 | +|------|-----------------|--------------| |
| 13 | +| **门控** | `feature('COORDINATOR_MODE')` + `CLAUDE_CODE_COORDINATOR_MODE=1` | 任务系统 V2(默认启用) | |
| 14 | +| **拓扑** | 星型:Coordinator 居中,Worker 外围 | 网状:对等 Agent 共享任务列表 | |
| 15 | +| **角色** | 明确分工:Coordinator 编排、Worker 执行 | 模糊:每个 Agent 自主认领任务 | |
| 16 | +| **通信** | `SendMessage` 定向通信 + `<task-notification>` | 任务文件系统 + 邮箱广播 | |
| 17 | +| **适用** | 需要集中决策的复杂任务 | 并行度高的独立子任务 | |
12 | 18 |
|
13 | | -## Coordinator Mode:一个指挥,多个执行 |
| 19 | +两者不是互斥的——Coordinator Mode 可以在 Swarm 架构之上运行,将 Coordinator 作为特殊的 Leader Agent。 |
14 | 20 |
|
15 | | -就像一个团队 leader 带着几个开发者: |
| 21 | +## Coordinator Mode:星型编排架构 |
16 | 22 |
|
17 | | -- **Coordinator**(协调者):负责理解需求、拆解任务、分配工作、汇总结果 |
18 | | -- **Workers**(执行者):各自领取任务独立执行,通过邮箱向 Coordinator 汇报 |
| 23 | +### 激活机制 |
19 | 24 |
|
| 25 | +```typescript |
| 26 | +// src/coordinator/coordinatorMode.ts:36 |
| 27 | +export function isCoordinatorMode(): boolean { |
| 28 | + if (feature('COORDINATOR_MODE')) { |
| 29 | + return isEnvTruthy(process.env.CLAUDE_CODE_COORDINATOR_MODE) |
| 30 | + } |
| 31 | + return false // 外部构建始终 false |
| 32 | +} |
20 | 33 | ``` |
21 | | - ┌─── Worker A (重构 API) |
22 | | - │ |
23 | | -Coordinator ──┼─── Worker B (更新测试) |
24 | | - │ |
25 | | - └─── Worker C (更新文档) |
| 34 | + |
| 35 | +Coordinator Mode 需要双重门控:构建时 `feature('COORDINATOR_MODE')` 和运行时环境变量。`matchSessionMode()` 在会话恢复时自动同步模式状态——如果恢复的会话是 coordinator 模式,它会翻转环境变量以确保一致性。 |
| 36 | + |
| 37 | +### Coordinator 的工具集 |
| 38 | + |
| 39 | +Coordinator 被剥夺了所有"动手"工具,只保留编排能力: |
| 40 | + |
| 41 | +| 工具 | 用途 | |
| 42 | +|------|------| |
| 43 | +| **Agent** | 启动新 Worker(`subagent_type: "worker"`) | |
| 44 | +| **SendMessage** | 向已有 Worker 发送后续指令 | |
| 45 | +| **TaskStop** | 中途停止走错方向的 Worker | |
| 46 | +| **subscribe_pr_activity** | 订阅 GitHub PR 事件(review comments、CI 结果) | |
| 47 | + |
| 48 | +Coordinator **不写代码、不读文件、不执行命令**——它只做三件事:理解需求、分配任务、综合结果。 |
| 49 | + |
| 50 | +### Worker 的工具权限 |
| 51 | + |
| 52 | +Worker 的可用工具由 `getCoordinatorUserContext()`(`coordinatorMode.ts:80`)动态注入到 System Prompt: |
| 53 | + |
| 54 | +```typescript |
| 55 | +// 简化模式下:只有 Bash + Read + Edit |
| 56 | +const workerTools = isEnvTruthy(process.env.CLAUDE_CODE_SIMPLE') |
| 57 | + ? [BASH_TOOL_NAME, FILE_READ_TOOL_NAME, FILE_EDIT_TOOL_NAME] |
| 58 | + : Array.from(ASYNC_AGENT_ALLOWED_TOOLS) |
| 59 | + .filter(name => !INTERNAL_WORKER_TOOLS.has(name)) |
| 60 | +``` |
| 61 | +
|
| 62 | +`INTERNAL_WORKER_TOOLS`(TeamCreate、TeamDelete、SendMessage、SyntheticOutput)被显式排除——Worker 不能嵌套创建团队或发送消息,防止不可控的递归。 |
| 63 | +
|
| 64 | +### Scratchpad:跨 Worker 的共享知识库 |
| 65 | +
|
| 66 | +当 `tengu_scratch` feature flag 启用时,Coordinator 拥有一个 Scratchpad 目录: |
| 67 | +
|
| 68 | +``` |
| 69 | +Scratchpad 目录: |
| 70 | + - Workers 可自由读写,无需权限审批 |
| 71 | + - 用于持久化的跨 Worker 知识 |
| 72 | + - 结构由 Coordinator 决定(无固定格式) |
| 73 | +``` |
| 74 | +
|
| 75 | +这是一个关键的协作原语——Worker A 的研究结果可以写入 Scratchpad,Worker B 直接读取,无需通过 Coordinator 中转。 |
| 76 | +
|
| 77 | +### `<task-notification>` 通信协议 |
| 78 | +
|
| 79 | +Worker 完成后,Coordinator 收到 XML 格式的通知: |
| 80 | +
|
| 81 | +```xml |
| 82 | +<task-notification> |
| 83 | + <task-id>agent-a1b</task-id> ← Worker 的 agentId |
| 84 | + <status>completed|failed|killed</status> |
| 85 | + <summary>Agent "Investigate auth bug" completed</summary> |
| 86 | + <result>Found null pointer in src/auth/validate.ts:42...</result> |
| 87 | + <usage> |
| 88 | + <total_tokens>N</total_tokens> |
| 89 | + <tool_uses>N</tool_uses> |
| 90 | + <duration_ms>N</duration_ms> |
| 91 | + </usage> |
| 92 | +</task-notification> |
26 | 93 | ``` |
27 | 94 |
|
28 | | -Coordinator 不自己写代码,它的职责是**编排**——确保所有 Worker 的工作能拼合在一起。 |
| 95 | +通知以 `user-role message` 形式送达,Coordinator 通过 `<task-notification>` 标签区分它和用户消息。`<task-id>` 用于 `SendMessage` 的 `to` 参数,实现定向续传。 |
| 96 | +
|
| 97 | +### Coordinator 的核心职责:综合(Synthesis) |
| 98 | +
|
| 99 | +Coordinator System Prompt(`coordinatorMode.ts:111-369`,约 260 行)明确要求 Coordinator **不能懒惰地委派理解**: |
| 100 | +
|
| 101 | +``` |
| 102 | +反模式(禁止): |
| 103 | + "Based on your findings, fix the auth bug" |
| 104 | + → 把理解的责任推给了 Worker |
| 105 | + |
| 106 | +正确做法: |
| 107 | + "Fix the null pointer in src/auth/validate.ts:42. |
| 108 | + The user field on Session (src/auth/types.ts:15) is |
| 109 | + undefined when sessions expire but the token remains cached. |
| 110 | + Add a null check before user.id access." |
| 111 | + → Coordinator 自己理解了问题,给出精确指令 |
| 112 | +``` |
| 113 | +
|
| 114 | +这是 Coordinator Mode 最核心的设计约束:Coordinator 必须先理解,再分配。 |
29 | 115 |
|
30 | 116 | ## Agent Swarms:蜂群式协作 |
31 | 117 |
|
32 | | -比 Coordinator 更松散的协作模式: |
| 118 | +Swarm 模式基于任务系统 V2(详见[任务管理](../tools/task-management.mdx)),核心机制是**共享任务列表 + 竞争认领**: |
| 119 | +
|
| 120 | +### 团队初始化 |
| 121 | +
|
| 122 | +``` |
| 123 | +Leader 创建团队(TeamCreateTool) |
| 124 | + ↓ |
| 125 | +设置 teamName → setLeaderTeamName() |
| 126 | + ↓ |
| 127 | +所有 teammate 自动获得相同的 taskListId |
| 128 | + ↓ |
| 129 | +teammate 启动时: |
| 130 | + 1. CLAUDE_CODE_TASK_LIST_ID 环境变量(显式覆盖) |
| 131 | + 2. teammate 上下文的 teamName(共享 leader 的任务列表) |
| 132 | + 3. CLAUDE_CODE_TEAM_NAME 环境变量 |
| 133 | + 4. leader 设置的 teamName |
| 134 | + 5. getSessionId()(兜底) |
| 135 | +``` |
| 136 | +
|
| 137 | +多级优先级确保了 Leader 和所有 Teammate 指向同一个任务列表,无需额外协调。 |
| 138 | +
|
| 139 | +### 任务认领与竞争 |
33 | 140 |
|
34 | | -- 多个 Agent 以对等身份同时工作 |
35 | | -- 没有中心化的指挥者 |
36 | | -- 通过消息邮箱互相通信和协调 |
37 | | -- 适合"各自负责一块、偶尔需要沟通"的场景 |
| 141 | +`claimTask()` 是 Swarm 的核心并发原语: |
38 | 142 |
|
39 | | -## Teammate 机制 |
| 143 | +``` |
| 144 | +Teammate A 调用 TaskList → 发现 task #3 是 pending |
| 145 | +Teammate B 同时发现 task #3 是 pending |
| 146 | + ↓ |
| 147 | +两者同时尝试 TaskUpdate(task #3, {status: "in_progress"}) |
| 148 | + ↓ |
| 149 | +文件锁 + 高水位标记保证原子性: |
| 150 | + - 第一个写入者获得 owner 锁定 |
| 151 | + - 第二个写入者收到 already_claimed 错误 |
| 152 | + ↓ |
| 153 | +获得任务的 teammate 执行工作 |
| 154 | + ↓ |
| 155 | +完成后 TaskUpdate(task #3, {status: "completed"}) |
| 156 | + → 依赖此任务的其他任务自动解锁 |
| 157 | + → tool_result 提示 "Call TaskList to find your next task" |
| 158 | +``` |
| 159 | +
|
| 160 | +### Teammate 的生命周期管理 |
| 161 | +
|
| 162 | +``` |
| 163 | +Teammate 异常退出 |
| 164 | + ↓ |
| 165 | +unassignTeammateTasks() |
| 166 | + → 扫描任务列表,找到 owner === teammateName 的未完成任务 |
| 167 | + → 重置为 pending + owner=undefined |
| 168 | + ↓ |
| 169 | +Leader 通过 mailbox 收到通知 |
| 170 | + → 重新分配或创建新 Teammate |
| 171 | +``` |
40 | 172 |
|
41 | | -进程内的"队友"——一种更轻量的协作方式: |
| 173 | +## 任务类型全景 |
42 | 174 |
|
43 | | -- 在同一个进程内运行,共享部分基础设施状态 |
44 | | -- 有独立的对话上下文和工具权限 |
45 | | -- 适合"我需要一个搭档帮忙看看这段代码"的场景 |
| 175 | +支撑多 Agent 协作的是 7 种任务类型(`src/tasks/types.ts`): |
46 | 176 |
|
47 | | -## 任务类型 |
| 177 | +| 任务类型 | 运行位置 | 状态管理 | 适用场景 | |
| 178 | +|----------|---------|---------|---------| |
| 179 | +| **LocalAgentTask** | 本地子进程 | `LocalAgentTaskState` | 标准子 Agent 任务 | |
| 180 | +| **LocalShellTask** | 本地 shell | `LocalShellTaskState` | 后台 shell 命令 | |
| 181 | +| **InProcessTeammateTask** | 同进程内 | `InProcessTeammateTaskState` | 轻量级进程内队友 | |
| 182 | +| **RemoteAgentTask** | 远程服务器 | `RemoteAgentTaskState` | 分布式 Agent(CCR) | |
| 183 | +| **DreamTask** | 后台静默 | `DreamTaskState` | 后台自主整理记忆 | |
| 184 | +| **LocalWorkflowTask** | 本地 | `LocalWorkflowTaskState` | 工作流编排 | |
| 185 | +| **MonitorMcpTask** | 本地 | `MonitorMcpTaskState` | MCP 监控任务 | |
48 | 186 |
|
49 | | -支撑多 Agent 协作的是丰富的任务类型: |
| 187 | +`InProcessTeammateTask` 与 `LocalAgentTask` 的关键差异:前者共享进程的内存空间和基础设施状态(如 MCP 连接池),但有独立的对话上下文和工具权限;后者是完全隔离的子进程,启动开销更大但更安全。 |
50 | 188 |
|
51 | | -| 任务类型 | 用途 | |
52 | | -|----------|------| |
53 | | -| **LocalAgentTask** | 本地子 Agent 任务 | |
54 | | -| **LocalShellTask** | 后台 shell 命令 | |
55 | | -| **InProcessTeammateTask** | 进程内队友 | |
56 | | -| **RemoteAgentTask** | 远程 Agent | |
57 | | -| **DreamTask** | 后台自主任务 | |
| 189 | +## Coordinator vs Swarm 的选择 |
58 | 190 |
|
59 | | -每种任务类型都有自己的生命周期管理、状态追踪和通信方式。 |
| 191 | +| 场景 | 推荐模式 | 原因 | |
| 192 | +|------|---------|------| |
| 193 | +| "重构认证系统,需要多模块协调" | Coordinator | 需要集中决策,Worker 间有依赖 | |
| 194 | +| "修复 10 个独立的 lint 警告" | Swarm | 任务独立,可完全并行 | |
| 195 | +| "研究方案 A 和方案 B,然后选一个实现" | Coordinator | 先并行研究,再集中决策 | |
| 196 | +| "在大仓库中搜索所有 TODO 并分类" | Swarm | 无依赖,各自领任务即可 | |
0 commit comments