本文是「51学通信」Claude Code 教程系列第 4 轮,聚焦 Agent 模式与自动化。如果你想跳过分派策略,直接学会"如何亲手定义一个专家子代理并安全地委派任务",这一篇就是为你准备的。读者交流可加站长爱卫生微信
gprshome201101。
本教程教你用 .claude/agents/ 目录亲手定义自定义子代理(subagent),并通过工具白名单、权限模式、worktree 隔离、后台运行四件套,把高风险或高吞吐的任务安全地"关进隔离上下文"交给专家执行。
学完后你将能够:
- 看懂子代理 frontmatter 的全部字段,并能按需取舍;
- 写出"只读安全扫描""worktree 隔离重构""后台测试补全"三类专家子代理;
- 让主代理用一句话、用 @提及、用 -p 无头模式批量调度它们;
- 给子代理装上专属审计 hook,全程留痕。
适用人群:已用过 Claude Code 基本交互、会读 settings.json、想从"单兵作战"升级到"委派小队"的开发者。
isolation: worktree、background、CLAUDE_CODE_SUBAGENT_MODEL 等较新特性,旧版部分字段不识别);claude 命令;utils.py 也行)。子代理是一个带独立上下文窗口、独立系统提示、独立工具权限的 Claude 实例。主代理通过 Task 工具把任务委派给它,它在自己的上下文里完成搜索、读文件、改代码,最后只把摘要交回主会话。
这一句话藏着三个关键价值:
Write/Edit,从机制上杜绝它误改代码。haiku 省钱,把推理活派给 opus 保质量。Claude Code 自带三类内置子代理,先认识它们,避免重复造轮子:
| 内置子代理 | 工具 | 用途 | 模型 |
|---|---|---|---|
Explore |
只读(拒绝 Write/Edit) | 代码搜索、文件发现、仓库探索 | 继承主会话,API 上封顶 Opus |
Plan |
只读 | plan 模式下做规划前的研究 | 继承主会话 |
general-purpose |
全工具 | 复杂多步任务、既搜又改 | 继承主会话 |
注意:
Explore和Plan会跳过你的 CLAUDE.md 和 git 状态以保持快速廉价;其它所有子代理(含你自定义的)都会加载这两者。
什么时候该自定义子代理? 当你发现自己反复用同一套指令生成同一类工作者时——比如"每次都要说'你是个安全审查员,只看不动'"——就该把它固化成一个 .claude/agents/xxx.md 文件。
子代理就是一个 Markdown 文件 + YAML frontmatter。正文是系统提示,frontmatter 是配置。只有 name 和 description 是必填,其余按需:
| 字段 | 必填 | 说明 |
|---|---|---|
name |
✅ | 小写字母+连字符的唯一标识;hook 里以 agent_type 收到此值 |
description |
✅ | 何时委派给它——Claude 靠这句话做路由决策 |
tools |
❌ | 允许的工具列表;省略=继承全部工具 |
disallowedTools |
❌ | 从继承集合里再剔除的工具 |
model |
❌ | sonnet/opus/haiku/fable/完整 ID/inherit;默认 inherit |
permissionMode |
❌ | default/acceptEdits/auto/dontAsk/bypassPermissions/plan |
maxTurns |
❌ | 最大轮次上限,防失控 |
skills |
❌ | 启动即注入完整内容的 Skill(区别于只列工具) |
mcpServers |
❌ | 该子代理可用的 MCP 服务器 |
hooks |
❌ | 仅作用于本子代理的生命周期钩子 |
memory |
❌ | user/project/local,跨会话学习 |
background |
❌ | true 则永远后台运行 |
effort |
❌ | low/medium/high/xhigh/max,覆盖会话力度 |
isolation |
❌ | worktree = 在临时 git worktree 里跑 |
color |
❌ | 任务列表里的显示颜色 |
initialPrompt |
❌ | 作为主会话代理运行时自动提交的首轮 |
最容易踩的两个坑:
tools 是"继承全部工具",不是"不给工具"。要只读,必须显式写 tools: Read, Grep, Glob。description 决定路由。写得含糊(如"帮我处理代码"),主代理就不知道何时该用它;写清触发场景(如"在代码修改后主动审查安全与最佳实践"),命中率才高。同一名字的子代理,优先级从高到低覆盖:
managed settings(组织级,最高)
↓
--agents CLI JSON(仅本次会话)
↓
.claude/agents/ ← 项目级,建议提交 git,团队共享
↓
~/.claude/agents/ ← 用户级,所有项目可用
↓
插件 agents/ 目录(最低)
django-migrator)→ 放 .claude/agents/,提交版本控制;code-improver)→ 放 ~/.claude/agents/;claude --agents '{
"debugger": {
"description": "Debugging specialist for errors and test failures.",
"prompt": "You are an expert debugger. Analyze errors, identify root causes, and provide fixes.",
"tools": ["Read", "Grep", "Glob", "Bash"],
"model": "sonnet"
}
}'
Claude Code 会监视
~/.claude/agents/和.claude/agents/目录,文件一改几秒内热加载,无需重启——除非该目录在会话启动时还不存在(首次创建某 scope 的第一个 agent 文件后仍需重启一次)。
目标是造一个只能看、不能改的安全审查专家。新建 .claude/agents/security-scan.md:
---
name: security-scan
description: 在代码修改后主动审查硬编码密钥、SQL 注入、命令注入等安全问题。只读,不改代码。
tools: Read, Grep, Glob
model: haiku
color: red
---
You are a security reviewer with read-only access.
Scan the provided paths for:
- hardcoded secrets (API keys, passwords, tokens)
- SQL injection (string-concatenated queries)
- command injection (shell=True with user input)
- path traversal
Output a table: file:line | severity | issue | fix hint.
Never modify files. If you find nothing, say "NO FINDINGS".
操作说明:把文件放进项目的 .claude/agents/,在 Claude Code 里说:
用 security-scan 子代理审查 src/ 目录。
预期结果:主代理委派给 security-scan,它在自己的上下文里 grep 整个目录,最后只回传一张问题表,主会话上下文保持干净。
常见问题:
- 主代理找不到它? 多半是该 agents/ 目录在会话启动前不存在——重启一次 Claude Code。
- 它居然去改文件? 检查 tools 是否漏写了 Read, Grep, Glob 而误省略(省略=全工具)。本例用 haiku 既快又省,因为审查是模式匹配活。
这次要造一个真能改代码的专家,但用 isolation: worktree 让它在一个临时 git worktree 里动手,绝不碰你的主工作区。新建 .claude/agents/refactor-worker.md:
---
name: refactor-worker
description: 在隔离的 git worktree 中执行函数级重构(提取、重命名、简化),改完跑测试,不破坏主分支。
tools: Read, Edit, Write, Bash, Grep, Glob
permissionMode: acceptEdits
isolation: worktree
model: sonnet
color: orange
---
You are a refactor specialist working in an isolated worktree.
Rules:
- Make the smallest change that achieves the goal.
- After editing, run the project's test command (detect from package.json / pytest config).
- If tests fail, revert your change and report the failure; do NOT commit.
- Summarize: what changed (files + nature), test result, and the diff path.
为什么 acceptEdits + worktree 是黄金组合:
- acceptEdits 让它免确认地写文件——但只在 worktree 里,所以即便写崩了,你的主分支毫发无损;
- worktree 默认从默认分支切出(不是你的脏 HEAD),改造基于干净基线;
- 子代理若没产生任何改动,worktree 会自动清理。
操作说明:
用 refactor-worker 子代理,把 utils.py 里那个 80 行的 parse_config 函数拆成三个职责单一的小函数,跑通测试。
预期结果:子代理在 /.claude/worktrees/ 下的一个临时目录里改代码、跑测试,最后回报"改了 3 个文件、测试通过、diff 在 worktree 路径"。你的主工作区 git status 一尘不染。
常见问题:
- 它在 worktree 里跑 cd 没生效? 子代理里 cd 不在 Bash 调用间持久化——子代理本就在 worktree 里工作,无需手动 cd。
- 子代理中途 worktree 目录被删导致命令报错? v2.1.203 起已修复,命令会直接报错而非偷偷落到主 checkout。
第三个专家负责给函数补单元测试,体量大、要跑很久,所以让它后台运行并具备跨会话记忆。新建 .claude/agents/test-writer.md:
---
name: test-writer
description: 为指定函数或模块补写单元测试并验证通过。适合批量、耗时任务,后台运行。
tools: Read, Write, Edit, Bash, Grep, Glob
model: sonnet
background: true
memory: project
color: green
---
You are a test engineer.
For each target function:
1. Read its implementation and existing tests.
2. Write focused unit tests covering happy path + edge cases + error cases.
3. Run the tests; iterate until green.
4. Remember (via project memory) which modules already have good coverage to avoid duplication.
Report: functions covered, tests added, pass/fail counts.
字段点睛:
- background: true:永远后台跑,你可以继续和主代理对话,完成时收到通知;
- memory: project:它会把"哪些模块已有覆盖"记到项目记忆里,下次不重复造测试。
自 v2.1.198 起,不显式设置
background时,Claude 会默认把子代理放后台。要前台阻塞拿结果,需在调用时指定。
-p 批量定义完三个专家,现在让它们干活。三种调度方式由轻到重:
方式 A:自然语言委派(交互式最常用)
直接说"用 refactor-worker 子代理去拆解 X 函数",主代理会通过 Task 工具委派。
方式 B:@ 提及强制委派
当主代理"忘记"用专家时,用 @refactor-worker 显式点名,强制走该子代理。
方式 C:-p 无头模式批量驱动(自动化核心)
把子代理和 -p(print/headless)结合,可造批量流水线。模型解析顺序为:CLAUDE_CODE_SUBAGENT_MODEL 环境变量 > 调用时 model 参数 > frontmatter 的 model > 主会话模型。所以你可以用环境变量临时给所有子代理换挡:
# 用 haiku 跑一遍快速安全扫描(省钱),结果存 JSON
CLAUDE_CODE_SUBAGENT_MODEL=haiku \
claude -p "用 security-scan 子代理审查整个 src/,输出问题清单" \
--output-format json > scan.json
并行委派:当多个子代理任务相互独立时,主代理可在单次响应里同时发出多个 Task 调用,它们并发执行。例如同时派 security-scan 审查、test-writer 补测、refactor-worker 重构三个不相关模块。
常见问题:并行前提是任务无依赖。若 B 要用 A 的产出,就不能并行——先跑 A、拿结果、再跑 B。
子代理可以在 frontmatter 里带自己的 hooks(插件子代理出于安全不支持此字段,需复制到 .claude/agents/)。给 refactor-worker 加一个 PostToolUse 钩子,把每次 Edit/Write 落盘记录到审计日志:
---
name: refactor-worker
# ... 其它字段同步骤 5 ...
hooks:
PostToolUse:
- matcher: "Edit|Write"
hooks:
- type: command
command: |
echo "[refactor-worker] $(date '+%H:%M:%S') tool=$TOOL_NAME" >> .claude/refactor-audit.log
---
(系统提示同前)
这样每次子代理改文件,.claude/refactor-audit.log 自动留痕,事后可审计它动了哪些文件。
把上面三个专家组装成一支小队,对同一个项目做一次并行体检+安全改造。在一个有 src/ 的 git 仓库里,对主代理说:
对 src/ 做一次三路并行:(1) security-scan 审查安全问题;(2) refactor-worker 在 worktree 里把
parse_config拆小并跑通测试;(3) test-writer 给validate_input补单测。三个任务互不依赖,请并发执行。
预期执行画面(主会话视角):
security-scan(haiku)几秒后回传问题表;refactor-worker(sonnet,worktree)跑测试期间,主会话空闲可用;test-writer(sonnet,后台)完成时弹通知;完成后用脚本核对 worktree 改动是否如预期:
# 查看隔离 worktree 里 refactor-worker 的改动
git -C .claude/worktrees/<worktree-dir> diff --stat
确认无误后再决定是否把 worktree 的成果合回主分支——安全委派的精髓就是:先隔离试验,再决定合并。
flowchart TD
U[用户一句话指令] --> MAIN[主会话/主代理]
MAIN -->|Task 委派| SEC[security-scan<br/>只读·haiku·red]
MAIN -->|Task 委派| REF[refactor-worker<br/>可写·worktree·acceptEdits]
MAIN -->|Task 委派| TW[test-writer<br/>后台·memory·green]
SEC -->|只回传摘要| MAIN
REF -->|worktree 隔离试验| WT[(临时 worktree)]
WT -->|测试通过?| DEC{验证}
DEC -->|是| MERGE[决定合并主分支]
DEC -->|否| RV[自动回退·不污染]
TW -->|完成通知| MAIN
REF -.PostToolUse hook.-> LOG[(refactor-audit.log)]
MAIN --> SUMMARY[汇总三方结论<br/>主上下文保持干净]
code.claude.com/docs/en/sub-agents(字段最权威出处)code.claude.com/docs/en/agent-sdk/subagents(SDK 里编程式调用子代理)hooks 字段的完整语法来源settings.json、git);纯前端/无 git 的项目营(worktree 隔离依赖 git)。tools 白名单的只读专家;能用 isolation: worktree + acceptEdits 完成一次不污染主分支的重构;能用 -p 驱动子代理产出 JSON 结果。[!tip] 51学通信知识星球 星主:爱卫生(微信:gprshome201101)——公众号「51学通信」创办者,19 年通信行业运维与讲师经验,著有《GPRS网络信令实例详解》《EPC原理与实践》《5G核心网原理与实践》三本纸质书(各大电商平台有售)。 星球定位:深耕 5G 核心网、IMS、NFV/AI、云原生等 ICT 领域,主打运维岗位与信令分析。 当前规模:5200 篇主题 / 990 个回答,198 元/年。 加入福利:加入星球后请加爱卫生微信,拉您进知识星球年度陪伴与答疑群——不限量回复您的各种问题,另有群内分享。 AI 加持:51学通信知识星球已作为 skill 接入 WorkBuddy,使用 deepseek-4-flash 在海量星球帖子中精准找贴、找视频、找 FAQ 和案例,做总结、找文档和 PPT 等场景全覆盖。
