【学习笔记】Claude Code 动态工作流(Dynamic Workflows)详解,并与 /goal 命令对比
本篇记录 Claude Code 的动态工作流(Dynamic Workflows),并把它与
/goal命令放在一起对比。两者都解决”让 Claude 持续干活、减少人盯着”这件事,但思路截然不同:动态工作流把编排逻辑写进一段可复用、可重跑的脚本,由 runtime 调度数十到上百个 subagent 并行执行;
/goal则是在当前会话里设置一个完成条件,让 Claude 一轮一轮地逼近目标,直到一个小模型判定条件满足。理解它们的分工,才能在合适的场景用合适的工具。
1. 一句话区分两者
先用最直观的方式建立一个心智模型:
| 动态工作流 | /goal | |
|---|---|---|
| 本质 | Claude 写的一段编排脚本,由 runtime 执行 | 当前会话里的一个”完成条件” |
| 谁决定下一步做什么 | 脚本(循环、分支都在代码里) | Claude 自己(每轮临场决定) |
| 并发规模 | 一次运行数十到上百个 subagent | 单 agent,一轮一轮串行推进 |
| 中间结果放哪 | 脚本变量里(不进主上下文) | Claude 的上下文窗口里 |
| 什么时候停 | 脚本执行完毕 | 一个独立的小模型判定条件已满足 |
| 可复用性 | 编排本身可保存为命令、可重跑 | 会话级,条件满足即清除 |
| 核心价值 | 把”计划”固化成代码,可并行 + 可对抗式自检 | 把”什么时候算做完”外包给一个廉价快速的评判模型 |
一句话总结:动态工作流把”怎么做”固化成脚本并并行放大,/goal 把”做没做完”交给一个独立评判者。 它们并不冲突,甚至可以组合使用。
2. 动态工作流是什么
2.1 核心定义
动态工作流(Dynamic Workflow)是一段编排 subagent 的 JavaScript 脚本。Claude 针对你描述的任务自己写出这段脚本,然后由一个 runtime 在后台执行,你的会话保持响应。
关键点拆解:
- Claude 写脚本,不是你写:你只需要描述任务,Claude 把循环、分支、并行 fan-out 都翻译成代码。
- 后台执行:脚本在独立于对话的环境里运行,中间结果留在脚本变量里,不占用 Claude 的上下文窗口——最终只有合并后的答案回到会话。
- 可重跑、可复用:每次运行都会把脚本写到会话目录下的文件里,你可以读取、diff、编辑后重新启动;满意了还能保存成自己的命令。
为什么这很重要?因为在大规模任务里,Claude 的上下文窗口是瓶颈。传统方式下无论是 subagent、skill 还是 agent team,编排者都是 Claude 本人——它逐轮决定下一步 spawn 什么、每个结果都落进上下文。一旦任务大起来,上下文先撑爆。动态工作流把”计划”从 Claude 脑子里搬进代码,Claude 的上下文只承载最终结论。
2.2 与 subagent / skill / agent team 的区别
官方给了一张很清晰的对比表,核心是”谁持有计划(who holds the plan)“:
| Subagents | Skills | Agent teams | Workflows | |
|---|---|---|---|---|
| 是什么 | Claude 派生出的 worker | Claude 遵循的指令 | 一个 lead agent 监督若干 peer 会话 | runtime 执行的脚本 |
| 谁决定下一步 | Claude,逐轮 | Claude,遵循 prompt | lead agent,逐轮 | 脚本 |
| 中间结果在哪 | Claude 上下文 | Claude 上下文 | 共享任务列表 | 脚本变量 |
| 可复用的是 | worker 定义 | 指令 | team 定义 | 编排本身 |
| 规模 | 每轮几个委派任务 | 同 subagent | 少量长期 peer | 数十到上百个 agent |
| 中断后 | 重启该轮 | 重启该轮 | teammate 继续跑 | 同会话内可恢复 |
可以看到,前三种方案的共同点是”Claude 是编排者”,结果都在上下文里;动态工作流是唯一一个把编排搬进代码、能横向扩展到上百 agent 的方案。
2.3 不只是”跑更多 agent”,还能做质量模式
把计划搬进代码还有一个被低估的好处:可以套用可复用的质量模式,而不只是无脑堆 agent 数量。典型的几种:
- 对抗式自检(adversarial verify):让独立 agent 互相挑刺、投票,多数通过才采纳,过滤掉”看着合理但其实错”的发现。
- 多角度起草 + 评审(judge panel):从几个独立角度各起草一版方案,平行打分,取最优并嫁接其他版本的亮点。
- 多模态扫荡(multi-modal sweep):多个 agent 各用一种检索角度(按容器 / 按内容 / 按实体 / 按时间),互不可见,覆盖单角度搜不全的长尾。
- 直到搜干为止(loop-until-dry):持续派 finder,直到连续若干轮没有新发现。
这些模式靠单轮对话是拼不出来的,必须由脚本来表达循环和聚合。
3. 怎么用动态工作流
⚠️ 关键区分:默认是”一次性”的,保存后才可反复调用
这是动态工作流最容易被误解的一点。你描述任务时,Claude 是为这次任务临时写一段脚本,跑完就结束——它不会自动变成以后能反复调用的命令。下次遇到类似任务,Claude 会重新写一个新脚本。
工作流其实分两层:
- 编排脚本:可临时现写,针对具体任务;落在本会话目录下,同会话内可重跑/恢复/编辑后重跑,但退出会话就没了。
- 命令:只有你手动保存(在
/workflows里按s,见 3.4)后,脚本才升级成一个/<名字>命令,未来任何会话都能调用、还能传args参数。一句话:未保存 = 一次性临时脚本;按
s保存 = 创建一次、永久可调用的命令。 别指望”用一次就自动存下来”。
3.1 三种触发方式
- 直接跑内置工作流:
/deep-research是内置示例,对一个问题多角度 fan-out 搜索、交叉核对来源、投票、产出带引用的报告。 - 在 prompt 里点名要一个工作流:用自己的话说”use a workflow / run a workflow”,或在 prompt 里包含关键字
ultracode,Claude 就会为该任务写一个工作流脚本而不是逐轮推进。 - 让 Claude 自动决定(ultracode 模式):执行
/effort ultracode,它把xhigh推理强度与自动工作流编排结合,此后会话里每个实质任务都可能触发工作流。
ultracode: audit every API endpoint under src/routes/ for missing auth checks小提示:
ultracode是会话级的,新开会话会重置;回到日常活儿用/effort high降档。它只在支持xhigh的模型上出现。如果误触发了关键字,在 macOS 上按Option+W(Windows/Linux 是Alt+W)可以取消这次高亮;要彻底关掉关键字触发,去/config关掉 Ultracode keyword trigger。
3.2 内置工作流:/deep-research
最快的上手路径就是直接跑 /deep-research:
/deep-research What changed in the Node.js permission model between v20 and v22?它会在后台多阶段工作,你的会话保持空闲,最后给你一份报告而不是一轮轮的对话记录。报告里每条结论都标注来源,交叉核对没通过的声明会被过滤掉。
3.3 审批与权限
启动一个运行前,Claude Code 会让你确认计划。CLI 里会展示规划的各阶段,选项包括:直接运行、本项目内对该工作流不再询问、先看原始脚本、取消。Ctrl+G 可以在编辑器里打开脚本,Tab 可以在运行前调整 prompt。
不同权限模式下,询问的时机不同:
| 权限模式 | 询问时机 |
|---|---|
| Default / accept edits | 每次都问(除非本项目对该工作流选了”不再问”) |
| Auto | 仅首次启动;任何 Yes 会记进用户设置,之后免问;ultracode 开启时完全跳过 |
Bypass permissions / claude -p / Agent SDK | 从不询问,直接启动 |
需要留意:权限模式只管”启动询问”这一层。工作流产出的 subagent 始终运行在 acceptEdits 模式、继承你的工具 allowlist,文件编辑自动放行。但不在 allowlist 里的 shell 命令、web fetch、MCP 工具,仍可能在运行中弹询问。所以长任务前,最好把 agent 需要的命令提前加进 allowlist。
3.4 保存为命令并传参
跑出一个满意的工作流后,可以把它保存成命令复用:/workflows → 选中该运行 → 按 s。保存位置(Tab 切换):
.claude/workflows/(项目级,跟仓库共享给所有 clone 的人)~/.claude/workflows/(用户级,全项目可用,仅自己可见)
保存后会以 /<名字> 形式出现在 / 补全里。同名时项目级优先。
保存的工作流还能通过 args 参数接收输入,脚本里以全局 args 读取,可以直接当数组/对象用,无需手动解析:
> Run /triage-issues on issues 1024, 1025, and 10303.5 观察运行:/workflows
工作流在后台跑,会话保持响应。任何时候执行 /workflows 可以列出运行中和已完成的运行,选中后进入进度视图:
| 按键 | 动作 |
|---|---|
↑ / ↓ | 选择阶段或 agent |
Enter 或 → | 钻进阶段、再钻进 agent 看它的 prompt、工具调用和结果 |
Esc | 退回一层 |
p | 暂停 / 恢复运行 |
x | 停掉选中的 agent,或(焦点在运行上时)停掉整个工作流 |
r | 重启选中的运行中 agent |
s | 把该运行的脚本保存为命令 |
4. 工作流如何运行
4.1 脚本即真相
每次运行都会把脚本写到 ~/.claude/projects/ 下你当前会话目录里的一个文件。Claude 启动时会拿到这个路径,所以你可以:
- 打开它,看 Claude 写了什么编排逻辑;
- 和上次运行的脚本 diff;
- 编辑后让 Claude 从编辑版重新启动。
runtime 会持续追踪每个 agent 的结果,这也是”同会话内可恢复”的基础。
4.2 运行时的约束
| 约束 | 原因 |
|---|---|
| 运行中不接受用户输入 | 只有 agent 的权限询问能暂停运行;需要阶段间人工签字的,把每个阶段拆成独立工作流 |
| 工作流脚本本身不能直接访问文件系统或 shell | agent 来读写文件、跑命令,脚本只负责协调 agent |
| 最多 16 个并发 agent(CPU 核少的机器更少) | 限制本地资源占用 |
| 单次运行总计最多 1,000 个 agent | 防止失控循环 |
4.3 恢复与成本
- 恢复:停止后可恢复——已完成的 agent 返回缓存结果,其余实跑。恢复仅限同一 Claude Code 会话;退出再开会从头来。
- 成本:一次运行可能比在对话里逐轮做同一件事显著更费 token,因为它会 spawn 很多 agent,计入你计划的用量和速率限制。控制成本的三招:
- 先小切片试跑——一个目录而非整个仓库、一个窄问题而非宽问题,用
/workflows看每个 agent 的 token 用量,随时停而不丢已完成的工作。 - 大跑前确认
/model——如果你平时会切小模型做日常活儿,开跑前确认模型。 - 让脚本给不需要最强模型的阶段路由小模型——描述任务时直接说。
- 先小切片试跑——一个目录而非整个仓库、一个窄问题而非宽问题,用
4.4 关闭工作流
三档开关:/config 里 toggle “Dynamic workflows”、在 ~/.claude/settings.json 设 "disableWorkflows": true、或设环境变量 CLAUDE_CODE_DISABLE_WORKFLOWS=1。组织级关闭则在 managed settings 里设 disableWorkflows,或用 Claude Code 管理后台的 toggle。关闭后,内置工作流命令不可用、ultracode 关键字失效、/effort 菜单移除 ultracode 选项。
5. /goal 是什么
5.1 核心机制
/goal设置一个完成条件,Claude 在没有你逐轮提示的情况下持续工作。每轮结束后,一个小型快速模型检查条件是否成立;不成立,Claude 就开下一轮而不是交还控制权;成立,目标自动清除。
它本质上是一个会话级的、基于 prompt 的 Stop hook 封装。每轮 Claude 结束时,把条件和当前对话发给你配置的小快模型(默认 Haiku),它返回 yes/no 加一句理由:
- no → Claude 继续干活,理由作为下一轮的指引;
- yes → 清除目标,在 transcript 里记一条”已达成”。
要求:Claude Code v2.1.139+,且必须在已接受 trust dialog 的 workspace 里运行(因为 evaluator 属于 hooks 系统)。disableAllHooks 或 managed allowManagedHooksOnly 开启时不可用。
5.2 适合什么样的任务
/goal 适合有可验证终态的实质工作:
- 把某个模块迁移到新 API,直到所有调用点都能编译、测试通过;
- 按设计文档实现功能,直到所有验收标准成立;
- 把大文件拆成聚焦的小模块,直到每个都低于体积预算;
- 清理一个带标签的 issue backlog,直到队列空了。
注意 evaluator 不独立跑命令、不读文件,它只能依据 Claude 自己在对话里呈现的内容来判断。所以条件要写成”Claude 的输出能证明的东西”。
5.3 写好一个条件
一个好条件通常包含三部分:
- 一个可测量的终态:测试结果、构建退出码、文件数量、空队列;
- 一个明确的检查方式:比如”
npm test退出码为 0”或”git status干净”; - 不能破坏的约束:比如”不修改任何其他测试文件”。
条件最多 4,000 字符。想约束运行时长,可以在条件里加一条 turn/时间子句,如 or stop after 20 turns。
5.4 用法速查
/goal all tests in test/auth pass and the lint step is clean # 设置(会立即开始一轮)
/goal # 不带参数 = 查看状态(条件、已运行时长、轮数、token、最新理由)
/goal clear # 提前清除补充:
stop / off / reset / none / cancel都是clear的别名;/clear新开会话也会清掉。- 会话结束时仍 active 的目标,用
--resume/--continue恢复会话时会带回来(但轮数、计时、token 基线重置);已达成或已清除的不会恢复。 - 非交互模式可用:
claude -p "/goal CHANGELOG.md has an entry for every PR merged this week"会一次跑到完成,Ctrl+C中断。 - 与 auto mode 互补:auto mode 在单轮内自动批准工具调用、Claude 自行判断做完与否;
/goal加的是一个独立的评判者,在每轮之后检查你的条件。auto 去 per-tool 的询问,/goal去 per-turn 的询问。
6. 全面对比
把两者放在一起,从七个维度对照:
6.1 解决的问题
- 动态工作流:解决”任务太大、单会话编排不过来 / 上下文装不下”——把编排固化成脚本,横向并行放大。
/goal:解决”任务有明确终点,但我不想逐轮催 Claude”——把”做没做完”外包给独立评判模型。
6.2 并行 vs 串行
- 动态工作流:并行,一次运行可调度数十到上百个 subagent(受 16 并发上限节流)。
/goal:串行,单 agent 一轮一轮推进。
6.3 上下文消耗
- 动态工作流:中间结果留脚本变量,只把最终答案回主上下文,省主上下文。
/goal:每轮结果都在主上下文里累积,长任务下上下文压力大。
6.4 可复用 / 可重跑
- 动态工作流:编排可保存为命令、可 diff、可编辑、可重跑、可恢复(同会话)。
/goal:会话级条件,满足即清除,不可跨会话复用(恢复也只带回 active 条件,统计重置)。
6.5 质量保障方式
- 动态工作流:脚本可表达对抗式自检、judge panel、loop-until-dry 等可复用质量模式——结构性更强。
/goal:靠 evaluator 判条件成立与否,是终态门禁,不做过程性交叉验证。
6.6 成本结构
- 动态工作流:贵——很多 agent,token 消耗可能显著高于对话推进;但每个阶段可路由小模型控本。
/goal:相对克制——主轮按需走,evaluator 跑小快模型、开销通常可忽略。
6.7 典型场景
| 场景 | 推荐 |
|---|---|
| 全仓库 bug 扫荡 / 安全审计 | 动态工作流(多角度并行 + 对抗式自检) |
| 500 文件 API 迁移 | 动态工作流(pipeline 逐文件迁移 + 验证) |
| 多来源交叉核对的研究报告 | 动态工作流(/deep-research) |
| 把一个模块迁到新 API 直到测试全绿 | /goal |
| 按设计文档实现直到验收标准成立 | /goal |
| 清空一个 issue backlog | /goal |
| 一个复杂决策,想从多角度起草再择优 | 动态工作流(judge panel) |
7. 它们可以组合吗
可以,而且组合起来很有用。一个典型模式是:用 /goal 持续推进,让其中的某些阶段由工作流完成。
比如”直到整个仓库的所有 API 端点都通过 auth 审计并修复”这种大目标:
- 工作流负责单次扫描/修复这种适合并行的活儿;
/goal负责整体终态门禁——每轮(可能含一次工作流运行)结束后,由独立 evaluator 判定”是否所有端点都已审计且无缺失”。
要注意两者的运行模型不同:工作流是”跑完脚本即止”,/goal 是”条件满足即止”。组合时,工作流作为推进手段,/goal 作为终止判据,分工清晰。
8. 选型决策清单
当你下次面对一个”想让 Claude 多干一会儿”的任务,按这几个问题快速分流:
- 任务能否拆成大量互相独立的子任务? 能 → 动态工作流的并行 fan-out 最划算。
- 子任务的结果需要互相交叉验证才可信吗? 需要 → 动态工作流(对抗式自检/judge panel)。
- 任务规模大到单会话上下文装不下中间过程吗? 是 → 动态工作流(中间结果不进主上下文)。
- 任务的终点是一个可由对话输出证明的客观条件吗?(测试通过、构建退出码、队列空)是 →
/goal。 - 你只是不想逐轮催,但任务本身是串行的? 是 →
/goal。 - 你希望这套流程以后能反复重跑、可版本化? 是 → 动态工作流(保存为命令)。
一句话收尾:要”并行放大 + 固化流程 + 交叉自检”,用动态工作流;要”持续推进 + 客观终态门禁”,用 `/goal”;两者还能组合。