claudecode学习 第 9 章 · Subagents

目标:讲清 Claude Code 的 subagent 架构------本质(独立的微型 agent 会话)、Agent 工具参数、内置 agent 类型、Task 系统、三种隔离模式、SendMessage 通信、硬限制。这是从"单 agent"到"多 agent 协作"的跃迁。 受众:专业程序员。本机版本 2.1.220


9.1 本质定义

从单 agent 到多 agent

Claude Code 默认是单 agent 模式------你和一个 agent 一对一聊天。但复杂任务需要并行和分工:

bash 复制代码
主 agent (你聊天的这个)
  │
  ├─→ Agent("搜索所有日志文件", type="Explore")       子 Agent 1
  ├─→ Agent("审查 auth 模块", type="general-purpose")  子 Agent 2
  └─→ Agent("检查性能问题", type="general-purpose")    子 Agent 3
        │
        ▼
  三个 agent 并行跑,各自有独立上下文
        │
        ▼
  主 agent 收结果、综合、回复你

Subagent = 一个独立的微型 agent 会话。 有自己的上下文窗口、自己的工具权限、自己的模型。和主 agent 的关系像"老板分活给组员"------组员只看自己那份任务,干完汇报。

为什么不一个人干完?

问题 Subagent 解法
上下文不够用 每个子 agent 有独立上下文,不会共享主 agent 的 token 池
需要并行 多个 agent 同时跑,不是 A → B → C 串行
任务需要专注 子 agent 只看自己那片,不被全局信息干扰
模型省钱 简单搜索用 haiku,疑难分析用 opus
需要隔离 worktree 保证并行写文件不冲突

上下文隔离是最关键的价值。一个 200K 上下文的单 agent 和一个派了 10 个 50K 上下文子 agent 的主 agent------后者覆盖的信息量远超前者,因为这 10 个上下文不共享 token 池


9.2 Agent 工具

工具定义

sdk-tools.d.ts 中确认的 Agent 工具输入:

typescript 复制代码
interface AgentInput {
  description: string;        // 3-5 词简述任务
  prompt: string;             // 给子 agent 的完整任务描述
  subagent_type?: string;     // 专用类型(可选,默认通用)
  model?: "sonnet" | "opus" | "haiku" | "fable";  // 覆盖默认模型
  run_in_background?: boolean; // 默认 true(后台跑)
  isolation?: "worktree" | "remote";   // 隔离模式
  name?: string;              // 起名,方便 SendMessage 续聊
}

关键参数说明

description

3-5 词的简短描述,用于 UI 展示和日志。不是给 agent 看的------是给你看的,让你在任务列表里知道谁在干什么。

prompt

给子 agent 的完整任务指令。这是子 agent 的"唯一的真实"------它不知道主对话在聊什么,不知道其他 agent 在干什么。它只看到这个 prompt。

subagent_type

不传则用默认的通用 agent。传入内置类型名(如 "Explore"、"Plan")或自定义类型名(.claude/agents/ 中定义的)。

model

覆盖子 agent 模型。不传则继承主 agent 的模型,或按 agent 类型定义的默认模型。注意:fork 类型的 agent 永远继承父模型,传了也会被忽略。

run_in_background

默认 true------子 agent 后台跑,主 agent 收到通知后才读结果。设为 false 时主 agent 同步等待------当你需要子 agent 的结果才能继续时用。

isolation

  • 默认:共享文件系统,子 agent 可以读/写和主 agent 相同的文件
  • "worktree":在临时 git worktree 里跑,文件操作在隔离副本中进行。代价:~200-500ms 初始化 + 磁盘占用
  • "remote":子 agent 在云端远程环境跑,始终后台执行

name

给子 agent 起名。之后可以 SendMessage({to: name}) 续聊。名字是语义化的(如 "bug-finder"、"code-reviewer"),不要用随机 ID。同名新 agent 会覆盖旧的。

结果约定

子 agent 的输出不直接展示给用户。SDK 的注释说:

"The agent's final report is not shown to the user --- relay what matters."

主 agent 收到子 agent 的结果后,消化整合,再以自己的话告诉用户。对用户来说是无感的------只看到最终答案,不知道背后多少 agent 在跑。


9.3 内置 Agent 类型

当前版本可用的内置类型:

类型 描述 适用场景
claude 通用型,什么都能干 任何没特定要求的任务
general-purpose 复杂研究、多步骤任务 搜索代码、执行多步操作
Explore 只读搜索 agent 扫大量文件找信息,不需要写
Plan 软件架构师 设计实施方案,不写代码
claude-code-guide Claude Code 问题专家 "Claude Code 怎么用"这类问题
statusline-setup 状态栏配置 配置终端状态栏

每个类型背后是一套预定义的 system prompt + 工具子集 。例如 Explore 被限制为只读(不允许 Edit/Write),Plan 不允许执行 shell 命令。

自定义 Agent 类型

.claude/agents/ 目录下创建 Markdown 文件:

bash 复制代码
.claude/agents/
└── security-reviewer.md   ← 定义一个叫 "security-reviewer" 的 agent 类型

格式和 slash command 类似:YAML frontmatter 定义能力,Markdown body 定义 system prompt。定义后即可通过 Agent({subagent_type: "security-reviewer"}) 使用。


9.4 Task 系统

是什么

子 agent 是一种 Task。Task 系统是管理所有后台工作的统一框架。

六个工具

工具 作用
TaskCreate 创建任务并加入任务列表
TaskList 列出所有任务及其状态
TaskGet 查某个任务的详细信息
TaskUpdate 更新状态(标记完成/设置依赖/分配 owner)
TaskStop 终止正在运行的任务
TaskOutput 读取已完成任务的输出

任务依赖

SDK 确认了依赖机制:

typescript 复制代码
interface TaskUpdateInput {
  addBlocks?: string[];     // 此任务完成后才解锁的任务
  addBlockedBy?: string[];  // 此任务等待的前置任务
}

这让 agent 可以编排复杂工作流:"先搜索文件(Task 1),搜完了并行审查(Task 2 + 3 + 4),审查完了合并报告(Task 5 依赖 2/3/4)。"

任务状态流转

scss 复制代码
pending  →  in_progress  →  completed
                ↓
             deleted    (手动删除)

主 agent 通过 TaskList 查看进度,通过 TaskGet 获取具体输出。


9.5 Agent 生命周期

arduino 复制代码
① 主 agent 调 Agent(description, prompt, type)
   │
② runtime 创建子 agent 会话
   分配独立上下文窗口
   加载对应 agent 类型的 system prompt
   │
③ 自动创建 Task 记录
   │
④ 子 agent 跑自己的 agent loop
   独立 Read / Grep / Bash / Edit
   独立管理自己的上下文
   不知道自己是被 spawn 的
   │
⑤ 子 agent 完成后返回结果(纯文本)
   │
⑥ Task 标为 completed
   │
⑦ 主 agent 收结果、消化、整合
   │
⑧ (可选) 主 agent 用 SendMessage 续聊此 agent
   或就此结束

关键认知

子 agent 不知道它是子 agent。 从它的视角看,这是一个全新的一对一会话------用户给了它一个 prompt,它完成任务返回。它不知道主对话在聊什么,不知道还有其他 agent 在并行跑。这种"信息最小化"是 subagent 设计的核心理念:不让不需要的信息占用上下文。


9.6 隔离模式

三种模式对比

默认 worktree remote
文件系统 共享 git worktree 副本 云端隔离
网络 共享 共享 云端独立
启动开销 ~200-500ms + 磁盘 网络延迟
适用场景 只读分析 并行写文件 远程执行环境
子 agent 类型 任意 通常配合 fork 任意

worktree 详解

worktree 隔离的本质:

markdown 复制代码
① git worktree add /tmp/claude-worktrees/agent-1
    创建当前 repo 的轻量副本

② 子 agent 的 cwd 切换到副本
    所有文件操作都在副本中进行

③ 子 agent 完成后:
    - 无改动 → 自动删除副本(不留痕迹)
    - 有改动 → 保留,主 agent 可以检查和合并

SDK 建议:"use ONLY when agents mutate files in parallel and would otherwise conflict"。不要滥用------每个 worktree 都有磁盘和初始化开销。

fork 类型

subagent_type: "fork" 是 worktree 的专用类型。它强制继承父 agent 的模型(忽略 model 参数)。二进制中确认了 FORK_SUBAGENT_TYPEisForkSubagentEnabledgetForkSubagentSource 等基础设施。


9.7 Agent 间通信

SendMessage 工具

json 复制代码
{
  "to": "bug-finder",
  "summary": "深挖第3个潜在bug",
  "message": "你之前找到的第3个null check问题,去读 src/auth/login.ts 验证一下"
}
  • to: 接收方 agent 的 name(不是 ID)。名字语义化,新同名 agent 覆盖旧的
  • summary: 5-10 词简要描述,UI 预览
  • message: 实际消息内容

可以发给谁

目标 用法
命名的子 agent SendMessage({to: "bug-finder"})
主对话 SendMessage({to: "main"}) ------ 仅子 agent 用

同一个子 agent 可以反复续聊------每次 SendMessage 都沿用上次的上下文(前提是没被回收)。


9.8 资源限制

环境变量

变量 控制
CLAUDE_CODE_MAX_SUBAGENT_SPAWN_DEPTH 递归深度(子 agent 可以自己 spawn 子 agent?最多几层)
CLAUDE_CODE_MAX_SUBAGENTS_PER_SESSION 单会话总 spawn 数上限
CLAUDE_CODE_MAX_CONCURRENT_SUBAGENTS 同时跑的数量上限
CLAUDE_CODE_SUBAGENT_MODEL 子 agent 默认模型
CLAUDE_SUBAGENT_BG_SHELL_MAX_MS 后台 shell 最长运行时间
CLAUDE_CODE_ENABLE_APPEND_SUBAGENT_PROMPT 是否允许追加 prompt
CLAUDE_CODE_FORK_SUBAGENT 是否启用 fork 类型
CLAUDE_CODE_FORWARD_SUBAGENT_TEXT 是否转发子 agent 文本
CLAUDE_CODE_SUBAGENT_CACHE_EVICT 缓存驱逐策略

这些是硬上限------到了就抛错。目的是防止 agent loop 失控时 spawn 数千个子 agent。

Subagent Park

不常用的子 agent 上下文不会立刻销毁------它被 "park" 到磁盘。下次 SendMessage 续聊时从 park 状态醒来复用。二进制中确认了:

c 复制代码
subagent-park              ← park 机制
SUBAGENT_PARK_REASON       ← park 原因(超时/主动park/资源压力)
isSubagentParkAbort        ← 是否因 abort 而 park
subagentParkAbortReason    ← abort 的具体原因

9.9 关键认知

  1. 子 agent 不知道自己是子 agent。 这是设计选择------信息最小化,每个 agent 只看到完成自己任务需要的信息。

  2. 上下文不共享 = 可以线性扩展。 单 agent 200K 上下文有限。10 个子 agent 各 50K ≠ 500K 上下文------它们的上下文是独立的,不共享 token 池。

  3. Agent 类型 = system prompt + 工具集 + 模型默认值。 选对类型不仅影响输出质量,也影响 token 成本(Explore 比 general-purpose 便宜)。

  4. 隔离是昂贵的。 worktree 有磁盘和初始化开销,只在并行写文件时才用。默认共享模式已经足够应对绝大多数场景。

  5. Task 系统是 Agent 的记账簿。 它让主 agent 知道谁在跑、跑完没、结果在哪------不需要靠"记忆"来追踪子任务。


相关推荐
lbzlbss1 小时前
AI 自动化测试流水线实战(二):Analyst 把 PRD 变 L0/L1 用例套件
agent
鱼日先生1 小时前
Dify 中级实验(04):迭代进阶——如何批量处理数据并守住性能边界?
agent·工作流·dify
circuitsosk2 小时前
不止于API调用:大模型推理加速与云原生服务化部署指南
python·云原生·agent·vllm·推理加速·大模型部署·ensorrt-llm
@Mr_LiuYang2 小时前
《深入理解 AI Agent:设计原理与工程实践 》实验1-2 深度搜索能力
人工智能·agent
苏灿烤鱼3 小时前
今日 GitHub 热门|Agent 记忆重回榜首,+2,690 项目却只排第三
typescript·agent·资讯
苏灿烤鱼3 小时前
GitHub #2 拆解|把工程经验装进 Agent,为什么仍会“静默失效”?
javascript·人工智能·agent
大模型momo12 小时前
告别单体 Agent:多智能体设计模式(Multi-Agent Patterns)深度实战手册
人工智能·agent·multi-agent·多agent
很楠爱上13 小时前
(附上相关学习资源)适合新手做的第一个agent项目*ovo*Dify Agent 全栈实战:从智能选车顾问到新能源汽车之家的端到端开发
人工智能·汽车·agent·项目·开发笔记
用户4693684832016 小时前
kimi-code 深度掌握系列文章-对话循环TurnFlow(五)
llm·agent