--- tags: - 多Agent - 协调者模式 - 蜂群模式 - 任务编排 create time: 2026-06-09 22:30 --- # 协调者与蜂群模式 - 多 Agent 高级编排 ## 概述 从源码角度解析 Claude Code 多 Agent 协作:Coordinator Mode 的 System Prompt 设计、Worker 生命周期、Task 通信协议和 Swarm 蜂群的任务分配机制。 ## 正文 ### 两种协作模式的架构差异 | 维度 | Coordinator Mode | Agent Swarms | |------|-----------------|--------------| | **门控** | `feature('COORDINATOR_MODE')` + `CLAUDE_CODE_COORDINATOR_MODE=1` | `CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=1` 环境变量 | | **拓扑** | 星型:Coordinator 居中,Worker 外围 | 星型+P2P 混合:Team Lead 协调,Teammate 间可直接通信 | | **角色** | 明确分工:Coordinator 编排、Worker 执行 | Team Lead 协调 + Teammate 自主认领任务 | | **通信** | `SendMessage` 定向通信 + `` | Mailbox 消息系统(message / broadcast) | | **适用** | 需要集中决策的复杂任务 | 并行度高、需要 Teammate 间直接协作的任务 | > [!info] > 两者不是互斥的——理论上 Coordinator Mode 可以在 Agent Teams 架构之上运行(概念层叠加,非嵌套团队),将 Coordinator 作为特殊的 Team Lead,但这部分集成(`workerAgent.ts` 中的 `getCoordinatorAgents`)目前为 stub 实现,尚未完整落地。 ### Coordinator Mode:星型编排架构 #### 激活机制 ```typescript // src/coordinator/coordinatorMode.ts:36 export function isCoordinatorMode(): boolean { if (feature('COORDINATOR_MODE')) { return isEnvTruthy(process.env.CLAUDE_CODE_COORDINATOR_MODE) } return false // 外部构建始终 false } ``` Coordinator Mode 需要双重门控:构建时 `feature('COORDINATOR_MODE')` 和运行时环境变量。`matchSessionMode()` 在会话恢复时自动同步模式状态——如果恢复的会话是 coordinator 模式,它会翻转环境变量以确保一致性。 #### Coordinator 的工具集 Coordinator 被剥夺了所有"动手"工具,只保留编排能力: | 工具 | 用途 | |------|------| | **Agent** | 启动新 Worker(`subagent_type: "worker"`) | | **SendMessage** | 向已有 Worker 发送后续指令 | | **TaskStop** | 中途停止走错方向的 Worker | | **subscribe_pr_activity** | 订阅 GitHub PR 事件(review comments、CI 结果) | > [!tip] > Coordinator **不写代码、不读文件、不执行命令**——它的核心职责是:理解需求、分配任务、综合结果,以及在无需工具时直接回答用户问题。 #### Worker 的工具权限 Worker 的可用工具由 `getCoordinatorUserContext()`(`coordinatorMode.ts:80`)动态注入到 System Prompt: ```typescript // 简化模式下:只有 Bash + Read + Edit const workerTools = isEnvTruthy(process.env.CLAUDE_CODE_SIMPLE) ? [BASH_TOOL_NAME, FILE_READ_TOOL_NAME, FILE_EDIT_TOOL_NAME] : Array.from(ASYNC_AGENT_ALLOWED_TOOLS) .filter(name => !INTERNAL_WORKER_TOOLS.has(name)) ``` `INTERNAL_WORKER_TOOLS`(TeamCreate、TeamDelete、SendMessage、SyntheticOutput)被显式排除——Worker 不能嵌套创建团队或发送消息,防止不可控的递归。 #### Scratchpad:跨 Worker 的共享知识库 当 `isScratchpadGateEnabled()`(内部检查 `tengu_scratch` feature gate)启用时,Workers 获得一个 Scratchpad 目录,Coordinator 通过其系统上下文知晓该目录的存在: - Workers 可自由读写,无需权限审批 - 用于持久化的跨 Worker 知识 - 结构由 Coordinator 决定(无固定格式) > [!tip] > 这是一个关键的协作原语——Worker A 的研究结果可以写入 Scratchpad,Worker B 直接读取,无需通过 Coordinator 中转。 #### \ 通信协议 Worker 完成后,Coordinator 收到 XML 格式的通知: ```xml agent-a1b completed|failed|killed Agent "Investigate auth bug" completed Found null pointer in src/auth/validate.ts:42... N N N ``` 通知以 `user-role message` 形式送达,Coordinator 通过 `` 标签区分它和用户消息。`` 用于 `SendMessage` 的 `to` 参数,实现定向续传。 #### Coordinator 的核心职责:综合(Synthesis) Coordinator System Prompt(`coordinatorMode.ts:111-369`,约 260 行)明确要求 Coordinator **不能懒惰地委派理解**: ```text 反模式(禁止): "Based on your findings, fix the auth bug" → 把理解的责任推给了 Worker 正确做法: "Fix the null pointer in src/auth/validate.ts:42. The user field on Session (src/auth/types.ts:15) is undefined when sessions expire but the token remains cached. Add a null check before user.id access." → Coordinator 自己理解了问题,给出精确指令 ``` > [!question] 为什么 Coordinator 必须先理解再分配? > 这是 Coordinator Mode 最核心的设计约束。如果 Coordinator 把理解的责任推给 Worker,它就失去了编排的价值——Worker 拿到模糊指令,可能走错方向,浪费 token 和时间。 ### Agent Teams (Swarm):蜂群式协作 Swarm 模式基于任务系统 V2,核心机制是**共享任务列表 + 竞争认领 + Mailbox 消息系统**。 #### 团队初始化 ```mermaid graph TD A["Team Lead 创建团队 TeamCreateTool"] --> B["设置 teamName"] B --> C["setLeaderTeamName()"] C --> D["所有 Teammate 自动获得相同的 taskListId"] D --> E["Teammate 启动时按优先级获取 taskListId"] E --> F["1. CLAUDE_CODE_TASK_LIST_ID 环境变量"] E --> G["2. Teammate 上下文的 teamName"] E --> H["3. CLAUDE_CODE_TEAM_NAME 环境变量"] E --> I["4. Lead 设置的 teamName"] E --> J["5. getSessionId() 兜底"] ``` 多级优先级确保了 Team Lead 和所有 Teammate 指向同一个任务列表,无需额外协调。 #### 架构组件 | 组件 | 角色 | |------|------| | **Team Lead** | 创建团队、分配任务、综合结果的主 Claude Code 会话 | | **Teammate** | 独立的 Claude Code 实例,各自拥有独立的上下文窗口 | | **Task List** | 共享的任务列表,Teammate 竞争认领和完成 | | **Mailbox** | 消息系统,支持 Teammate 间直接通信 | #### Mailbox 消息系统 Mailbox 是 Teammate 间通信的核心原语,支持两种消息模式(`broadcast` 模式来自源码推断,官方文档未明确细分): | 模式 | 作用 | 场景 | |------|------|------| | **message** | 定向发送给指定 Teammate | 传递具体指令、请求协作 | | **broadcast** | 广播给所有 Teammate | 全局通知、状态同步 | Mailbox 的关键特性: - **自动投递**:消息自动送达目标 Teammate 的对话上下文 - **空闲通知**(TeammateIdle):Teammate 完成当前任务进入空闲时,自动通过 Mailbox 通知 Team Lead - **直接通信**:与 Coordinator Mode 不同,Teammate 之间可以直接通信,无需经过 Lead 中转 #### Hook 事件 Agent Teams 提供三个关键 Hook 事件,用于在团队生命周期中注入自定义逻辑: | Hook | 触发时机 | 典型用途 | |------|---------|---------| | **TaskCreated** | 新任务添加到任务列表时 | 自动分配、优先级排序 | | **TaskCompleted** | 任务标记为完成时 | 结果通知、依赖解锁 | | **TeammateIdle** | Teammate 完成所有任务进入空闲时 | Lead 重新分配、动态扩缩容 | #### 限制 > [!warning] > 当前 Agent Teams 实现存在以下限制: > - **不支持嵌套团队**:Teammate 不能再创建子团队 > - **每 session 一个团队**:一个会话只能属于一个团队 > - **Lead 固定**:Team Lead 创建后不可更换 > - **不支持 in-process Teammate 的会话恢复**:进程重启后 in-process 类型 Teammate 的状态丢失 #### 持久化存储 团队状态通过文件系统持久化,确保进程重启后可恢复: ```text ~/.claude/teams/{team-name}/config.json ← 团队配置 ~/.claude/tasks/{team-name}/ ← 共享任务列表(文件锁保护) ``` #### 任务认领与竞争 `claimTask()` 是 Agent Teams 的核心并发原语: ```mermaid graph TD A["Teammate A 调用 TaskList"] --> C["发现 task #3 是 pending"] B["Teammate B 同时发现 task #3 是 pending"] --> C C --> D["两者同时尝试 TaskUpdate"] D --> E["文件锁保证原子性"] E --> F["第一个写入者获得 owner 锁定"] E --> G["第二个写入者收到 already_claimed 错误"] F --> H["获得任务的 teammate 执行工作"] H --> I["完成后 TaskUpdate task #3 completed"] I --> J["依赖此任务的其他任务自动解锁"] I --> K["tool_result 提示 Call TaskList to find your next task"] ``` #### Teammate 的生命周期管理 ```mermaid graph TD A["Teammate 异常退出"] --> B["unassignTeammateTasks()"] B --> C["扫描任务列表找到 owner === teammateName 的未完成任务"] C --> D["重置为 pending + owner=undefined"] D --> E["Team Lead 感知途径"] E --> F["1. 任务状态变化通过共享任务列表"] E --> G["2. Mailbox 空闲通知 TeammateIdle hook"] F --> H["Team Lead 重新分配任务或创建新 Teammate"] G --> H ``` ### 任务类型全景 支撑多 Agent 协作的是 7 种任务类型(`src/tasks/types.ts`): | 任务类型 | 运行位置 | 状态管理 | 适用场景 | |----------|---------|---------|---------| | **LocalAgentTask** | 本地子进程 | `LocalAgentTaskState` | 标准子 Agent 任务 | | **LocalShellTask** | 本地 shell | `LocalShellTaskState` | 后台 shell 命令 | | **InProcessTeammateTask** | 同进程内 | `InProcessTeammateTaskState` | 轻量级进程内队友 | | **RemoteAgentTask** | 远程服务器 | `RemoteAgentTaskState` | 分布式 Agent(CCR) | | **DreamTask** | 后台静默 | `DreamTaskState` | 后台自主整理记忆 | | **LocalWorkflowTask** | 本地 | `LocalWorkflowTaskState` | 工作流编排 | | **MonitorMcpTask** | 本地 | `MonitorMcpTaskState` | MCP 监控任务 | > [!tip] > `InProcessTeammateTask` 与 `LocalAgentTask` 的关键差异:前者共享进程的内存空间和基础设施状态(如 MCP 连接池),但有独立的对话上下文和工具权限;后者是完全隔离的子进程,启动开销更大但更安全。 ### Coordinator vs Agent Teams 的选择 | 场景 | 推荐模式 | 原因 | |------|---------|------| | "重构认证系统,需要多模块协调" | Coordinator | 需要集中决策,Worker 间有依赖 | | "修复 10 个独立的 lint 警告" | Agent Teams | 任务独立,Teammate 可完全并行 | | "研究方案 A 和方案 B,然后选一个实现" | Coordinator | 先并行研究,再集中决策 | | "在大仓库中搜索所有 TODO 并分类" | Agent Teams | 无依赖,各自领任务即可 | ## 关联笔记 - [[sub-agents]] - [[worktree-isolation]]