Claude Code Subagent 系统:完整设计与源码分析

基于 Claude Code npm 包 source map 泄露快照 (2026-03-31) 的源码分析。

适用于团队内部分享,理解 AI Agent 多级派生与协同的工程范式。


一、设计哲学

Claude Code 的 subagent 系统解决一个核心问题:单个 agent 无法高效处理所有任务。有些任务需要深度探索(读大量文件),有些需要独立编写代码(隔离修改),有些需要多个 agent 并行工作。

源码中体现的设计原则:

  1. Cache 复用优先:Fork 子 agent 继承父 agent 的完整系统提示和工具列表,实现字节级 prompt cache 命中
  2. 隔离可控:从共享 CWD 到 git worktree 到远程环境,三级隔离按需选择
  3. 工具收敛:子 agent 的工具集是父 agent 的子集,通过多层过滤递进收窄
  4. 生命周期解耦:前台/后台可动态切换,中断可恢复

二、Subagent 类型体系

2.1 三种执行模式

模式触发条件上下文工具集阻塞父 agent
同步前台run_in_background=false(默认)新建(无历史)agent 定义过滤后
异步后台run_in_background=truebackground: true新建(无历史)异步安全子集
Forksubagent_type 未指定 + FORK_SUBAGENT 启用继承父 agent 完整对话父 agent 完全相同否(强制异步)

2.2 Agent 定义类型层次

文件:src/tools/AgentTool/loadAgentsDir.ts

typescript
type AgentDefinition = BuiltInAgentDefinition | CustomAgentDefinition | PluginAgentDefinition

type BaseAgentDefinition = {
  agentType: string                  // 唯一标识(如 'Explore', 'Plan', 'worker')
  whenToUse: string                  // 何时使用的描述
  tools?: string[]                   // 工具白名单;undefined = 所有可用工具
  disallowedTools?: string[]         // 工具黑名单
  skills?: string[]                  // 预加载的技能
  mcpServers?: AgentMcpServerSpec[]  // agent 专属 MCP 服务器
  hooks?: HooksSettings              // 会话级 hook 定义
  color?: AgentColorName             // UI 颜色
  model?: string                     // 'inherit'|'haiku'|'sonnet'|'opus'
  effort?: EffortValue               // 推理深度
  permissionMode?: PermissionMode    // 'acceptEdits'|'plan'|'bubble'|'auto'
  maxTurns?: number                  // 最大迭代轮数
  memory?: AgentMemoryScope          // 'user'|'project'|'local'
  isolation?: 'worktree'|'remote'    // 文件系统隔离级别
  background?: boolean               // 是否始终异步
  omitClaudeMd?: boolean             // 是否排除 CLAUDE.md
  criticalSystemReminder_EXPERIMENTAL?: string  // 每轮注入的关键提醒
}

2.3 Agent 定义来源

来源位置优先级示例
built-in代码内置最低Explore, Plan, code-reviewer
userSettings~/.claude/agents/*.md用户自定义 agent
projectSettings.claude/agents/*.md中高项目级 agent
policySettings组织策略企业级 agent
plugin已安装插件按插件插件提供的 agent

内置 agent 示例:

typescript
// ONE_SHOT_BUILTIN_AGENT_TYPES — 一次性 agent,不期望后续通信
const ONE_SHOT_BUILTIN_AGENT_TYPES = new Set(['Explore', 'Plan'])

2.4 Agent 定义格式(Markdown)

用户可以在 .claude/agents/ 中创建 markdown 文件定义自定义 agent:

markdown
---
agentType: my-reviewer
whenToUse: Use for code review tasks
tools: ['Read', 'Grep', 'Glob']
model: sonnet
maxTurns: 10
permissionMode: plan
---

You are a code reviewer. Focus on...

三、工具过滤:三级收窄

3.1 过滤层次

文件:src/tools/AgentTool/agentToolUtils.ts + src/constants/tools.ts

父 agent 的完整工具集(44+ 内置 + MCP) Layer 1: 全局禁止 ALL_AGENT_DISALLOWED_TOOLS: TaskOutput, EnterPlanMode, ExitPlanMode, AskUserQuestion, TaskStop, Workflow + AgentTool(外部用户:防止无限递归) Layer 2: 自定义 agent 额外禁止 CUSTOM_AGENT_DISALLOWED_TOOLS = ALL_AGENT_DISALLOWED_TOOLS(目前相同) Layer 3: 异步 agent 白名单限制 ASYNC_AGENT_ALLOWED_TOOLS: Read, Bash, Grep, Glob, Edit, Write, WebSearch, WebFetch, NotebookEdit, Skill, ToolSearch, TodoWrite, EnterWorktree, ExitWorktree 额外:in-process 队友可用:AgentTool, TaskCreate/Get/List/Update, SendMessage, Cron* Layer 4: Agent 定义级别 agent.disallowedTools: ['Write'] → 移除 Write agent.tools: ['Read', 'Grep'] → 仅保留这两个 子 agent 最终可用工具集

3.2 核心过滤函数

typescript
export function filterToolsForAgent({
  tools, isBuiltIn, isAsync, permissionMode
}): Tools {
  return tools.filter(tool => {
    // MCP 工具始终允许
    if (tool.name.startsWith('mcp__')) return true

    // Plan 模式下允许 ExitPlanMode
    if (toolMatchesName(tool, EXIT_PLAN_MODE_V2_TOOL_NAME)
        && permissionMode === 'plan') return true

    // 全局禁止
    if (ALL_AGENT_DISALLOWED_TOOLS.has(tool.name)) return false

    // 自定义 agent 额外禁止
    if (!isBuiltIn && CUSTOM_AGENT_DISALLOWED_TOOLS.has(tool.name)) return false

    // 异步 agent 白名单
    if (isAsync && !ASYNC_AGENT_ALLOWED_TOOLS.has(tool.name)) {
      // in-process 队友的额外白名单
      if (isAgentSwarmsEnabled() && isInProcessTeammate()) {
        if (IN_PROCESS_TEAMMATE_ALLOWED_TOOLS.has(tool.name)) return true
      }
      return false
    }

    return true
  })
}

3.3 Fork 路径的特殊处理

Fork 子 agent 设置 useExactTools: true跳过所有过滤,直接继承父 agent 的完整工具集。这确保了与父 agent 字节级相同的工具 schema,从而命中 prompt cache。


四、Subagent 上下文创建

4.1 上下文隔离函数

文件:src/utils/forkedAgent.ts

typescript
export function createSubagentContext(
  parentContext: ToolUseContext,
  overrides?: SubagentContextOverrides,
): ToolUseContext {

  // ① AbortController:新子控制器链接到父控制器
  //    父 abort → 子自动 abort;子 abort → 父不受影响
  const abortController = overrides?.shareAbortController
    ? parentContext.abortController
    : createChildAbortController(parentContext.abortController)

  // ② AppState 访问:包装为自动设置 shouldAvoidPermissionPrompts
  //    后台 agent 无法弹出权限对话框,自动拒绝
  const getAppState = () => ({
    ...parentContext.getAppState(),
    toolPermissionContext: {
      ...parentContext.getAppState().toolPermissionContext,
      shouldAvoidPermissionPrompts: true,
    },
  })

  return {
    // ③ 可变状态:全部克隆,隔离父子
    readFileState: cloneFileStateCache(parentContext.readFileState),
    nestedMemoryAttachmentTriggers: new Set(),
    loadedNestedMemoryPaths: new Set(),
    discoveredSkillNames: new Set(),
    contentReplacementState: /* 克隆 */,

    // ④ 状态变更回调:默认为 no-op(子 agent 的 setAppState 不影响父)
    setAppState: () => {},
    setAppStateForTasks: parentContext.setAppStateForTasks ?? parentContext.setAppState,
    //   ↑ 任务注册回调始终可达根 store(后台任务需要在任何嵌套深度注册/清理)

    // ⑤ UI 回调:子 agent 无 UI
    setToolJSX: undefined,
    addNotification: undefined,
    setStreamMode: undefined,

    // ⑥ 拒绝追踪:独立实例,防止子 agent 的拒绝计数影响父
    localDenialTracking: createDenialTrackingState(),

    // ⑦ 查询追踪:深度 + 1
    queryTracking: {
      chainId: randomUUID(),
      depth: (parentContext.queryTracking?.depth ?? -1) + 1,
    },

    // ⑧ 继承不可变数据
    options: parentContext.options,
    fileReadingLimits: parentContext.fileReadingLimits,
  }
}

4.2 关键隔离决策

字段隔离方式原因
readFileState克隆 LRU cache防止子 agent 的 Read 操作污染父的文件缓存
abortController新子控制器(链接父)子 abort 不影响父,但父 abort 传播到子
setAppStateno-op子 agent 不能修改全局状态
setAppStateForTasks共享根 store后台任务必须能在任何嵌套层注册
localDenialTracking独立实例子 agent 的权限拒绝不应触发父的熔断器
contentReplacementState克隆工具结果落盘决策需要独立追踪

五、Agent 执行引擎

5.1 runAgent() — 核心执行生成器

文件:src/tools/AgentTool/runAgent.ts

① 初始化 (agentId + MCP) ② 上下文构建 (系统提示) Fork? Yes 父的 rendered prompt (cache) No agent 定义的 getSystemPrompt() ③ 工具组装 ④ 预加载技能 (skills) ⑤ 主查询循环 for await (query(...)) { yield message } 记录 sidechain 转录(支持恢复) ⑥ 清理 (finally) MCP disconnect / hooks clear / cache clear / kill bg bash
typescript
export async function* runAgent(params: {
  agentDefinition: AgentDefinition
  promptMessages: Message[]
  toolUseContext: ToolUseContext
  canUseTool: CanUseToolFn
  isAsync: boolean
  availableTools: Tools
  useExactTools?: boolean         // Fork: 使用父 agent 完全相同的工具
  forkContextMessages?: Message[] // Fork: 完整父对话上下文
  worktreePath?: string           // Worktree 隔离路径
  model?: ModelAlias
  maxTurns?: number
}): AsyncGenerator<Message, void> {

  // ① 初始化
  const agentId = createAgentId()
  const { mergedClients, agentTools, cleanup } = await initializeAgentMcpServers(
    agentDefinition, parentMcpClients
  )

  // ② 上下文构建
  const systemPrompt = isFork
    ? params.forkParentSystemPrompt
    : buildAgentSystemPrompt(agentDefinition, toolUseContext)

  if (shouldOmitClaudeMd(agentDefinition)) {
    userContext = { ...userContext, claudeMd: undefined }
  }

  // ③ 工具组装
  const agentTools = useExactTools
    ? params.availableTools
    : assembleToolPool(workerPermissionContext, mcpTools)

  // ④ 预加载技能
  for (const skillName of agentDefinition.skills ?? []) {
    const resolved = resolveSkillName(skillName, commands)
    if (resolved) {
      skillMessages.push(createSkillMessage(resolved))
    }
  }

  // ⑤ 主查询循环
  try {
    for await (const message of query({
      messages: [...skillMessages, ...promptMessages],
      systemPrompt,
      canUseTool,
      toolUseContext: agentToolUseContext,
      maxTurns: maxTurns ?? agentDefinition.maxTurns,
    })) {
      yield message
      await recordSidechainTranscript([message], agentId, lastUuid)
    }
  } finally {
    // ⑥ 清理
    cleanup()
    clearSessionHooks()
    clearFileStateCache()
    clearTodosRegistry()
    killBackgroundBashTasks()
  }
}

5.2 系统提示构建

Fork 路径:直接传入父 agent 的 renderedSystemPrompt,确保字节级一致。

typescript
// 源码注释解释原因:
// re-calling getSystemPrompt() at fork-spawn time can diverge
// (GrowthBook cold→warm) and bust the cache

Normal 路径

typescript
const systemPrompt = enhanceSystemPromptWithEnvDetails(
  agentDefinition.getSystemPrompt({ toolUseContext }),
  { projectRoot, gitStatus, platform }
)

上下文优化


六、同步执行路径

6.1 前台注册

typescript
const registration = registerAgentForeground({
  agentId, description, prompt, selectedAgent,
  autoBackgroundMs: getAutoBackgroundMs()  // 默认 120 秒
})
// 返回:{ taskId, backgroundSignal, cancelAutoBackground }

6.2 消息竞赛循环

typescript
// 两个 Promise 竞赛:下一条消息 vs 后台化信号
const raceResult = await Promise.race([
  agentIterator.next().then(r => ({ type: 'message', result: r })),
  backgroundPromise  // 用户点击「后台运行」或超时 120 秒
])

if (raceResult.type === 'message') {
  // 正常处理消息,继续循环
  agentMessages.push(raceResult.result.value)
} else {
  // 动态后台化:前台 → 后台转换
  backgroundAgentTask(foregroundTaskId)
  registerAsyncAgent({ ... })          // 注册为异步任务
  resumeAgentBackground({ ... })       // 从当前进度继续
  wasBackgrounded = true               // 跳过同步完成
}

6.3 后台提示 UI

2 秒后(PROGRESS_THRESHOLD_MS)显示后台化提示:

typescript
toolUseContext.setToolJSX({ jsx: <BackgroundHint /> })

6.4 同步完成

如果未被后台化:

typescript
const result = finalizeAgentTool(agentMessages, agentId, metadata)
// → { agentId, agentType, content, totalToolUseCount, totalDurationMs, totalTokens, usage }
return { data: { status: 'completed', ...result } }

七、异步执行路径

7.1 异步注册

typescript
const task = registerAsyncAgent({
  agentId, description, prompt, selectedAgent,
  setAppState: rootSetAppState,
  toolUseId: toolUseContext.toolUseId,
})

创建 LocalAgentTaskState

typescript
{
  type: 'local_agent',
  status: 'running',
  agentId,
  abortController,         // 独立(不链接父,异步 agent 存活独立于父)
  isBackgrounded: true,
  pendingMessages: [],     // 通过 SendMessage 排队的消息
  retain: false,           // 是否在 UI 中保留
  evictAfter?: number,     // 自动清理时间
}

7.2 异步生命周期

文件:src/tools/AgentTool/agentToolUtils.ts

typescript
export async function runAsyncAgentLifecycle({
  taskId, abortController, makeStream, metadata,
  description, toolUseContext, rootSetAppState,
  enableSummarization, getWorktreeResult,
}) {
  const tracker = createProgressTracker()

  try {
    // ① 消息流迭代
    for await (const message of makeStream(onCacheSafeParams)) {
      agentMessages.push(message)

      // ② 实时进度更新
      updateAsyncAgentProgress(taskId, getProgressUpdate(tracker), rootSetAppState)

      // ③ SDK 进度事件
      emitTaskProgress(tracker, taskId, toolUseId, description, startTime, lastToolName)
    }

    // ④ 结果定稿
    const result = finalizeAgentTool(agentMessages, taskId, metadata)

    // ⑤ 状态转换
    completeAsyncAgent(result, rootSetAppState)

    // ⑥ 危险操作分类(可选)
    const warning = await classifyHandoffIfNeeded({ agentMessages, tools, ... })

    // ⑦ Worktree 结果
    const worktreeResult = await getWorktreeResult()

    // ⑧ 通知用户
    enqueueAgentNotification({
      taskId, description, status: 'completed',
      finalMessage, usage, worktreeResult,
    })

  } catch (error) {
    if (error instanceof AbortError) {
      killAsyncAgent(taskId, rootSetAppState)
      enqueueAgentNotification({ status: 'killed', ... })
    } else {
      failAsyncAgent(taskId, error, rootSetAppState)
      enqueueAgentNotification({ status: 'failed', ... })
    }
  } finally {
    clearInvokedSkillsForAgent(agentId)
  }
}

7.3 进度数据结构

typescript
type AgentToolProgress = {
  toolUseCount: number
  tokenCount: number
  lastActivity?: ToolActivity       // 最近的工具调用
  recentActivities?: ToolActivity[] // 最近 N 个工具调用
  summary?: string                  // 后台摘要
}

八、Fork Subagent — Prompt Cache 最大化

8.1 设计动机

传统 subagent 每次都重建系统提示 + 工具 schema。Fork 子 agent 复用父 agent 的完全相同的 API 请求前缀,实现 prompt cache 命中。

8.2 启用条件

typescript
export function isForkSubagentEnabled(): boolean {
  if (feature('FORK_SUBAGENT')) {
    if (isCoordinatorMode()) return false      // 协调器模式不 fork
    if (getIsNonInteractiveSession()) return false  // 非交互模式不 fork
    return true
  }
  return false
}

8.3 Fork 消息构建

typescript
export function buildForkedMessages(
  directive: string,
  assistantMessage: AssistantMessage,
): Message[] {
  // ① 克隆父 agent 的助手消息(包含所有 tool_use 块)
  const fullAssistantMessage = { ...assistantMessage, uuid: randomUUID() }

  // ② 为每个 tool_use 创建占位 tool_result
  const toolResultBlocks = toolUseBlocks.map(block => ({
    type: 'tool_result',
    tool_use_id: block.id,
    content: [{ type: 'text', text: 'Fork started — processing in background' }],
  }))

  // ③ 返回:[完整助手消息, 用户消息(占位结果 + 指令)]
  return [fullAssistantMessage, createUserMessage({
    content: [...toolResultBlocks, { type: 'text', text: directive }],
  })]
}

8.4 Fork 指令模板

xml
<fork_boilerplate>
STOP. READ THIS FIRST.

You are a forked worker process. You ARE the fork. Do NOT spawn sub-agents;
execute directly.

Rules:
1. Execute the task directly using available tools
2. Do NOT spawn sub-agents or delegate
3. Work within your assigned scope only
4. Report results in the specified format
...

Output format:
Scope: ...
Result: ...
Key files: ...
Files changed: ...
Issues: ...
</fork_boilerplate>

<DIRECTIVE_PREFIX>your assigned scope

8.5 递归防护

typescript
export function isInForkChild(messages: Message[]): boolean {
  // 扫描消息中是否存在 <fork_boilerplate> 标签
  // 如果是 → 拒绝再次 fork(防止无限递归)
  return messages.some(msg => msg.content?.includes('<fork_boilerplate>'))
}

8.6 Fork vs Normal 对比

维度ForkNormal Agent
subagent_type省略必须指定
系统提示父 agent 的(字节级相同)agent 定义的
对话上下文继承父完整对话空白开始
工具集父 agent 完全相同过滤后子集
Prompt cache命中父的 cache独立 cache
执行方式强制异步可同步/异步
Thinking 配置继承父默认禁用

九、Worktree 隔离

9.1 触发方式

typescript
if (effectiveIsolation === 'worktree') {
  const slug = `agent-${earlyAgentId.slice(0, 8)}`
  worktreeInfo = await createAgentWorktree(slug)
}

9.2 Worktree 创建流程

文件:src/utils/worktree.ts

createAgentWorktree(slug) 快速恢复 已存在? Yes 复用 No 创建 worktree git worktree add -B <branch> <path> <base> slug 校验:字母数字 + ._-,最长 64 字符 slug 扁平化:user/feature → user+feature(防 D/F 冲突) 后置设置 performPostCreationSetup() 复制 settings.local.json → .claude/ 符号链接大目录:node_modules, .turbo(避免磁盘膨胀) 从主仓库配置 git hooks 复制 .worktreeinclude 文件(gitignore 但 agent 需要的文件)

9.3 Worktree 清理

typescript
async function cleanupWorktreeIfNeeded(worktreeInfo) {
  if (await hasWorktreeChanges(worktreeInfo.worktreePath)) {
    // 有改动 → 保留 worktree,返回路径和分支名
    return { worktreePath, worktreeBranch }
  } else {
    // 无改动 → 删除 worktree 和分支
    await removeWorktree(worktreeInfo.worktreePath)
    return undefined
  }
}

9.4 Fork + Worktree

Fork 子 agent 收到一条路径翻译通知:

typescript
export function buildWorktreeNotice(parentCwd, worktreeCwd): string {
  return `You've inherited the conversation context above from a parent agent
    working in ${parentCwd}. You are operating in an isolated git worktree at
    ${worktreeCwd} — same repository, same relative file structure, separate
    working copy. Paths in the inherited context refer to the parent's working
    directory; translate them to your worktree root. Re-read files before
    editing if the parent may have modified them since they appear in the context.`
}

十、多 Agent 协同

10.1 Coordinator 模式

文件:src/coordinator/coordinatorMode.ts

CLAUDE_CODE_COORDINATOR_MODE 启用时,主 agent 变为协调器:

typescript
export function getCoordinatorSystemPrompt(): string {
  return `You are Claude Code, an AI assistant that orchestrates software
    engineering tasks across multiple workers.

    ## Your Tools
    - Agent — Spawn a new worker
    - SendMessage — Continue an existing worker
    - TaskStop — Stop a running worker

    ## Workers
    Workers execute tasks autonomously. Each worker has access to standard
    tools but CANNOT spawn sub-workers. When you launch a worker, provide
    a clear, self-contained prompt.`
}

协调器的工具集

typescript
export const COORDINATOR_MODE_ALLOWED_TOOLS = new Set([
  AGENT_TOOL_NAME,
  SEND_MESSAGE_TOOL_NAME,
  TASK_STOP_TOOL_NAME,
  SYNTHETIC_OUTPUT_TOOL_NAME,
])

10.2 团队创建(TeamCreateTool)

文件:src/tools/TeamCreateTool/TeamCreateTool.ts

typescript
// 创建团队文件(共享可变状态)
const teamFile: TeamFile = {
  name: finalTeamName,
  description,
  createdAt: Date.now(),
  leadAgentId,
  members: [{
    agentId: leadAgentId,
    name: TEAM_LEAD_NAME,
    agentType: leadAgentType,
    joinedAt: Date.now(),
    cwd: getCwd(),
    subscriptions: [],
  }],
}
await writeTeamFileAsync(finalTeamName, teamFile)

10.3 Agent 间通信(SendMessageTool)

文件:src/tools/SendMessageTool/SendMessageTool.ts

邮箱模型:Agent 不直接调用对方,而是通过邮箱投递:

typescript
async function handleMessage(recipientName, content, summary, context) {
  await writeToMailbox(recipientName, {
    from: senderName,
    text: content,
    summary,
    timestamp: new Date().toISOString(),
    color: senderColor,
  }, teamName)

  return { data: { success: true, message: `Message sent to ${recipientName}'s inbox` } }
}

自动恢复:如果目标 agent 已停止,SendMessage 会自动恢复它:

typescript
if (task.status !== 'running') {
  // 自动恢复停止的 agent
  await resumeAgentBackground({
    agentId,
    prompt: input.message,
    toolUseContext: context,
    canUseTool,
  })
  return { data: { success: true, message: 'Agent resumed in the background' } }
}

十一、Agent 恢复机制

文件:src/tools/AgentTool/resumeAgent.ts

恢复触发(/resume 或 SendMessage 发给已停止 agent) loadAgentTranscript(agentId) 从 sidechain JSONL 加载转录 reconstructMessages() 过滤空白/孤立/未完成 reconstructForSubagentResume() 重建工具结果缓存 validateWorktree() 检查/刷新 mtime resolveAgent() 按 agentType 查找定义 registerAsyncAgent() + runAgent()

十二、MCP 服务器初始化

12.1 两类 MCP 客户端

typescript
type AgentMcpServerSpec =
  | string                              // 引用:使用已有 mcp.json 中的服务器
  | { [name: string]: McpServerConfig } // 内联:agent 专属服务器

// 引用型:共享父的连接,agent 退出时不清理
// 内联型:创建新连接,agent 退出时清理

12.2 初始化流程

typescript
async function initializeAgentMcpServers(agentDefinition, parentClients) {
  const referencedClients = []   // 共享父连接
  const inlineClients = []       // 新建连接
  const cleanupFns = []

  for (const spec of agentDefinition.mcpServers ?? []) {
    if (typeof spec === 'string') {
      // 引用型:从父 client 查找并复用
      const existing = parentClients.find(c => c.name === spec)
      if (existing) referencedClients.push(existing)
    } else {
      // 内联型:创建新连接
      const client = await connectToServer(spec)
      inlineClients.push(client)
      cleanupFns.push(() => client.disconnect())
    }
  }

  return {
    mergedClients: [...parentClients, ...inlineClients],
    agentTools: getToolsFromClients(inlineClients),
    cleanup: () => cleanupFns.forEach(fn => fn()),
  }
}

十三、完整生命周期图

用户消息触发 AgentTool AgentTool.call() ① Agent 选择 subagent_type 省略 + FORK 启用? → Yes: FORK_AGENT(继承完整上下文)/ No: 按 subagent_type 查找 agent 定义 ② 权限模式解析 bypassPermissions > acceptEdits > agent > auto ③ 工具过滤 filterToolsForAgent() → resolveAgentTools() / Fork: useExactTools=true ④ Worktree 创建 (如果 isolation='worktree') ⑤ 执行方式决策 同步 → registerAgentForeground() / 异步 → registerAsyncAgent() 同步路径 消息竞赛循环 Promise.race(message, background) message → 继续循环 bg 信号 → 转异步路径 完成 → finalize 动态转换 异步路径 runAsyncAgentLifecycle() ① 消息流迭代 ② 实时进度更新 ③ 结果定稿 ④ 状态转换 ⑤ 通知用户 runAgent() 生成器 系统提示构建 Fork: 父的 rendered / Normal: agent 定义 工具组装 Fork: 完全相同 / Normal: 过滤后重组 MCP 服务器初始化 引用型: 复用父连接 / 内联型: 新建连接 主查询循环 for await (query(...)) 清理 (finally) yield 消息到父 / 记录 sidechain 转录 / MCP disconnect / hooks+cache clear / kill bg bash

十四、关键源码文件清单

src/tools/AgentTool/ AgentTool.tsx 主入口(输入校验、agent 选择、执行路径分发) runAgent.ts 执行引擎(上下文构建、查询循环、MCP 初始化) agentToolUtils.ts 工具解析、结果定稿、进度追踪、异步生命周期 forkSubagent.ts Fork 语义(消息构建、指令模板、递归防护) loadAgentsDir.ts Agent 定义加载(Markdown/JSON 解析、多来源合并) prompt.ts 动态 prompt 生成(agent 列表、能力描述) constants.ts 常量(AGENT_TOOL_NAME, ONE_SHOT_BUILTIN_AGENT_TYPES) agentColorManager.ts UI 颜色分配 resumeAgent.ts 恢复中断 agent(转录加载、worktree 验证) agentMemory.ts Agent 持久化记忆 agentDisplay.ts 渲染工具 builtInAgents.ts 内置 agent 注册 UI.tsx 进度渲染(搜索/读取折叠) src/utils/ forkedAgent.ts createSubagentContext()、runForkedAgent() worktree.ts Worktree 创建/清理/验证 src/coordinator/ coordinatorMode.ts 协调器模式(系统提示、工具限制) src/tools/ SendMessageTool/ Agent 间通信(邮箱模型、自动恢复) TeamCreateTool/ 团队创建(团队文件、任务列表目录) TeamDeleteTool/ 团队解散 src/constants/ & src/ tools.ts工具过滤常量 Task.ts任务类型定义(local_agent, in_process_teammate 等)

十五、可借鉴的设计模式

模式Claude Code 做法可借鉴场景
Cache 复用 Fork子 agent 继承父的完整 prompt + 工具,字节级 cache 命中需要频繁派生子任务的 agent 系统
三级工具收窄全局禁止 → 自定义禁止 → 异步白名单 → agent 定义级多角色、多权限的 agent 体系
上下文隔离克隆可变状态克隆、不可变数据共享、回调 no-op父子 agent 间状态管理
动态前后台切换Promise.race(消息 vs 后台信号),运行时转换长时间运行任务的用户体验
邮箱通信模型不直接调用,通过邮箱投递 + 自动恢复解耦的多 agent 通信
Sidechain 转录独立 JSONL 文件记录,支持恢复可中断/恢复的后台任务
Worktree 隔离git worktree + 符号链接大目录 + 自动清理需要文件系统隔离的并行任务
递归防护isInForkChild() 扫描标签防止无限 fork任何允许自我派生的系统
Markdown 定义YAML frontmatter + 正文作为 system prompt用户可自定义的 agent 配置
多来源合并built-in < user < project < policy + MCP 过滤分层配置系统

文件来源:Claude Code npm 包 source map 泄露快照 (2026-03-31)
分析日期:2026-04-08