Coordinator Pattern
此内容尚不支持你的语言。
Coordinator mode fundamentally changes how Claude Code operates. Instead of a single agent doing everything, the main Claude instance becomes a coordinator that delegates work to parallel worker agents. It is enabled via the CLAUDE_CODE_COORDINATOR_MODE environment variable and gated behind the COORDINATOR_MODE feature flag.
Activation
Section titled “Activation”export function isCoordinatorMode(): boolean { if (feature('COORDINATOR_MODE')) { return isEnvTruthy(process.env.CLAUDE_CODE_COORDINATOR_MODE) } return false}When coordinator mode is active, the entire built-in agent set is replaced:
if (feature('COORDINATOR_MODE')) { if (isEnvTruthy(process.env.CLAUDE_CODE_COORDINATOR_MODE)) { const { getCoordinatorAgents } = require('../../coordinator/workerAgent.js') return getCoordinatorAgents() // Completely different agent roster }}Architecture
Section titled “Architecture”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:#333The coordinator has exactly three tools for worker management:
| Tool | Purpose |
|---|---|
| Agent | Spawn a new worker |
| SendMessage | Continue an existing worker (send follow-up to its agent ID) |
| TaskStop | Stop a running worker |
The Coordinator System Prompt
Section titled “The Coordinator System Prompt”The coordinator system prompt (getCoordinatorSystemPrompt()) is a detailed ~370-line document that defines the coordinator’s behavior. Key sections:
Role Definition
Section titled “Role Definition”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 toolsTask Workflow Phases
Section titled “Task Workflow Phases”The coordinator operates in structured phases:
flowchart LR R[Research<br/>Workers parallel] --> S[Synthesis<br/>Coordinator] S --> I[Implementation<br/>Workers] --> V[Verification<br/>Workers] V -->|failures| S| Phase | Who | Purpose |
|---|---|---|
| Research | Workers (parallel) | Investigate codebase, find files, understand problem |
| Synthesis | Coordinator | Read findings, craft implementation specs |
| Implementation | Workers | Make targeted changes per spec, commit |
| Verification | Workers | Test changes work |
Worker Communication Protocol
Section titled “Worker Communication Protocol”Workers report results via <task-notification> XML messages that arrive as user-role messages:
<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>Concurrency Rules
Section titled “Concurrency Rules”The coordinator prompt explicitly encodes concurrency constraints:
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 Injection
Section titled “Worker Context Injection”The coordinator injects worker capability information into its own context via getCoordinatorUserContext():
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 }}Internal tools (TeamCreate, TeamDelete, SendMessage, SyntheticOutput) are filtered from the worker capability list — workers shouldn’t know about coordinator internals.
Synthesis: The Coordinator’s Core Job
Section titled “Synthesis: The Coordinator’s Core Job”The most critical design principle in the coordinator prompt is synthesis ownership. The coordinator must understand research findings before directing follow-up work:
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.
// Anti-pattern — lazy delegation (bad)Agent({ prompt: "Based on your findings, fix the auth bug", ... })
// Good — synthesized specAgent({ 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 vs. Spawn Decision
Section titled “Continue vs. Spawn Decision”The coordinator must decide whether to continue an existing worker (preserving its context) or spawn a fresh one:
| Situation | Mechanism | Reason |
|---|---|---|
| Research explored exactly the files needed | Continue | Worker already has files in context |
| Research was broad, implementation is narrow | Spawn fresh | Avoid context noise |
| Correcting a failure | Continue | Worker has error context |
| Verifying another worker’s code | Spawn fresh | Fresh eyes, no implementation assumptions |
| Wrong approach entirely | Spawn fresh | Clean slate avoids anchoring on failed path |
Session Mode Persistence
Section titled “Session Mode Persistence”Coordinator mode is persisted per session. When resuming a session, the mode is matched:
export function matchSessionMode( sessionMode: 'coordinator' | 'normal' | undefined,): string | undefined { const currentIsCoordinator = isCoordinatorMode() const sessionIsCoordinator = sessionMode === 'coordinator'
if (currentIsCoordinator === sessionIsCoordinator) return undefined
// Flip the env var to match the 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.'}This ensures that resuming a coordinator session re-enters coordinator mode, even if the env var isn’t set.