Coordinator Pattern
coordinator 模式从根本上改变了 Claude Code 的运作方式。主 Claude 实例不再独自完成所有工作,而是成为一个coordinator,将任务委托给并行的 worker agent。该模式通过 CLAUDE_CODE_COORDINATOR_MODE 环境变量启用,并受 COORDINATOR_MODE feature flag 控制。
export function isCoordinatorMode(): boolean { if (feature('COORDINATOR_MODE')) { return isEnvTruthy(process.env.CLAUDE_CODE_COORDINATOR_MODE) } return false}coordinator 模式激活时,整套内置 agent 集合会被替换:
if (feature('COORDINATOR_MODE')) { if (isEnvTruthy(process.env.CLAUDE_CODE_COORDINATOR_MODE)) { const { getCoordinatorAgents } = require('../../coordinator/workerAgent.js') return getCoordinatorAgents() // 完全不同的 agent 阵容 }}graph TD
U[User] <-->|conversation| C[Coordinator]
C -->|Agent tool| W1[Worker 1: Research]
C -->|Agent tool| W2[Worker 2: Implement]
C -->|Agent tool| W3[Worker 3: Verify]
C -->|SendMessage| W1
C -->|TaskStop| W2
W1 -.->|task-notification| C
W2 -.->|task-notification| C
W3 -.->|task-notification| C
style C fill:#f9f,stroke:#333,stroke-width:2px
style W1 fill:#bbf,stroke:#333
style W2 fill:#bbf,stroke:#333
style W3 fill:#bbf,stroke:#333
coordinator 拥有三个专门用于 worker 管理的 tool:
| Tool | 用途 |
|---|---|
| Agent | 派生新 worker |
| SendMessage | 继续已有 worker(向其 agent ID 发送后续指令) |
| TaskStop | 停止正在运行的 worker |
Coordinator System Prompt
Section titled “Coordinator System Prompt”coordinator system prompt(getCoordinatorSystemPrompt())是一份约 370 行的详细文档,定义了 coordinator 的行为。关键部分如下:
You are Claude Code, an AI assistant that orchestrates software engineeringtasks across multiple workers.
You are a coordinator. Your job is to:- Help the user achieve their goal- Direct workers to research, implement and verify code changes- Synthesize results and communicate with the user- Answer questions directly when possible — don't delegate work that you can handle without tools任务工作流阶段
Section titled “任务工作流阶段”coordinator 以结构化的阶段运作:
flowchart LR
R[Research<br/>Workers parallel] --> S[Synthesis<br/>Coordinator]
S --> I[Implementation<br/>Workers] --> V[Verification<br/>Workers]
V -->|failures| S
| 阶段 | 执行者 | 目的 |
|---|---|---|
| Research | Worker(并行) | 调查代码库、查找文件、理解问题 |
| Synthesis | Coordinator | 读取发现、制定实现规格 |
| Implementation | Worker | 按规格进行针对性修改并提交 |
| Verification | Worker | 测试修改是否生效 |
Worker 通信协议
Section titled “Worker 通信协议”Worker 通过 <task-notification> XML 消息汇报结果,这些消息以 user 角色消息的形式到达:
<task-notification> <task-id>{agentId}</task-id> <status>completed|failed|killed</status> <summary>{human-readable status summary}</summary> <result>{agent's final text response}</result> <usage> <total_tokens>N</total_tokens> <tool_uses>N</tool_uses> <duration_ms>N</duration_ms> </usage></task-notification>coordinator prompt 明确编码了并发约束:
Parallelism is your superpower. Workers are async. Launch independentworkers concurrently whenever possible.
Manage concurrency:- Read-only tasks (research) — run in parallel freely- Write-heavy tasks (implementation) — one at a time per set of files- Verification can sometimes run alongside implementation on different file areasWorker Context 注入
Section titled “Worker Context 注入”coordinator 通过 getCoordinatorUserContext() 将 worker 能力信息注入自身的 context:
export function getCoordinatorUserContext( mcpClients: ReadonlyArray<{ name: string }>, scratchpadDir?: string,): { [k: string]: string } { if (!isCoordinatorMode()) return {}
const workerTools = isEnvTruthy(process.env.CLAUDE_CODE_SIMPLE) ? [BASH_TOOL_NAME, FILE_READ_TOOL_NAME, FILE_EDIT_TOOL_NAME].sort().join(', ') : Array.from(ASYNC_AGENT_ALLOWED_TOOLS) .filter(name => !INTERNAL_WORKER_TOOLS.has(name)) .sort() .join(', ')
let content = `Workers spawned via the Agent tool have access to these tools: ${workerTools}`
if (mcpClients.length > 0) { const serverNames = mcpClients.map(c => c.name).join(', ') content += `\n\nWorkers also have access to MCP tools from connected MCP servers: ${serverNames}` }
if (scratchpadDir && isScratchpadGateEnabled()) { content += `\n\nScratchpad directory: ${scratchpadDir}Workers can read and write here without permission prompts.Use this for durable cross-worker knowledge.` }
return { workerToolsContext: content }}内部 tool(TeamCreate、TeamDelete、SendMessage、SyntheticOutput)会从 worker 能力列表中过滤掉——worker 不应了解 coordinator 的内部机制。
Synthesis:Coordinator 的核心职责
Section titled “Synthesis:Coordinator 的核心职责”coordinator prompt 中最关键的设计原则是synthesis 所有权。coordinator 必须理解 research 发现后,再指导后续工作:
Never write "based on your findings" or "based on the research."These phrases delegate understanding to the worker instead of doingit yourself. You never hand off understanding to another worker.
// 反模式——懒惰委托(错误)Agent({ prompt: "Based on your findings, fix the auth bug", ... })
// 正确——经过 synthesis 的规格说明Agent({ prompt: "Fix the null pointer in src/auth/validate.ts:42.The user field on Session is undefined when sessions expire butthe token remains cached. Add a null check before user.id access —if null, return 401 with 'Session expired'. Commit and reportthe hash.", ... })Continue 与 Spawn 的决策
Section titled “Continue 与 Spawn 的决策”coordinator 必须决定是继续现有 worker(保留其 context)还是派生新 worker:
| 场景 | 机制 | 原因 |
|---|---|---|
| Research 已精确探索了所需文件 | Continue | Worker 的 context 中已有这些文件 |
| Research 范围较广,实现较为聚焦 | Spawn fresh | 避免 context 噪音 |
| 纠正失败 | Continue | Worker 已有错误 context |
| 验证另一个 worker 的代码 | Spawn fresh | 全新视角,无实现假设 |
| 方向完全错误 | Spawn fresh | 从零开始,避免锚定在失败路径上 |
Session 模式持久化
Section titled “Session 模式持久化”coordinator 模式按 session 持久化。恢复 session 时,模式会被匹配:
export function matchSessionMode( sessionMode: 'coordinator' | 'normal' | undefined,): string | undefined { const currentIsCoordinator = isCoordinatorMode() const sessionIsCoordinator = sessionMode === 'coordinator'
if (currentIsCoordinator === sessionIsCoordinator) return undefined
// 翻转环境变量以匹配 session if (sessionIsCoordinator) { process.env.CLAUDE_CODE_COORDINATOR_MODE = '1' } else { delete process.env.CLAUDE_CODE_COORDINATOR_MODE }
return sessionIsCoordinator ? 'Entered coordinator mode to match resumed session.' : 'Exited coordinator mode to match resumed session.'}这确保恢复 coordinator session 时会重新进入 coordinator 模式,即使环境变量未设置也能正常工作。