<!-- title: 造专家子代理：白名单隔离委派 -->

> 本文是「51学通信」Claude Code 教程系列第 4 轮，聚焦 **Agent 模式与自动化**。如果你想跳过分派策略，直接学会"如何亲手定义一个专家子代理并安全地委派任务"，这一篇就是为你准备的。读者交流可加站长爱卫生微信 `gprshome201101`。

## 概述

本教程教你用 `.claude/agents/` 目录**亲手定义自定义子代理（subagent）**，并通过**工具白名单、权限模式、worktree 隔离、后台运行**四件套，把高风险或高吞吐的任务安全地"关进隔离上下文"交给专家执行。

学完后你将能够：
- 看懂子代理 frontmatter 的全部字段，并能按需取舍；
- 写出"只读安全扫描""worktree 隔离重构""后台测试补全"三类专家子代理；
- 让主代理用一句话、用 `@提及`、用 `-p` 无头模式批量调度它们；
- 给子代理装上专属审计 hook，全程留痕。

**适用人群**：已用过 Claude Code 基本交互、会读 `settings.json`、想从"单兵作战"升级到"委派小队"的开发者。

## 前置条件

- Claude Code **v2.1.198 及以上**（本教程用到 `isolation: worktree`、`background`、`CLAUDE_CODE_SUBAGENT_MODEL` 等较新特性，旧版部分字段不识别）；
- 一个 **git 仓库**作为练习场（worktree 隔离依赖 git）；
- 终端能跑 `claude` 命令；
- 一个需要改造的小项目（哪怕是一个 `utils.py` 也行）。

---

## 步骤 1：理解子代理——把"脏活重活"关进隔离上下文

子代理是一个**带独立上下文窗口、独立系统提示、独立工具权限的 Claude 实例**。主代理通过 **Task 工具**把任务委派给它，它在自己的上下文里完成搜索、读文件、改代码，最后**只把摘要**交回主会话。

这一句话藏着三个关键价值：

1. **上下文隔离**：子代理翻遍整个仓库、读了一堆日志，这些中间产物**不污染**主会话上下文。主会话只收到一句结论。
2. **能力约束**：你可以限制子代理**只能用某些工具**——比如一个只读审查代理根本拿不到 `Write`/`Edit`，从机制上杜绝它误改代码。
3. **模型分级**：把简单活派给 `haiku` 省钱，把推理活派给 `opus` 保质量。

Claude Code 自带三类内置子代理，先认识它们，避免重复造轮子：

| 内置子代理 | 工具 | 用途 | 模型 |
|---|---|---|---|
| `Explore` | 只读（拒绝 Write/Edit） | 代码搜索、文件发现、仓库探索 | 继承主会话，API 上封顶 Opus |
| `Plan` | 只读 | plan 模式下做规划前的研究 | 继承主会话 |
| `general-purpose` | 全工具 | 复杂多步任务、既搜又改 | 继承主会话 |

> **注意**：`Explore` 和 `Plan` 会**跳过你的 CLAUDE.md 和 git 状态**以保持快速廉价；其它所有子代理（含你自定义的）都会加载这两者。

**什么时候该自定义子代理？** 当你发现自己**反复用同一套指令生成同一类工作者**时——比如"每次都要说'你是个安全审查员，只看不动'"——就该把它固化成一个 `.claude/agents/xxx.md` 文件。

---

## 步骤 2：认识子代理的"身份证"——frontmatter 字段全解

子代理就是一个 **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` 决定路由**。写得含糊（如"帮我处理代码"），主代理就不知道何时该用它；写清触发场景（如"在代码修改后**主动**审查安全与最佳实践"），命中率才高。

---

## 步骤 3：scope 决策——子代理文件放哪儿

同一名字的子代理，优先级从高到低覆盖：

```
managed settings（组织级，最高）
   ↓
--agents CLI JSON（仅本次会话）
   ↓
.claude/agents/      ← 项目级，建议提交 git，团队共享
   ↓
~/.claude/agents/    ← 用户级，所有项目可用
   ↓
插件 agents/ 目录（最低）
```

- **团队共享的专家**（如本项目专属的 `django-migrator`）→ 放 `.claude/agents/`，提交版本控制；
- **个人习惯型专家**（如你私人定制的 `code-improver`）→ 放 `~/.claude/agents/`；
- **临时试一下** → 用 CLI 临时定义，不留盘：

```bash
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 文件后仍需重启一次）。

---

## 步骤 4：实战第一刀——写一个只读安全扫描子代理

目标是造一个**只能看、不能改**的安全审查专家。新建 `.claude/agents/security-scan.md`：

```markdown
---
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` 既快又省，因为审查是模式匹配活。

---

## 步骤 5：实战第二刀——worktree 隔离的重构执行子代理

这次要造一个**真能改代码**的专家，但用 `isolation: worktree` 让它在一个**临时 git worktree** 里动手，绝不碰你的主工作区。新建 `.claude/agents/refactor-worker.md`：

```markdown
---
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。

---

## 步骤 6：实战第三刀——后台运行 + 持久记忆的测试补全子代理

第三个专家负责给函数补单元测试，体量大、要跑很久，所以让它**后台运行**并具备**跨会话记忆**。新建 `.claude/agents/test-writer.md`：

```markdown
---
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 会默认把子代理放后台**。要前台阻塞拿结果，需在调用时指定。

---

## 步骤 7：主代理如何委派——显式、并行、`-p` 批量

定义完三个专家，现在让它们干活。三种调度方式由轻到重：

**方式 A：自然语言委派**（交互式最常用）

直接说"用 refactor-worker 子代理去拆解 X 函数"，主代理会通过 Task 工具委派。

**方式 B：`@` 提及强制委派**

当主代理"忘记"用专家时，用 `@refactor-worker` 显式点名，强制走该子代理。

**方式 C：`-p` 无头模式批量驱动**（自动化核心）

把子代理和 `-p`（print/headless）结合，可造批量流水线。模型解析顺序为：`CLAUDE_CODE_SUBAGENT_MODEL` 环境变量 > 调用时 model 参数 > frontmatter 的 model > 主会话模型。所以你可以**用环境变量临时给所有子代理换挡**：

```bash
# 用 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。

---

## 步骤 8：给子代理装专属审计 hook

子代理可以在 frontmatter 里带自己的 `hooks`（插件子代理出于安全不支持此字段，需复制到 `.claude/agents/`）。给 `refactor-worker` 加一个 PostToolUse 钩子，把每次 Edit/Write 落盘记录到审计日志：

```markdown
---
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` 补单测。三个任务互不依赖，请并发执行。

**预期执行画面**（主会话视角）：

- 三个 Task 同时出现在任务列表，分别带红/橙/绿颜色标记；
- `security-scan`（haiku）几秒后回传问题表；
- `refactor-worker`（sonnet，worktree）跑测试期间，主会话空闲可用；
- `test-writer`（sonnet，后台）完成时弹通知；
- 主会话最后**汇总三方结论**——而整个过程产生的中间日志、搜索结果、worktree 文件内容，**一个字都没进主会话上下文**。

完成后用脚本核对 worktree 改动是否如预期：

```bash
# 查看隔离 worktree 里 refactor-worker 的改动
git -C .claude/worktrees/<worktree-dir> diff --stat
```

确认无误后再决定是否把 worktree 的成果合回主分支——**安全委派的精髓就是：先隔离试验，再决定合并**。

---

## 工作流程图

```mermaid
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/>主上下文保持干净]
```

---

## 延伸阅读

- **官方文档 · Create custom subagents**：`code.claude.com/docs/en/sub-agents`（字段最权威出处）
- **官方文档 · Subagents in the SDK**：`code.claude.com/docs/en/agent-sdk/subagents`（SDK 里编程式调用子代理）
- **官方文档 · Automate with hooks**：子代理 `hooks` 字段的完整语法来源
- **官方文档 · Isolate sessions with worktrees**：worktree 隔离机制的深入说明
- 进阶可继续探索 **agent teams**（会话间通信）与 **background agents**（多会话并行监控），这是子代理之上的更高级编排。

## 训练营适用性评估

- **适合的训练营类型**：Claude Code 进阶实战营、AI 工程师提效训练营、企业级 AI 辅助开发内训。要求学员有 2–4 周 Claude Code 使用经验。
- **不适合**：零基础营（需先掌握基本交互、`settings.json`、git）；纯前端/无 git 的项目营（worktree 隔离依赖 git）。
- **预计教学时长**：讲师演示 + 学员动手约 **2.5–3 小时**。建议拆成两节：第一节（步骤 1–4，概念+只读专家，约 60 分钟），第二节（步骤 5–8 + 实战小队，约 90–120 分钟）。
- **考核点**：学员能独立写出带正确 `tools` 白名单的只读专家；能用 `isolation: worktree` + `acceptEdits` 完成一次不污染主分支的重构；能用 `-p` 驱动子代理产出 JSON 结果。
- **延伸练习**：把本教程的三专家扩展成"五专家小队"（再加文档生成专家、性能剖析专家），并给每个专家配一条专属审计 hook。

---

## 参考来源

1. [Create custom subagents — Claude Code Docs](https://code.claude.com/docs/en/sub-agents) — 子代理 frontmatter 字段、scope 优先级、内置子代理、模型解析顺序的权威出处
2. [Claude Code Subagents: The Complete Guide (2026) — amux](https://amux.io/guides/claude-code-subagents/) — 子代理何时该用、何时反受其害的实战视角
3. [Subagent Frontmatter — Developers Digest](https://www.developersdigest.tech/guides/subagent-frontmatter) — frontmatter 各字段（model/effort/tools/mcpServers/skills/memory/scope）的逐项解读
4. [Claude Code Subagents: The Complete Guide — ComputingForGeeks](https://computingforgeeks.com/claude-code-subagents-guide/) — 子代理与并行会话的关系、组合用法示例
5. [Claude Code Explained (2026): MCP, Skills, Subagents, Hooks & Plugins — alexop.dev](https://alexop.dev/posts/understanding-claude-code-full-stack/) — 把子代理放进 MCP/Skills/Hooks/Plugins 全景里理解

> [!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 等场景全覆盖。

![51学通信知识星球海报-扫码加入](https://wiki.500nian.com/images/zhixingqiu_qrcode.png)
