AgentTool 是 Claude Code 中实现任务委托与多代理协作的核心工具,允许主代理将复杂任务委托给专门的子代理执行,或通过协调器模式编排多个工作代理并行处理大型任务。该工具支持同步/异步执行、进程内/独立进程代理、Fork 继承上下文等多种协作模式,是构建可扩展 AI 工作流的关键基础设施。
核心架构概览
AgentTool 的设计遵循分层委托原则:主代理通过调用 Agent 工具生成子代理,子代理继承父代理的工具池、权限上下文和会话状态,同时拥有独立的对话历史和执行环境。这种架构使得任务可以递归分解,形成代理树结构。
graph TB
A[Main Session<br/>QueryEngine] --> B[AgentTool]
B --> C{Execution Mode}
C -->|Sync| D[LocalAgentTask<br/>Foreground]
C -->|Async| E[LocalAgentTask<br/>Background]
C -->|Teammate| F[Teammate Spawn]
C -->|Fork| G[Fork Subagent]
D --> H[runAgent<br/>Direct Execution]
E --> H
F --> I{Backend Type}
I -->|In-Process| J[InProcessBackend<br/>AsyncLocal Context]
I -->|Tmux| K[TmuxBackend<br/>Separate Process]
I -->|ITerm| L[ITermBackend<br/>Split Pane]
G --> H
H --> M[Agent Definition]
M --> N[Built-in Agents]
M --> O[Custom Agents]
M --> P[Plugin Agents]
N --> Q[General-Purpose]
N --> R[Explore]
N --> S[Plan]
N --> T[Verification]
J --> U[SendMessage<br/>Inter-agent Comm]
K --> U
L --> U
style A fill:#e1f5ff
style B fill:#fff4e1
style C fill:#f0f0f0
style F fill:#ffe1f5
style G fill:#e1ffe1
Sources: AgentTool.tsx, runAgent.ts, LocalAgentTask.tsx
代理定义体系
Agent Definition 接口结构
每个代理由 AgentDefinition 定义,包含执行行为、权限限制、工具集配置等元数据。系统支持三种代理来源:内置代理(Built-in)、自定义代理(Custom,来自项目/用户配置)、插件代理(Plugin)。
| 属性 | 类型 | 说明 | 示例 |
|---|---|---|---|
agentType | string | 代理类型标识符,用于 subagent_type 参数 | "general-purpose", "Explore" |
whenToUse | string | 主代理判断何时使用此代理的提示文本 | ”Use for codebase exploration…” |
tools | string[] | 允许的工具列表(白名单),["*"] 表示全部 | ["Bash", "Read", "Write"] |
disallowedTools | string[] | 禁用的工具列表(黑名单) | ["Agent", "FileEdit"] |
model | string | 指定模型或 "inherit" 继承父代理模型 | "haiku", "opus", "inherit" |
permissionMode | PermissionMode | 权限模式:"default"、"plan"、"bubble" | "bubble" 冒泡权限到父终端 |
mcpServers | AgentMcpServerSpec[] | 代理专属的 MCP 服务器配置 | ["slack", {jira: {...}}] |
maxTurns | number | 最大代理轮次限制,防止无限循环 | 200 |
background | boolean | 强制异步后台执行 | true |
memory | AgentMemoryScope | 持久化内存作用域 | "user", "project", "local" |
isolation | string | 隔离模式:"worktree" 或 "remote" | "worktree" 创建临时 git worktree |
Sources: loadAgentsDir.ts, constants.ts
内置代理类型
系统预装四种专用代理,针对常见工作流优化:
1. General-Purpose Agent(通用代理)
默认代理类型,适用于研究复杂问题、代码搜索、多步骤任务。继承父代理全部工具,无文件修改限制,返回简洁报告。
{
agentType: 'general-purpose',
tools: ['*'], // 所有工具
whenToUse: 'General-purpose agent for researching complex questions...',
// model: 未指定 → 使用 getDefaultSubagentModel()
}
Sources: generalPurposeAgent.ts
2. Explore Agent(探索代理)
只读代码库探索专用代理,禁用所有文件修改工具(Write、Edit),仅保留搜索和读取能力。使用 Haiku 模型(外部用户)或继承模型(内部),快速响应。
{
agentType: 'Explore',
disallowedTools: ['Agent', 'ExitPlanMode', 'FileEdit', 'FileWrite', 'NotebookEdit'],
model: process.env.USER_TYPE === 'ant' ? 'inherit' : 'haiku',
omitClaudeMd: true, // 省略 CLAUDE.md 上下文节省 token
// 只读强制:禁止 mkdir, touch, rm, cp, mv, git commit 等
}
Sources: exploreAgent.ts
3. Plan Agent(规划代理)
只读架构设计代理,用于生成实现计划、识别关键文件、评估架构权衡。与 Explore 类似但输出包含”Critical Files for Implementation”章节。
{
agentType: 'Plan',
disallowedTools: ['Agent', 'ExitPlanMode', 'FileEdit', 'FileWrite', 'NotebookEdit'],
model: 'inherit',
// 输出格式:Scope, Result, Key files, Files changed, Issues
}
Sources: planAgent.ts
4. Verification Agent(验证代理)
证据收集与验证代理(实验性功能),用于验证其他代理的工作成果。通过 GrowthBook 开关 tengu_hive_evidence 启用。
Sources: builtInAgents.ts
自定义代理配置
用户可在 .claude/agents/ 目录创建 Markdown 文件定义自定义代理,通过 YAML frontmatter 配置:
---
description: Database migration specialist
tools: [Bash, Read, Write]
model: sonnet
permissionMode: default
maxTurns: 50
mcpServers:
- postgres-admin # 引用现有 MCP 服务器
- monitoring: # 内联定义
command: node
args: [./monitoring-mcp.js]
---
You are a database migration expert. Always create backups before modifying schemas...
Sources: loadAgentsDir.ts
执行模式与生命周期
同步 vs 异步执行
AgentTool 支持两种执行模式,通过 run_in_background 参数控制:
sequenceDiagram
participant Main as Main Agent
participant AgentTool
participant Task as LocalAgentTask
participant Subagent as Subagent Process
alt 同步模式 (run_in_background=false)
Main->>AgentTool: Agent({prompt, subagent_type})
AgentTool->>Task: registerAsyncAgent(foreground)
Task->>Subagent: runAgent() [阻塞]
Subagent-->>Task: 返回结果
Task-->>AgentTool: 同步返回 result
AgentTool-->>Main: 直接返回工具结果
else 异步模式 (run_in_background=true)
Main->>AgentTool: Agent({prompt, run_in_background: true})
AgentTool->>Task: registerAsyncAgent(background)
Task->>Subagent: runAgent() [非阻塞]
AgentTool-->>Main: 返回 {status: "async_launched", agentId, outputFile}
Subagent-->>Task: 完成后触发通知
Task->>Main: <task-notification> 消息
end
异步执行关键优势:
- 主线程非阻塞:主代理继续处理其他任务,不等待子代理完成
- 进度追踪:通过
outputFile路径查看中间状态(使用 Read 或 Bash tail) - 完成通知:子代理完成后通过
<task-notification>XML 消息通知主代理 - 后台任务面板:UI 自动显示运行中的代理,支持 Ctrl+O 展开/折叠
Sources: AgentTool.tsx, LocalAgentTask.tsx
任务状态管理
LocalAgentTaskState 维护代理的完整生命周期状态:
type LocalAgentTaskState = {
type: 'local_agent'
agentId: string
prompt: string
agentType: string
abortController?: AbortController
result?: AgentToolResult
progress?: AgentProgress // 实时进度:toolUseCount, tokenCount, lastActivity
isBackgrounded: boolean // true = 后台运行
pendingMessages: string[] // SendMessage 队列(轮次边界处理)
retain: boolean // UI 保持任务(防止 GC)
diskLoaded: boolean // 已从 JSONL 引导
evictAfter?: number // 驱逐截止时间
}
进度追踪机制:
ProgressTracker累积输入 token(取最新值)和输出 token(求和)recentActivities数组保留最近 5 个工具调用活动createActivityDescriptionResolver()从工具的getActivityDescription()预计算人类可读描述
Sources: LocalAgentTask.tsx
Fork 子代理:上下文继承
Fork 子代理是实验性功能(通过 FORK_SUBAGENT feature flag 启用),允许子代理继承父代理的完整对话历史,实现真正的上下文共享。
Fork vs 标准子代理对比
| 维度 | Fork 子代理 | 标准子代理 |
|---|---|---|
| 上下文 | 继承父代理所有历史消息 | 空白对话,仅接收 prompt |
| 系统提示 | 复用父代理已渲染的 system prompt | 根据代理定义重新生成 |
| Prompt Cache | 与父代理共享缓存前缀(字节级相同) | 独立缓存,无共享 |
| 触发方式 | 省略 subagent_type 参数 | 指定 subagent_type="xxx" |
| 适用场景 | 研究任务、实现工作(需要上下文) | 专门任务(探索、规划) |
| 模型选择 | 必须继承父模型(cache 一致性) | 可指定任意模型 |
Fork 消息构造
为保持 prompt cache 共享,所有 fork 子代理必须生成字节级相同的 API 请求前缀:
// 构造 fork 消息序列
function buildForkedMessages(directive: string, assistantMessage: AssistantMessage) {
// 1. 保留父代理完整的 assistant 消息(所有 tool_use 块)
const fullAssistantMessage = clone(assistantMessage)
// 2. 为每个 tool_use 生成占位符 tool_result(相同文本)
const toolResults = toolUseBlocks.map(block => ({
type: 'tool_result',
tool_use_id: block.id,
content: [{ type: 'text', text: 'Fork started — processing in background' }]
}))
// 3. 追加子代理指令文本块
const directiveBlock = { type: 'text', text: buildChildMessage(directive) }
return [fullAssistantMessage, createUserMessage([...toolResults, directiveBlock])]
}
关键约束:
- 所有 fork 子代理使用相同占位符文本,仅最后指令块不同
- 递归 fork 防护:检测
<fork_boilerplate>标签拒绝嵌套 fork - 子代理系统提示覆盖:“default to forking” 指令仅适用于父代理
Sources: forkSubagent.ts
多代理协作:Teammate 系统
Teammate 系统实现多代理并行协作,每个 teammate 在独立进程或独立终端面板中运行,通过邮箱机制(Mailbox)进行异步消息传递。
协作架构
graph LR
A[Team Lead<br/>Main Session] --> B[SendMessage]
B --> C{Recipient}
C -->|@alice| D[Alice's Mailbox]
C -->|@bob| E[Bob's Mailbox]
C -->|*| F[Broadcast<br/>All Mailboxes]
D --> G[Alice Agent<br/>In-Process/Tmux]
E --> H[Bob Agent<br/>In-Process/Tmux]
G --> I[Process Messages<br/>Update Tasks]
H --> I
I --> J[Reply via SendMessage]
J --> K[Lead's Mailbox]
K --> A
style A fill:#e1f5ff
style B fill:#fff4e1
style D fill:#ffe1f5
style E fill:#ffe1f5
Teammate 后端类型
| 后端 | 进程模型 | 隔离性 | 适用场景 |
|---|---|---|---|
| In-Process | 同进程 AsyncLocal | 共享内存,独立上下文 | 轻量级协作,快速启动 |
| Tmux | 独立进程(tmux pane) | 完全隔离,可持久化 | 长时间任务,断线保持 |
| ITerm | 独立进程(iterm split-pane) | 完全隔离 | macOS 原生体验 |
Teammate 生成流程
// AgentTool 调用时检测 team_name + name → 触发 teammate spawn
if (teamName && name) {
const result = await spawnTeammate({
name, // teammate 名称(用于 @mentions)
prompt, // 初始指令
team_name: teamName,
use_splitpane: true,
plan_mode_required: spawnMode === 'plan',
model: model ?? agentDef?.model,
agent_type: subagent_type
}, toolUseContext)
return {
status: 'teammate_spawned',
teammate_id: result.teammate_id,
tmux_pane_id: result.tmux_pane_id,
...
}
}
Sources: spawnMultiAgent.ts, SendMessageTool.ts
消息传递协议
SendMessage 工具支持点对点和广播两种模式:
// 点对点消息
await SendMessage({
to: "alice",
summary: "Code review needed",
message: "Please review the authentication changes in src/auth/"
})
// 广播消息
await SendMessage({
to: "*",
summary: "Sprint planning",
message: "All agents: prioritize performance optimization tasks"
})
// 结构化消息(关闭请求)
await SendMessage({
to: "bob",
message: {
type: "shutdown_request",
reason: "Task completed successfully"
}
})
邮箱存储:消息以 JSON 格式存储在 ~/.claude/mailbox/<team>/<agent>.json,支持离线消息累积。
Sources: SendMessageTool.ts, teammateMailbox.ts
协调器模式
协调器模式是多代理编排的高级形态,主代理退化为纯协调者,通过 Agent 工具生成多个工作代理(worker agents)并行处理子任务。
协调器核心原则
- 不检查工作代理:禁止用 Agent 去查看另一个 Agent 的状态,工作代理完成后会主动通知
- 委托高层任务:不要用工作代理执行简单命令(如读取文件),委托研究、实现、验证等实质性工作
- 不指定模型:工作代理使用默认模型处理实质性任务
- 继续已完成代理:通过 SendMessage 继续已完成的工作代理,利用其已加载的上下文
协调器系统提示
function getCoordinatorSystemPrompt(): string {
return `
You are Claude Code, an AI assistant that orchestrates software engineering tasks across multiple workers.
## 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
Every message you send is to the user. Worker results are internal signals — never thank or acknowledge them.
## Your Tools
- Agent - Spawn a new worker
- SendMessage - Continue an existing worker
- TaskStop - Stop a running worker
### Agent Results
Worker results arrive as **user-role messages** containing \`<task-notification>\` XML:
\`\`\`xml
<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>
\`\`\`
Use the <task-id> value with SendMessage to continue that worker.
`
}
协调器工作流示例
// 用户:修复认证 bug
// 协调器:
Agent({
description: "Investigate auth bug",
subagent_type: "worker",
prompt: "Search for null pointer exceptions in authentication flow..."
})
Agent({
description: "Research secure token storage",
subagent_type: "worker",
prompt: "Investigate best practices for token storage..."
})
// 并行启动两个工作代理 → 继续处理其他用户请求
// 工作代理 1 完成:
<task-notification>
<task-id>agent-a1b</task-id>
<status>completed</status>
<result>Found null pointer in src/auth/validate.ts:42</result>
</task-notification>
// 协调器:
SendMessage({
to: "agent-a1b",
message: "Fix the null pointer in src/auth/validate.ts:42 and add tests"
})
Sources: coordinatorMode.ts
代理内存持久化
代理支持三种作用域的持久化内存,通过 memory 字段配置:
| 作用域 | 存储路径 | 生命周期 | 用例 |
|---|---|---|---|
| user | ~/.claude/agent-memory/<agentType>/ | 跨项目共享 | 用户偏好、全局知识 |
| project | <project>/.claude/agent-memory/<agentType>/ | 项目级共享 | 项目特定约定、架构决策 |
| local | <project>/.claude/agent-memory-local/<agentType>/ | 本地独享(不提交 VCS) | 临时状态、实验数据 |
内存加载机制
// 代理启动时加载内存
async function loadAgentMemoryPrompt(agentType: string, scope: AgentMemoryScope) {
const memoryDir = getAgentMemoryDir(agentType, scope)
await ensureMemoryDirExists(memoryDir)
// 读取所有 .md 文件并合并为 prompt
return buildMemoryPrompt(memoryDir)
}
// 代理执行过程中可通过 Write 工具追加内存
// 内存文件路径:{memoryDir}/knowledge.md
远程内存挂载:通过 CLAUDE_CODE_REMOTE_MEMORY_DIR 环境变量将本地内存重定向到远程挂载点(支持跨机器共享)。
Sources: agentMemory.ts
工具过滤与权限控制
工具过滤策略
子代理的工具池通过多层过滤构建:
graph TD
A[Parent Tool Pool] --> B{Is Built-in?}
B -->|Yes| C[Remove ALL_AGENT_DISALLOWED_TOOLS]
B -->|No| D[Remove ALL + CUSTOM_AGENT_DISALLOWED_TOOLS]
C --> E{Is Async?}
D --> E
E -->|Yes| F[Filter by ASYNC_AGENT_ALLOWED_TOOLS]
E -->|No| G[Keep All Remaining]
F --> H{In-Process Teammate?}
H -->|Yes| I[Add Agent + Task Tools]
H -->|No| J[Strict Async Filter]
I --> K[Final Tool Pool]
G --> K
J --> K
style A fill:#e1f5ff
style K fill:#e1ffe1
禁用工具列表:
ALL_AGENT_DISALLOWED_TOOLS:所有代理禁用(如 Coordinator 工具)CUSTOM_AGENT_DISALLOWED_TOOLS:仅自定义代理禁用(如某些权限敏感工具)ASYNC_AGENT_ALLOWED_TOOLS:异步代理白名单(限制后台代理能力)
权限冒泡(Bubble Mode)
permissionMode: "bubble" 将子代理的权限请求转发到父代理终端,保持交互连续性:
// 子代理执行 Bash 命令时
if (permissionMode === 'bubble') {
// 通过 leaderPermissionBridge 发送权限请求
const request = createPermissionRequest(toolName, input)
await sendPermissionRequestViaMailbox(request)
// 父代理终端显示权限对话框
// 用户批准后通过 mailbox 返回决策
const response = await pollPermissionResponse(request.request_id)
return response.decision // 'allow' | 'deny'
}
Sources: agentToolUtils.ts, leaderPermissionBridge.ts
进程内 Teammate 上下文隔离
In-Process Teammate 使用 AsyncLocalStorage 实现上下文隔离,在同一进程内运行多个代理而不互相干扰:
// Teammate 上下文
interface TeammateContext {
identity: {
agentId: string
name: string
color: string
teamName: string
}
mailboxPath: string
permissionRequestQueue: Queue
}
// 上下文包装器
function runWithTeammateContext<T>(
context: TeammateContext,
fn: () => Promise<T>
): Promise<T> {
return teammateAsyncLocalStorage.run(context, fn)
}
// 在任何地方获取当前 teammate 上下文
function getTeammateContext(): TeammateContext | undefined {
return teammateAsyncLocalStorage.getStore()
}
关键隔离维度:
- 会话状态:每个 teammate 拥有独立的消息历史和 AppState 片段
- 权限上下文:独立的 permission mode 和工具访问控制
- 文件状态缓存:克隆父代理的缓存快照,避免跨代理污染
- MCP 客户端:继承父代理连接,但可扩展代理专属服务器
Sources: inProcessRunner.ts, teammateContext.ts
MCP 服务器继承与扩展
子代理可以继承父代理的 MCP 客户端,同时定义代理专属的 MCP 服务器:
// 代理定义中指定 MCP 服务器
{
agentType: "slack-notifier",
mcpServers: [
"slack", // 引用现有服务器
{ "jira": { // 内联定义
command: "npx",
args: ["-y", "@anthropic/jira-mcp-server"]
}}
],
requiredMcpServers: ["slack"] // 强制要求 slack 必须可用
}
// 代理启动时初始化 MCP
async function initializeAgentMcpServers(
agentDefinition: AgentDefinition,
parentClients: MCPServerConnection[]
) {
const agentClients = [...parentClients] // 继承父代理
for (const spec of agentDefinition.mcpServers) {
if (typeof spec === 'string') {
// 引用现有服务器 → 复用父代理连接(共享客户端)
const client = await connectToServer(spec, getConfigByName(spec))
agentClients.push(client)
} else {
// 内联定义 → 创建新连接(代理独享)
const client = await connectToServer(name, config)
agentClients.push(client)
newlyCreatedClients.push(client) // 标记为待清理
}
}
// 清理函数:仅关闭代理独享的客户端
return { clients: agentClients, cleanup: () => closeNewClients() }
}
Plugin-Only Policy 兼容:当 MCP 锁定为插件专属时,用户控制的代理跳过 frontmatter MCP 服务器,但插件代理和内置代理(管理员信任)仍可加载。
Sources: runAgent.ts
高级使用模式
模式 1:研究-实现分离
// 主代理:启动研究代理
const researchResult = await Agent({
subagent_type: "Explore",
prompt: "Find all authentication endpoints and their validation logic",
run_in_background: true
})
// 研究代理完成后,主代理启动实现代理
// 研究结果通过 context 传递
模式 2:并行验证
// 协调器:启动多个验证代理
await Agent({ subagent_type: "worker", prompt: "Verify API contract compliance" })
await Agent({ subagent_type: "worker", prompt: "Verify database schema integrity" })
await Agent({ subagent_type: "worker", prompt: "Verify security best practices" })
// 三个代理并行执行,结果通过 <task-notification> 汇总
模式 3:Fork 上下文共享
// Fork 继承父代理上下文,适用于需要历史信息的任务
await Agent({
// 省略 subagent_type → 触发 fork
prompt: "Based on our previous discussion about microservices, implement the user service",
name: "user-service-impl" // 可选:在 teams panel 显示名称
})
模式 4:工作树隔离
// 在隔离的 git worktree 中运行代理(避免污染主分支)
await Agent({
subagent_type: "general-purpose",
prompt: "Implement experimental feature X",
isolation: "worktree" // 创建临时 worktree
})
模式 5:团队协作
// 启动多个 teammate 并行工作
await Agent({
name: "alice",
team_name: "backend-team",
prompt: "Implement user authentication"
})
await Agent({
name: "bob",
team_name: "backend-team",
prompt: "Implement API rate limiting"
})
// 通过 SendMessage 协调
await SendMessage({
to: "alice",
message: "Bob finished rate limiting. Please integrate with auth flow."
})
最佳实践
1. 选择正确的代理类型
- 需要代码修改 → General-Purpose 或自定义代理
- 只读探索 → Explore Agent(Haiku 模型,快速响应)
- 架构规划 → Plan Agent(继承模型,深度分析)
- 需要上下文 → Fork 子代理(继承对话历史)
- 并行协作 → Teammate(独立进程,消息传递)
2. 异步 vs 同步决策
- 任务时长 < 30 秒 → 同步执行(实时反馈)
- 任务时长 > 30 秒 → 异步执行(
run_in_background: true) - 需要中间检查 → 异步 + Read
outputFile - 多任务并行 → 协调器模式 + 多个异步代理
3. 权限模式选择
- 默认:子代理独立请求权限(打断用户)
- Bubble:权限冒泡到父终端(连续交互)
- Plan:需要计划批准(验证模式)
- Auto:自动批准安全操作(快速执行)
4. 代理内存使用
- 用户偏好 →
memory: "user"(跨项目共享) - 项目约定 →
memory: "project"(团队可见) - 临时状态 →
memory: "local"(不提交 VCS)
5. 性能优化
- Prompt Cache 优化:使用 Fork 子代理共享缓存前缀
- Token 节省:Explore/Plan 代理设置
omitClaudeMd: true - 模型选择:只读任务使用 Haiku,复杂推理使用 Sonnet/Opus
- 并行启动:在单个消息中调用多个 Agent 工具
Sources: prompt.ts, AgentTool.tsx
相关主题
- 工具架构:Tool 接口与权限模型 - 了解 Tool 基础接口
- 协调器模式:多代理任务协调 - 协调器深度解析
- MCP 服务:服务器连接、资源管理与协议实现 - MCP 集成机制
- 查询引擎:QueryEngine 对话生命周期管理 - 主会话执行流程