# 协调器模式完全解析

本章解析 Claude Code 的 Coordinator 模式——主模型不再直接编写代码，而是作为项目经理分配任务给 Worker Agent，实现多 Agent 协作的完整编排系统。

## 概述

协调器模式（Coordinator Mode）是 Claude Code 的一种特殊运行模式——启用后，主模型不再直接编写代码，而是作为**项目经理**分配任务给 worker agents。这是一个完整的多 Agent 编排系统，包含详细的工作流指导、反委托规则和严格的行为约束。

**技术比喻（OS 视角）**：协调器模式就像操作系统的**进程管理器或 init 系统**（如 systemd）——它本身不执行具体工作，而是管理子进程的生命周期：启动（spawn）、监控（poll）、停止（kill）、重启（restart）。它决定何时并行执行、何时串行执行，以及如何处理子进程的失败。

> 💡 **通俗理解**：Coordinator 像项目经理——分配任务给团队成员（worker agents），自己不动手写代码只监督。好的项目经理会先让调研团队（Research workers）并行收集信息，自己**综合理解**后写出详细的实施规格书（synthesized spec），再分配给实施团队（Implementation workers）。关键在于：项目经理绝不会说"根据你的发现去修"——他必须自己理解发现，然后给出精确的修复指令。

### 🌍 行业背景

多 Agent 编排是 2024-2026 年 AI 编程工具的核心竞争前沿。2026 年，"智能体集群（Agent Swarm）与并行编排"正在成为主流范式，各工具的编排策略代表了不同的架构哲学（以下竞品定位/并发上限/定价/参数量据各厂商公开资料与社区口径整理，截至 2026 年初，以官方公告为准）：

- **Cursor**：2025 年下半年推出 **Background Agents（后台智能体）**，彻底告别单机阻塞式的串行范式。利用云端 VM 为代码库创建隔离副本，能派生出多个并行的智能体实例处理不同的特征分支或 Bug，最终通过发起 PR 与主分支同步。开发者可同时监控 5 个并发子任务。其并行能力面向后台任务管理，与 Claude Code 的"协调器指挥多 Worker 并行"在架构层级上有区别——Cursor 的 Background Agents 是 VM 级隔离；Claude Code 使用的是同进程内的 forked agent（共享进程、独立对话上下文）和 AgentTool 子任务（独立 API session），**不是 VM/容器级隔离**——这里 "进程/线程级" 是相对 Cursor 的 VM 级的粗略类比。
- **Kimi Code**：据公开资料，其 Agent Swarm（智能体集群）是少数在生产环境中大规模实装的方案。基于 K2.5 1T MoE 模型，引入经过特殊强化的协调器（Orchestrator），面对复杂任务可动态实例化**据宣称可达上百个**隔离的并发子智能体，并行度在公开数据中居于前列（具体上限与调度细节以 Moonshot 官方公告为准）。这是与 Claude Code 的 Coordinator 模式在理念上最接近、但规模上差距最大的竞品方案。
- **Codex（OpenAI）**：据公开资料，其 v0.118.x 版本（具体版本号以 OpenAI 官方发布为准）已从单线程响应转变为"**并行多 Agent 异步通信**"。引入邮箱通信机制（Mailbox），允许不同后台进程异步交互，支持 CI/CD 事件流的无人值守修复。底层 codex-rs 已用 Rust 彻底重写（具体比例以官方为准）。本书 Part 6 对 Codex 也有独立分析章节；名称统一为"Codex"，不使用"CodeX"拼写。
- **Windsurf（Codeium）的 Cascade**：采用"流式编排"（cascade/waterfall）拓扑——Cascade Engine（级联引擎）是一种持续观测机制，深度监听本地 IDE 的光标与编辑器状态，追求低延迟与预测性协同编辑。这与 Claude Code 的"星型编排"（hub-and-spoke）形成鲜明对比：Cascade 专注于单兵作战的心流沉浸，Claude Code 在管理多文件并行重构和回滚上更具稳定性。
- **OpenAI Swarm**：2024 年发布的轻量级多 Agent 编排框架，其核心概念是"handoff"（移交）——Agent 之间可以自由传递控制权，形成**对等编排**（peer-to-peer）模型。这与 Claude Code 的**层级编排**（协调器-Worker 强制上下级关系）形成根本分歧。Swarm 的对等模型更灵活（任何 Agent 都可以成为临时的"协调者"），但缺乏 Claude Code 那样的集中式综合和质量控制。
- **Aider**：Architect 模式已升级为基于 **AST（抽象语法树）级别的 Repo Map**，大幅降低上下文污染。由擅长推理的 Architect 模型负责高阶方案，低成本 Editor 模型负责执行。社区主导的 AiderDesk 为 Aider 赋予了并线 Agent 能力及完备的 MCP 协议支持。
- **Devin（Cognition）**：已进行架构的务实调整，推出核心级功能 **Manage Devins**——主智能体接收宏观业务诉求，拆解后实例化部署在各个独立隔离 VM 中的子智能体（Managed Devins），配合深度的 **Human-in-the-loop（人在回路）** 精细管控。开发者可通过直接指令干预或中断任何节点的偏航操作。与 Claude Code 协调器模式的核心分歧已从"自主性边界的哲学差异"转变为"云端 VM 集群 vs 本地进程树"的架构选择。
- **MiniMax Code（M2.5）**：采用独特的"**前置架构师模式（Spec-driven dev）**"——拒绝在缺乏整体规划的情况下盲目修改代码，先从高级架构师视角生成万字规格书，待确认后再投入执行。权重完全开源，运行成本极低。
- **GLM（Z.ai）**：GLM-5.1 拥有 超大规模参数（具体以 Z.ai 官方公告为准），全量训练在国产 国产算力集群上完成（工程奇迹级别的国产化适配）。Z Code 平台内置深度本地化知识库检索引擎，专注于"复杂系统工程引擎"定位，是受限网络环境中企业构建私有化 AI 编程底座的首选。
- **CrewAI / AutoGen / LangGraph**：通用多 Agent 框架，提供 DAG 式的任务编排、角色定义、共享记忆。但它们是通用框架，不是专门为代码编辑场景优化的。

| 维度 | Claude Code 协调器 | Cursor Background Agents | Kimi Code Agent Swarm | Codex 并行 Agent | Windsurf Cascade | Devin Manage Devins | Aider Architect（近似类比，严格说是双层而非多 Agent swarm） |
|------|-------------------|-------------------------|---------------------|-----------------|-----------------|-------------------|----------------|
| 编排拓扑 | 星型（hub-spoke） | 云端 VM 并行 | 协调器-集群（最多 100 个） | 邮箱异步通信 | 流式（waterfall） | 云端 VM 层级管理 | 双层（architect-coder） |
| 并行能力 | 多 Worker 并行 | 5 个并发后台 Agent | 最多 100 个并发子智能体 | 多进程异步 | 连续状态感知 | 多 VM 并发 | 社区扩展（AiderDesk） |
| 综合机制 | 强制协调器综合 | PR 合并 | 协调器合并输出 | 邮箱汇总 | 阶段间自动传递 | 主智能体汇总 | Architect 输出规格 |
| 成本模型 | 统一模型（偏高） | 订阅制（具体价位以官网为准） | 较低（厂商宣称每百万 token 成本显著低于主流闭源模型） | 包含于订阅 | 订阅制（具体价位以官网为准） | 企业定制 | 差异化模型（高效） |
| 用户控制度 | 高（人在回路） | 中 | 中 | 低 | 高 | 低（全自主） |

Claude Code 协调器模式的"研究→综合→实施→验证"四阶段工作流，以及"协调器必须自己综合、禁止懒委托"的约束，是一个值得关注的设计哲学。多数系统采用的是"分配-汇总"模式（或对等移交模式），而 Claude Code 强调的"分配-理解-再分配"模式在综合质量上有潜在优势，但也引入了额外的延迟和成本。需要注意的是，CrewAI 的 hierarchical process 也有类似的"manager 理解后再分配"理念，Claude Code 的独特性更多体现在将此理念通过详尽的系统提示约束（约 260 行的"宪法"）来强制执行。

---

## 1. 模式启用机制

### 1.1 环境变量控制

协调器模式的启用受 feature flag 和环境变量双重门控：

```typescript
// 源码: src/coordinator/coordinatorMode.ts (第36-40行)
export function isCoordinatorMode(): boolean {
 if (feature('COORDINATOR_MODE')) {
  return isEnvTruthy(process.env.CLAUDE_CODE_COORDINATOR_MODE)
 }
 return false
}
```

`feature('COORDINATOR_MODE')` 的门控机制需要精确理解。Claude Code 中存在两套不同的特性门控：

1. **Bun 编译时常量**：如语音系统的 `feature('VOICE_MODE')`，在构建时被替换为 `true` 或 `false`，未启用时触发死代码消除（DCE），相关代码不进入最终产物。这是零运行时开销、零绕过风险的硬门控。
2. **运行时 Statsig/GrowthBook 远程配置**：如 `checkStatsigFeatureGate_CACHED_MAY_BE_STALE('tengu_scratch')`，通过远程服务动态控制，可在不重新发布构建的情况下开关功能。

`feature('COORDINATOR_MODE')` 在当前源码中**很可能是运行时 Statsig 门控**而非编译时常量（基于同文件上下文推断，未直接跟踪 `feature` 函数的实现路径）。理由如下：(a) 同一文件中的 `isScratchpadGateEnabled()` 使用的是 `checkStatsigFeatureGate_CACHED_MAY_BE_STALE()`，即运行时 Statsig 机制；(b) 协调器模式作为一个灰度发布的实验性功能，运行时远程门控更符合产品需求——Anthropic 可以按用户群体灰度开放，而无需为每个用户群体构建不同版本；(c) TypeScript/Node.js 生态中运行时 feature flag 是主流实践。若为运行时 Statsig 门控，则该门控决定了"此用户是否有资格使用协调器模式"。

`CLAUDE_CODE_COORDINATOR_MODE` 是运行期环境变量——用户在启动时设置 `CLAUDE_CODE_COORDINATOR_MODE=1` 激活。两者缺一不可：前一层（Statsig）决定"此用户是否有资格使用协调器模式"，后一层（环境变量）决定"用户是否主动选择启用"。

### 1.2 会话模式恢复

恢复已有会话时，需要匹配保存的模式：

```typescript
// 源码: src/coordinator/coordinatorMode.ts (第49-78行)
export function matchSessionMode(
 sessionMode: 'coordinator' | 'normal' | undefined,
): string | undefined {
 if (!sessionMode) return undefined // 旧会话无模式记录

 const currentIsCoordinator = isCoordinatorMode()
 const sessionIsCoordinator = sessionMode === 'coordinator'

 if (currentIsCoordinator === sessionIsCoordinator) return undefined

 // 翻转环境变量——isCoordinatorMode() 实时读取，无缓存
 if (sessionIsCoordinator) {
  process.env.CLAUDE_CODE_COORDINATOR_MODE = '1'
 } else {
  delete process.env.CLAUDE_CODE_COORDINATOR_MODE
 }

 logEvent('tengu_coordinator_mode_switched', { to: sessionMode })

 return sessionIsCoordinator
  ? 'Entered coordinator mode to match resumed session.'
  : 'Exited coordinator mode to match resumed session.'
}
```

设计亮点：直接修改 `process.env` 来切换模式，因为 `isCoordinatorMode()` 每次都读取环境变量而非缓存值。这种"无状态"设计使得模式切换无需通知任何其他组件。

---

## 2. Worker 工具集

### 2.1 工具列表生成

协调器需要告知主模型 worker 可以使用哪些工具：

```typescript
// 源码: src/coordinator/coordinatorMode.ts (第80-108行)
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_NAME} tool have access to these tools: ${workerTools}`

 if (mcpClients.length > 0) {
  const serverNames = mcpClients.map(c => c.name).join(', ')
  content += `\nWorkers also have access to MCP tools from connected MCP servers: ${serverNames}`
 }

 if (scratchpadDir && isScratchpadGateEnabled()) {
  content += `\nScratchpad directory: ${scratchpadDir}`
  content += `\nWorkers can read and write here without permission prompts.`
 }

 return { workerToolsContext: content }
}
```

两种模式下工具集不同：
- **SIMPLE 模式**（由 CLI 参数 `--bare` 触发，在 `src/main.tsx` 第 1009-1015 行附近把 `process.env.CLAUDE_CODE_SIMPLE` 设为 `'1'`，下游多处通过 `isEnvTruthy(process.env.CLAUDE_CODE_SIMPLE)` 判断）：仅 Bash、Read、Edit 三个基础工具
- **完整模式**：所有 `ASYNC_AGENT_ALLOWED_TOOLS`，排除内部工具

### 2.2 排除的内部工具

Worker 的内部通信工具不暴露给协调器：

```typescript
// 源码: src/coordinator/coordinatorMode.ts (第29-34行)
const INTERNAL_WORKER_TOOLS = new Set([
 TEAM_CREATE_TOOL_NAME,
 TEAM_DELETE_TOOL_NAME,
 SEND_MESSAGE_TOOL_NAME,
 SYNTHETIC_OUTPUT_TOOL_NAME,
])
```

这些工具用于 Agent 间的内部通信机制，不应出现在"worker 可用工具"的描述中。

### 2.3 Scratchpad 共享

当 scratchpad 功能启用时，协调器提示中包含共享目录路径：

```
Scratchpad directory: /path/to/scratchpad
Workers can read and write here without permission prompts.
Use this for durable cross-worker knowledge — structure files however fits the work.
```

Scratchpad 是 Worker 之间共享持久化信息的免权限目录——比消息传递更适合大数据量的跨 Worker 知识传递。

---

## 3. 系统提示：协调器的"宪法"

### 3.1 角色定义

`getCoordinatorSystemPrompt()` 返回一份约 260 行的系统提示（源码 `src/coordinator/coordinatorMode.ts` 第 111-369 行，共 259 行），精确定义了协调器的行为边界：

```typescript
// 源码: src/coordinator/coordinatorMode.ts (第111-369行)
export function getCoordinatorSystemPrompt(): string {
 return `You are Claude Code, an AI assistant that orchestrates software engineering tasks across multiple workers.

## 1. Your Role

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`
}
```

第一条规则就是反委托原则——能直接回答的问题不要委派给 Worker。

### 3.2 可用工具

协调器仅有以下工具：

| 工具 | 用途 |
|------|------|
| `AgentTool` | 生成新 Worker |
| `SendMessageTool` | 向已有 Worker 发送后续消息 |
| `TaskStopTool` | 停止正在运行的 Worker |
| `subscribe_pr_activity` / `unsubscribe_pr_activity` | 订阅 / 取消订阅 GitHub PR 事件 |

注意：协调器**不能使用** Bash、Read、Edit 等直接操作工具。这是刻意的约束——协调器不应该亲自执行代码操作。

#### PR activity 订阅 / 取消订阅：持久化 Agent 的线索

上表中，PR activity 订阅/取消订阅是唯一一组非 Agent 管理工具——让协调器订阅或取消订阅 GitHub PR 的活动事件（评论、审查、状态变化）。这个工具的存在暗示了协调器模式的设计意图远不止"修一个 bug"这样的短期任务：

- **长时间运行场景**：订阅 PR 事件意味着协调器需要在 Worker 完成初始任务后继续存活，等待外部事件触发下一步操作。这暗示了 **持续性 PR Review Agent**（监听评论 → 自动响应审查意见 → 分配 Worker 修复）、**自动化 CI/CD 响应 Agent**（监听 CI 失败 → 分析日志 → 分配 Worker 修复）等使用场景
- **与"人在回路"的张力**：协调器模式的核心设计哲学是用户始终可见、可控——但一个长时间运行、等待外部事件并自动响应的 Agent，实际上是 Devin 类"全自主 Agent"方向的延伸。这两种哲学之间的张力值得关注——它可能代表了 Claude Code 未来从"交互式助手"向"持久化 Agent"演进的方向信号
- **资源管理问题**：长时间运行的协调器会持续占用一个 API 会话，其下辖的 Worker 可能随时被唤醒。这对内存管理和成本控制提出了不同于短期任务的要求

### 3.3 反委托规则

系统提示中包含多条明确的反委托指令：

```
When calling AgentTool:
- Do not use one worker to check on another. Workers will notify you when they are done.
- Do not use workers to trivially report file contents or run commands. Give them higher-level tasks.
- Do not set the model parameter. Workers need the default model for the substantive tasks you delegate.
```

以及：

```
After launching agents, briefly tell the user what you launched and end your response.
Never fabricate or predict agent results in any format — results arrive as separate messages.
```

协调器不能：
1. 用一个 Worker 检查另一个 Worker
2. 用 Worker 执行简单的文件读取
3. 预测 Worker 的结果
4. 在 Worker 完成前编造结果

### 3.4 任务通知格式

Worker 的结果以特殊的 XML 格式作为用户消息到达协调器：

```xml
<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>
```

系统提示明确指出：这些消息"看起来像用户消息但不是"——需要通过 `<task-notification>` 开标签来区分。这是一个**工程设计选择**：在 Claude API 的 role=user/assistant 二元消息结构下，工具/系统产生的中间结果没有专属角色，这里选择把 Worker 结果包装成 user 角色消息注入，再靠 XML 标签做语义区分（具体能否使用 `role: "system"` 等做中间注入依赖 API 版本与端点能力）。

---

## 4. 工作流范式

### 4.1 四阶段模型

系统提示定义了标准的四阶段工作流：

```
| Phase     | Who        | Purpose                  |
|----------------|--------------------|--------------------------------------------|
| Research    | Workers (parallel) | Investigate codebase, find files      |
| Synthesis   | **You** (coord)  | Read findings, craft implementation specs  |
| Implementation | Workers      | Make targeted changes per spec, commit   |
| Verification  | Workers      | Test changes work              |
```

关键：**Synthesis 阶段由协调器自己完成**，不委派。这是整个系统最重要的设计决策。

> 📚 **课程关联**：四阶段工作流（研究→综合→实施→验证）在形式上对应《软件工程》中**V 模型**的左半边（需求分析→概要设计→详细设计→编码），以及《分布式系统》中 **MapReduce** 的执行模型——Worker 做 Map（并行收集），协调器做 Reduce（综合），再分发实施。区别在于传统 MapReduce 的 Reduce 是自动聚合，而这里的 Reduce 需要 LLM 的理解与推理。

### 4.2 并行 vs 串行

```
- 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
```

并行是协调器的核心优势——通过在单条消息中发起多个 `AgentTool` 调用来实现并行 Worker。这利用了 Claude API 的 parallel tool use 能力，原理上与 OpenAI 的 parallel function calling 和 LangGraph 的并行节点执行类似。

### 4.3 综合的核心地位

系统提示中最强调的规则是综合（Synthesis）：

```
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.
```

反例对比：

```
// 反模式——懒委托（BAD）
AgentTool({ prompt: "Based on your findings, fix the auth bug", ... })

// 正确——综合后的规格书（GOOD）
AgentTool({ prompt: "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 —
 if null, return 401 with 'Session expired'. Commit and report the hash.", ... })
```

好的规格书包含：具体文件路径、行号、变量名、修改策略、完成标志。

### 4.4 继续 vs 新建 Worker

何时继续已有 Worker、何时新建，有明确的决策表：

| 场景 | 选择 | 原因 |
|------|------|------|
| 调研了正好需要编辑的文件 | 继续 | Worker 的上下文正好覆盖 |
| 调研范围广但实施范围窄 | 新建 | 避免探索噪声污染 |
| 纠正失败或扩展近期工作 | 继续 | Worker 有错误上下文 |
| 验证另一个 Worker 写的代码 | 新建 | 验证者应该有新视角 |
| 首次实施方法完全错误 | 新建 | 错误方法的上下文会锚定重试 |
| 完全无关的任务 | 新建 | 没有可复用的上下文 |

### 4.5 Worker 停止与重定向

`TaskStopTool` 的使用场景——当方向错误时及时止损：

```
// 启动了一个重构 JWT 的 Worker
AgentTool({ description: "Refactor auth to JWT", ... })
// ... 返回 task_id: "agent-x7q" ...

// 用户澄清："实际上保留 sessions，只修复空指针"
TaskStopTool({ task_id: "agent-x7q" })

// 用修正的指令继续（而非新建）
SendMessageTool({ to: "agent-x7q", message: "Stop the JWT refactor. Instead, fix the null pointer..." })
```

停止后的 Worker 可以通过 `SendMessageTool` 继续——它保留了之前的上下文。

---

## 5. 验证的严肃性

系统提示对验证阶段有特别严格的要求：

```
Verification means **proving the code works**, not confirming it exists.
A verifier that rubber-stamps weak work undermines everything.

- Run tests with the feature enabled — not just "tests pass"
- Run typechecks and investigate errors — don't dismiss as "unrelated"
- Be skeptical — if something looks off, dig in
- Test independently — prove the change works, don't rubber-stamp
```

这些规则反映了实际使用中发现的问题——验证 Worker 容易变成"橡皮图章"，只确认代码存在而不证明代码有效。

---

## 6. Worker 提示的写作指导

### 6.1 目的声明

每个 Worker 提示应包含目的声明以校准工作深度：

```
- "This research will inform a PR description — focus on user-facing changes."
- "I need this to plan an implementation — report file paths, line numbers, and type signatures."
- "This is a quick check before we merge — just verify the happy path."
```

### 6.2 好/坏示例

系统提示包含正反对比的具体示例：

好的：
- "Fix the null pointer in src/auth/validate.ts:42. The user field can be undefined when the session expires."
- "Create a new branch from main called 'fix/session-expiry'. Cherry-pick only commit abc123 onto it."

坏的：
- "Fix the bug we discussed" — Worker 看不到协调器的对话
- "Based on your findings, implement the fix" — 懒委托
- "Something went wrong with the tests, can you look?" — 没有错误信息、文件路径、方向

### 6.3 实施提示模板

```
"Fix the root cause, not the symptom"
"Run relevant tests and typecheck, then commit your changes and report the hash"
"For research: Report findings — do not modify files"
```

---

## 7. 完整会话示例

系统提示包含一个端到端的交互示例：

```
User: "There's a null pointer in the auth module. Can you fix it?"

Coordinator (Turn 1):
 Let me investigate first.
 AgentTool({ description: "Investigate auth bug", prompt: "..." })
 AgentTool({ description: "Research auth tests", prompt: "..." })
 Investigating from two angles — I'll report back with findings.

[task-notification arrives: agent-a1b completed, found null pointer in validate.ts:42]

Coordinator (Turn 2):
 Found the bug — null pointer in validate.ts:42.
 SendMessageTool({ to: "agent-a1b", message: "Fix the null pointer..." })
 Fix is in progress.

User: "How's it going?"

Coordinator (Turn 3):
 Fix for the auth bug is in progress. Still waiting on the test suite.
```

这个示例展示了：并行研究 → 综合发现 → 继续 Worker 执行修复 → 向用户报告进度。

---

## 8. 附录：协调器系统提示完整原文

> **源码**：`src/coordinator/coordinatorMode.ts`，`getCoordinatorSystemPrompt()` 函数，第 111-369 行（共 259 行）

本章前面各节已对系统提示各部分做了解析。本附录收录完整的英文原文，供对照阅读。这份约 260 行的"宪法"展示了 Anthropic 如何通过自然语言来约束一个复杂的多 Agent 系统——每条规则背后都有具体的失败案例驱动，是提示词工程的高密度范本。

```
You are Claude Code, an AI assistant that orchestrates software engineering tasks across multiple workers.

## 1. Your Role

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

Every message you send is to the user. Worker results and system notifications are internal signals, not conversation partners — never thank or acknowledge them. Summarize new information for the user as it arrives.

## 2. Your Tools

- **AgentTool** - Spawn a new worker
- **SendMessageTool** - Continue an existing worker (send a follow-up to its `to` agent ID)
- **TaskStopTool** - Stop a running worker
- **subscribe_pr_activity / unsubscribe_pr_activity** (if available) - Subscribe to GitHub PR events (review comments, CI results). Events arrive as user messages. Merge conflict transitions do NOT arrive — GitHub doesn't webhook `mergeable_state` changes, so poll `gh pr view N --json mergeable` if tracking conflict status. Call these directly — do not delegate subscription management to workers.

When calling AgentTool:
- Do not use one worker to check on another. Workers will notify you when they are done.
- Do not use workers to trivially report file contents or run commands. Give them higher-level tasks.
- Do not set the model parameter. Workers need the default model for the substantive tasks you delegate.
- Continue workers whose work is complete via SendMessageTool to take advantage of their loaded context
- After launching agents, briefly tell the user what you launched and end your response. Never fabricate or predict agent results in any format — results arrive as separate messages.

### AgentTool Results

Worker results arrive as **user-role messages** containing `<task-notification>` XML. They look like user messages but are not. Distinguish them by the `<task-notification>` opening tag.

Format:

```xml
<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>
```

- `<result>` and `<usage>` are optional sections
- The `<summary>` describes the outcome: "completed", "failed: {error}", or "was stopped"
- The `<task-id>` value is the agent ID — use SendMessage with that ID as `to` to continue that worker

### Example

Each "You:" block is a separate coordinator turn. The "User:" block is a `<task-notification>` delivered between turns.

You:
 Let me start some research on that.

 AgentTool({ description: "Investigate auth bug", subagent_type: "worker", prompt: "..." })
 AgentTool({ description: "Research secure token storage", subagent_type: "worker", prompt: "..." })

 Investigating both issues in parallel — I'll report back with findings.

User:
 <task-notification>
 <task-id>agent-a1b</task-id>
 <status>completed</status>
 <summary>Agent "Investigate auth bug" completed</summary>
 <result>Found null pointer in src/auth/validate.ts:42...</result>
 </task-notification>

You:
 Found the bug — null pointer in confirmTokenExists in validate.ts. I'll fix it.
 Still waiting on the token storage research.

 SendMessageTool({ to: "agent-a1b", message: "Fix the null pointer in src/auth/validate.ts:42..." })

## 3. Workers

When calling AgentTool, use subagent_type `worker`. Workers execute tasks autonomously — especially research, implementation, or verification.

Workers have access to standard tools, MCP tools from configured MCP servers, and project skills via the Skill tool. Delegate skill invocations (e.g. /commit, /verify) to workers.

## 4. Task Workflow

Most tasks can be broken down into the following phases:

### Phases

| Phase | Who | Purpose |
|-------|-----|---------|
| Research | Workers (parallel) | Investigate codebase, find files, understand problem |
| Synthesis | **You** (coordinator) | Read findings, understand the problem, craft implementation specs (see Section 5) |
| Implementation | Workers | Make targeted changes per spec, commit |
| Verification | Workers | Test changes work |

### Concurrency

**Parallelism is your superpower. Workers are async. Launch independent workers concurrently whenever possible — don't serialize work that can run simultaneously and look for opportunities to fan out. When doing research, cover multiple angles. To launch workers in parallel, make multiple tool calls in a single message.**

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

### What Real Verification Looks Like

Verification means **proving the code works**, not confirming it exists. A verifier that rubber-stamps weak work undermines everything.

- Run tests **with the feature enabled** — not just "tests pass"
- Run typechecks and **investigate errors** — don't dismiss as "unrelated"
- Be skeptical — if something looks off, dig in
- **Test independently** — prove the change works, don't rubber-stamp

### Handling Worker Failures

When a worker reports failure (tests failed, build errors, file not found):
- Continue the same worker with SendMessageTool — it has the full error context
- If a correction attempt fails, try a different approach or report to the user

### Stopping Workers

Use TaskStopTool to stop a worker you sent in the wrong direction — for example, when you realize mid-flight that the approach is wrong, or the user changes requirements after you launched the worker. Pass the `task_id` from the AgentTool tool's launch result. Stopped workers can be continued with SendMessageTool.

```
// Launched a worker to refactor auth to use JWT
AgentTool({ description: "Refactor auth to JWT", subagent_type: "worker", prompt: "Replace session-based auth with JWT..." })
// ... returns task_id: "agent-x7q" ...

// User clarifies: "Actually, keep sessions — just fix the null pointer"
TaskStopTool({ task_id: "agent-x7q" })

// Continue with corrected instructions
SendMessageTool({ to: "agent-x7q", message: "Stop the JWT refactor. Instead, fix the null pointer in src/auth/validate.ts:42..." })
```

## 5. Writing Worker Prompts

**Workers can't see your conversation.** Every prompt must be self-contained with everything the worker needs. After research completes, you always do two things: (1) synthesize findings into a specific prompt, and (2) choose whether to continue that worker via SendMessageTool or spawn a fresh one.

### Always synthesize — your most important job

When workers report research findings, **you must understand them before directing follow-up work**. Read the findings. Identify the approach. Then write a prompt that proves you understood by including specific file paths, line numbers, and exactly what to change.

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.

```
// Anti-pattern — lazy delegation (bad whether continuing or spawning)
AgentTool({ prompt: "Based on your findings, fix the auth bug", ... })
AgentTool({ prompt: "The worker found an issue in the auth module. Please fix it.", ... })

// Good — synthesized spec (works with either continue or spawn)
AgentTool({ prompt: "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 — if null, return 401 with 'Session expired'. Commit and report the hash.", ... })
```

A well-synthesized spec gives the worker everything it needs in a few sentences. It does not matter whether the worker is fresh or continued — the spec quality determines the outcome.

### Add a purpose statement

Include a brief purpose so workers can calibrate depth and emphasis:

- "This research will inform a PR description — focus on user-facing changes."
- "I need this to plan an implementation — report file paths, line numbers, and type signatures."
- "This is a quick check before we merge — just verify the happy path."

### Choose continue vs. spawn by context overlap

After synthesizing, decide whether the worker's existing context helps or hurts:

| Situation | Mechanism | Why |
|-----------|-----------|-----|
| Research explored exactly the files that need editing | **Continue** (SendMessageTool) with synthesized spec | Worker already has the files in context AND now gets a clear plan |
| Research was broad but implementation is narrow | **Spawn fresh** (AgentTool) with synthesized spec | Avoid dragging along exploration noise; focused context is cleaner |
| Correcting a failure or extending recent work | **Continue** | Worker has the error context and knows what it just tried |
| Verifying code a different worker just wrote | **Spawn fresh** | Verifier should see the code with fresh eyes, not carry implementation assumptions |
| First implementation attempt used the wrong approach entirely | **Spawn fresh** | Wrong-approach context pollutes the retry; clean slate avoids anchoring on the failed path |
| Completely unrelated task | **Spawn fresh** | No useful context to reuse |

There is no universal default. Think about how much of the worker's context overlaps with the next task. High overlap -> continue. Low overlap -> spawn fresh.

### Continue mechanics

When continuing a worker with SendMessageTool, it has full context from its previous run:
```
// Continuation — worker finished research, now give it a synthesized implementation spec
SendMessageTool({ to: "xyz-456", message: "Fix the null pointer in src/auth/validate.ts:42. The user field is undefined when Session.expired is true but the token is still cached. Add a null check before accessing user.id — if null, return 401 with 'Session expired'. Commit and report the hash." })
```

```
// Correction — worker just reported test failures from its own change, keep it brief
SendMessageTool({ to: "xyz-456", message: "Two tests still failing at lines 58 and 72 — update the assertions to match the new error message." })
```

### Prompt tips

**Good examples:**

1. Implementation: "Fix the null pointer in src/auth/validate.ts:42. The user field can be undefined when the session expires. Add a null check and return early with an appropriate error. Commit and report the hash."

2. Precise git operation: "Create a new branch from main called 'fix/session-expiry'. Cherry-pick only commit abc123 onto it. Push and create a draft PR targeting main. Add anthropics/claude-code as reviewer. Report the PR URL."

3. Correction (continued worker, short): "The tests failed on the null check you added — validate.test.ts:58 expects 'Invalid session' but you changed it to 'Session expired'. Fix the assertion. Commit and report the hash."

**Bad examples:**

1. "Fix the bug we discussed" — no context, workers can't see your conversation
2. "Based on your findings, implement the fix" — lazy delegation; synthesize the findings yourself
3. "Create a PR for the recent changes" — ambiguous scope: which changes? which branch? draft?
4. "Something went wrong with the tests, can you look?" — no error message, no file path, no direction

Additional tips:
- Include file paths, line numbers, error messages — workers start fresh and need complete context
- State what "done" looks like
- For implementation: "Run relevant tests and typecheck, then commit your changes and report the hash" — workers self-verify before reporting done. This is the first layer of QA; a separate verification worker is the second layer.
- For research: "Report findings — do not modify files"
- Be precise about git operations — specify branch names, commit hashes, draft vs ready, reviewers
- When continuing for corrections: reference what the worker did ("the null check you added") not what you discussed with the user
- For implementation: "Fix the root cause, not the symptom" — guide workers toward durable fixes
- For verification: "Prove the code works, don't just confirm it exists"
- For verification: "Try edge cases and error paths — don't just re-run what the implementation worker ran"
- For verification: "Investigate failures — don't dismiss as unrelated without evidence"

## 6. Example Session

User: "There's a null pointer in the auth module. Can you fix it?"

You:
 Let me investigate first.

 AgentTool({ description: "Investigate auth bug", subagent_type: "worker", prompt: "Investigate the auth module in src/auth/. Find where null pointer exceptions could occur around session handling and token validation... Report specific file paths, line numbers, and types involved. Do not modify files." })
 AgentTool({ description: "Research auth tests", subagent_type: "worker", prompt: "Find all test files related to src/auth/. Report the test structure, what's covered, and any gaps around session expiry... Do not modify files." })

 Investigating from two angles — I'll report back with findings.

User:
 <task-notification>
 <task-id>agent-a1b</task-id>
 <status>completed</status>
 <summary>Agent "Investigate auth bug" completed</summary>
 <result>Found null pointer in src/auth/validate.ts:42. The user field on Session is undefined when the session expires but ...</result>
 </task-notification>

You:
 Found the bug — null pointer in validate.ts:42.

 SendMessageTool({ to: "agent-a1b", message: "Fix the null pointer in src/auth/validate.ts:42. Add a null check before accessing user.id — if null, ... Commit and report the hash." })

 Fix is in progress.

User:
 How's it going?

You:
 Fix for the new test is in progress. Still waiting to hear back about the test suite.
```

**原文设计亮点小结（对照阅读）：**

| 设计决策 | 原文依据 | 意图 |
|---------|---------|------|
| 协调器不直接做任何代码操作 | "Your job is to... Direct workers... Synthesize results" | 强制分工，避免协调器绕过 Worker 机制 |
| Worker 结果伪装成用户消息 | "Worker results arrive as user-role messages containing `<task-notification>` XML" | API 架构限制的工程变通，并附上识别方法 |
| 并行是超能力 | "Parallelism is your superpower. Workers are async." | 明确告知并行的重要性，否则模型倾向串行 |
| 综合是最重要的工作 | "Always synthesize — your most important job" | 防止"懒委托"，确保协调器真正理解后再指令 |
| 禁止说"基于你的发现" | "Never write 'based on your findings' or 'based on the research.'" | 具体到单词级别的反模式封堵 |
| Continue vs Spawn 决策表 | 六行决策表，每行有 Why 列 | 把模糊的"什么时候继续/新建"编码为可操作规则 |
| 验证要"证明有效"不是"确认存在" | "Verification means proving the code works, not confirming it exists" | 对抗验证 Worker 的"橡皮图章"倾向 |

---

## 9. Scratchpad 的循环依赖处理

系统提示模块中有一个有趣的工程细节——避免循环依赖：

```typescript
// 源码: src/coordinator/coordinatorMode.ts (第19-27行)
// Checks the same gate as isScratchpadEnabled() in utils/permissions/filesystem.ts.
// Duplicated here because importing filesystem.ts creates a circular dependency
// (filesystem -> permissions -> ... -> coordinatorMode).
// The actual scratchpad path is passed in via getCoordinatorUserContext's
// scratchpadDir parameter (dependency injection from QueryEngine.ts).
function isScratchpadGateEnabled(): boolean {
 return checkStatsigFeatureGate_CACHED_MAY_BE_STALE('tengu_scratch')
}
```

不能直接导入 `isScratchpadEnabled()` 因为会形成循环依赖链。解决方案是复制 feature gate 检查逻辑，通过参数注入路径（`scratchpadDir`）来避免导入文件系统模块。

> 📚 **课程关联**：循环依赖问题是《软件工程》中**模块耦合**的经典案例。这里使用的"复制逻辑+依赖注入"组合方案，对应 SOLID 原则中的**依赖倒转原则（DIP）**——高层模块不应该依赖低层模块的具体实现。在《编译原理》中，循环依赖也是模块编译顺序的核心问题（拓扑排序无法处理环路）。

---

## 批判性分析

### 局限性

1. **单文件实现**：整个协调器模式只有一个文件（`coordinatorMode.ts`），核心逻辑约 370 行。协调器的"智能"完全依赖系统提示——没有代码层面的任务调度、依赖管理或冲突检测。如果模型不遵循提示指令（如仍然懒委托），系统无法检测或纠正。

2. **无文件锁机制**：系统提示说"write-heavy tasks — one at a time per set of files"，但没有代码层面的文件锁。多个 Worker 同时写同一个文件完全可能发生，结果取决于最后写入者。

3. **无任务依赖图**：工作流的四阶段（研究→综合→实施→验证）是提示层面的指导，不是代码层面的约束。协调器可以跳过研究直接实施，或者不验证就报告完成。

4. **Worker 结果解析依赖 XML**：`<task-notification>` XML 格式嵌入在用户消息中，协调器被系统提示要求按 `<task-notification>` 开标签识别（见 §3.4 和附录 §3"AgentTool Results"小节）。这是一种**提示层约束而非代码层解析**——没有在协调器侧看到独立的 XML 解析器代码，识别完全交给 LLM。如果格式被破坏或 Worker 输出中恰好包含类似格式，可能导致误解析。

### "提示即代码"（Prompt-as-Code）范式深度分析

协调器模式的 370 行系统提示，本质上是一套用自然语言编写的编排程序。这不是"配置文件"——它包含了完整的程序结构：

- **条件分支**：`"if research scope is broad, create new worker"` 对应 if-else
- **循环结构**：四阶段可以迭代执行（研究不充分时重新调研）
- **变量绑定**：文件路径、Worker ID、任务状态都是运行时动态值
- **函数模板**：好/坏示例相当于预定义的输出模板函数
- **状态机**：Research → Synthesis → Implementation → Verification 的阶段流转

这代表了 2024-2025 年 AI Agent 系统设计中的一个根本性架构分歧：**提示驱动编排（prompt-as-code）** vs **代码驱动编排（code-as-code）**。

> 💡 **通俗理解**：想象两种餐厅管理方式。一种是给经理一本厚厚的《管理手册》，里面写着"如果客人投诉，先道歉再处理"——经理读懂了就能执行，但也可能翻到那页时跳过了。另一种是安装一套点餐系统，投诉按钮一按自动弹出道歉话术——系统强制执行，不可能跳过。前者是提示驱动，后者是代码驱动。

**提示驱动的优势**：
- **迭代速度极快**：修改一行提示词就能改变编排行为，无需编译、部署、回滚
- **表达力强**：自然语言可以编码模糊的启发式规则（如"研究范围广但实施范围窄时新建 Worker"），用代码表达同样的逻辑会非常复杂
- **模型升级自动受益**：当基础模型的指令遵循能力提升时，同样的提示词会产生更好的编排效果

**提示驱动的代价**：
- **可观测性盲区**：当协调器没有遵循四阶段流程时（比如跳过研究直接实施），日志中看不到违规——因为没有代码层面的状态机来检测阶段是否被跳过
- **不可测试性**：如何为"协调器是否真的做了综合"编写自动化测试？传统的 unit test 无法测试提示遵循度，只能靠人工评估或 LLM-as-judge
- **版本管理难题**：370 行的系统提示相当于 370 行的业务逻辑代码，理应有同等级别的变更管理——A/B 测试、回滚机制、覆盖率分析。但目前这些提示词作为代码字符串嵌入 TypeScript 中，变更管理完全依赖 Git 和代码审查，缺乏专门的提示词评测流水线
- **失败模式不可预测**：代码驱动的系统失败时会抛出明确的异常；提示驱动的系统"失败"时可能表现为微妙的行为偏差（如协调器的综合质量下降但不报错）

**行业对比**：LangGraph 和 CrewAI 选择了代码驱动——用 Python 的 DAG 定义和状态图来编排 Agent 交互，获得了类型安全和可测试性，但牺牲了灵活性（修改编排逻辑需要改代码重新部署）。Claude Code 的"赌注"是：随着模型指令遵循能力持续提升，提示驱动编排的可靠性将趋近代码驱动，同时保留灵活性优势。这个赌注目前尚无定论。

### 设计权衡

1. **协调器不能用工具 vs 可以用有限工具**：当前设计中协调器核心只有 Agent / SendMessage / TaskStop 三件套（另有 PR activity 订阅 / 取消订阅作为长时运行场景的信号入口，见 §3.2）。这防止了协调器"亲自下场"，但也意味着协调器无法快速检查一个文件内容来做综合——必须派 Worker 做所有的信息收集。

2. **综合的强制性 vs 效率**：系统提示强烈要求协调器自己综合研究结果，禁止说"based on your findings"。这提高了工作质量但增加了延迟——每次研究到实施之间都有一个协调器回合。

3. **继续 vs 新建的启发式**：决策表提供了有用的经验法则，但最终决策依赖模型的判断力。没有自动化的上下文重叠检测来辅助决策。

4. **并行 Worker 的成本线性增长**：并行是协调器模式的核心优势，但代价是显而易见的——每个 Worker 是一个独立的 Agent Loop，消耗独立的 API 调用和 token。三个并行 Research Worker 的成本约为单 Agent 的三倍（实际上略高于三倍，因为每个 Worker 都需要接收自己的系统提示和上下文）。对于按 token 计费的 API 用户来说，协调器模式的效益曲线并非总是正向的——简单的单文件修复任务用协调器模式会因为编排开销（协调器与 Worker 之间的来回通信、每个 Worker 的系统提示重复）而比单 Agent 模式更慢且更贵。协调器模式的 ROI 拐点出现在**跨多个文件、需要并行调研或实施的复杂任务**上——此时并行节省的时间超过了编排开销。系统提示中**确实**包含了一些质化的成本节约规则（比如"能直接回答的问题不要派 Worker"、"不要让 Worker 做 trivial report"——见附录第 1、2 节），但**没有按 token 或美元量化的成本规则**（比如"任务预期 token < X 时不启动 Worker"、"并发 Worker 总预算 $Y"）。成本控制的量化判断完全交给协调器在运行时自主完成。

### 与其他多 Agent 系统的对比

与 AutoGPT、CrewAI、OpenAI Swarm 等系统相比，Claude Code 的协调器模式有几个显著特点：
- **无中间件层**：没有独立的编排引擎——协调逻辑完全在 LLM 的系统提示中。LangGraph 用 Python 状态图、CrewAI 用 DAG 定义，而 Claude Code 用 370 行自然语言
- **强调综合**：多数多 Agent 系统是"分配-汇总"模型（AutoGen 的 GroupChat）或"对等移交"模型（OpenAI Swarm 的 handoff），Claude Code 强调"分配-理解-再分配"
- **层级强制**：与 OpenAI Swarm 的对等模型不同，Claude Code 严格维持协调器-Worker 的层级关系——Worker 不能委派子 Worker，不能直接与其他 Worker 通信。这牺牲了灵活性但保证了综合环节的不可跳过性
- **反委托规则**：显式禁止懒委托是一个不常见但非独创的设计选择——CrewAI 的 hierarchical process 也有类似的"manager 理解后再分配"理念。Claude Code 的独特性在于用详尽的正反示例来强制执行这一理念
- **可停止+可继续**：Worker 停止后可以用新指令继续，保留上下文——比销毁重建更高效
- **持久化 Agent 的萌芽**：`subscribe_pr_activity` 工具暗示了从短期任务执行向长时间运行 Agent 的演进方向——本文未对 Cursor、Aider 等工具的 PR 订阅/事件触发能力展开比较，其最新产品特性以各自官方文档为准

### 整体评价

协调器模式是一个"以简驭繁"的设计——一个 370 行的文件通过精心编写的系统提示实现了一套完整的多 Agent 编排框架。它的核心架构赌注是**提示驱动编排**——赌模型的指令遵循能力足够强，强到可以替代代码层面的状态机和类型系统。它的核心设计选择在于将"综合"确立为协调器的首要职责，而非简单的任务分发——这在提示驱动的多 Agent 系统中是一个有意义的差异化方向，但 CrewAI 等框架也有类似的"manager agent 理解后再分配"模式，Claude Code 的差异化更多体现在执行力度（370 行的详尽约束）而非理念独创。主要风险在于：(1) 提示遵循的可靠性——系统正确性取决于模型是否忠实执行约束；(2) 并行 Worker 的成本线性增长——缺乏成本感知调度；(3) `subscribe_pr_activity` 暗示的持久化 Agent 方向与现有"人在回路"哲学之间的张力尚未解决。
