Subagent 不是函数 - claude_0x06

目录概要

  1. 把"员工"这个类比讲到底
  2. Subagent 跟 Command / Skill 的本质分野
  3. 16 字段 frontmatter:人事档案里写了什么
  4. memory 字段------v2.1.33 加的,最被低估的设计
  5. isolation: worktree 是什么妖术
  6. initialPromptbackgroundmcpServers------被忽略的三个能力
  7. 5 个官方内置 agent 的用途对照
  8. Subagent 不能调用 Subagent------这条规则的代价
  9. 写 subagent 的三种典型风格
  10. 踩过的坑

1. 把"员工"这个类比讲到底

前两篇讲 Command 是"按钮"、Skill 是"工具"。按钮没脑子、工具没人格,按下去或者拿起来就完事。Subagent 不一样------Subagent 是会思考、带记忆、有权限边界、能独立拿工具干活的员工

但把 Subagent 只当"能自己干活的脚本"理解是不够的。员工跟自动化脚本的真正区别是:

维度 自动化脚本 员工
输入 严格参数列表 模糊目标描述
权限 调用者的 岗位自己的
记忆 无(每次从头) 岗位 + 个人
判断 确定性 在规则内自主决策
上下文 纯数据 工作历史 + 公司规则

Subagent 的 16 个 frontmatter 字段,大半都是在模仿一家公司对员工的管理机制------工具白名单是"你能用哪些工具"、memory 是"你的工作笔记"、maxTurns 是"你这个任务最多推进几轮再汇报"、isolation 是"给你单独开个工位"。

理解了这层之后,Subagent 的字段表就不是一堆参数,而是一份人事档案。这篇按人事档案的视角展开。


2. Subagent 跟 Command / Skill 的本质分野

第 02 篇的对比表放这里再贴一次------但这次我们专门看 Subagent 那一列:

维度 Command Skill Subagent
心智模型 按钮 工具 员工
运行上下文 主对话内联 主对话内联 独立子上下文
跨会话记忆 有(memory 字段)
预加载其他扩展 有(skills 字段)
能被 / 触发 (不出现在 / 菜单)
能自动触发 (description 匹配)

四个" "和一个""放一起------这些就是 Subagent 比前两者复杂两倍的理由。

具体来说:

graph TB subgraph Main[主对话上下文] U[用户消息] C[Claude 主模型] end subgraph Hire[招人流程] C -->|识别描述匹配| Dispatch[派遣 subagent] end subgraph Iso[子上下文 独立工位] Sub[Subagent] Mem[自己的 memory] Skills[自己的预加载 skills] Tools[自己的工具白名单] Hooks[自己的 hooks] end Dispatch --> Sub Sub --> Mem Sub --> Skills Sub --> Tools Sub --> Hooks Sub -->|只返回结果| C style Iso fill:#fcc style Main fill:#cfc

这张图里有三个关键点:

  1. 派遣不是 import------Subagent 启动是 "hire a contractor for a job",不是"call a function"。主对话只看到派遣和结果两端。
  2. 隔离是默认的------中间的读 50 个文件、跑 10 次 grep、调 5 个 API 全部不进主对话。
  3. 状态是长期的------memory 字段让员工下次上岗还记得上次的事。

2.1 先造一个最小能跑的员工

如果只看字段表,很容易变成背配置。先放一个小到不能再小的 agent,感受一下它到底怎么落地:

markdown 复制代码
<!-- .claude/agents/mini-reviewer.md -->
---
name: mini-reviewer
description: Review small diffs for obvious correctness issues.
tools: Read, Grep, Glob, Bash(git diff *)
memory: project
---

You review small code changes.

Before starting, check your memory for project-specific review patterns.
After finishing, update your memory with any reusable finding.

Return only:
1. Findings
2. Residual risk

怎么调用?

text 复制代码
请用 mini-reviewer subagent 看一下我当前 git diff。

@agent-mini-reviewer review the current git diff

第一种是自然语言,Claude 会判断要不要派。第二种是 @agent-<name>,更像是你直接点名这个员工上岗。跑完之后,可以去 .claude/agent-memory/mini-reviewer/ 看它有没有写 MEMORY.md。这一步很重要,不然 memory 只是配置里好看,实际没形成工作习惯。


3. 16 字段 frontmatter:人事档案里写了什么

Subagent 的 frontmatter 比 Command/Skill 多 3 个字段------16 个。完整样本:

yaml 复制代码
---
name: release-notes-agent          # 员工工号(必填,小写加连字符)
description: Use this agent PROACTIVELY when ...  # 什么情况下派遣(必填)
tools: Read, Write, Edit, Bash     # 工具白名单(默认继承一切)
disallowedTools: Bash(rm *)        # 黑名单(从继承/白名单里扣)
model: sonnet                      # 员工脑子:haiku/sonnet/opus/inherit
permissionMode: acceptEdits        # 权限策略
maxTurns: 5                        # 最多几轮自主推进
skills:                            # 预加载 skills 到 system prompt
  - git-log-reader
mcpServers:                        # 这员工能连哪些外部服务
  - playwright
hooks:                             # 员工级的生命周期 hook
  PreToolUse: [...]
memory: project                    # 记忆作用域:user/project/local
background: false                  # 是否始终后台运行
effort: high                       # 干活用力程度
isolation: worktree                # 给单独工位(git worktree)
initialPrompt: "Always start by..." # 入职自动说的第一句话
color: green                       # 终端显示颜色
---

16 字段按"管什么"分组:

mindmap root((Subagent 16 字段)) 身份 name description color 能力 tools disallowedTools skills mcpServers 行为 model effort permissionMode maxTurns initialPrompt 状态 memory 隔离 isolation background 生命周期 hooks

前三组(身份/能力/行为)大多数字段跟 Command / Skill 语义一致,这里不重复。我们挑 最能把 Subagent 和 Command / Skill 拉开距离的 5 个展开:

  • memory
  • isolation
  • initialPrompt
  • background
  • mcpServers

这 5 个字段组合起来,才是"员工"跟"工具"的根本差别。


4. memory 字段------v2.1.33 加的,最被低估的设计

memory 是 v2.1.33(2026 年 2 月)加的新字段。没这个字段之前,每次派遣 subagent 都是"白板上岗"------员工永远是新员工

4.1 三种作用域

yaml 复制代码
memory: user      # 全个人跨项目
memory: project   # 项目级,checked in,团队共享
memory: local     # 项目级,git 忽略,个人用

三种作用域的物理位置跟 Claude Code 的 settings 层级完全对应:

Scope 磁盘路径 Git 共享 典型用途
user ~/.claude/agent-memory/<name>/ 跨项目的员工经验(我的 code-reviewer 在哪家都用同一套习惯)
project .claude/agent-memory/<name>/ 项目级团队共享知识(团队 review 规则)
local .claude/agent-memory-local/<name>/ 否(gitignored) 项目里的个人 sidenote

4.2 内部目录结构

javascript 复制代码
~/.claude/agent-memory/code-reviewer/
├── MEMORY.md            ← 首 200 行进 agent 启动时的 system prompt
├── react-patterns.md    ← 按主题分拆的细节,用到才读
└── security-checklist.md

跟 Skill 的渐进式揭露是同一个思路------MEMORY.md 是索引页,主题文件按需读。如果 MEMORY.md 超过 200 行,agent 会主动把内容搬到子文件保持索引干净。

4.3 跟其他"memory"系统的关系

Claude Code 里名字叫 memory 的东西有四个,容易混:

系统 写入者 读取者 作用域
CLAUDE.md 你(手动) 主 Claude + 所有 agent 项目
Auto-memory 主 Claude(自动) 只有主 Claude 项目 × 用户
/memory 命令 你(编辑器) 只有主 Claude 项目 × 用户
Agent memory agent 自己 只有那个 agent 可选 user/project/local

这是一套分层记忆架构------CLAUDE.md 是"公司手册",auto-memory 是"主 Claude 的工作笔记",agent memory 是"某个岗位自己的笔记"。四套互不干扰,各读各的。

4.4 让 agent 真的用 memory

memory 字段给了存储,也会把 MEMORY.md 的前 200 行塞进 agent 启动上下文。但 它不会自动把每次工作都总结进去------必须在 agent 正文里显式指示。一个标准做法的 agent 正文结构:

markdown 复制代码
## Your Task

1. **Collect**: Follow the `git-log-reader` skill instructions to gather commits between tags
2. **Classify**: Categorize commits using Conventional Commits semantics
3. **Memory**: Update your agent memory with the release metadata for future version comparisons

调用时还可以显式提醒:

arduino 复制代码
> 生成 v2.4.0 的 release notes,参考你之前记录的 v2.3.x 分类习惯

agent 收到这个会先读自己的 MEMORY.md(有历史记录的笔记),再决定怎么回答。

一个常见误会:memory 不会自动总结。你不告诉 agent "更新你的 memory",它通常不会主动把经验沉淀下来。这点跟 auto-memory(主 Claude 会自动攒)不一样。


5. isolation: worktree 是什么妖术

yaml 复制代码
---
name: dependency-upgrader
description: Upgrade and test a single dependency. Use PROACTIVELY when user asks to bump a package version.
isolation: worktree
tools: Read, Write, Edit, Bash(npm *), Bash(git *)
---

加了 isolation: worktree 之后,这个 agent 启动时 Claude Code 会:

  1. 自动 git worktree add 一个临时分支工作区
  2. agent 在这个工作区里改文件、跑测试
  3. agent 跑完:
    • 有改动 → 保留 worktree,告诉主对话路径和分支
    • 无改动 → 自动清理
graph TB Main[主对话
工作目录 /project] --> Hire[派遣 agent] Hire --> WT[git worktree add /project/.cc-wt/abc123] WT --> Run[agent 在 .cc-wt/abc123 执行] Run --> Test{有改动?} Test -->|有| Keep[保留工作区
返回路径 + 分支] Test -->|无| Clean[自动清理] Keep --> Main Clean --> Main style WT fill:#ff9 style Keep fill:#cfc style Clean fill:#fcc

5.1 为什么好

两件事同时成立:

  • agent 的改动物理上不影响主工作目录------你的 IDE 没看到变化
  • 真的 checkout 到分支------agent 不是在 sandbox 里编辑虚拟文件,它在跑真实的 git 分支

这比"直接在主目录改"安全------看到结果不满意不用 git reset,删 worktree 就行。也比 docker/container 隔离更轻------就是 git 自己的能力。

5.2 最好用的场景

场景 为什么 worktree 是对的
依赖升级 + 跑测试 升级过程污染 node_modules、lockfile;失败时主目录干净
批量 refactor 试验 一次改 100 个文件,结果不合适就整体丢弃
跨 PR 并行任务 两个 agent 各自 worktree,互不冲突
长运行迁移脚本 agent 跑一晚上,主目录里你正常干别的

5.3 限制

  • 不适合 "needs to see actual current index" 的任务(例如 git diff 看未暂存改动)
  • 小项目没必要------worktree 的创建/销毁有 overhead
  • 不能嵌套------worktree 里启动的 subagent 不会再开新 worktree

6. initialPromptbackgroundmcpServers------被忽略的三个能力

6.1 initialPrompt

yaml 复制代码
---
name: oncall-responder
description: Handle incoming pages with runbook lookup
initialPrompt: |
  Before anything else:
  1. Check your memory for similar past incidents.
  2. Read `.claude/runbooks/` for the relevant runbook.
  3. Start with impact assessment before remediation.
---

initialPrompt 最容易被误解。

它不是"每次被 Agent tool 派遣时都抢在用户输入前跑一遍"。更准确地说:当这个 agent 作为 main session agent 运行时(比如 claude --agent oncall-responder,或者在 settings 里配置 "agent": "oncall-responder"),initialPrompt 会被自动提交成第一轮 user message,并且会拼在用户自己的 prompt 前面。

所以它更像"这个员工今天作为主值班人上岗时,先做的开场动作"。

这跟 agent 的 system prompt(文件正文)区别在哪?

  • System prompt:agent 的"人设" + "规则",普通 subagent 派遣也会稳定生效
  • initialPrompt :agent 作为 main session agent 启动后的"第一个动作",是可变状态机的初始化

用场景:

  • 员工上岗自动先"读一遍最近的团队 slack 总结"
  • 每次 session 开始自动"load 昨天的 progress log"
  • 调试类 agent 先"确认环境状态再动手"

这个字段特别容易被忽略 ,但也别滥用。普通一次性 subagent 的关键初始化,最好仍然写进 agent 正文或派遣 prompt 里;initialPrompt 更适合值班、驻场、长期 session 这种场景。

6.2 background: true

yaml 复制代码
---
name: nightly-metric-collector
description: Pull nightly metrics and save to CSV
background: true
---

background: true 把 agent 变成后台任务------从派遣起它就不阻塞主对话,agent 跑完的结果进 /tasks 列表。

适合:

  • 长时间跑的数据拉取
  • 定时周期性任务(配合 /schedule
  • 大批量文件处理

不适合:

  • 需要和用户实时交互的任务
  • 任务结果主对话立刻要用
  • 临时需要追问权限或补充信息的任务(后台 subagent 缺权限时,很多交互会直接失败或被拒绝)

6.3 mcpServers

mcpServers 是把外部系统配给某个岗位,而不是把所有 server 都扔给所有人。

yaml 复制代码
---
name: sentry-investigator
description: Investigate production exceptions from Sentry.
mcpServers:
  - sentry-prod
tools: Read, Grep, Glob
---

这背后的思路很简单:code-reviewer 不需要连生产 Sentry,dependency-upgrader 也不需要连 Jira。真正需要外联的是某几个岗位,就把 MCP server 挂到那几个岗位上。这样 system prompt 里的 tool schema 少一点,权限面也小一点。

MCP 这一块第 10 篇会专门拆。这里先记住一句:agent 级 mcpServers 是岗位权限,不是项目默认权限


7. 5 个官方内置 agent 的用途对照

Claude Code 自带 5 个 agent,很多人只知道 general-purpose 一个。其他 4 个是专职员工,用好省很多 token:

# Agent Model 工具 什么时候派它
1 general-purpose inherit 全部 复杂多步任务(默认)
2 Explore haiku 只读(无 Write/Edit) 快速搜码 / 找文件 / 回答仓库结构问题
3 Plan inherit 只读 plan mode 里做前期 research 和设计
4 statusline-setup sonnet Read, Edit 帮你配置 statusline
5 claude-code-guide haiku Glob/Grep/Read/WebFetch/WebSearch 回答关于 Claude Code、Agent SDK、Claude API 本身的问题

7.1 Explore 是最被低估的一个

你问 Claude "这个仓库里 user auth 相关的代码在哪?"------主 Claude 会自己跑十几个 Grep,填满上下文,然后给你答案。

换成:

markdown 复制代码
> 用 Explore agent 告诉我 user auth 代码在哪

Explore 是 haiku + 只读,启动快、便宜、只返回结论。主对话里只进"auth 相关代码在:src/auth/*"这一句,不是十几个 Grep 的 token。

一个实用经验------做仓库探索时永远显式指派 Explore。这是最容易省 token 的一个习惯。

7.2 Plan agent 跟 plan mode 的关系

/plan 进 plan mode 时,Claude Code 内部派遣的就是 Plan agent。你用 /plan 之后看到的"思考过程"是 Plan agent 的输出,主 Claude 只拿到最终方案。

这是为什么 plan mode 比"我自己问 Claude 想想方案"更干净------隔离。


8. Subagent 不能调用 Subagent------这条规则的代价

这是项目 CLAUDE.md 里最该写一遍、但大家容易忽略的警告:

Subagents cannot invoke other subagents via bash commands. Use the Agent tool (renamed from Task in v2.1.63; Task(...) still works as an alias):

ini 复制代码
Agent(subagent_type="agent-name", description="...", prompt="...", model="haiku")

这条规则的关键是两个"不能"和一个"可以"

  • 不能Bash("claude --agent my-agent ...") 调 agent
  • 不能 在 subagent 正文里用/agents切换
  • 可以Agent 工具(或旧名 Task 工具)调起另一个 subagent

为什么定这条规则?

因为 subagent 已经是独立上下文------再嵌一层 subagent 需要 orchestrator 自己维护调用栈。目前设计是让 Agent 工具专门处理这种派遣,保证返回值能正确回流上层。

8.1 实际中的表现

写 agent 指令时要注意用词:

markdown 复制代码
# ❌ 错误写法(容易被理解成 bash 调用)
Then launch the validation-agent to verify the output.

# ✅ 正确写法
Then use the Agent tool with subagent_type "validation-agent" to verify the output.

上一句里 "launch" 这个词让 Claude 有 50% 概率写成 Bash("claude --agent validation-agent ...")------然后就错了。明确写 "use the Agent tool" 能避免这个歧义。

8.2 重命名历史:Task → Agent

v2.1.63 之前工具叫 Task,之后重命名为 Agent。旧名保留作 alias,两种都能用。很多存量 command/agent 文档里还写着旧名:

markdown 复制代码
### Step 2: Gather commits

Use the Task tool to invoke the release-notes agent:

遇到新老文档混用不要困惑。但新写代码时建议用 Agent------更准确。


9. 写 subagent 的三种典型风格

跟 Command 的三种形态类似,Subagent 也有三种典型风格:

9.1 风格一:专家型员工(知识密集)

yaml 复制代码
---
name: code-reviewer
description: Use PROACTIVELY to review code for quality, security, and conventions.
tools: Read, Grep, Glob, Bash(git *)
model: sonnet
memory: user
---

You are a senior code reviewer with 15 years of experience...

## Review Dimensions
- Correctness
- Security
- Performance
- Readability
- Testability

## How you work
1. Read your MEMORY.md for patterns you've seen before
2. Review the diff
3. Update MEMORY.md with new patterns

特点:纯只读 + 记忆驱动。依靠 memory 跨会话积累经验。review 得越多越老练。

9.2 风格二:执行型员工(工具密集)

03 篇里的 release-notes-agent 就是这种:

yaml 复制代码
---
name: release-notes-agent
description: Use PROACTIVELY when you need to compile release notes between two git tags
tools: Bash(git *), Read, Write, Edit
model: sonnet
maxTurns: 5
permissionMode: acceptEdits
memory: project
skills:
  - git-log-reader
---

特点:明确的工作流 + 预加载 skill + 有限 turns。一次派遣做一件事。agent 正文短(body 30 行左右足够),细节都在 skill 里。

9.3 风格三:驻场型员工(initialPrompt + background

yaml 复制代码
---
name: metrics-watcher
description: Continuously watch service metrics and flag anomalies
background: true
initialPrompt: |
  Start by reading your memory for the baseline from yesterday.
  Load current metrics from Grafana.
  Diff them. Flag anything >20% deviation.
  Report every 15 minutes or on anomaly.
memory: user
tools: WebFetch, Read, Write
---

特点:长期驻场 + 周期行为。进程起来就干活,主对话基本不管它。


10. 踩过的坑

坑 1:description 里不写 PROACTIVELY

这个是 Subagent 最常见的坑。description 里没有 PROACTIVELY 关键字,Claude 主动派遣的概率会明显下降------你经常得自己说 "用 xxx-agent 去干这件事"。

PROACTIVELY 更像一个强提示,不是布尔开关。写了不保证 100% 会用,不写也不是绝对不会用;但它确实能把这个 agent 从"手动档"往"自动档"推一截。

坑 2:tools 写成单词拼接

yaml 复制代码
# 错
tools: Read Write Edit

# 对
tools: Read, Write, Edit
# 或
tools:
  - Read
  - Write
  - Edit

YAML 不容空格分隔。踩了会报解析错,但错误信息不明显。

坑 3:skills 字段填了用户触发的 skill

yaml 复制代码
# 危险
skills:
  - release-notes-formatter    # 这是用户可触发的直接 skill

这样写不是报错,而是:skill 的全文被灌进 agent system prompt------浪费 token,并且用户用不用得到这个 skill 就看 agent 记不记得。

预加载只填 user-invocable: false 的 skill(明确作为私人手册设计的)。

坑 4:maxTurns: 3 太小

复杂任务 3 turns 经常不够------agent 还没发现问题就被强制停了。

建议:

  • 简单拉取/格式化:3-5
  • 多步 research:10-20
  • 长运行或 refactor:50+ 或不设限

坑 5:memory 设成 project 但 agent 不写

上面讲过------memory 存储是自动的,但写入要 agent 自己动手。正文里必须显式 "Update your memory with ..."

坑 6:agent 正文里说 "launch the other agent"

Subagent 不能调 Subagent 用 bash,必须用 Agent 工具。"launch" 这个词容易让模型以为是 bash 启动------第 8 节详述。

坑 7:isolation: worktree 用在小项目上

几 KB 的项目加 worktree 就是"高射炮打蚊子"------worktree 创建/销毁的 overhead 比整个任务还大。几百 MB 以上的项目才值得。


复盘一下

Subagent 的 16 字段比 Command/Skill 多那 5 个------memoryisolationinitialPromptbackgroundmcpServers------恰好是把"工具"升级为"员工"的那 5 个能力:

  • memory 让员工能跨会话积累
  • isolation 让员工有独立工位
  • initialPrompt 让员工入职自动化
  • background 让员工长期驻场
  • mcpServers 让员工独立外联

剩下的字段(tools/model/effort/maxTurns/permissionMode/hooks)大多跟 Command/Skill 共享语义。记熟了前 5 个,其余字段就是微调。

写到这儿,Command / Skill / Subagent 三个核心扩展点拆完了。但仔细看你会发现每一篇都反复提到一个东西------hooks。每个扩展都有 hooks 字段、每个扩展都能挂自己的生命周期钩子、on-demand hooks 和 PreToolUse 埋点都在这里。下一篇把 hooks 单独拎出来讲------27 个 hook 事件、同步 vs 异步、matcher 的精确控制、跨平台声音通知的实现。


Footnotes

外部链接

相关推荐
派拉软件1 小时前
从 IAM 到 AAM,重构 AI Agent 时代的访问控制体系
大数据·人工智能·网络安全·重构·iam·身份与访问控制·aam
SteveSenna1 小时前
Pika数据采集与处理
人工智能·学习
kunlong_luo2 小时前
用 200 行 Python 搭一个全本地 RAG:一次笔记本工程师的踩坑实录
人工智能
前端7412 小时前
Cursor 被 SpaceX 盯上了:600 亿美元买的不是编辑器,是你的键盘
人工智能
俊哥V2 小时前
每日 AI 研究简报 · 2026-04-23
人工智能·ai
czkm2 小时前
AI有情绪吗?从AI夸我是写作领域大神说起
人工智能·程序员·ai编程
smileNicky2 小时前
Spring AI系列之基于MCP协议实现天气预报工具插件
人工智能·spring boot·spring
deephub2 小时前
LLM 幻觉的架构级修复:推理参数、RAG、受约束解码与生成后验证
人工智能·python·大语言模型·ai幻觉
uzong2 小时前
最新:DeepSeek V4 国产大模型之光,万亿参数重构 AI 格局,让国产大模型迈入普惠新纪元
人工智能·后端