Claude Code · 2026-05-28 · Research Preview

谁持有
plan?

Subagent、Skill、Workflow 经常被混为一谈。但官方把三者放进同一张表对比时,区分它们的其实只有一个问题:编排任务的那个 plan,到底在谁手里——是 Claude 一回合一回合临场拿主意,还是一段写好了就能重跑的代码。

Subagent
Skill
Workflow
GenAI Playbook · Claude Code 深度解析
核心判据

不是「哪个更强」,
而是 plan 在谁手里

“With subagents and skills, Claude is the orchestrator: it decides turn by turn what to spawn next, and every result lands in Claude's context. A workflow script holds the loop, the branching, and the intermediate results itself, so Claude's context holds only the final answer.”

— Claude Code Docs · Orchestrate subagents at scale [官方]

可以这样记:Skill 存下来的是「指令」,Workflow 存下来的是「编排的过程本身」。两者根本不是一回事,所以 Workflow 谈不上替代 Skill,它俩各管各的。

交互演示

自己切一下:plan 归谁,
中间结果往哪儿堆

在这三种做法之间切一下,盯住两点:那枚标着 PLAN 的方块这会儿滑进了谁的盒子,右边那一步步的中间结果又往哪儿堆。

Plan 持有者

Claude's Context
逐回合临场编排
{ }
Script · 代码
脚本持有编排
◆ PLAN

中间结果落点

CLAUDE'S CONTEXT WINDOW
谁决定下一步
中间结果存在
规模
中断时
官方对比表

plan 的归属,正沿着列易手

这张表不该横着比谁强谁弱,而该顺着列往下看:「plan 在谁手里」是怎么从最左列一路交到最右列的。高亮的那一行,就是分界点。

SubagentsSkillsWorkflows
是什么Claude spawn 的一个 workerClaude 遵循的指令runtime 执行的一段脚本
谁决定下一步跑什么Claude,逐回合Claude,跟着 prompt 走脚本
中间结果存在哪Claude 的 contextClaude 的 context脚本变量
可复现的是什么worker 定义指令编排本身
规模每回合几个委派同 subagent每次 run 几十到几百个 agent
中断时重启该回合重启该回合同一会话内可 resume

表中每一行均出自 code.claude.com/docs/en/workflows [官方]。

三个真实样本

三份文件,分别长这样

上面那些区别听着抽象,落到磁盘上其实就是三种不同的文件。把它们摆在一起,表里「可复现的是什么」那一行立刻就具体了。

Subagent

一个隔离的 worker

.claude/agents/security-scout.md

你存下来、以后能复用的,是一份 worker 定义:它带哪些工具、读什么、用哪个模型。至于什么时候真把它叫起来干活,还是 Claude 当场定。

---
name: security-scout
description: 隔离 context 里扫单个文件的注入风险
tools: Read, Grep
model: sonnet
---
你是安全审查员。只读给定文件,找出未经校验
的输入流向危险 sink 的路径。逐条返回
{ file, line, risk },不修复、不展开无关分析。
Skill

一段可复用的指令

skills/pdf-fill/SKILL.md

你存下来、以后能复用的,是一段指令:一套步骤,外加用得着时才展开的参考。Claude 照着走,但具体怎么走还是它自己拿捏。

---
name: pdf-fill
description: 填写 PDF 表单域;需要把数据
  写进 PDF 表单时使用。
---
# 填写 PDF 表单

1. pdftk dump_data_fields 列出所有字段
2. 把用户数据映射到字段名
3. 生成 FDF,再 pdftk fill_form 回填

→ 字段名对照见 references/field-map.md
Workflow

编排本身,写成代码

workflows/bug-hunt.js

你存下来、以后能复用的,是编排本身:循环、分支、谁来验证谁,全写死在脚本里。下次跑的还是同一套流程,不靠 Claude 临场记得。

export const meta = {
  name: 'bug-hunt',
  description: '全库找 bug,逐条对抗验证后再报',
  phases: [{ title: 'Find' }, { title: 'Verify' }],
}

// 各维度并行找;每条 finding 一冒头就独立验证
const found = await pipeline(DIMENSIONS,
  d => agent(d.prompt, { phase: 'Find', schema: BUGS }),
  rv => parallel(rv.bugs.map(b => () =>
    agent(`试着推翻这条:${b.title}`,
          { phase: 'Verify', schema: VERDICT })
      .then(v => ({ ...b, ok: v.isReal })))))

return found.flat().filter(b => b.ok)   // 只留验证为真的

样本为示意:Subagent / Skill 文件格式依官方约定,Workflow 脚本依官方运行时 API(agent() / pipeline() / parallel() / meta)。

为什么这件事要紧

中间结果不进 context,
context 才不会腐烂

这正是 Workflow 能一口气跑上几小时、甚至几天的根本原因。用 Skill 或 Subagent 时,每个中间结果都会塞回 context window:任务越大,窗口越满,也就越容易腐化(rot)。Workflow 把这些结果留在脚本变量里,Claude 自始至终只看到最后那个答案。

“Because the coordination happens outside the conversation, the plan stays on track no matter how big the task gets.”

— Claude Code Docs [官方]
运行机制

workflow 凭什么跑得出
单遍做不到的结果

它真正厉害的地方不在于「能跑更多 agent」,而在于把保证质量的套路直接写进了循环:让几份结论互相挑错、从几个角度各写一版再比、一轮轮改到结果稳定为止。

1
动态规划

你把任务说清楚,Claude 当场写出一段 JS 编排脚本(所谓 dynamic,就是针对你这个任务临时生成、而非套用现成模板),再把它拆成一个个子任务。

2
分头并行铺开

脚本用 parallel() / pipeline() 这些写法,把活儿摊给几十、上百个 subagent 同时干。pipeline 的妙处是:每件活各走各的流程,互不卡着,谁先干完谁先走,不用排队等最慢的那个。

3
互相挑错验证

每条结果在汇总之前,先过一道检查:另外几个 agent 各自上来挑刺、专门想把它推翻,被多数人否掉的就直接扔掉。再让 schema 约定好返回格式,省得事后还得去解析一堆文本。

反复跑到答案稳定

官方原话是 “the run keeps iterating until the answers converge”:答案稳定下来才算结束,而不是跑满固定的几轮。最后把这些结果拢成一个统一的答案交回给你。

16
并发 agent 上限,CPU 核数少时还会更低
1,000
单次 run 的 agent 总数上限,用来防止失控循环
0
运行途中能插入的用户输入,唯有权限提示才会暂停它
1
resume 只在同一会话内有效,退出后下次从头再跑
不是替代,是组合

两者各管各的,还能搭着用

两者根本不在一个层面上。一个 workflow 分头派出去的每个 agent,照样可以先挂上一个 skill 再干活。它们是搭配着用的,不是二选一。

Skill

改变「模型知道什么、会做什么」

把知识和指令按需一点点喂给模型,说白了就是把「怎么写提示词」做成了现成产品。官方讲得很直接:skill 的结果不保证每次一样,因为指令是交给 Claude 自己理解的,到底怎么走,还是它一回合一回合临场定。

Workflow

改变「怎么把成批 agent 稳稳编排起来」

编排的逻辑从 Claude 的上下文里挪了出来,变成脚本里的 for 循环、if 分支和 pipeline() 调用。脚本一写定,「谁持有 plan」就从 Claude 手里,交到了这段写死的代码手里。

// 在 workflow 脚本里,让 agent 带着 skill 跑
await agent(prompt, {
  agentType: 'code-reviewer', // 复用 skill
  schema: FINDINGS
})
怎么选

什么时候用哪个

Subagent

隔出一段脏活单独跑

  • 想用一个干净的 context 去跑探索或搜索
  • 把噪音挡在主 context 之外
  • 一回合派出去几个,结果收回来你接着拿主意
Skill

把一套做法固定下来

  • 手上有一套可复用的做法、规范或知识
  • 希望 Claude 每次都照同一套思路来
  • 能接受结果因模型的临场判断而略有出入
Workflow

编排大到 context 装不下时

  • 整库级别的 bug hunt 或安全审计
  • 牵动上千文件的迁移与现代化
  • 重要决策想让多个独立 agent 反复核两遍
旗舰案例

Bun:Zig → Rust,11 天

这是官方专门拿出来讲的大案例。四个 workflow 一环扣一环:第一个把 Zig 代码里每处的内存生命周期理清楚,第二个逐个文件翻成 Rust、每个文件还配两名 reviewer,第三个反复跑编译和测试直到全绿,最后一个通宵跑优化、一处一处单独开 PR 等人来审。

~750K
行 Rust 代码
11
天,从第一个 commit 到合并
99.8%
现有测试套件的通过率
4
个 workflow 串联完成
⚠ 几个不能略过的前提

别把它读成「随便哪个迁移都能 11 天搞定」。这个成绩背后的前提相当苛刻(结合官方的限定说明,以及 Bun 仓库里那份一手的 rust-rewrite-plan.md [第三方]):

  • 还没上生产:官方原话就是 “While not yet in production”,而且 99.8% 终究不是 100%。
  • 用的是「绞杀式」渐进迁移,不是推倒重来:Zig 和 Rust 始终打包在同一个程序里,按一个个类逐步开关切换。
  • 每切换一处都要过几道关:跑测试、新旧结果比对(shadow-diff),还有性能不能掉超过 2%。是这些检查逼出来的结果,不是「写完就信」。
  • 既有测试覆盖率本就极高,又是工具作者本人挑大梁的单人项目。

真正该记住的是:只要这块代码够重要、测试够硬、检查关卡够严,把流程写成确定的脚本、再让它反复编译测试到全绿,确实能把原本按季度估的活压进几天。所以落地的正确姿势,是先挑这么一块去试,而不是把「11 天」这个数照搬到所有项目上。