1. Claude Code中的Subagents机制解析
Claude Code的Subagents(子代理)是一种专门用于处理特定任务的AI助手机制。这种设计允许开发者将辅助性任务委托给独立的子代理执行,从而保持主对话上下文的整洁和高效。
1.1 Subagents的核心价值
Subagents机制主要解决了以下几个关键问题:
-
上下文隔离:当某个辅助任务会产生大量中间输出(如搜索结果、日志内容或文件内容)时,这些内容会占用宝贵的主对话上下文窗口。通过Subagents,这些中间过程被隔离在子代理的独立上下文中,只有最终摘要返回主对话。
-
任务专业化:可以为不同类型的任务创建专门的Subagents,每个子代理都有定制的系统提示、特定的工具访问权限和独立的权限设置。
-
资源优化:可以将任务路由到更适合(通常也更经济)的模型上执行,例如使用Haiku模型处理简单的查询任务。
-
工作流管理:支持并行处理多个独立任务,并通过明确的委托机制保持工作流的清晰性。
典型的Subagents应用场景包括:
- 代码审查和质量检查
- 调试和错误分析
- 数据查询和研究
- 测试执行和结果分析
- 文档生成和整理
1.2 Subagents的工作原理
每个Subagent都在自己独立的上下文窗口中运行,具有以下特点:
-
独立上下文:子代理看不到主对话的历史记录、已调用的技能或已读取的文件内容。
-
任务委托:Claude会根据任务描述和子代理配置自动决定何时委托任务,也可以由开发者显式调用特定子代理。
-
结果返回:子代理完成任务后,将相关结果摘要返回给主对话,而不是所有中间过程。
-
资源分配:子代理可以使用与主对话不同的模型,以优化资源使用。
技术实现上,Subagents是通过带有YAML frontmatter的Markdown文件定义的。这些文件包含子代理的元数据配置和行为指令,存储在特定目录中供Claude Code加载和使用。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. Subagents的类型与配置
2.1 内置Subagents
Claude Code提供了一系列内置的Subagents,用于常见任务:
| 子代理名称 | 模型继承 | 工具限制 | 主要用途 |
|---|---|---|---|
| Explore | 继承主对话(限制为Opus) | 只读工具 | 代码搜索和探索 |
| Plan | 继承主对话 | 只读工具 | 规划期间的研究 |
| General-purpose | 继承主对话 | 所有工具 | 复杂研究和多步操作 |
这些内置子代理在交互式会话中默认可用,但可以通过配置进行限制或禁用。
2.2 自定义Subagents创建
创建自定义Subagents的基本流程:
-
定义子代理文件:在特定目录中创建Markdown文件,包含YAML frontmatter和系统提示。
-
配置关键参数:
name: 子代理的唯一标识符description: 描述子代理的用途,Claude用它来决定何时委托tools: 子代理可用的工具列表model: 指定使用的模型(sonnet/opus/haiku)或继承主对话
-
存储位置选择:
- 项目级:
.claude/agents/(适合项目特定子代理) - 用户级:
~/.claude/agents/(适合跨项目使用的子代理)
- 项目级:
示例子代理定义(代码审查专家):
markdown复制---
name: code-reviewer
description: 扫描文件并提供可读性、性能和最佳实践方面的改进建议
tools: Read, Grep, Glob
model: sonnet
---
您是一个代码改进专家。对于发现的每个问题,请解释问题、显示当前代码并提供改进版本。
2.3 子代理的作用域与优先级
子代理的存储位置决定了它的作用范围和优先级:
- 托管设置 (最高优先级):通过组织管理员部署
- CLI标志定义:启动Claude Code时通过JSON传递
- 项目级:项目目录中的
.claude/agents/ - 用户级:用户主目录中的
~/.claude/agents/ - 插件提供 (最低优先级):通过插件安装的子代理
当多个子代理同名时,Claude Code会使用优先级更高的定义。
3. Subagents的高级配置与使用
3.1 工具访问控制
Subagents默认继承主对话的工具访问权限,但可以通过配置进行精细控制:
- 允许列表模式:通过
tools字段明确指定可用的工具
yaml复制tools: Read, Grep, Glob, Bash
- 拒绝列表模式:通过
disallowedTools字段排除特定工具
yaml复制disallowedTools: Write, Edit
- MCP工具控制:可以按服务器限制MCP工具
yaml复制disallowedTools: mcp__github # 禁用GitHub相关的MCP工具
3.2 权限模式
通过permissionMode字段控制子代理的权限行为:
| 模式 | 行为描述 |
|---|---|
| default | 标准权限检查,会提示用户 |
| acceptEdits | 自动接受文件编辑和常见文件系统命令 |
| auto | 自动模式:后台分类器审查命令 |
| dontAsk | 自动拒绝权限提示 |
| bypassPermissions | 跳过权限提示(谨慎使用) |
| plan | 计划模式(只读探索) |
3.3 生命周期钩子(Hooks)
可以为子代理配置生命周期钩子,在特定事件发生时执行自定义操作:
- 工具使用前后:
yaml复制hooks:
PreToolUse:
- matcher: "Bash"
hooks:
- type: command
command: "./scripts/validate-command.sh"
PostToolUse:
- matcher: "Edit|Write"
hooks:
- type: command
command: "./scripts/run-linter.sh"
- 子代理启动/停止:
json复制{
"hooks": {
"SubagentStart": [
{
"matcher": "db-agent",
"hooks": [
{ "type": "command", "command": "./scripts/setup-db-connection.sh" }
]
}
],
"SubagentStop": [
{
"hooks": [
{ "type": "command", "command": "./scripts/cleanup-db-connection.sh" }
]
}
]
}
}
3.4 持久化内存
通过memory字段为子代理启用持久化内存:
yaml复制memory: project # 也可以是user或local
启用后,子代理可以:
- 在内存目录中积累知识
- 跨会话保留学习成果
- 通过MEMORY.md文件存储重要信息
4. Subagents的调用与管理
4.1 调用方式
- 自动委托:Claude根据任务描述和子代理配置自动选择
claude复制Use the test-runner subagent to fix failing tests
- 显式调用(@-mention):确保特定子代理运行
claude复制@"code-reviewer (agent)" look at the auth changes
- 会话范围调用:整个会话使用子代理的配置
bash复制claude --agent code-reviewer
4.2 运行模式
Subagents可以在两种模式下运行:
-
前台模式:
- 阻塞主对话直到完成
- 权限提示直接显示给用户
- 适合需要即时结果的场景
-
后台模式:
- 与主对话并发运行
- 权限提示在主会话中显示
- 适合长时间运行的非关键任务
从v2.1.198开始,Subagents默认在后台运行,只有在需要结果才能继续时才会在前台运行。
4.3 常见使用模式
- 隔离高容量操作:
claude复制Use a subagent to run the test suite and report only the failing tests
- 并行研究:
claude复制Research the authentication, database, and API modules in parallel
- 工作流链接:
claude复制Use the code-reviewer, then the optimizer subagent
- 嵌套子代理:子代理可以生成自己的子代理(最多5层深度)
5. 实用示例与最佳实践
5.1 代码审查子代理示例
markdown复制---
name: code-reviewer
description: 专家级代码审查,专注于质量、安全和可维护性
tools: Read, Grep, Glob, Bash
model: inherit
---
您是一位高级代码审查专家,确保代码质量和安全的高标准。
审查清单:
- 代码清晰可读
- 函数和变量命名恰当
- 无重复代码
- 正确的错误处理
- 无暴露的密钥或API密钥
- 实现了输入验证
- 良好的测试覆盖率
- 考虑了性能因素
按优先级提供反馈:
1. 关键问题(必须修复)
2. 警告(应该修复)
3. 建议(考虑改进)
5.2 调试子代理示例
markdown复制---
name: debugger
description: 错误和测试失败调试专家
tools: Read, Edit, Bash, Grep, Glob
---
您是一位擅长根本原因分析的调试专家。
调试流程:
1. 捕获错误信息和堆栈跟踪
2. 确定重现步骤
3. 定位失败位置
4. 实施最小修复
5. 验证解决方案
对于每个问题,提供:
- 根本原因解释
- 支持诊断的证据
- 具体的代码修复
- 测试方法
- 预防建议
5.3 数据库只读查询子代理
markdown复制---
name: db-reader
description: 执行只读数据库查询
tools: Bash
hooks:
PreToolUse:
- matcher: "Bash"
hooks:
- type: command
command: "./scripts/validate-readonly-query.sh"
---
您是具有只读访问权限的数据库分析师。
当被要求分析数据时:
1. 识别包含相关数据的表
2. 编写高效的SELECT查询
3. 清晰地呈现结果
您不能修改数据。如果被要求执行写入操作,请解释您只有读取权限。
配套的验证脚本:
bash复制#!/bin/bash
INPUT=$(cat)
COMMAND=$(echo "$INPUT" | jq -r '.tool_input.command // empty')
if echo "$COMMAND" | grep -iE '\b(INSERT|UPDATE|DELETE|DROP|CREATE|ALTER)\b' > /dev/null; then
echo "Blocked: Write operations not allowed" >&2
exit 2
fi
exit 0
5.4 最佳实践建议
-
设计原则:
- 保持子代理专注单一职责
- 编写清晰详细的描述
- 合理限制工具访问权限
- 为特定领域定制系统提示
-
性能优化:
- 将高容量操作委托给子代理
- 为简单任务使用轻量级模型
- 利用后台模式处理非关键任务
-
团队协作:
- 将项目级子代理纳入版本控制
- 通过插件共享常用子代理
- 为常见任务建立标准化子代理
-
安全考虑:
- 为敏感操作使用适当的权限模式
- 对数据库访问等操作实施hook验证
- 定期审查子代理的工具权限
6. 常见问题排查
6.1 子代理未被调用
可能原因及解决方案:
- 描述不明确:确保子代理的description字段清晰描述其用途
- 作用域问题:检查子代理文件是否存储在正确的位置
- 名称冲突:确保没有更高优先级的同名子代理
- 工具限制:主对话可能需要启用Agent工具
6.2 权限问题
常见场景:
-
子代理操作被拒绝:
- 检查子代理的permissionMode设置
- 确认主对话的权限设置是否覆盖子代理
-
hook验证失败:
- 确保hook脚本有执行权限
- 验证脚本返回正确的退出代码(0=允许,2=拒绝)
6.3 性能问题
优化建议:
- 模型选择:为简单任务使用haiku等轻量模型
- 上下文管理:将产生大量输出的任务委托给子代理
- 并行处理:使用后台模式运行独立任务
6.4 调试技巧
-
查看子代理转录:
- 位置:
~/.claude/projects/{project}/{sessionId}/subagents/ - 格式:
agent-{agentId}.jsonl
- 位置:
-
环境变量:
CLAUDE_CODE_FORK_SUBAGENT:控制分叉模式CLAUDE_CODE_DISABLE_BACKGROUND_TASKS:禁用后台任务
-
日志信息:
- 关注子代理启动和停止时的系统消息
- 检查hook脚本的输出和错误信息
7. 扩展与集成
7.1 与插件系统集成
子代理可以通过插件分发和共享:
- 将子代理定义放在插件的
agents/目录 - 插件安装后,子代理对所有用户可用
- 支持递归扫描子目录,便于组织
7.2 与MCP服务器集成
通过mcpServers字段为子代理提供专属服务连接:
yaml复制mcpServers:
- playwright:
type: stdio
command: npx
args: ["-y", "@playwright/mcp@latest"]
- github
7.3 与Agent SDK集成
在编程式使用场景中:
- 通过SDK选项配置子代理
- 使用
CLAUDE_AGENT_SDK_DISABLE_BUILTIN_AGENTS控制内置子代理 - 实现自定义的子代理管理逻辑
7.4 与技能(Skills)系统集成
通过skills字段预加载技能内容:
yaml复制skills:
- api-conventions
- error-handling-patterns
这为子代理提供了领域知识,而无需在执行期间动态加载。
