Dynamic Workflows
大规模子代理编排——让几十个代理协同完成一个任务
脚本化编排、对抗性验证、可恢复执行一个代理不够
当任务大到单次对话装不下的时候,怎么办?
全仓库审计
500 个文件逐一检查安全漏洞。一个代理读到第 30 个文件时,上下文已经塞满了,最早发现的问题被挤出记忆。
大规模迁移
把整个项目从 ESLint 迁移到 Oxlint——配置文件、插件、规则覆盖,每个包都需要独立处理。一个代理跑不完。
结果可信度
让 Claude 做了一次深度研究,返回了一份报告。但你不知道哪些结论站得住脚——它没有自己验证过自己的结论。
四种方式对比
Subagents、Skills、Agent Teams、Workflows 各有分工
| Subagents | Skills | Agent Teams | Workflows | |
|---|---|---|---|---|
| 本质 | Claude 生成的工人 | Claude 遵循的指令 | 主代理监督对等会话 | 运行时执行的脚本 |
| 谁决定下一步 | Claude,逐轮 | Claude,遵循提示 | 主代理,逐轮 | 脚本 |
| 中间结果 | 上下文窗口 | 上下文窗口 | 共享任务列表 | 脚本变量 |
| 可重复性 | 工人定义 | 指令 | 团队定义 | 编排本身 |
| 规模 | 每轮几个 | 同 Subagents | 少量长期会话 | 数十到数百 |
| 中断恢复 | 重启当前轮 | 重启当前轮 | 同伴继续 | 可恢复 |
架构概览
用户会话、Workflow Runtime 和子代理的三层关系

图:Workflow 运行时架构——从用户输入到最终结果的三层结构
【AI 生图提示词】请生成一张中文技术架构示意图,风格简洁、配色柔和、适合教学: - 画面主体:三层架构图。顶层是"用户会话"(单个圆角矩形),中间层是"Workflow Runtime"(大圆角矩形,内含"JavaScript 脚本执行环境"和"Journal 日志系统"两个子块),底层是多个"子代理"(并行排列的小圆角矩形,标注 Agent1、Agent2...Agent N) - 各元素关系:用户会话通过箭头向下连接到 Runtime,Runtime 通过多条箭头向下分发到各个子代理。Journal 与脚本执行环境用虚线双向箭头连接 - 关键标注:用户会话旁标注"上下文只保留最终答案",Runtime 内标注"并发上限 16",脚本执行环境内列出 agent()、parallel()、pipeline()、phase() 四个函数名 - 配色建议:浅蓝/浅灰背景,深色文字,Runtime 边框用橙色标注,子代理用浅绿色填充 - 画面比例:16:9 - 避免:过度装饰、3D 效果、杂乱的颜色
脚本怎么来的
从你输入提示词到 Workflow 运行,中间发生了什么
CLAUDE_CODE_WORKFLOWS=1(字符串)且账户计划支持 Dynamic Workflows(Max/Team 默认开,Pro 需在 /config 手动打开)。详情见本章末尾的排错指南。
你输入:ultracode: 审查 src/routes/ 下每个路由文件是否缺少认证检查
Claude Code:检测到 "ultracode" 关键字 → 高亮显示 → 弹出确认提示
┌─────────────────────────────────────────────────┐
│ Dynamic workflow requested for this turn │
│ Esc to ignore │
│ │
│ Phases: │
│ 1. Scan — 发现所有路由文件 │
│ 2. Review — 每个文件一个代理并行审查 │
│ 3. Verify — 对抗性验证每个发现 │
│ 4. Report — 汇总报告 │
│ │
│ ⚠️ Token usage will be high │
│ │
│ [Yes, run it] [View raw script] [No] │
└─────────────────────────────────────────────────┘
你选择 "View raw script" → Claude 把生成的 JS 脚本展示给你
你选择 "Yes, run it" → Workflow Runtime 在后台接管执行
你输入:/workflows # 随时查看进度
# 你的会话保持响应,可以继续做其他事
你不需要自己写脚本
Claude 根据你的任务描述即时生成 JavaScript 脚本。你只需要用自然语言描述要做什么,Claude 决定怎么编排。脚本写好后保存在会话目录下,你可以查看、编辑、重新运行。
为什么是 JavaScript
脚本需要表达循环、分支、并行这些确定性的控制流——而不是让模型逐轮决定下一步。JavaScript 是 Workflow Runtime 能执行的唯一语言。脚本里没有文件系统访问,所有读写操作都由子代理完成。
脚本结构
Claude 生成的脚本长什么样
// 1. 元数据块(必须是纯字面量,不能有变量或计算)
export const meta = {
name: 'my-workflow',
description: '做什么事',
phases: [
{ title: 'Phase1', detail: '描述' },
{ title: 'Phase2', detail: '描述' },
],
};
// 2. 脚本主体
phase('Phase1');
const results = await parallel(items.map(item => () =>
agent(`处理 ${item}`, { schema: MY_SCHEMA, phase: 'Phase1' })
));
phase('Phase2');
const final = await agent('综合所有结果', { phase: 'Phase2' });
return { final, count: results.length };
脚本能做什么
使用 agent()、parallel()、pipeline()、phase()、log()、workflow() 编排子代理。读取 args 获取外部输入,通过 return 返回结果。
脚本不能做什么
没有文件系统或 Node.js API 访问。代理负责读写文件和运行命令,脚本只负责协调。Date.now()、Math.random() 会直接抛错——为了保证可缓存和可恢复。
agent() 原语
派生一个子代理执行任务,返回结果
// 最简用法:返回代理的文本输出
const result = await agent('审查 src/auth.ts 的安全性');
// 带 schema:强制返回结构化 JSON(模型会自动重试直到匹配)
const bugs = await agent('找出这个文件里的 bug', {
schema: {
type: 'object',
properties: {
bugs: { type: 'array', items: {
type: 'object',
properties: {
file: { type: 'string' },
line: { type: 'number' },
severity: { type: 'string', enum: ['high','medium','low'] },
}
}}
}
}
});
// 常用选项
await agent('审查代码', {
label: 'review:auth', // 进度视图中的显示名
phase: 'Review', // 分配到进度组
isolation: 'worktree', // 在独立 git worktree 中运行
agentType: 'general-purpose' // 使用自定义子代理类型
});
schema 是 Workflow 的核心机制之一。它迫使子代理返回符合 JSON Schema 的结构化数据,而不是自由文本。后续阶段可以直接用这些数据做判断,不需要再解析。
并行原语
parallel() 是屏障,pipeline() 是流水线——默认用 pipeline
parallel() — 屏障式
等所有任务完成才返回。适合需要看到全部结果才能做决定的场景。
const all = await parallel([
() => agent('搜索角度A'),
() => agent('搜索角度B'),
() => agent('搜索角度C'),
]);
// 这里拿到全部 3 个结果
const deduped = dedup(all);
pipeline() — 流水线
每个 item 独立流经所有阶段,无屏障。Item A 在阶段 3 时,Item B 可能还在阶段 1。
const results = await pipeline(
files,
(file) => agent(`审查 ${file}`),
(review) => agent(`验证 ${review.file}`)
);
// 更快,因为没有等待屏障
parallel()。分开 ≠ 需要同步。pipeline() 的默认性能更好。只有当后续阶段真的需要跨项合并或去重时,才用 parallel()。
选择决策
什么时候用 parallel,什么时候用 pipeline
✅ 用 parallel 的理由
- 去重/合并:需要跨全部结果去重后再处理
- 提前退出:根据总数决定是否跳过("0 个发现,跳过验证")
- 跨项引用:后续提示词需要引用"其他发现"
❌ 不该用 parallel 的理由
- "我先 flatten 一下"→ 在 pipeline 的 stage 里做就行
- "阶段在概念上是分开的"→ 分开 ≠ 需要同步
- "代码更整洁"→ 屏障有真实的延迟代价
pipeline()。只有当你发现自己在写"先 parallel() → 做 transform → 再 parallel()",而中间的 transform 不依赖跨项数据时,你应该用 pipeline() 并把 transform 放在 stage 里。
辅助原语
phase、log、workflow、budget、args
| 原语 | 作用 | 示例 |
|---|---|---|
phase(title) | 设置进度分组 | phase('Verify') |
log(msg) | 输出进度消息 | log(`${bugs.length} bugs found`) |
workflow(name, args?) | 嵌套调用另一个工作流 | await workflow('deep-research', { question: topic }) |
budget.total | 总 token 预算(未设则为 null) | while (budget.remaining() > 50000) |
budget.spent() | 已消耗 token | 见上 |
args | 外部传入的参数 | args.weekStart |
// 按预算控制深度
const bugs = [];
while (budget.total && budget.remaining() > 50000) {
const result = await agent('Find bugs', { schema: BUGS_SCHEMA });
bugs.push(...result.bugs);
log(`${bugs.length} found, ${Math.round(budget.remaining()/1000)}k remaining`);
}
// 嵌套调用内置工作流
const report = await workflow('deep-research', 'Claude Code hooks 原理');
workflow() 只支持一层嵌套。子工作流内再调用 workflow() 会抛错。子工作流共享父级的并发上限、代理计数和 token 预算。
对抗性验证
让 N 个"怀疑者"代理力图反驳每个发现
// 对每个发现,派 3 个独立怀疑者
const VOTES = 3;
const REFUTATIONS_TO_KILL = 2;
const verified = await parallel(findings.map(f => () =>
parallel(Array.from({ length: VOTES }, (_, i) => () =>
agent(`Be SKEPTICAL. Try to REFUTE this claim:
"${f.claim}"
Source: ${f.source}
Return refuted: true/false with evidence.`, {
schema: VERDICT_SCHEMA
})
)).then(verdicts => {
const valid = verdicts.filter(Boolean);
const refuted = valid.filter(v => v.refuted).length;
const survives = valid.length >= REFUTATIONS_TO_KILL
&& refuted < REFUTATIONS_TO_KILL;
return { ...f, survives, refutedVotes: refuted };
})
));
const confirmed = verified.filter(f => f.survives);
循环与多视角
Loop-Until-Dry + Perspective-Diverse Verify
const seen = new Set();
const confirmed = [];
let dry = 0;
while (dry < 2) { // 连续 2 轮没新发现就停
const found = (await parallel(FINDERS.map(f => () =>
agent(f.prompt, { phase: 'Find', schema: BUGS })
))).filter(Boolean).flatMap(r => r.bugs);
const fresh = found.filter(b => !seen.has(key(b)));
if (!fresh.length) { dry++; continue; }
dry = 0;
fresh.forEach(b => seen.add(key(b)));
// 每个发现用 3 个不同视角独立评判
const judged = await parallel(fresh.map(b => () =>
parallel(['correctness','security','repro'].map(lens => () =>
agent(`Judge "${b.desc}" via the ${lens} lens`, {
phase: 'Verify', schema: VERDICT
})
)).then(vs => ({
b,
real: vs.filter(Boolean).filter(v => v.real).length >= 2
}))
));
confirmed.push(...judged.filter(v => v.real).map(v => v.b));
}
seen),不是对"已确认"去重。否则被拒绝的发现在下一轮会重新出现,循环永远不收敛。
质量模式总结
四种模式可以根据任务自由组合
🎯 对抗性验证
每个发现 → N 个怀疑者反驳 → 低于多数存活则丢弃。
适用:审计、研究——防止"听起来对但实际错"的结论。
🔍 多视角验证
每个验证者用不同视角(正确性、安全性、性能、可复现性)评判。
适用:代码审查——比 N 个相同视角的冗余验证更强。
⚖️ 评判团
N 个独立方案 → 并行评分 → 从获胜方案综合,嫁接亚军优点。
适用:架构设计、方案选型——解空间很大时。
🔄 循环直到枯竭
持续派生发现器,直到 K 轮没有新发现。
适用:Bug 扫描、安全审计——不知道总量有多大时。
/deep-research
Claude Code 内置的深度研究工作流——也是最好的学习范例

图:/deep-research 五阶段流程——从问题分解到带引用报告
【AI 生图提示词】请生成一张中文技术流程示意图,风格简洁、配色柔和、适合教学: - 画面主体:五个阶段从左到右的流程图,每个阶段是一个圆角矩形,用箭头连接。阶段分别为:Scope(1个代理)、Search(5个并行代理)、Fetch(去重+获取15个来源)、Verify(每个声明3个对抗验证)、Synthesize(1个代理写报告) - 各元素关系:Scope 分解为 5 个角度,每个角度一个 Search 代理。Search 结果流入 Fetch 做去重。Fetch 提取的声明流入 Verify 做 3 投验证。Verify 存活的声明流入 Synthesize 写最终报告 - 关键标注:在 Verify 阶段标注"2/3 反驳即淘汰",在 Search 阶段标注"5 个并行",在 Fetch 阶段标注"Top 15 来源" - 配色建议:浅灰背景,Scope/Synthesize 用蓝色,Search/Verify 用橙色,Fetch 用绿色。箭头统一用深灰色 - 画面比例:16:9 - 避免:过度装饰、3D 效果、杂乱的颜色
研究脚本详解
/deep-research 的核心逻辑拆解
// 阶段1:分解问题
phase("Scope");
const scope = await agent(
"Decompose this question into 5 search angles...\n" + QUESTION,
{ schema: SCOPE_SCHEMA } // 强制返回结构化角度列表
);
// 阶段2+3:搜索 + 获取(pipeline,无屏障延迟)
const searchResults = await pipeline(
scope.angles,
(angle) => agent(SEARCH_PROMPT(angle), { schema: SEARCH_SCHEMA }),
(searchResult) => {
// URL 去重 + 预算控制
const novel = dedupAndBudget(searchResult.results);
return parallel(novel.map(source => () =>
agent(FETCH_PROMPT(source), { schema: EXTRACT_SCHEMA })
));
}
);
// 阶段4:3 投对抗性验证
phase("Verify");
const voted = await parallel(rankedClaims.map(claim => () =>
parallel([0,1,2].map(v => () =>
agent(VERIFY_PROMPT(claim, v), { schema: VERDICT_SCHEMA })
)).then(verdicts => ({
...claim,
survives: valid >= 2 && refuted < 2
}))
));
// 阶段5:综合报告
phase("Synthesize");
const report = await agent("Synthesize...", { schema: REPORT_SCHEMA });
触发方式
三种方式让 Claude 写出并运行一个 Workflow
方式一:提示词触发
在提示词中包含 ultracode 关键字,或用自然语言说 "use a workflow"。
ultracode: 审查 src/routes/ 下
每个端点是否缺少认证检查
Claude Code 会高亮关键字并显示确认提示,按 Esc 取消。如果快捷键无效,用鼠标点击 "No" 按钮也可以取消。
方式二:全局 ultracode
设置 /effort ultracode,Claude 自动为每个重要任务规划 Workflow。
/effort ultracode
每个请求可能变成多个连续 Workflow:理解 → 实现 → 验证。更费 token,适合关键任务。
方式三:运行命令
直接运行内置或已保存的 Workflow 命令。
# 内置
/deep-research Claude Code hooks 原理
# 保存过的自定义
/vue-newsletter {"weekStart":"2026-06-04"}
保存与复用
一次写好、反复运行的 Workflow 才是真正的价值
# 查看运行中的工作流
/workflows
# 选择一个成功的运行,按 s 保存
# 保存位置选择:
.claude/workflows/ ← 项目级(团队共享,随仓库分发)
~/.claude/workflows/ ← 个人级(所有项目可用,仅自己可见)
# 保存后像 slash command 一样调用
/my-code-review
# 传入参数
/triage-issues issues 1024, 1025, and 1030
# 同名时,项目级优先于个人级
实战:代码审查
多维度审查 + 对抗性验证的完整 Workflow
export const meta = {
name: 'review-changes',
description: 'Review changed files across dimensions, verify each finding',
phases: [
{ title: 'Review', detail: '三个维度并行审查' },
{ title: 'Verify', detail: '对抗性验证每个发现' },
],
};
const DIMENSIONS = [
{ key: 'bugs', prompt: 'Review for correctness bugs...' },
{ key: 'perf', prompt: 'Review for performance issues...' },
{ key: 'security', prompt: 'Review for security vulnerabilities...' },
];
const results = await pipeline(
DIMENSIONS,
(d) => agent(d.prompt, {
label: `review:${d.key}`,
phase: 'Review',
schema: FINDINGS_SCHEMA
}),
(review) => parallel(review.findings.map(f => () =>
agent(`Adversarially verify: ${f.title}`, {
label: `verify:${f.file}`,
phase: 'Verify',
schema: VERDICT_SCHEMA
}).then(v => ({ ...f, verdict: v }))
))
);
const confirmed = results.flat()
.filter(Boolean)
.filter(f => f.verdict?.isReal);
return { confirmed };
运行管理
查看进度、暂停恢复、成本控制
# 查看所有运行
/workflows
# 在进度视图中可用的快捷键:
↑/↓ 选择阶段或代理
Enter/→ 展开查看详细内容
p 暂停或恢复运行
x 停止选中的代理或整个工作流
s 保存脚本为命令
Esc 返回上一层
p 暂停无效,用 /workflows 进入视图后点击暂停按钮即可。
暂停与恢复
停止后可以恢复。已完成的 agent() 调用从 Journal 缓存直接返回,只重新执行未完成或被修改的部分。
注意:恢复只在同一会话内有效。退出 Claude Code 后再启动会重新开始。
成本控制
一个 Workflow 可能消耗大量 token。建议:
- 先在小范围试跑(一个目录而非整个仓库)
/workflows视图显示每个代理的 token 用量- 可随时停止,已完成的工作不会丢失
- 用
/model确认当前模型
运行约束
Workflow Runtime 的安全边界
| 约束 | 原因 |
|---|---|
| 无运行中用户输入 | 只有代理权限提示可以暂停运行。需要人工审批的阶段,拆成独立的 Workflow |
| 无直接文件系统或 Shell 访问 | 代理负责读写和执行命令,脚本只负责协调代理 |
| 最多 16 个并发代理 | 限制本地资源使用(CPU 核心数较少时自动降低) |
| 每次运行最多 1000 个代理 | 防止失控循环 |
Date.now() 等抛错 | 保证 Journal 缓存的可恢复性——非确定性函数会使缓存失效 |
agent() 调用的输入和输出。暂停后恢复时,相同输入直接返回缓存结果。如果脚本里用了 Date.now(),每次恢复都会得到不同值,缓存全部失效。如果需要时间戳,通过 args 从外部传入。
关闭 Workflow
三种方式禁用 Dynamic Workflows
| 方式 | 持久性 | 说明 |
|---|---|---|
/config 切换 | 跨会话 | 在设置中关闭 "Dynamic workflows" 开关 |
settings.json | 跨会话 | 设置 "disableWorkflows": true |
| 环境变量 | 启动时读取 | CLAUDE_CODE_DISABLE_WORKFLOWS=1 |
关闭后:ultracode 关键字不再触发、/deep-research 不可用、/effort ultracode 从菜单中移除。
排错指南
ultracode 不触发
症状:提示词包含 ultracode 但 Claude 没有生成 Workflow。
修复:Workflow 触发需要同时满足两个条件:
- 环境变量
CLAUDE_CODE_WORKFLOWS=1(字符串,不是数字) - 账户计划支持 Dynamic Workflows(Max/Team/Enterprise 默认开启,Pro 需在
/config手动启用)
用 echo $CLAUDE_CODE_WORKFLOWS 确认变量已设置。如果用 /config 找不到 "Dynamic workflows" 开关,说明当前账户未支持该功能。
运行卡住不动
症状:Workflow 启动后进度不动。
修复:可能是权限提示在等待你批准。用 /workflows 查看状态。把需要的命令提前加入 allowedTools。
schema 匹配失败
症状:代理反复重试,消耗大量 token。
修复:简化 schema 定义,减少 required 字段,或去掉嵌套层级。过于复杂的 schema 会导致模型反复尝试。
token 消耗过快
症状:一次运行消耗远超预期。
修复:先在小范围试跑。检查 /model,考虑对简单阶段用更小的模型。停止运行不会丢失已完成的工作。
Date.now() 报错
症状:脚本执行时报 "Date.now is not available"。
修复:这是设计限制。通过 args 传入时间戳。用 index 值(而非随机数)来区分代理。
恢复后结果不同
症状:暂停后恢复,结果跟之前不一样。
修复:如果修改了脚本,被修改的 agent() 调用会重新执行。只有参数不变的调用才使用缓存。
动手练习
让 Claude 为你的项目生成一个 Workflow
- 在 Claude Code 中输入带
ultracode关键字的审查请求 - 选择 "View raw script" 查看生成的脚本
- 运行 Workflow,用
/workflows监控进度 - 运行完成后按
s保存为可复用的命令
ultracode: 审查 src/ 目录下所有文件的代码质量,从正确性、安全性、性能三个维度并行审查,每个发现经过 3 个独立验证者确认
参考答案
一个典型的审查 Workflow 运行过程
# 步骤 1:触发 Workflow
> ultracode: 审查 src/ 下所有文件,从正确性、安全性、性能
> 三个维度并行审查,每个发现经过独立验证
# 步骤 2:Claude 生成脚本,确认运行
Dynamic workflow requested for this turn · Alt+W to ignore
# 步骤 3:查看运行进度
/workflows
# 输出示例:
┌─ Review ────────── 3/3 agents ──── 45,230 tokens ──
│ review:bugs ✅ 12 findings
│ review:perf ✅ 8 findings
│ review:security ✅ 5 findings
├─ Verify ────────── 25/25 agents ─── 183,400 tokens ─
│ verify:auth.ts:42 2-1 ✓ survives
│ verify:api.ts:108 1-2 ✗ killed
│ ...
└─ Complete ─ 11 confirmed findings
# 步骤 4:保存成功运行
Press s → save as "code-review" → .claude/workflows/
# 下次直接调用:
/code-review
课程总回顾
十一章走完,从入门到大规模编排
到这里,你已经能
- 理解 Workflow 与 Subagents/Teams 的区别
- 读懂和编写 Workflow 脚本
- 使用 agent/parallel/pipeline 编排子代理
- 应用对抗性验证等质量模式提升结果可信度
- 保存和复用 Workflow 命令
- 管理运行、控制成本、排查问题
延伸阅读
官方文档
- A harness for every task: dynamic workflows in Claude Code — 官方介绍,含六种编排模式详解
- Orchestrate Teams of Claude Code Sessions — Agent Teams 对比
- Create Custom Subagents — 子代理定义
社区资源
- Claude Code Adds Dynamic Workflows for Parallel Agent Coordination — InfoQ 技术深度分析
- awesome-claude-code-workflows — 社区工作流集合
- shinpr/claude-code-workflows — 生产级工作流框架