每个任务都需要一个 Harness:Claude Code 动态工作流全解析
Thariq Shihipar 和 Sid Bidasaria 揭示了 Claude Code 的下一层编排抽象——把计划从 Claude 的上下文窗口搬到 JavaScript 脚本里,用 runtime 驱动数十到数百个 sub-agent 的并发协调。这不是多 Agent,这是 Agent 的操作系统。
Part 1: 杂志长文
工程级解读从 "Claude 能写代码" 到 "Claude 能指挥一个 Agent 军团"——理解动态工作流为什么是 Claude Code 迄今最重要的编排升级。
这篇文章回答的问题:Claude Code 的动态工作流(Dynamic Workflow)到底在运行时做了什么?它和 sub-agent / skill / agent team 有什么本质区别?我什么时候该用它?
这篇文章应该回答但没回答的问题:一个 workflow 脚本的实际代码长什么样?runtime 和 Claude 主会话之间的进程隔离边界在哪?当 workflow 内部 agent 崩溃时,已有阶段的缓存结果如何安全地传递给恢复后的 agent?这些在原文和官方文档中都语焉不详,我在下面的架构拆解中会基于文档推断并标注。
从 Harness 到 Workflow:一个概念的进化
2025 年底,Anthropic 工程博客发表了 Effective Harnesses for Long-Running Agents,提出了一个核心洞察:当 Agent 执行长任务时,你需要给它一个 harness(安全带/执行框架)——一个围绕模型构建的外部编排结构,负责分解任务、管理上下文重置、在 session 之间传递状态。
那个时代的 harness 是手写的:initializer agent 做任务分解,coding agent 一个 feature 一个 feature 地实现,session 之间通过结构化的 artifact 文件做 handoff。它有效,但是是静态的——你需要提前设计好每一个阶段。
2026 年 6 月,Thariq Shihipar 和 Sid Bidasaria(Anthropic Claude Code 团队)发表了 A Harness for Every Task: Dynamic Workflows in Claude Code。这篇文章揭示了一个质变:harness 不再是你手写的,而是 Claude 自己为每个任务动态生成的。
Workflows allow you to dynamically create execution frameworks that enable Claude to natively solve problems within Claude Code.
工作流允许你动态创建执行框架,让 Claude 在 Claude Code 内原生地解决问题。
它到底在做什么?一句话版本
动态工作流 = Claude 根据你的任务描述,实时生成一个 JavaScript 脚本 → 一个独立的 runtime 在后台执行这个脚本 → 脚本通过特殊函数生成和协调数十到数百个 sub-agent → 你的主会话保持响应,只接收最终结果。
核心转换是:计划(plan)从 Claude 的上下文窗口搬到了代码里。在 sub-agent 模式下,Claude 每个 turn 都要决定"接下来做什么",所有中间结果都塞进 context window。在 workflow 模式下,脚本持有循环、分支和中间结果,Claude 的上下文只装最终答案。
这意味着几件事:
- 规模上限跳了一个数量级:sub-agent 模式下你能跑几个 delegated task;workflow 可以跑几十到上百个 agent。
- 编排可复现:一个成功的 workflow 脚本可以保存为命令,下次同样的任务一键运行。
- 质量模式可编程:你可以让独立的 agent 之间互相 adversarial review,或从多个角度起草方案再投票选最优。
它不做什么
原文和文档都很诚实地指出了限制:动态工作流 消耗更多 token。一个 workflow run 的成本可能是单次对话的 10-50 倍。它也不支持运行中间的用户输入——你不能在阶段之间插入人工审批,如果你需要审批,就得把每个阶段作为独立的 workflow 来跑。
另外,workflow 的 sub-agent 运行在 acceptEdits 模式(自动接受文件编辑),但 shell 命令和 web 请求仍然遵循你的 allowlist 配置。长任务跑一半弹权限确认,是真实会发生的体验问题。
示例 Prompts:你能拿它干什么
原文给了一组极具想象力的示例 prompt,展示了 workflow 的边界:
间歇性 Bug 猎杀
"这个测试大约每 50 次运行失败一次。用 workflow 复现它,提出假设,在不同的 worktree 里做对抗性测试。/goal 在一个假设被验证之前不要停。"
规则自动发现
"用 workflow 审查我最近 50 个 session,识别我反复做的纠正,把这些重复问题转化为 CLAUDE.md 规则。"
多角度决策
"让不同的 agent 分别从投资者、客户、竞争对手的视角分析我的商业计划。"
注意这些例子中的共同模式:它们都是"单次对话无法有效协调的规模"。这就是 workflow 的甜区——不是替代 sub-agent,而是当 sub-agent 的编排复杂度超出 Claude 单个 turn 的决策能力时,把编排本身代码化。
从 Harness 到 Workflow 的技术跃迁
文章的后半部分(原文截断处)解释了 workflow 的技术机制。结合官方文档,我可以重建完整的运行时模型:
动态工作流执行一个 JavaScript 文件,这个文件包含若干特殊函数用于生成和协调 sub-agent。脚本还包含标准 JavaScript 函数如 JSON.parse()、数组操作等,用于处理中间结果。
Runtime 在一个隔离环境中执行脚本,与你的对话分离。中间结果留在脚本变量中,不进入 Claude 的 context。每次 run 的脚本会写入 ~/.claude/projects/ 下的会话目录——你可以读取、diff、编辑这个脚本,甚至要求 Claude 从编辑后的版本重新启动。
A workflow moves the plan into code. [...] The script holds the loop, the branching, and the intermediate results itself, so Claude's context holds only the final answer.
工作流把计划搬进了代码。脚本持有循环、分支和中间结果,所以 Claude 的上下文只装最终答案。
Part 2: 架构拆解
运行时模型理解动态工作流的关键不是"它是什么",而是"它实际运行在哪里、调用链路是什么、谁是进程内的、谁是跨进程的"。
运行时拓扑
(生成 JS 脚本)
(隔离进程)
(并发 ≤ 16)
关键部件拆解
| 部件 | 运行位置 | 职责 | 数据流向 |
|---|---|---|---|
| Claude 主会话 | Claude Code 主进程 | 接收 prompt → 生成 JS 脚本 → 启动 runtime → 等待结果 | Prompt in → Script out → Final result in |
| Workflow Runtime | 独立隔离进程 | 执行 JS 脚本,管理 phase 间顺序屏障和 phase 内并发 | 脚本变量存中间结果;不进入主会话 context |
| Workflow Script (.js) | 写入 ~/.claude/projects/ | 包含 phase 定义、agent 生成函数、分支逻辑、中间结果处理 | 可被用户读取/diff/编辑 |
| Sub-agent | Runtime 内的独立 Claude 会话 | 执行单个子任务(搜索、分析、编码、审查等) | 结果 → 脚本变量 → 下一个 phase |
| Phase(阶段) | Runtime 内的概念单位 | 一组可并发的 agent;阶段间是顺序屏障 | 阶段间:全完成才下一步;阶段内:并发执行 |
阶段屏障语义(IMPORTANT)
Workflow 的并发模型是 阶段间顺序屏障 + 阶段内并发:
- Phase 之间:必须等当前 phase 的所有 agent 完成后,才进入下一个 phase。这是一个 barrier(屏障)语义——类似分布式系统中的 MPI barrier。
- Phase 内部:同一 phase 的 agent 并发执行,最多 16 个同时运行。
- 总上限:每次 run 最多 1,000 个 agent。
这意味着如果你在 phase 1 派了 10 个 agent 做搜索,phase 2 派了 5 个 agent 做交叉验证,执行顺序是:10 个搜索 agent 全部完成 → 5 个验证 agent 开始。中间结果通过脚本变量传递。
Workflow Script 的内部结构
脚本包含什么
- Phase 定义:脚本声明多个阶段,每个阶段指定 agent 数量和任务
- Agent 生成函数:特殊函数(非标准 JS)用于创建 sub-agent 并传入 prompt
- 结果收集:标准 JS(数组操作、JSON 处理)处理中间结果
- 分支/循环:根据中间结果决定下一步做什么
- args 参数:全局变量,接收用户在命令行传入的参数
脚本不能做什么
- 不能直接访问文件系统或 shell:只有 agent 才能读写文件和执行命令
- 不能接收中间用户输入:run 开始后无人值守
- 不能超过 16 个并发 agent:受 CPU 核心数限制
- 不能超过 1,000 个 agent 总量:防止失控循环
与 Sub-agent / Skill / Agent Team 的本质区别
| 维度 | Sub-agents | Skills | Agent Teams | Workflows |
|---|---|---|---|---|
| 谁决定下一步 | Claude,逐 turn | Claude,遵循 prompt | Lead agent,逐 turn | 脚本(代码) |
| 中间结果存在哪 | Claude 的 context window | Claude 的 context window | 共享 task list | 脚本变量(不占 context) |
| 可复现性 | Worker 定义可复现 | 指令可复现 | Team 定义可复现 | 整个编排可复现 |
| 规模 | 每 turn 几个 | 同 sub-agent | 几个长期运行的 peer | 几十到上百个 agent |
| 中断恢复 | 重启整个 turn | 重启整个 turn | Teammate 继续运行 | 同一 session 内可恢复 |
触发方式:三种进入 Workflow 的路径
1. Prompt 内含关键词
在 prompt 中包含 ultracode 或自然语言 "use a workflow"。Claude 写一个 workflow 脚本然后执行。单次任务用这个。
2. /effort ultracode
设置 session 级别为 ultracode。Claude 为每个有实质性的任务自动规划 workflow。每个请求都可能触发多个 workflow(理解代码 → 修改 → 验证)。
3. 运行已保存的命令
之前保存的 workflow 变成 /command,可重复运行。内置的 /deep-research 就是一个 bundled workflow。
保存与复用
一个成功的 workflow run 可以通过 /workflows 界面按 s 保存为命令。保存位置有两个:
项目级(.claude/workflows/)
- 随 repo 一起提交
- 团队共享
- 适合:code review、发布检查、迁移脚本
个人级(~/.claude/workflows/)
- 所有项目可用
- 仅自己可见
- 适合:研究、分析、个人习惯
传入参数通过 args 全局变量。脚本可以直接调用数组和对象方法,无需手动解析。
Part 3: 手搓对比
手搓版 vs 官方版在 Workflow 出现之前,人们怎么手动做这件事?官方工具在哪些工程细节上做了产品化?
| 维度 | 手搓版(sub-agent + skill + hook) | 官方 Workflow |
|---|---|---|
| 编排载体 | CLAUDE.md 指令 + skill prompt + shell hook | JavaScript 脚本,Claude 动态生成 |
| 中间结果存储 | 写入临时文件 → 下一个 agent 读取 | 脚本变量,runtime 自动管理 |
| 并发控制 | 手动管理,无上限保证 | 最多 16 并发,受 CPU 限制自动调整 |
| 阶段间协调 | 依赖 Claude 的 turn-by-turn 判断 | 代码化的屏障语义,确定性执行 |
| 可复现性 | 低——同样的 prompt 不一定产生同样的编排 | 高——脚本可保存、diff、编辑、重跑 |
| 上下文压力 | 高——所有中间结果进入主 context window | 低——中间结果留在 runtime,主会话只收最终结果 |
| 暂停/恢复 | 不支持——中断即丢失 | 支持——已完成的 agent 缓存结果,恢复后只重跑未完成部分 |
| 可观测性 | 靠 Claude 的 turn-by-turn 输出 | /workflows 界面:phase 级进度、token 用量、agent 详情 |
| 成本控制 | 难以预估 | 每阶段显示 token 用量,可随时停止不丢已完成工作 |
| 学习曲线 | 需要深入理解 prompt 工程和 agent 编排 | 自然语言触发,Claude 自动生成脚本 |
Part 4: 选型决策框架
什么时候用什么不是所有任务都需要 workflow。用一个决策表来决定。
| 场景 | 推荐方案 | 为什么 |
|---|---|---|
| 改一个 bug / 写一个小功能 | 直接对话 或 sub-agent | 单 agent 足够,不需要编排 |
| 代码审查、发布检查 | Skill 或 sub-agent | 流程固定、步骤少,skill prompt 就够 |
| 重构涉及 10+ 文件 | Workflow(ultracode 关键词) | 多文件并发修改 + 交叉验证,需要编排 |
| 全仓库 bug 扫描 | Workflow | 需要大量 agent 并发搜索 + 结果汇总 |
| 500 文件迁移 | Workflow(保存为命令) | 可重复、可恢复、大规模并发 |
| 深度研究问题 | Workflow(/deep-research) | 多角度搜索 + 交叉验证 + 投票过滤 |
| 团队协作多天项目 | Agent Team | 需要长期运行、peer 间通信、人工介入 |
| 间歇性 bug 复现 | Workflow(adversarial 模式) | 多 worktree 并发 + 假设验证循环 |
诚实限制
Workflow 的已知短板
- Token 消耗高:一个 run 可能是单次对话的 10-50 倍
- 不支持中间用户输入:无法在阶段间插入人工审批
- Session 内恢复:退出 Claude Code 后 workflow 丢失,下次从头开始
- 权限弹窗中断:shell 命令不在 allowlist 中会中断长任务
- 模型绑定:所有 agent 默认使用 session 模型,除非脚本指定其他模型
Workflow 的真正优势
- 编排确定性:代码化的阶段屏障比 turn-by-turn 判断可靠
- Context 隔离:中间结果不挤占主会话 context window
- 可复现:保存脚本 → 一键重跑 → diff 结果
- 质量模式:adversarial review、多角度投票等结构化质量保证
- 可观测性:phase 级进度、token 用量、agent 详情
Part 5: 苏格拉底对话
师生对话用一个具体场景理解 workflow 的编排逻辑。
我最近在用 sub-agent 做代码审查,让它一次查 5 个文件。但经常出现 sub-agent 的结果把主 context 塞满了,后面 Claude 就开始"忘记"之前的结果。Workflow 能解决这个?
你刚好踩到了 sub-agent 模式的核心瓶颈。中间结果全进 context window,对吧?那你想想——如果有一个地方可以"暂存"中间结果,不让它进 context,会怎样?
那就只有最终审查结论进入主 context?但谁来做"暂存"这件事?
这就是 workflow 的核心转换。在 sub-agent 模式下,Claude 本身既是执行者也是调度器——每个 turn 都要决定"接下来做什么",所有结果都回流到它的 context。Workflow 把"调度器"的角色从 Claude 的思考过程中搬到了一个 JavaScript 脚本里。
你把中间结果存在脚本变量中,让 runtime 执行脚本。Claude 的 context 只在最后接收一个汇总结果。
那这个脚本谁写的?我不可能每次手动写 JS 来编排 agent 吧?
这就是"动态"的含义——Claude 自己写。你只需要在 prompt 里说 "use a workflow" 或包含 "ultracode" 关键词,Claude 就会根据你的任务描述生成一个 JS 脚本,然后交给 runtime 执行。
所以链路是:你的自然语言 prompt → Claude 写 JS 脚本 → runtime 执行 → 结果回传。你全程不碰代码。
但等等——如果脚本里一个 phase 的 10 个 agent 并发跑完了,结果怎么传给下一个 phase?是通过文件还是内存?
脚本变量。Runtime 在内存中管理每个 agent 的返回值,下一个 phase 的 agent 可以通过脚本逻辑读取这些值。这就是为什么脚本里可以用标准 JS 的数组操作和 JSON 处理——你用代码而不是 prompt 来做数据流编排。
而"阶段间"是屏障语义——phase 1 的所有 agent 都完成后,才启动 phase 2。这是确定性的,不依赖 Claude 的判断。
那如果我有一个审查任务——先让 10 个 agent 并发搜 bug,再让 3 个 agent 交叉验证结果,最后汇总——workflow 确实比 sub-agent 更合适。但 token 成本呢?
这正是需要权衡的地方。一个 workflow run 可能是单次对话的 10-50 倍 token。建议是:先在小切片上跑——一个目录而不是整个 repo——看 token 用量,再决定是否扩大规模。
Workflow 的真正价值不只是"跑更多 agent",而是"编排可复现"——一个成功的审查流程可以保存为命令,每次代码提交都跑一遍,结果是确定性的。
最后问一个——它和 Agent Team 有什么区别?Team 也是多个 agent 协作啊。
关键区别在"谁持有计划"。Agent Team 中,lead agent 逐 turn 决定下一步——它还是依赖 Claude 的实时判断。Workflow 中,计划在脚本里,执行是确定性的。
另一个维度是规模:Team 适合几个长期运行的 peer;Workflow 适合几十到上百个短命的 agent 批处理。
如果你需要 peer 之间持续通信和人工介入,用 Team。如果你需要大规模、可复现、无人值守的编排,用 Workflow。
所以本质上,Workflow 是把 Agent 编排从"prompt engineering"升级到了"code engineering"——从依赖模型的实时判断,变成了依赖代码的确定性执行。
精准。而且这个升级带来了一个副产品:编排的可审计性。你可以打开脚本文件,看到 Claude 到底规划了什么。你可以 diff 两次 run 的脚本,看编排逻辑怎么变。你可以编辑脚本然后重跑。这些在 sub-agent 模式下都做不到。
但这也引出一个开放问题——当 Claude 自己写编排脚本时,脚本的质量如何保证?谁来 review Claude 写的 workflow?这是下一层递归的问题了。
Part 6: 个性化洞察
跟尾巴有什么关系基于你的技术栈、工作模式和项目场景,这对你意味着什么。
1. 把 prepme 项目的 issue.md 审查 workflow 化
为什么跟你有关:你已经在用 CLAUDE.md 管理 issue.md 和 changelog。一个 workflow 可以自动扫描所有代码变更 → 对照 issue.md 检查修复状态 → 生成 changelog 草稿 → adversarial review 是否遗漏。保存为 /review-issues 命令,每次 commit 后自动跑。
你可以怎么做:下次有 3+ 个 bug 修复时,用 ultracode: 审查最近的所有提交,对照 issue.md 逐条验证修复 触发 workflow,成功后保存到 .claude/workflows/。
2. 重构你的 multi-agent 编排策略
为什么跟你有关:你 CLAUDE.md 里写了"3+ 子任务并发协同,1-2 个单委派"——这正是 workflow 的甜区判断标准。现在你有了更精确的工具选择:sub-agent(1-2 个委派)→ Agent Team(3-5 个协作)→ Workflow(10+ 个大规模编排)。
你可以怎么做:更新 CLAUDE.md 的"执行"小节,加入 workflow 触发条件:当预估步骤 > 5 且不需要中间人工审批时,优先考虑 workflow。
3. 创建 /deep-code-review workflow
为什么跟你有关:你已经有 code-review 和 linus-review skill。但 skill 的局限是结果全进 context。一个 workflow 可以让多个 agent 并发审查不同维度(安全、性能、可维护性),结果汇总后只传一个结构化报告给主会话。
你可以怎么做:下次做 PR 审查时用 ultracode: 对当前 diff 做安全 + 性能 + 可维护性三维并发审查,成功后保存为 /deep-code-review。
4. Token 成本是真实约束
为什么跟你有关:你日常重度使用 Claude Code。Workflow 的 10-50x token 成本意味着一次 deep-research 可能烧掉你一整天的用量配额。
你可以怎么做:先用小切片测试。在 CLAUDE.md 中加一条规则:"workflow 触发前先用小切片估算 token 成本,超过 $5 的 run 需要确认。"
5. 把你的高频 workflow 分享出去
为什么跟你有关:你目标是做开源贡献者。Workflow 保存在 .claude/workflows/ 下,天然就是可分享的。你的翻译解读流程、issue 管理流程、code review 流程——都可以作为 workflow 模板开源。
你可以怎么做:在 prepme 或新项目中积累 3-5 个稳定 workflow 后,整理为 awesome-claude-workflows 仓库发布。
6. 警惕 Workflow 的"银弹陷阱"
为什么跟你有关:Anthropic 自己说"best practices are still evolving"。Workflow 是一个年轻的抽象层,API 可能在未来版本中变化。过度依赖 workflow 可能导致迁移成本。
你可以怎么做:保持 workflow 脚本的简洁和可读性。定期 review 保存的 workflow,在新版本 Claude Code 发布后检查是否有更简单的方式完成同样的任务。