跳转到内容

Coordinator Pattern

coordinator 模式从根本上改变了 Claude Code 的运作方式。主 Claude 实例不再独自完成所有工作,而是成为一个coordinator,将任务委托给并行的 worker agent。该模式通过 CLAUDE_CODE_COORDINATOR_MODE 环境变量启用,并受 COORDINATOR_MODE feature flag 控制。

src/coordinator/coordinatorMode.ts
export function isCoordinatorMode(): boolean {
if (feature('COORDINATOR_MODE')) {
return isEnvTruthy(process.env.CLAUDE_CODE_COORDINATOR_MODE)
}
return false
}

coordinator 模式激活时,整套内置 agent 集合会被替换:

src/tools/AgentTool/builtInAgents.ts
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(getCoordinatorSystemPrompt())是一份约 370 行的详细文档,定义了 coordinator 的行为。关键部分如下:

You are Claude Code, an AI assistant that orchestrates software engineering
tasks 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

coordinator 以结构化的阶段运作:

flowchart LR
    R[Research<br/>Workers parallel] --> S[Synthesis<br/>Coordinator]
    S --> I[Implementation<br/>Workers] --> V[Verification<br/>Workers]
    V -->|failures| S
阶段执行者目的
ResearchWorker(并行)调查代码库、查找文件、理解问题
SynthesisCoordinator读取发现、制定实现规格
ImplementationWorker按规格进行针对性修改并提交
VerificationWorker测试修改是否生效

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 independent
workers 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 areas

coordinator 通过 getCoordinatorUserContext() 将 worker 能力信息注入自身的 context:

src/coordinator/coordinatorMode.ts
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(TeamCreateTeamDeleteSendMessageSyntheticOutput)会从 worker 能力列表中过滤掉——worker 不应了解 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 doing
it 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 but
the token remains cached. Add a null check before user.id access —
if null, return 401 with 'Session expired'. Commit and report
the hash.", ... })

coordinator 必须决定是继续现有 worker(保留其 context)还是派生新 worker:

场景机制原因
Research 已精确探索了所需文件ContinueWorker 的 context 中已有这些文件
Research 范围较广,实现较为聚焦Spawn fresh避免 context 噪音
纠正失败ContinueWorker 已有错误 context
验证另一个 worker 的代码Spawn fresh全新视角,无实现假设
方向完全错误Spawn fresh从零开始,避免锚定在失败路径上

coordinator 模式按 session 持久化。恢复 session 时,模式会被匹配:

src/coordinator/coordinatorMode.ts
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 模式,即使环境变量未设置也能正常工作。