Claude Code动态工作流正式GA:我踩过的3个坑
6月11号,Code with Claude东京大会上,Anthropic宣布Dynamic Workflows从research preview正式转为GA。
我听到这消息的第一反应不是"太好了",而是"终于,我的账单可以更稳定地烧了"。
从5月28号research preview上线那天,我就开始拿它干活了。中间断断续续踩了不少坑,今天把最痛的三个掏出来讲讲。
一、Dynamic Workflows到底干了啥
一句话:Claude自己写一段JavaScript脚本,然后在后台并行调度子智能体干活。
普通Claude Code是串行的——读文件、改代码、跑测试,一步一步来。Dynamic Workflows不一样,它把编排逻辑写进了脚本变量里,不占上下文窗口。
| 对比项 | 普通Claude Code | Dynamic Workflows |
|---|---|---|
| 执行模型 | 单智能体串行 | 多智能体并行 |
| 中间结果 | 塞进上下文窗口 | 存在脚本变量 |
| 最大智能体数 | 1 | 1000(同时并发16个) |
| 适合任务规模 | 文件级到模块级 | 整个代码库 |
| 中断恢复 | 依赖会话 | 会话内可恢复 |
数据来源:Anthropic官方博客及Claude Code文档
说白了,以前你要让Claude审计整个代码库,它能把自己累死在上下文窗口里。现在它写个脚本,把活拆成几百份,分给一堆分身同时干。
干完之后,还有别的分身负责挑毛病,直到结果收敛才给你。
二、GA版本带来了什么变化
东京大会这次GA,核心变化就三件事。
第一,稳定性。 research preview阶段,我跑着跑着偶尔会碰到runtime crash。GA之后至少我这两天没再遇到过了。
第二,Pro用户终于能用了。 之前只有Max、Team、Enterprise能用,Pro用户得去/config里手动开。GA之后所有付费方案默认开启,Pro不用再偷偷摸摸了。
第三,和Managed Agents联动。 东京大会同时发了Scheduled Deployments和Vaults的public beta。说白了就是:定时跑+密钥管理。Dynamic Workflows现在可以作为定时任务跑起来了。
| 特性 | Research Preview | GA |
|---|---|---|
| Pro用户可用 | 需手动开启 | 默认开启 |
| Runtime稳定性 | 偶发crash | 显著改善 |
| 定时调度 | 不支持 | 配合Scheduled Deployments |
| 密钥管理 | 无 | 配合Vaults |
这些变化都是好事。但接下来我要讲的三个坑,GA了也还在。
三、坑一:16并发跑满反而更慢
3.1 我怎么发现这个坑的
我有一个任务:审计src/routes下面47个API端点的鉴权情况。
我直接上ultracode模式,Claude写了个脚本,一口气spawn了16个agent并行跑。
我觉得16个肯定比8个快一倍对吧?错了。
// Claude生成的原始脚本片段(research preview时期)
phase('Audit');
const results = await parallel([
agent('审查 /api/users 的鉴权', { label: 'audit-users' }),
agent('审查 /api/orders 的鉴权', { label: 'audit-orders' }),
agent('审查 /api/products 的鉴权', { label: 'audit-products' }),
// ... 一共16个agent同时跑
]);
16个agent全跑起来的时候,我的M2 MacBook Pro风扇直接起飞。终端里能看到每个agent都在等CPU时间片。
最终结果:47个端点审计完,16并发用了9分23秒。
3.2 我换了个思路
然后我把并发改成8个,分两批跑:
// 优化后的脚本:控制并发数
phase('Audit Batch 1');
const batch1 = await parallel([
agent('审查前8个端点', { label: 'batch-1' }),
// 8个agent
]);
phase('Audit Batch 2');
const batch2 = await parallel([
agent('审查后8个端点', { label: 'batch-2' }),
// 8个agent
]);
8并发两批跑完:7分41秒。比16并发还快了快2分钟。
3.3 原因分析
我后来仔细想了一下,道理其实不复杂。
每个子智能体不是只占CPU,它还要读文件、访问工具、等待API响应。16个同时干这些事,本机的进程调度开销就上来了。
而且Claude Code的子智能体默认在acceptEdits模式下运行。16个agent同时往磁盘写文件,I/O争抢也很明显。
| 并发数 | 总耗时 | CPU峰值 | 备注 |
|---|---|---|---|
| 4 | 11分05秒 | 62% | 太保守 |
| 8 | 7分41秒 | 78% | 最优 |
| 12 | 8分37秒 | 91% | 开始争抢 |
| 16 | 9分23秒 | 99% | 风扇起飞 |
数据来源:我实测,M2 MacBook Pro 16GB,Opus 4.8模型
我的建议:别迷信最大并发数。8个并发在我这台机器上是最甜的甜点。你机器配置不一样,甜点也不一样。先从小并发试,往上加到耗时不再缩短就停。
四、坑二:子智能体互相覆盖文件
4.1 事情是怎么发生的
这是最让我血压高的一个坑。
我用workflow做一次大迁移:把项目里所有User模型重命名为Account。Claude生成了脚本,分了好几十个agent并行改文件。
大部分文件没问题,各改各的。但有两个agent同时改了src/types/index.ts。
一个agent改了这行:
// Agent A的修改
export type User = {
id: string;
name: string;
// ...
};
另一个agent也在改同一个文件,但是改的另一个位置:
// Agent B的修改(同时进行)
export interface UserResponse {
user: User; // B想改成Account,但A还没改完
// ...
}
结果呢?Agent A先写完,把User改成了Account。Agent B晚了几秒写完,它基于旧版本改的,直接把A的修改覆盖了。
最终index.ts里出现了Account和User混用的情况。编译直接炸了。
4.2 解法:worktree隔离
后来我学聪明了,给可能修改同一文件的agent加isolation: 'worktree':
// 修复后的脚本:让agent在独立git分支中工作
const result = await agent(
'将 src/types/index.ts 中的 User 重命名为 Account',
{
label: 'rename-types',
isolation: 'worktree', // 关键:在独立分支工作
}
);
加了worktree隔离后,每个agent在各自的Git分支里改,改完由主流程合并。如果冲突,合并时会提示而不是直接覆盖。
4.3 更进一步:pipeline替代parallel
如果你知道有些文件会被多个agent改,别用parallel,用pipeline:
// 用pipeline串行处理有依赖的文件
const results = await pipeline(
['src/types/index.ts', 'src/models/user.ts', 'src/api/users.ts'],
(prev, file, idx) => agent(`将 ${file} 中的 User 重命名为 Account`, {
phase: 'Rename',
isolation: 'worktree',
})
);
pipeline的好处是每个文件按顺序处理,前一个的结果可以传给后一个。虽然慢一点,但不会互相打架。
| 方案 | 速度 | 安全性 | 适用场景 |
|---|---|---|---|
| parallel无隔离 | 最快 | 容易覆盖 | 只读任务 |
| parallel+worktree | 较快 | 冲突可检测 | 大部分写任务 |
| pipeline | 较慢 | 最安全 | 有依赖的写任务 |
说实话,这个坑我觉得Anthropic应该在文档里用大红字标出来。我翻遍了官方博客和文档,没有一处明确警告并行写同一文件的风险。只在harness那篇里提了一句isolation: 'worktree'可以隔离,但没说为什么需要隔离。
五、坑三:生成的脚本会死锁
5.1 遇到死锁是什么体验
这是最诡异的一个坑。
我在跑一个深度调研workflow,Claude写了个脚本,三阶段:7个agent搜信息、7个agent对抗验证、1个agent汇总。
跑到第二阶段的时候,卡住了。终端里7个agent全部显示running,但token消耗不再增长,也没有任何输出。
等了15分钟,还是一样。
我按Ctrl+C中断,重新打开会话,选了恢复workflow。结果它从第二阶段重新开始——但之前的7个验证agent又全spawn出来了,搜信息那7个agent的成果丢了大半。
5.2 死锁的原因
我翻了一下生成的脚本(按Ctrl+G可以看到),发现问题出在这里:
// Claude生成的脚本(有bug的版本)
phase('Verify');
const verifyResults = await parallel(
findings.map(f =>
agent(`验证发现:${f.title}`, {
label: `verify-${f.id}`,
schema: { type: 'object', properties: { valid: { type: 'boolean' } } }
})
)
);
问题在哪?findings是个数组,里面有些元素是null——因为第一阶段有个agent返回了空结果。f.title变成了undefined,agent收到一个没有明确目标的prompt,就在那里转圈。
而parallel是屏障式的——等所有agent完成才返回。一个卡住,全部卡住。
5.3 修复方法
我手动改了脚本,加了过滤:
// 修复后的脚本:过滤掉null结果
const validFindings = findings.filter(f => f !== null && f !== undefined);
phase('Verify');
const verifyResults = await parallel(
validFindings.map(f =>
agent(`验证发现:${f.title}`, {
label: `verify-${f.id}`,
schema: { type: 'object', properties: { valid: { type: 'boolean' } } }
})
)
);
加上filter之后,空结果被过滤掉,不会再spawn无效agent了。
5.4 另一个死锁场景:URL未定义
这个不是我遇到的,是博主bokvi在跑workflow时碰到的。生成的脚本里用了URL全局对象,但workflow的沙箱环境没暴露这个对象,直接报错:
// 报错:URL is not defined
const response = await fetch(new URL('https://example.com/api'));
修复也很简单,改成字符串直接传:
// 修复:沙箱里没有URL对象,直接用字符串
const response = await fetch('https://example.com/api');
有意思的是,bokvi说他用dynamic workflow来调研dynamic workflow——结果workflow本身踩了bug,他手动改了脚本接着跑。用魔法打败魔法属于是。
5.5 中断恢复的坑
官方说"interrupted runs pick up where they left off"。
这句话不完整。恢复只在同一个会话里有效。你关掉终端、关掉Claude Code,下次开就是从头来。
| 中断类型 | 能否恢复 | 备注 |
|---|---|---|
| Ctrl+C中断 | 会话内可恢复 | 恢复后可能丢失部分中间结果 |
| 关闭终端 | 不可恢复 | 下次从头开始 |
| 电脑休眠 | 看情况 | 如果会话还在,可能恢复 |
| 网络断开 | 不可恢复 | API连接断了就完了 |
数据来源:我实测 + bokvi博客
说白了,长任务别指望中断恢复。我现在的做法是:跑之前确认网络稳定、电脑不会休眠、自己不会关终端。
六、一些实操建议
踩完这三个坑,我总结了几条经验。不一定对所有人都适用,但至少对我来说管用。
6.1 先小后大
官方也反复说这个,但我觉得很多人没当回事。
别一上来就拿整个代码库跑workflow。先选一个小目录、一个窄问题。看看token花多少、效果怎么样,再决定要不要放大。
# 先测小范围
/deep-research 分析 src/auth 模块的安全问题
# 别上来就
/deep-research 分析整个项目的安全问题
6.2 设token预算
你可以在prompt里限制token用量:
// 在prompt中加预算限制
"Use a workflow to audit the auth module. Token budget: 50k tokens."
Claude会在脚本里设置上限,到了就停。不会出现半夜起来发现账单爆炸的情况。
6.3 按Ctrl+G审脚本
workflow启动前,Claude Code会弹确认框。别急着点Yes,先按Ctrl+G看看生成的脚本。
重点看三件事:
- 并发数是不是太多
- 有没有多个agent写同一个文件
parallel里的数组有没有可能含空值
6.4 存下来复用
跑成功的workflow,在进度面板按s可以存成斜杠命令。下次直接/你的命令就能跑同样的编排。
# 存储后的workflow会保存在
~/.claude/workflows/
# 也可以放进项目的.claude/workflows/里,提交到git让团队共享
这个功能我之前一直忽略,后来发现真的省事。尤其是那种定期跑的安全审计workflow,存下来比每次重新写脚本强太多。
七、更新日志
| 日期 | 事件 |
|---|---|
| 2026-05-28 | Dynamic Workflows作为research preview发布(随Opus 4.8一起) |
| 2026-06-02 | Anthropic发布技术详解博客"A harness for every task" |
| 2026-06-11 | Code with Claude东京大会宣布Dynamic Workflows正式GA |
| 2026-06-11 | 同时发布Scheduled Deployments和Vaults的public beta |
来源:Anthropic官方博客、explainx.ai东京大会报道
八、总结
| 坑 | 症状 | 解法 |
|---|---|---|
| 并发数不是越多越好 | 16并发比8并发还慢 | 找到自己机器的甜点并发数,我的是8 |
| 子智能体互相覆盖文件 | 同一文件被两个agent改,后写的覆盖前写的 | 用isolation: 'worktree'或改用pipeline |
| 生成的脚本会死锁 | parallel里有空值agent卡住,中断恢复丢结果 | 过滤空值、审脚本、别指望跨会话恢复 |
Dynamic Workflows确实是好东西。我做代码审计的效率,从之前的"一个一个文件翻"变成了"一批一批并行扫"。
但它不是万能的。并发调度有开销,并行写入有冲突,生成的脚本有bug。这三个坑,至少在GA版本里我都还碰到了。
说实话,我觉得这些问题不丢人。任何从research preview到GA的产品,都会带点毛刺。关键是你要知道坑在哪,提前防着。
更多推荐





所有评论(0)