本教程聚焦 Claude Code 于 2026 年 5 月正式落地的动态工作流(Dynamic Workflows)——一项让 Claude 自己编写 JavaScript 编排脚本、把成百上千个子代理(subagent)调度成一整条流水线的自动化能力。你将学到:动态工作流与子代理、Skill、Agent Teams 的本质区别;如何用 ultracode 关键词触发编排;如何读懂、保存、参数化、续跑 Claude 写出的脚本;以及成本、权限与无人值守(claude -p)下的实战控制。适合已经熟悉 -p 模式与基础子代理、希望把"人盯单次对话"升级为"代码化可复跑大规模编排"的中高级用户。
.claude/workflows/ 的行为需 v2.1.178+)。/config 的 Dynamic workflows 行手动开启。claude;若要在脚本里复跑,建议同时具备 git 与一个待处理的真实代码仓库。子代理(Subagents)、Skill、Agent Teams、Workflows 都能完成多步骤任务,区别在于"谁掌握计划"。
在子代理、Skill、Agent Teams 模式下,Claude 自己当指挥:它逐轮决定下一步派谁、分什么活,而每一步的中间结果都回到 Claude 的上下文窗口里。规模一大,上下文就会被日志挤爆,编排也变得不可复现。
动态工作流把计划搬进代码。Claude 针对你描述的任务,写出一个 JavaScript 编排脚本;一个独立运行时在后台执行它,会话保持响应。循环、分支、中间结果都存在脚本变量里,Claude 的上下文只保留最终答案。脚本可读、可改、可重新运行——这就是"脚本取代上下文窗口"的核心思想。
| 维度 | 子代理 Subagents | Skill | Agent Teams | 动态工作流 Workflows |
|---|---|---|---|---|
| 本质 | Claude 派生的工作者 | Claude 遵循的指令 | 主代理监督若干同伴会话 | 运行时执行的脚本 |
| 谁决定下一步 | Claude,逐轮 | Claude,按提示 | 主代理,逐轮 | 脚本 |
| 中间结果在哪 | Claude 上下文 | Claude 上下文 | 共享任务列表 | 脚本变量 |
| 可复用的是什么 | 工作者定义 | 指令本身 | 团队定义 | 整套编排 |
| 规模 | 单轮几次委派 | 同子代理 | 少量长跑同伴 | 数十到数百个代理 |
| 中断后 | 重启该轮 | 重启该轮 | 同伴继续跑 | 同会话内可续跑 |
另一层价值在于可复用的质量模式:脚本可以让多个独立代理互相"对抗式审查(adversarial review)"彼此的发现,或从多个独立角度起草方案再权衡,从而得到比单趟遍历更可信的结果——这不仅是"跑更多代理",而是"跑得更稳"。
Claude 写出的脚本并非任意 JS,而是运行在受控沙箱里、只能调用一组固定原语的程序。掌握这组原语,你就能读懂并微调 Claude 的产出:
agent(prompt, {label, phase, schema, model, isolation, agentType}):派生一个子代理,返回它的最终文本;带 schema 时返回结构化对象(强制走结构化输出工具,免解析)。parallel(thunks):屏障式并发,等所有任务返回;某任务抛错会落成 null,不会拖垮整批。pipeline(items, stage1, stage2, ...):流水线,每个 item 独立穿过所有阶段,阶段间无屏障,墙钟等于最慢的单条链路——这是大规模编排的默认骨架。phase(title):声明一个进度阶段,配合 /workflows 视图分组展示。log(message):向用户输出一行进度旁白。args:保存的工作流可接收的结构化入参全局变量。budget:当前轮次的 token 目标,用于按预算动态扩缩 finder 数量。注意几条硬约束(脚本里无法使用):Date.now()、Math.random()、无参 new Date() 都会抛错——它们会破坏"可续跑"的确定性。时间戳需通过 args 传入,随机性靠"按 index 变化 prompt"来实现。
/deep-research最快体验动态工作流的方式是跑内置命令 /deep-research,它针对一个问题在多个角度扇出网络检索、抓取并交叉校验来源、对每条论断投票,最后产出带引用的报告。
/deep-research Node.js v20 到 v22 的权限模型发生了哪些变化?
预期行为:
Yes 后,运行在后台启动,你的会话保持响应。↓ 聚焦、Enter 展开,或运行 /workflows 用方向键选中该运行、Enter 进入进度视图。进入 /workflows 后,视图列出每个阶段的代理数、token 总量、耗时。底部按键说明:
| 按键 | 动作 |
|---|---|
↑ / ↓ |
选择阶段或代理 |
Enter / → |
钻入阶段,再钻入单个代理查看其 prompt、最近工具调用与结果 |
Esc |
返回上一层 |
j / k |
代理详情溢出时滚动 |
p |
暂停 / 恢复运行 |
x |
停止选中代理,或(焦点在整条运行时)停止整条工作流 |
r |
重启某个运行中的代理 |
s |
把本次运行的脚本保存为命令 |
常见问题:报告迟迟不出——多半是某个阶段的代理在等不在白名单里的工具确认。解决:开跑前把代理需要的命令加进工具白名单(见第六节)。
两种触发方式:
方式 A:单次任务里带 ultracode 关键词(或自然语言"用工作流来做"/"run a workflow")。关键词会被高亮,Claude 据此为该任务写脚本而非逐轮推进:
ultracode: 审计 src/routes/ 下每个 API 端点是否缺少鉴权检查
若误触,macOS 按 Option+W、Windows/Linux 按 Alt+W 取消本次高亮;要彻底关闭关键词触发,在 /config 关掉 Ultracode keyword trigger。
方式 B:整会话开启 /effort ultracode——它把 xhigh 推理强度与自动工作流编排合二为一。开启后 Claude 对每个实质性任务都会规划工作流;单个请求甚至可能变成"理解代码 → 实施改动 → 验证"一连串多条工作流。注意:ultracode 仅当前会话有效,重开会话即重置,且回到常规工作要 /effort high 降档。
批准计划:CLI 会在运行前展示规划的阶段,给出选项:
Yes, run it:开始运行;Yes, and don't ask again for <name> in <path>:开始,且本项目该工作流今后不再询问;View raw script:先读脚本;No:取消;Ctrl+G 在编辑器打开脚本;Tab 在运行前调整 prompt。是否看到此提示取决于权限模式(见下表)。值得强调:无论你会话处于什么模式,工作流派生的子代理始终以 acceptEdits 模式运行并继承你的工具白名单,文件编辑自动放行;但不在白名单里的 shell、网络抓取、MCP 工具仍可能在运行中弹确认——长跑前先把它们加进白名单。
| 权限模式 | 何时弹出批准 |
|---|---|
| Default / accept edits | 每次运行(除非已选"本项目不再询问") |
| Auto | 仅首次启动;任一 Yes 会记入用户设置,后续自动启动;ultracode 下直接跳过 |
Bypass permissions / claude -p / Agent SDK |
从不,立即启动 |
每次运行都会把脚本写到会话目录下的 ~/.claude/projects/<session>/ 里。Claude 启动时会拿到该路径——你可以直接要求它"把刚才写的脚本路径给我",然后打开阅读、与上次运行的脚本 diff、甚至编辑后让 Claude 用修改版重跑。
下面是一段典型编排脚本的结构(以"路由鉴权审计"为例,省略 schema 细节)。它体现官方推荐的默认流水线 + 对抗式校验模式:先按维度找问题,每个发现立即独立校验,校验通过的才进入综合。
export const meta = {
name: 'auth-audit',
description: '审计 src/routes 下缺失鉴权的端点',
phases: [{ title: '扫描' }, { title: '校验' }],
};
const ROUTES = [
'src/routes/users.ts',
'src/routes/orders.ts',
'src/routes/admin.ts',
// ...args 传入或 glob 得到的全部路由文件
];
phase('扫描');
// 流水线:每个文件独立穿过"扫描 → 校验",阶段间无屏障
const results = await pipeline(
ROUTES,
(file) => agent(
`读取 ${file},列出所有未做鉴权检查的端点及缺失的中间件`,
{ label: `scan:${file}`, phase: '扫描', schema: FINDINGS_SCHEMA }
),
(scan, file) => parallel((scan?.findings || []).map((f) => () =>
agent(
`对抗式核验:${f.title} 真的缺鉴权吗?默认怀疑,给出依据`,
{ label: `verify:${file}`, phase: '校验', schema: VERDICT_SCHEMA }
).then((v) => ({ ...f, file, verdict: v }))
))
);
// 只保留校验通过的真实问题
const confirmed = results
.flat().filter(Boolean)
.filter((f) => f.verdict?.isReal);
log(`确认 ${confirmed.length} 处鉴权缺失`);
return { confirmed };
关键读法:
meta 必须是纯字面量,phases 的标题与 phase() 调用一一对应,否则进度视图对不上。pipeline 而非"先 parallel 全扫、再 parallel 全校验"——后者会引入屏障,快文件被慢文件拖着白白等待。schema 把非结构化文本变成可校验对象,下游 .filter() 直接可用,免去正则解析。budget 可用于按 token 预算扩缩 finder:while (budget.total && budget.remaining() > 50_000) { ... },没设目标时 remaining() 为 Infinity,所以务必先判 budget.total。一条工作流跑出满意结果后,按 s 保存。保存对话框里 Tab 在两个位置间切换:
.claude/workflows/(项目级):随仓库克隆共享给团队;~/.claude/workflows/(用户级):所有项目可用,仅你可见。保存后它就成了 /<name> 命令,出现在 / 自动补全里,与内置的 /deep-research 并列。v2.1.178 起,保存到项目位置会写入从当前工作目录到仓库根之间已存在的最近一个 .claude/workflows/(适合 monorepo 按包归位);同名时项目级优先于用户级。
参数化靠 args 全局变量。保存的工作流在运行时可接收结构化入参:
> 用 /triage-issues 处理 issue 1024、1025、1030
Claude 把列表作为结构化数据传给脚本,args 在脚本内是数组,可直接 args.map(...),不必先解析字符串。省略 args 时它为 undefined。
注意:
args必须是真 JSON 值而非字符串化的 JSON,否则args.filter/args.map会抛错。
工作流全程在后台,会话始终可交互。/workflows 随时列出运行中与已完成的运行。
续跑是动态工作流区别于子代理的关键能力:停掉一条运行后,已完成的代理返回缓存结果,剩余部分实时重跑。从 /workflows 选中运行按 p 即可,或让 Claude 用同一脚本重启。
限制:续跑仅在同一 Claude Code 会话内有效。退出 Claude Code 时若仍有工作流在跑,下次会话会全新启动该工作流——这是设计取舍,保证确定性。
一条工作流派生大量代理,单次运行的 token 消耗显著高于对话式推进,且计入套餐用量与速率限制。控制手段:
/workflows 实时显示每个代理的 token,随时停而不丢已完成工作。/model;或在描述任务时直接要求"扫描阶段用更小的模型"。动态工作流在 CLI、桌面端、IDE 扩展、非交互的 claude -p 以及 Agent SDK 上均可用,禁用设置在所有界面通用。
无人值守场景(CI/管道)的两条要点:
claude -p 与 Agent SDK 没有人可被提示,工具调用按你配置的权限规则直接执行,工作流立即启动不询问。务必在开跑前把代理需要的命令写进白名单。acceptEdits + 继承白名单运行——这是默认安全位,意味着文件改动会自动发生,需配合白名单收敛"能跑什么命令、能访问哪些 MCP 工具"。关闭工作流(任选其一,跨会话持久):
/config 里关掉 Dynamic workflows;~/.claude/settings.json 设 "disableWorkflows": true;CLAUDE_CODE_DISABLE_WORKFLOWS=1(启动时读取,放哪都生效);"disableWorkflows": true,或用 Claude Code 管理后台开关。关闭后,内置工作流命令不可用、ultracode 关键词不再触发、/effort 菜单移除 ultracode 项。
目标:把"路由鉴权审计"做成团队可一键复跑、可按 issue 列表参数化的命令。
1. 触发并迭代。在仓库根目录:
ultraccode: 审计 src/routes/ 下每个端点的鉴权缺口,
对每个候选发现用独立代理对抗式核验,只保留核验通过的真实问题,
按文件聚合输出 Markdown 报告
2. 审阅脚本。批准前选 View raw script,确认它的扇出对象是路由文件全集、校验阶段默认怀疑(isReal 默认 false)、综合阶段去重。
3. 小切片试跑。先临时把脚本里 ROUTES 缩成两个文件,确认 findings → verify → filter(isReal) 链路闭合、token 可控,再恢复全集。
4. 保存为命令。运行 /workflows,选中运行,按 s,Tab 选 .claude/workflows/,命名为 auth-audit,回车。此后:
/auth-audit # 审计全部路由
/auth-audit routes=["src/routes/admin.ts"] # 带结构化 args 只审指定文件
5. 接入 CI(无人值守)。在流水线脚本里:
claude -p "/auth-audit" --output-format json > audit.json
# audit.json 即脚本 return 的结构化结果,可直接被下游解析
claude -p 下工作流立即启动、无人工确认;--output-format json 让脚本 return 的对象原样落盘,供 CI 判定"是否存在 confirmed 缺口 → 是否阻断合并"。
6. 续跑。若本地长跑被中断,同会话内 /workflows → 选中 → p 续跑,已完成文件走缓存;CI 里则因每次新会话只能全新重跑,故务必保证脚本幂等(校验阶段对同一发现结论一致)。
flowchart TD
A[prompt 带 ultracode 关键词] --> B{权限模式判断}
B -->|Default/acceptEdits| C[弹批准: Yes/不再问/看脚本/No]
B -->|Auto| D[首次确认后自动启动]
B -->|Bypass / claude -p / SDK| E[立即启动 无确认]
C --> F[Claude 写 JS 编排脚本]
D --> F
E --> F
F --> G[脚本写入 ~/.claude/projects/会话/]
G --> H[后台运行时执行]
H --> I[16并发/1000上限内扇出子代理]
I --> J[中间结果存脚本变量 不进上下文]
J --> K{暂停?}
K -->|是| L[已完成代理缓存 剩余实时重跑]
K -->|否| M[综合阶段: 去重/对抗校验]
L --> M
M --> N[最终答案返回会话]
N --> O{满意?}
O -->|是, 按 s| P[保存为 .claude/workflows/ 命令]
O -->|否| Q[编辑脚本 让 Claude 用修改版重跑]
Q --> H
-p 模式与子代理章节之后。/deep-research 动手约 45 分钟;自定义工作流的编写、保存、参数化与 CI 接入约 90 分钟;总计约 2.5–3 课时。/config 与 /model 基本操作、claude -p 非交互模式。.claude/workflows/ 下、带 args 参数、可被 CI 用 --output-format json 调用的团队级工作流命令。claude -p 与 CI 接入的工程实践。claude -p 与 Agent SDK 非交互运行机制,含 --output-format 与权限规则。continue/resume/fork 会话管理,解释工作流"同会话续跑"的会话边界。[!tip] 51学通信知识星球 星主:爱卫生(微信:gprshome201101)——公众号「51学通信」创办者,19 年通信行业运维与讲师经验,著有《GPRS网络信令实例详解》《EPC原理与实践》《5G核心网原理与实践》三本纸质书(各大电商平台有售)。 星球定位:深耕 5G 核心网、IMS、NFV/AI、云原生等 ICT 领域,主打运维岗位与信令分析。 当前规模:5200 篇主题 / 990 个回答,198 元/年。 加入福利:加入星球后请加爱卫生微信,拉您进知识星球年度陪伴与答疑群——不限量回复您的各种问题,另有群内分享。 AI 加持:51学通信知识星球已作为 skill 接入 WorkBuddy,使用 deepseek-4-flash 在海量星球帖子中精准找贴、找视频、找 FAQ 和案例,做总结、找文档和 PPT 等场景全覆盖。
