## 子代理协作模式

想象一下：你让 Claude 帮你重构一个大模块，但在重构之前，你需要它先搞清楚三件事 — 现有的 API 接口有哪些、数据库 schema 是什么样的、测试覆盖率如何。在普通模式下，Claude 只能串行地一件一件查。但如果它能同时派出三个"分身"去分别调查呢？

这就是子代理的魅力。

## 什么是子代理

### Agent 工具的概念

子代理（Subagent）是 Claude Code 中一种特殊的工具，它允许主会话创建独立的 Claude 实例来执行特定任务。你可以把它理解为"Claude 雇了一个助手"。

主会话的 Claude 是项目经理，负责统筹全局。当遇到需要深入调查的子任务时，它可以启动一个子代理去专门处理，自己则继续处理其他事情。

### 子代理 vs 主会话的区别

| 特性 | 主会话 | 子代理 |
|------|--------|--------|
| 上下文 | 包含完整对话历史 | **独立的上下文窗口**，只包含任务描述 |
| 生命周期 | 持续到你关闭 Claude Code | 任务完成后自动结束 |
| 工具访问 | 所有已授权工具 | 可被限制为特定工具子集 |
| 执行方式 | 与你交互式对话 | 自主执行，完成后返回结果 |
| 上下文消耗 | 所有操作消耗同一上下文 | **不消耗主会话的上下文** |
| 结果 | 直接展示 | 以摘要形式返回给主会话 |

最关键的区别是**独立上下文窗口**。子代理有自己的上下文空间，它的探索过程不会撑大主会话的上下文。只有最终结果会被传回主会话 — 这就像你派人出差调研，他回来后只需要给你一份报告，而不是把整个调研过程复述一遍。

### 独立上下文窗口的优势

为什么独立上下文这么重要？举个实际例子：

假设你需要 Claude 分析一个有 200 个文件的项目。如果在主会话中逐个读取文件，每个文件平均 200 行，光文件内容就占了 40000 行上下文。加上 Claude 的分析过程，很快就会把上下文撑满。

用子代理就不一样了。子代理在自己的上下文里读取和分析这些文件，最后只传回一份几百行的分析报告。主会话的上下文几乎没有增加，你还有充足的空间继续后续工作。

## 内置子代理类型

Claude Code 的子代理实际上并不是固定的"类型"，而是由主会话根据任务性质灵活创建的。不过在实践中，子代理通常承担以下几类角色：

### Explore（代码搜索和探索）

这是最常见的子代理用途。当 Claude 需要理解项目的某个方面时，它会启动一个 Explore 子代理：

**能力**：
- 读取文件（Read）
- 搜索代码（Grep、Glob）
- 查看目录结构
- 分析代码依赖关系

**限制**：
- 通常只赋予只读工具
- 不能修改文件
- 不能执行命令

**典型场景**：
```
分析 src/services/ 目录下所有服务的公共接口
找出所有引用了 UserService 的文件
理解认证中间件的工作流程
```

### Plan（架构设计和规划）

用于制定计划或设计方案的子代理：

**能力**：
- 所有 Explore 能力
- 网络搜索（查文档、最佳实践）
- 生成详细的方案文档

**典型场景**：
```
设计一个缓存层的架构方案
评估从 REST 迁移到 GraphQL 的可行性
制定数据库分表策略
```

### 通用任务（General-Purpose）

处理具体执行任务的子代理，拥有完整的工具访问权限：

**能力**：
- 读写文件
- 执行命令
- 运行测试
- 安装依赖

**典型场景**：
```
在后台运行完整的测试套件
生成 API 文档
执行代码格式化
```

## 使用子代理的场景

### 场景 1：代码搜索和理解

当你需要 Claude 深入理解一个陌生的代码库时，子代理可以高效地完成探索：

```
我刚接手这个项目，请帮我全面了解它的架构：
1. 用子代理分析后端的目录结构和核心模块
2. 用子代理分析前端的组件树和状态管理
3. 用子代理分析数据库 schema 和实体关系
然后综合三方面的信息，给我一份项目架构概览。
```

Claude 可能会启动三个子代理并行执行这些任务，然后汇总它们的报告。

### 场景 2：并行调研多个方案

需要比较多种技术方案时，子代理的并行能力非常有用：

```
我需要为项目选择一个消息队列。请分别调研以下方案：
1. Redis Streams — 查看我们现有的 Redis 配置是否支持
2. RabbitMQ — 评估引入新依赖的成本
3. 直接用 PostgreSQL 的 LISTEN/NOTIFY
对每个方案，分析优缺点和与我们项目的兼容性。
```

### 场景 3：后台运行长任务

某些任务耗时较长（如运行测试、生成文档），可以放到子代理中后台执行：

```
请在后台运行项目的完整测试套件，我继续做其他事情。
测试跑完后告诉我结果。
```

Claude 会启动一个后台子代理来执行测试，你可以继续和主会话对话，不需要等待。

### 场景 4：隔离高风险操作

当你需要执行一些可能有风险的操作时，可以用子代理来隔离：

```
请用子代理尝试以下操作：
1. 切换到一个临时分支
2. 尝试升级 React 到 19.x
3. 运行构建，看有多少兼容性错误
4. 把错误列表发给我
不要在主分支上操作。
```

## 子代理实战教程

### 示例 1：用子代理理解陌生代码库

假设你第一天接手一个中型 Python 项目（约 50 个源文件），需要快速了解它的结构。

**你的提示词：**

```
这是我第一天接手这个项目，请帮我快速建立对项目的理解。
用子代理来并行分析以下方面：

1. 项目结构和入口点 — 扫描目录结构，找到 main 入口、路由定义、配置文件
2. 数据模型 — 分析所有 model 文件，画出实体关系
3. 业务逻辑 — 分析 services 目录，理解核心业务流程
4. 外部依赖 — 分析 requirements.txt 和实际的 import，找出关键依赖

最后请综合所有信息，给我一份不超过 500 字的项目概览。
```

**Claude 的执行过程：**

Claude 会创建多个子代理分别执行任务。每个子代理独立探索，然后返回结果。整个过程你会看到类似这样的输出：

```
正在启动 4 个子代理进行并行分析...

[子代理 1] 分析项目结构...
  - 扫描了 52 个 Python 文件
  - 找到入口点：main.py → FastAPI app
  - 路由定义在 routers/ 目录（8 个路由模块）
  - 配置：config.py + .env

[子代理 2] 分析数据模型...
  - 找到 12 个 SQLAlchemy 模型
  - 核心实体：User, Organization, Project, Task, Comment
  - 关键关系：User ← many-to-many → Organization, Project → has-many → Task

[子代理 3] 分析业务逻辑...
  - 9 个 service 文件
  - 核心流程：用户管理、项目管理、任务分配、通知系统
  - 异步任务处理使用 Celery

[子代理 4] 分析外部依赖...
  - 32 个直接依赖
  - 关键依赖：FastAPI, SQLAlchemy, Celery, Redis, Alembic
  - 发现 2 个未使用的依赖（requests, beautifulsoup4）
```

最后 Claude 综合四个子代理的结果，给你一份结构清晰的项目概览。

### 示例 2：并行启动多个子代理对比方案

你正在考虑如何实现实时通知功能，想比较几种方案：

```
我需要给项目添加实时通知功能。请帮我并行评估以下三种方案：

方案 A：WebSocket（使用 FastAPI 内置的 WebSocket 支持）
方案 B：Server-Sent Events（SSE）
方案 C：轮询（Polling）

对每种方案，请分析：
1. 与我们现有架构的兼容性（检查现有代码）
2. 实现复杂度（大约需要改多少文件）
3. 性能和可扩展性
4. 客户端兼容性

然后给我一个对比表格和你的推荐。
```

**Claude 的对比结果可能是：**

```
三个子代理已完成分析。综合对比如下：

| 评估维度 | WebSocket | SSE | 轮询 |
|----------|-----------|-----|------|
| 架构兼容性 | 需要新增 WebSocket 路由 | 可复用现有 HTTP 路由 | 完全兼容 |
| 实现复杂度 | 高（约 8 个文件） | 中（约 4 个文件） | 低（约 2 个文件） |
| 实时性 | 最好（全双工） | 好（服务端推送） | 一般（取决于轮询间隔） |
| 可扩展性 | 需要 WebSocket 负载均衡 | 可用 CDN | 最简单 |
| Celery 集成 | 需要额外的消息桥接 | 可直接消费 Celery 事件 | 轮询数据库即可 |

**推荐**：考虑到你们已经使用 Celery + Redis，SSE 是最佳选择。
它可以直接订阅 Redis 频道获取 Celery 事件，实现复杂度适中，
而且不需要额外的基础设施。
```

### 示例 3：后台子代理运行测试

你正在修改代码，同时想知道测试结果：

```
请在后台运行 pytest，跑完整个测试套件。我继续改代码，跑完了告诉我。
```

Claude 会启动一个后台子代理执行测试。你可以继续和 Claude 对话、修改代码。当测试完成后，你会看到结果通知：

```
后台测试已完成。结果：
- 总计：247 个测试
- 通过：241 个
- 失败：4 个
- 跳过：2 个

失败的测试：
1. test_order_service.py::test_calculate_total_with_discount
   AssertionError: 99.99 != 100.0
2. test_user_service.py::test_create_user_duplicate_email
   IntegrityError: 测试数据库未正确清理
3. ...

需要我帮你分析这些失败的测试吗？
```

## 子代理配置

### 通过 CLAUDE.md 引导子代理行为

虽然你不能直接"配置"子代理的参数，但可以通过 `CLAUDE.md` 来引导 Claude 在何时以及如何使用子代理：

```markdown
## 子代理使用规范

### 何时使用子代理
- 分析超过 10 个文件的任务，应使用子代理
- 需要对比多个方案时，为每个方案启动独立子代理
- 运行测试应在后台子代理中执行

### 子代理任务描述模板
启动子代理时，任务描述应包含：
1. 明确的目标（做什么）
2. 范围限制（不做什么）
3. 输出格式（返回什么样的结果）

### 子代理结果处理
子代理的结果必须包含：
- 分析摘要（不超过 200 字）
- 关键发现列表
- 相关文件路径
- 潜在风险或问题
```

### 理解子代理可用的工具

子代理能使用哪些工具，取决于主会话对它的授权。在实践中：

- **只读任务**：通常只赋予 Read、Grep、Glob 等搜索工具
- **执行任务**：赋予 Bash、Write、Edit 等写入工具
- **网络任务**：赋予 WebSearch、WebFetch 等网络工具

你可以通过自然语言来暗示工具范围：

```
请用子代理分析（只读）src/models/ 目录下所有模型的关系。
```

加上"只读"这个提示，Claude 就倾向于创建一个只有搜索和阅读能力的子代理。

### 后台执行

子代理可以在后台运行，不阻塞你和主会话的交互。当你说"在后台..."或"异步..."时，Claude 会使用 `run_in_background` 参数：

```
请在后台帮我做两件事：
1. 运行完整的 lint 检查
2. 检查所有依赖是否有已知的安全漏洞
我继续改代码，完成后告诉我结果。
```

后台子代理完成后，系统会通知 Claude，Claude 再把结果转告你。

## 最佳实践

### 1. 给子代理清晰的任务描述

子代理的上下文是全新的 — 它不知道你之前和主会话聊了什么。所以任务描述必须自包含：

**不好的做法：**

```
用子代理检查一下刚才说的那个问题。
```

（子代理不知道"刚才说的那个问题"是什么）

**好的做法：**

```
用子代理检查 src/services/payment_service.py 中的
process_refund() 方法是否正确处理了并发退款请求。
需要关注数据库事务隔离级别和乐观锁的使用。
```

### 2. 善用并行子代理提升效率

当多个任务之间没有依赖关系时，让它们并行执行：

```
请并行执行以下任务：
1. [子代理 A] 分析前端代码中所有的 API 调用点
2. [子代理 B] 分析后端的 API 端点和参数定义
3. [子代理 C] 检查 API 文档是否与实际接口一致

三个任务完成后，汇总出 API 不一致的地方。
```

### 3. 不要过度使用子代理

子代理不是万能的。以下场景直接在主会话中处理更高效：

- **简单的文件查看**：读一两个文件，直接 `@` 引用就行
- **简单的搜索**：搜索一个关键词，主会话做更快
- **需要持续交互的任务**：子代理是"一次性"的，不适合需要多轮对话的任务
- **依赖前一步结果的串行任务**：用子代理反而增加复杂度

经验法则：如果任务可以用一两句话描述清楚，而且不需要读取大量文件，就直接在主会话做。

### 4. 理解子代理的结果传递机制

子代理完成任务后，它的结果会以**摘要形式**传回主会话。这意味着：

- 子代理读取的文件原文**不会**完整传回（太大了）
- 只有子代理的分析结论和关键信息会传回
- 如果你需要看子代理发现的某个具体文件，要在主会话中自己再读一次

```
子代理告诉我 payment_service.py 第 127 行有问题，
请帮我看看这个文件的 120-140 行。
```

### 5. 用子代理做"试探性"操作

不确定某个方案是否可行？用子代理来试探，而不是在主分支上冒险：

```
请用子代理做个实验：
1. 创建一个临时目录 /tmp/experiment
2. 把 src/models/user.py 复制进去
3. 尝试用 dataclasses 替代 SQLAlchemy 的声明式模型
4. 看看会有什么问题

不要动项目的任何文件。
```

## 进阶：子代理与其他功能配合

### 子代理 + Plan 模式

Plan 模式下也可以使用子代理。这是一个强大的组合 — 用子代理在计划阶段做深入调研：

```
（Plan 模式下）
请用子代理帮我调研以下问题，然后基于调研结果制定迁移计划：
1. 当前所有 REST API 的端点列表和调用频率
2. 哪些端点已经有 GraphQL 的等价实现
3. 客户端代码中对 REST API 的依赖程度
```

### 子代理 + MCP 工具

如果你配置了 MCP 服务器（如数据库查询工具），子代理也可以使用它们：

```
请用子代理连接数据库，分析以下内容：
1. 各表的数据量
2. 慢查询 Top 10
3. 缺失的索引
用数据库 MCP 工具来执行查询。
```

### 子代理 + Hooks

你可以通过 Hooks 在子代理执行特定操作时触发自定义逻辑。例如，当子代理完成测试后自动发送通知：

```json
{
  "hooks": {
    "Notification": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "curl -X POST https://hooks.slack.com/... -d '{\"text\": \"$MESSAGE\"}'"
          }
        ]
      }
    ]
  }
}
```

## 常见问题

**Q：子代理能看到我和主会话的对话历史吗？**

A：不能。子代理的上下文是全新的，只包含 Claude 给它的任务描述。这也是为什么任务描述必须自包含。不过，子代理可以读取 `CLAUDE.md`，所以项目级的规范和约定对子代理也有效。

**Q：子代理可以启动"子子代理"吗？**

A：可以，但不建议嵌套太深。通常一层子代理就够了。

**Q：多个子代理之间可以通信吗？**

A：不能直接通信。如果你需要子代理 B 依赖子代理 A 的结果，只能等 A 完成后，由主会话把结果传给 B。

**Q：子代理会消耗额外的 API 配额吗？**

A：是的。子代理使用独立的上下文窗口，每个子代理的输入和输出都会消耗 token。不过由于子代理的上下文通常较小（只包含特定任务），总体消耗往往比在主会话中做同样的事情更少。

**Q：如何知道子代理正在做什么？**

A：Claude 会在主会话中显示子代理的执行状态。你可以看到它启动了哪些子代理、每个子代理正在做什么、是否已完成。