Claude Code 把编排写进代码:Dynamic Workflows 详解

一个 11 天搬完 75 万行代码的 PR

先看一个数字。

Bun 的作者 Jarred Sumner 做了一次运行时迁移:约 75 万行 Rust 代码,11 天搬完,原有测试 99.8% 通过。对应的 PR 是 oven-sh/bun#30412,公开可查。

75 万行不是改几个函数,是改一整套运行时。11 天也不是一个团队连轴转的工期,而是一个人带着工具干出来的活。这次迁移的主力,就是 Claude Code 在 v2.1.154 里随 Opus 4.8 一起放出来的新功能------Dynamic Workflows。

我第一次看到这个案例时的反应是:一个对话窗口里的 AI,怎么可能扛得动这么大的活?答案是,它没在对话窗口里扛。它把活拆成了一段在你本机跑的脚本。

这篇文章讲清楚这件事是怎么发生的,以及它和你已经在用的 subagent、skill、agent teams 有什么本质不同。先说明,这是 research preview(研究预览),还在早期。

单个 agent 一次跑不完的那些活

日常用 Claude Code,大部分任务一个会话就解决了:读几个文件、改一处逻辑、跑个命令、修个 bug。这类活串行干完就行。

但总有一类任务,一次对话装不下:

  • 整个服务范围的 bug 排查------你不知道问题藏在哪几个文件里,得把范围铺开了一处处看。
  • 动辄上百文件的迁移------每个文件的改法相似,但数量大到一轮一轮派根本派不完。
  • 一个需要从多个角度反复推敲才敢拍板的方案------你想要的不是一个答案,是好几个独立答案打过架之后剩下的那个。

这三类活有个共同点:中间结果太多。排查会产出一大堆"疑似问题",迁移会产出上百个"改完待验证的文件",方案推敲会产出 N 个互相竞争的草案。这些中间结果,传统模式下全都得经过 Claude 的脑子。这就是问题所在。

核心转变:把编排写进代码

官方对这个功能的一句话定义是:A workflow moves the plan into code.------一个 workflow 把计划搬进了代码。

平时 Claude 干复杂活,是这么干的:想一步,派个 subagent 去做,等它回来,读结果,再想下一步,再派。编排逻辑活在 Claude 的脑子里,靠一轮一轮的对话往前推。

Dynamic Workflows 改的是这件事。Claude 不再逐轮在脑子里调度,而是先把整个编排过程写成一段可执行的 JavaScript 脚本:哪里要扇出上百个任务、哪里要并发、哪里要等齐、哪个结果喂给哪个下一步------全写进代码里。写完,这段脚本自己跑。

换句话说,编排从"一段对话"变成了"一段程序"。循环、分支、把中间结果攒起来这些事,本来压在 Claude 的注意力上,现在压给了 JS 运行时。

运行模型:它不是服务端的引擎

这是最容易误解、也最关键的一节。很多人一听"workflow"就以为是跑在 Anthropic 服务端的某个编排引擎。不是。

Workflow 就是 Claude Code 在你本机跑的一段 JavaScript 脚本。agent()parallel()pipeline() 这些控制流,全在你的机器上执行。

这个运行时是"无脑的、确定性的"。它只会做三件事:循环、拼字符串、await。它本身不含任何 LLM------它就是个普通的 JS 运行时,给它同样的输入会走同样的路径。

那智能从哪来?只有当脚本执行到 agent() 那一行,运行时才临时去雇一个 LLM subagent 来干这一段活。这个 subagent 调模型的方式,和你对话窗口里的主 Claude 完全一样,走 Anthropic 原生的 Messages API。脚本是骨架,agent() 是骨架上临时接进来的肌肉。

还有一个反直觉的点:脚本跑的时候,你正在对话的那个主 Claude,根本没在运行。它发出 Workflow 调用的那一回合就结束了,脚本在后台独立跑。等脚本跑完,一条通知把主 Claude 叫醒,它再去读最终结果。主 Claude 全程在睡觉,醒来只看结论。运行情况你可以用 /workflows 命令查。

这就是为什么它扛得住 75 万行的迁移:真正循环上百遍的是那个本身不调用模型的 JS 运行时,不是任何一个 LLM 的上下文窗口。

跟 subagent / skill / agent teams 的区别

把已有的协作能力捋一遍,分层就清楚了:

  • session:单个 agent 实例,从头干到尾,串行。
  • subagent:主 agent 派生小弟去搜文件、读代码、跑命令,干完汇报回来。
  • agent teams:多个独立的 Claude Code 实例像团队一样并行,队员之间还能互相通信,是网状协作。
  • workflow:树状结构------一个 claude 扇出上百个 task,每个 task 走 implementer → 两个 verifier → fixer 三层,最后扇入返回。

subagent 和 skill 模式下,编排者始终是 Claude:它逐轮决定下一步派谁,而每个 subagent 的返回都要先回到 Claude 的上下文窗口,它读完才能决定下一步。规模一大,上下文装不下海量中间结果,注意力也被稀释------这正是上面"中间结果太多"那个痛点的根。

workflow 模式把编排者换掉了:脚本自己持有循环、分支、中间结果,Claude 的上下文里只剩最后那个答案。

复用维度也不一样。subagent 复用的是"一个工作者",skill 复用的是"一条指令",而 workflow 复用的是"整套编排逻辑"------写好一次能存下来反复运行。

怎么用

入口是 /workflows 命令,用它创建和查看运行。

每个脚本必须以 export const meta = {...} 开头。meta 必须是纯字面量------不能有变量、不能有函数调用、不能有模板插值。它定义 name、一行 description(会显示在权限弹窗里)、以及 phases

核心原语有这么几个:

javascript 复制代码
export const meta = {
  name: "migrate-files",
  description: "迁移并逐文件验证",
  phases: [{ title: "scan" }, { title: "migrate" }, { title: "verify" }],
};

// 脚本体直接从 meta 之后开始,是顶层 await ------ 没有 export default,不用包在函数里

// agent(prompt, opts):spawn 一个 subagent,带 schema 时强制结构化输出
const files = await agent("列出所有待迁移文件", { schema: FileList });

// pipeline(items, ...stages):流水线,无 barrier,默认推荐
await pipeline(
  files,
  (f) => agent("迁移 " + f),   // stage 1
  (f) => agent("验证 " + f),   // stage 2
);

// parallel(thunks):并发,是 barrier,等所有完成才返回
await parallel([() => agent("汇总报告"), () => agent("生成 changelog")]);

pipeline 没有 barrier------item A 可以已经走到 stage 3,item B 还在 stage 1,谁也不等谁。parallel 是 barrier,等所有任务都完成才返回。另外还有 phase(title) 分阶段、log(msg) 输出进度、args 入参、budget 控制 token 预算,以及 workflow() 嵌套一层。

两条硬上限要记住:并发上限是 min(16, CPU 核数 - 2);单个 workflow 生命周期里 agent 总数上限 1000。

几个值得抄的编排范式

脚本能写编排,就意味着你可以把一些"反复推敲"的套路固化下来。官方给了几个:

  • adversarial verify(对抗式校验):对每个发现,spawn 多个独立的 skeptic 来投票,多数否决就把这个发现杀掉。专治那种"看着合理、其实是错的"结论。
  • judge panel(评委团):生成 N 个独立方案,并行打分,从胜出的那个综合出最终结果。前面说的"从多个角度反复推敲才敢拍板",落地就是这个。
  • loop-until-dry:面对规模未知的发现,持续 spawn,直到连续 K 轮都没有新东西冒出来为止。你不知道要排查多少处时用它。
  • pipeline 默认优于 barrier :默认用 pipeline,让每个 item 各跑各的。只有当某个阶段真的需要前一阶段的全部结果时,才换成 parallel barrier 等齐。

这几个范式都不是新概念,但能写进一段可存可复用的脚本里,意义就不一样了------下次遇到同类任务,直接跑。

小结

Dynamic Workflows 做的事,一句话说完:把 Claude 脑子里的编排逻辑,搬进一段在你本机跑的、无脑确定性的 JavaScript 脚本;脚本负责循环和攒中间结果,只在 agent() 那一行临时雇 LLM 干活,跑完叫醒主 Claude 读结论。

它不和 subagent、skill、agent teams 抢饭碗,而是补上了它们够不着的那一格:单个 agent 一次跑不完、中间结果多到上下文装不下的大任务。75 万行的 Bun 迁移就是证据。

它还是 research preview,但这个方向值得早点上手------用 /workflows 起一个最小脚本,把你手头那个"一次对话装不下"的活试着拆进代码里。

相关推荐
创世宇图2 小时前
Claude Opus 4.8 深度实测:动态多 Agent 协同、Effort Control 与幻觉抑制的工程化解析
ai·llm·agent·claude·ai工程化
m0_535817554 小时前
macOS上Claude Code安装配置保姆级教程:国内直连API,从0到1跑通(附避坑指南)
gpt·macos·ai·node.js·claude·claudecode·88api
沉默王二6 小时前
每月13亿免费Token,14家AI大厂的API任你用,包括Gemini
github·claude·gemini
AI悦创Python辅导8 小时前
一份 CLAUDE.md,让 Claude Code 不再每次从零开始
claude
空空潍8 小时前
解锁ClaudeCode浏览器访问,极速效率-Playwright Cli
ai·claude·playwright-cli
周易宅10 小时前
Claude Code “Not logged in“ 问题解决方案
ai·claude
青山如墨雨如画10 小时前
【Claude】Win11系统VSCode环境中Claude+Deepseek报错的全自动解决方式
vscode·aigc·claude·authropic
码哥字节1 天前
30 秒描述需求,5 分钟出稿,我的述职演示文稿就这么做好了
openai·claude
ZzT1 天前
Harness 怎么扩展:skill、配置目录与 hook
openai·ai编程·claude