Claude Code Wiki
首页 深入解析 工具系统

AgentTool:子代理与多代理协作

高级 工具系统

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)。

属性类型说明示例
agentTypestring代理类型标识符,用于 subagent_type 参数"general-purpose", "Explore"
whenToUsestring主代理判断何时使用此代理的提示文本”Use for codebase exploration…”
toolsstring[]允许的工具列表(白名单),["*"] 表示全部["Bash", "Read", "Write"]
disallowedToolsstring[]禁用的工具列表(黑名单)["Agent", "FileEdit"]
modelstring指定模型或 "inherit" 继承父代理模型"haiku", "opus", "inherit"
permissionModePermissionMode权限模式:"default""plan""bubble""bubble" 冒泡权限到父终端
mcpServersAgentMcpServerSpec[]代理专属的 MCP 服务器配置["slack", {jira: {...}}]
maxTurnsnumber最大代理轮次限制,防止无限循环200
backgroundboolean强制异步后台执行true
memoryAgentMemoryScope持久化内存作用域"user", "project", "local"
isolationstring隔离模式:"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)并行处理子任务。

协调器核心原则

  1. 不检查工作代理:禁止用 Agent 去查看另一个 Agent 的状态,工作代理完成后会主动通知
  2. 委托高层任务:不要用工作代理执行简单命令(如读取文件),委托研究、实现、验证等实质性工作
  3. 不指定模型:工作代理使用默认模型处理实质性任务
  4. 继续已完成代理:通过 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

相关主题