Single Agent 模型
Claude Code 的 agent 系统从一个简单的抽象出发:single agent 是一个自包含的单元,拥有自己的 system prompt、tool 集合、模型偏好和行为约束。每个 sub-agent——无论是内置的还是用户自定义的——都是这一模型的实例。
AgentDefinition 类型层次
Section titled “AgentDefinition 类型层次”所有 agent 共享一个定义在 src/tools/AgentTool/loadAgentsDir.ts 中的基类型:
// src/tools/AgentTool/loadAgentsDir.ts — BaseAgentDefinitionexport type BaseAgentDefinition = { agentType: string // 唯一标识符(如 "general-purpose"、"Explore") whenToUse: string // 供父 agent 决定何时派生的描述 tools?: string[] // 允许的 tool(undefined = 全部,['*'] = 全部) disallowedTools?: string[] // 明确禁用的 tool skills?: string[] // 预加载的 skill 名称 mcpServers?: AgentMcpServerSpec[] hooks?: HooksSettings color?: AgentColorName model?: string // "inherit" = 继承父级模型,或指定模型 ID effort?: EffortValue permissionMode?: PermissionMode maxTurns?: number memory?: AgentMemoryScope // 'user' | 'project' | 'local' isolation?: 'worktree' | 'remote' background?: boolean omitClaudeMd?: boolean // 跳过 CLAUDE.md 注入(为只读 agent 节省 token) // ...}三种具体类型继承自此基类型:
classDiagram
class BaseAgentDefinition {
+agentType: string
+whenToUse: string
+tools?: string[]
+model?: string
+memory?: AgentMemoryScope
+isolation?: string
}
class BuiltInAgentDefinition {
+source: "built-in"
+getSystemPrompt(params): string
}
class CustomAgentDefinition {
+source: SettingSource
+getSystemPrompt(): string
+filename?: string
}
class PluginAgentDefinition {
+source: "plugin"
+getSystemPrompt(): string
+plugin: string
}
BaseAgentDefinition <|-- BuiltInAgentDefinition
BaseAgentDefinition <|-- CustomAgentDefinition
BaseAgentDefinition <|-- PluginAgentDefinition
内置 Agent
Section titled “内置 Agent”内置 agent 注册在 src/tools/AgentTool/builtInAgents.ts:
export function getBuiltInAgents(): AgentDefinition[] { if ( isEnvTruthy(process.env.CLAUDE_AGENT_SDK_DISABLE_BUILTIN_AGENTS) && getIsNonInteractiveSession() ) { return [] // SDK 用户可以从空白状态开始 }
if (feature('COORDINATOR_MODE')) { if (isEnvTruthy(process.env.CLAUDE_CODE_COORDINATOR_MODE)) { const { getCoordinatorAgents } = require('../../coordinator/workerAgent.js') return getCoordinatorAgents() // 完全不同的 agent 集合 } }
const agents: AgentDefinition[] = [ GENERAL_PURPOSE_AGENT, STATUSLINE_SETUP_AGENT, ] // 条件性添加... if (areExplorePlanAgentsEnabled()) { agents.push(EXPLORE_AGENT, PLAN_AGENT) } // ... return agents}六个内置 agent 各司其职:
| Agent | 模型 | Tool | 核心特性 |
|---|---|---|---|
| General Purpose | 默认 sub-agent | ['*'](全部) | 多步骤任务的主力 |
| Explore | haiku(外部)/ inherit(内部) | 只读(无 Edit/Write/Agent) | 快速代码库搜索,omitClaudeMd: true |
| Plan | inherit | 只读(同 Explore) | 架构规划,omitClaudeMd: true |
| Verification | inherit | 只读 + Bash + WebFetch | 对抗性测试,background: true |
| Claude Code Guide | haiku | Glob/Grep/Read/WebFetch/WebSearch | 文档查询,permissionMode: 'dontAsk' |
| Statusline Setup | sonnet | 仅 Read/Edit | 状态栏配置,color: 'orange' |
内置 Agent 的设计模式
Section titled “内置 Agent 的设计模式”只读强制执行。 Explore 和 Plan agent 均通过 disallowedTools 实现只读模式,而非通过特殊的”只读”标志:
export const EXPLORE_AGENT: BuiltInAgentDefinition = { agentType: 'Explore', disallowedTools: [ AGENT_TOOL_NAME, // 禁止派生 sub-agent EXIT_PLAN_MODE_TOOL_NAME, FILE_EDIT_TOOL_NAME, // 禁止编辑 FILE_WRITE_TOOL_NAME, // 禁止写入 NOTEBOOK_EDIT_TOOL_NAME, ], omitClaudeMd: true, // 在 3400 万次以上 Explore 派生中节省约 5-15 Gtok/周 // ...}通过 omitClaudeMd 优化 token。 只读 agent 不需要 CLAUDE.md 中的提交/PR/lint 规范。omitClaudeMd 标志会将这些内容从 agent 的 userContext 中剥离,在规模化场景下节省可观的开销。
对抗性 prompt。 Verification agent 拥有最复杂的 system prompt(约 130 行),专门用于对抗 LLM 倾向于草草确认结果的问题:
const VERIFICATION_SYSTEM_PROMPT = `You are a verification specialist.Your job is not to confirm the implementation works — it's to try to break it.
You have two documented failure patterns. First, verification avoidance:when faced with a check, you find reasons not to run it...`自定义 Agent 加载
Section titled “自定义 Agent 加载”自定义 agent 从带有 frontmatter 的 markdown 文件或 JSON 定义中加载。getAgentDefinitionsWithOverrides() 中的加载流水线:
flowchart LR
A[loadMarkdownFilesForSubdir 'agents'] --> B[parseAgentFromMarkdown]
C[loadPluginAgents] --> D[Plugin agents]
E[getBuiltInAgents] --> F[Built-in agents]
B --> G[All agents list]
D --> G
F --> G
G --> H[getActiveAgentsFromList]
H --> I[Active agents<br/>deduplicated by priority]
Agent 优先级系统
Section titled “Agent 优先级系统”当多个 agent 共享相同的 agentType 时,优先级链决定哪个生效:
// src/tools/AgentTool/loadAgentsDir.ts — getActiveAgentsFromListconst agentGroups = [ builtInAgents, // 最低优先级 pluginAgents, userAgents, // ~/.claude/agents/ projectAgents, // 仓库中的 .claude/agents/ flagAgents, // feature flag 管理 managedAgents, // 策略/企业管理(最高优先级)]
const agentMap = new Map<string, AgentDefinition>()for (const agents of agentGroups) { for (const agent of agents) { agentMap.set(agent.agentType, agent) // 后面的组覆盖前面的 }}这意味着项目级 agent 定义可以覆盖内置 agent,而 managed/policy agent 可以覆盖一切。
Markdown Agent 格式
Section titled “Markdown Agent 格式”.claude/agents/code-reviewer.md 中的自定义 agent:
---name: code-reviewerdescription: "Reviews code changes for quality and correctness"tools: - Read - Glob - Grep - Bashmodel: inheritpermissionMode: bypassPermissionsmaxTurns: 50memory: project---
You are a code review specialist. Review the provided code changes...frontmatter 经过 Zod 验证(AgentJsonSchema),markdown 正文成为 system prompt。当设置了 memory 时,system prompt 会动态追加 agent 特定的 memory 内容:
getSystemPrompt: () => { if (isAutoMemoryEnabled() && memory) { return systemPrompt + '\n\n' + loadAgentMemoryPrompt(agentType, memory) } return systemPrompt}Agent 专属 MCP Server
Section titled “Agent 专属 MCP Server”Agent 可以声明自己的 MCP server 需求:
// MCP server spec 的两种形式export type AgentMcpServerSpec = | string // 按名称引用:"slack" | { [name: string]: McpServerConfig } // 内联:{ "my-server": { command: "..." } }声明了 requiredMcpServers 的 agent,在对应 server 不可用时会被过滤掉:
export function hasRequiredMcpServers( agent: AgentDefinition, availableServers: string[],): boolean { return agent.requiredMcpServers.every(pattern => availableServers.some(server => server.toLowerCase().includes(pattern.toLowerCase()), ), )}Agent Tool
Section titled “Agent Tool”Agent tool(src/tools/AgentTool/)是主 agent 派生 sub-agent 的方式。当主 Claude 实例决定使用 sub-agent 时,它会调用 Agent tool,并传入与某个活跃 agent 定义匹配的 subagent_type 参数。该 tool 随后:
- 从
activeAgents中解析 agent 定义 - 通过
getSystemPrompt()构造 system prompt - 选择模型(继承、指定 ID 或默认 sub-agent 模型)
- 使用 agent 的 tool 集合和 prompt fork 一个新对话
- 将 agent 的最终响应返回给父级
这创建了清晰的父→子关系:每个 agent 在自己的 context 中以自己的约束条件运行,而父级保留对派发和结果解释的完全控制权。