Files
claude-code/docs/features/workflow-scripts.md
claude-code-best 3edc370aa1 feat(workflow): 默认并发降为 3 并支持 per-run maxConcurrency 注入
- DEFAULT_MAX_CONCURRENCY=3 替代旧的 min(16, cores-2);MAX_CONCURRENCY_CAP=16 保留为用户输入的绝对上限
- 新增 clampMaxConcurrency() 处理 undefined/<1/>CAP 边界
- WorkflowInput schema 新增 maxConcurrency: number.int().min(1).max(16).optional()
- 引擎层 context/runWorkflow 全链路透传:semaphore 容量来自 per-run 入参
- WorkflowTool prompt 增加指引:fan-out 场景先用 AskUserQuestion 与用户确认并发再启动
- 同步 ultracode skill + audit workflow spec 的并发文字(删 cpu-cores 公式)
- 同步 docs/features/workflow-scripts.md 旧公式

Co-Authored-By: glm-5.2 <zai-org@claude-code-best.win>
2026-06-14 10:16:29 +08:00

11 KiB
Raw Blame History

WORKFLOW_SCRIPTS — 确定性多 agent 工作流编排

Feature FlagFEATURE_WORKFLOW_SCRIPTS=1 引擎包:@claude-code-best/workflow-engine(确定性 JS 脚本编排,零核心层运行时依赖) 集成层:src/workflow/

一、功能概述

WORKFLOW_SCRIPTS 让 Claude Code 用确定性 JavaScript 脚本编排多个子 agent可分解/并行、多视角置信、规模超单上下文、可 resume/可审计。

  • 编排原语agent / parallel / pipeline / phase / log / workflow(见引擎包)。
  • 确定性:脚本在受限沙箱内执行,禁用 Date.now() / Math.random() / 无参 new Date(),保证 journal 可重放。
  • 深度后端:单一 claude-code AgentAdapter 接入当前会话体系provider / model / agentType / 工具workflow 内的 agent() 调用真实子 agent。
  • 监控面板/workflows 双栏实时面板(见 §六)。
  • 编排手册/ultracode 注入编排工作法(见 §七)。

历史说明:早期版本为 YAML/JSON DSL + 全 Stub 实现(WorkflowDetailDialog 等),已全量重写为引擎驱动的 JS 方案。

二、实现架构

   .claude/workflows/<name>.ts        Workflow 工具name/script/scriptPath/args/resumeFromRunId
            │                                       │
            ▼                                       ▼
   namedWorkflowCommands.ts              src/workflow/wiring.ts (createWorkflowToolCore)
   /<name> 命令发现)                              │
                                                   ▼
                                      WorkflowService门面launch/kill/subscribe/listRuns/listNamed
                                                   │
                                  ┌────────────────┼─────────────────┐
                                  ▼                ▼                 ▼
                          ports.ts            registry.ts        progress/
                       (端口聚合)      AgentAdapterRegistry  bus + store
                                  │                │
                                  ▼                ▼
                      hostHandle.ts        backends/claudeCodeBackend.ts
                     (不透明 host       (深度读会话体系,跑真实 agent
                                  │
                                  ▼
                  @claude-code-best/workflow-engine
                  runWorkflow / hooks / journal / budget / 并发信号量)

2.1 模块清单

文件 职责
引擎 packages/workflow-engine/src/ 确定性脚本沙箱 + hooks + journal + budget + 信号量;导出 createWorkflowTool
工具装配 src/workflow/wiring.ts createWorkflowToolCore() —— 用 WorkflowService.ports 组装 Workflow 工具
服务门面 src/workflow/service.ts WorkflowService 单例:launch / kill / subscribe / listRuns / listNamed / getWorkflowService()
端口 src/workflow/ports.ts createWorkflowPorts() 聚合所有端口agentRunner/registry/progress/task/journal/permission/logger/hostFactory
后端注册 src/workflow/registry.ts buildRegistry() 注册 claude-code 后端并设为默认
深度后端 src/workflow/backends/claudeCodeBackend.ts AgentAdapteragentType/model 解析会话体系,跑真实子 agent结构化输出
Host 句柄 src/workflow/hostHandle.ts buildHostBundle() 不透明包装 toolUseContext/canUseTool/parentMessage
进度总线 src/workflow/progress/bus.ts 基于 Set 的进度事件发射
进度状态 src/workflow/progress/store.ts reduceragentId 精确关联 agent_done(修并发竞态)
监控面板 src/workflow/panel/*.tsx /workflows 双栏 UI见 §六)
命名命令 src/workflow/namedWorkflowCommands.ts 扫描 .claude/workflows/ 生成 /<name> 命令
权限请求 src/workflow/WorkflowPermissionRequest.tsx workflow 启动权限 UI

2.2 注册点

位置 内容
src/tools.ts:152-153,254 createWorkflowToolCore() 动态加载并注册 Workflow 工具feature-gated
src/commands.ts:95-97,392 /workflows 命令local-jsx加载 panelCall.js
src/skills/bundled/ultracode.ts + index.ts /ultracode 知识 skillregisterBundledSkill

三、编排原语

workflow 脚本内可用的钩子(语义详见引擎包 engine/hooks.ts

原语 语义
agent(prompt, opts?) 派发一个子 agent返回最终文本opts.schema结构化对象。optsmodel / agentType / label / phase / schema
parallel([() => …]) 并发跑 thunk 数组,barrier(等全部完成);单项抛错 → 该项 null,其余保留
pipeline(items, s1, s2, …) 每个 item 链式过各 stageitem 间无 barrierstage 内顺序;单 item 某 stage 抛错 → 该 item null
phase(title) 标记阶段(面板按此分组展示)
log(msg) 进度日志(面板展示,无状态变更)
workflow(name | { scriptPath }, args?) 嵌套一层子 workflow仅允许一层

硬限:单次 parallel/pipelineMAX_ITEMS_PER_CALL4096单 workflow 总 agent ≤ MAX_TOTAL_AGENTS1000并发 cap 默认 = DEFAULT_MAX_CONCURRENCY3可经 Workflow 工具的 maxConcurrency 入参覆盖,绝对上限 MAX_CONCURRENCY_CAP16

四、编写 workflow

脚本置于 .claude/workflows/<name>.js|.mjs(也接受 .ts,但引擎不转译 TS,含类型注解会报语法错——推荐 .js/.mjs),自动成为 /<name> 命令。

// .claude/workflows/review-changes.js
export const meta = {
  name: 'review-changes',
  description: '按维度审查改动并对抗式验证',
  phases: [{ title: 'Review' }, { title: 'Verify' }],
}

const DIMENSIONS = [
  { key: 'bugs', prompt: '找正确性 bug' },
  { key: 'perf', prompt: '找性能问题' },
]

const results = await pipeline(
  DIMENSIONS,
  d => agent(d.prompt, { label: `review:${d.key}`, phase: 'Review' }),
  review => parallel(
    (review.findings || []).map(f => () =>
      agent(`对抗式验证:${f.title}`, { phase: 'Verify' })
    )
  )
)
return results.flat().filter(Boolean)

脚本执行约束(引擎执行模型,违反直接报错):

脚本是 new AsyncFunction函数体,不是 ESM 模块:

  • importagent/parallel/pipeline/phase/log/workflowargs/budget 是注入的形参,直接用。
  • 禁 TS 语法:不要类型注解(x: number)、interfaceenumas、泛型。引擎不转译,即便文件是 .ts 也会原样报语法错。
  • 只允许一处 export const meta = {...}(引擎正则提取剥离);不要 export 其他、不要 export default
  • 顶层 return 返回结果

确定性约束(违反则 resume 失效):

  • Date.now() / Math.random() / 无参 new Date()(沙箱强制抛错)。需时间戳/随机种子经 args 传入。
  • export const meta = { ... } 必须是纯字面量(无变量、函数调用、模板插值)——加载期求值,否则抛 ScriptError

五、Workflow 工具

模型通过 Workflow 工具启动 workflowinput schema 见引擎包 tool/schema.ts

字段 说明
script 内联脚本字符串
name 命名 workflow 名(对应 .claude/workflows/<name>
scriptPath 脚本文件路径
args 透传给脚本的 args(任意 JSON 值)
resumeFromRunId 从既有 runId 重放(已完成 agent() 秒回,发散点后现场重跑)

六、监控面板:/workflows

/workflows 打开三区焦点面板local-jsx全屏

  • 顶部 tabs:每个 run 一个 tab状态圆点 + workflow 名 + #runId短码);同名脚本多次跑会多个 tab。
  • 左 phase 侧栏All + 合并 meta 声明的 phase未启动 pending 灰)与实际 phase running / done选中即决定右栏筛选。
  • 右 agent 列表:按选中 phase 过滤;状态色 + 行尾文字(running / object / text / dead)。

键位Tab/Shift+Tab 切 run · / 切左右焦点列phases ↔ agents· / 列内移动 · r resume · x kill · n 新建提示 · q/Esc 退出。

视觉:无内框,左右一条竖线分隔;聚焦列标题橙粗;选中/光标行铺橙底(backgroundColor),文字色不变。

进度按引擎 agentId 精确关联 agent_done(解决并发 LIFO 竞态。pending phase 来自 run_started 事件携带的 meta.phasesstore 落地 declaredPhases,面板 mergePhases 合并。useSyncExternalStore 订阅 WorkflowService,稳定快照,无变更不重渲染。

七、/ultracode skill

/ultracodesrc/skills/bundled/ultracode.ts)注入多 agent workflow 编排工作法:何时用 / 何时不用、编排原语速查、质量模式库adversarial-verify / judge-panel / loop-until-dry / multi-modal-sweep / completeness-critic、确定性约束、后端路由、resume/budget、文件与命令。

纯知识 prompt skill:零运行时副作用,不改主循环、不切换行为开关。调用即把手册注入上下文。

八、resume / journal / budget

  • journal:每次 run 记录到 .claude/workflow-runs/<runId>/journal.jsonlresumeFromRunId 重放 journal已完成 agent() 秒回缓存结果。
  • budgetbudget.total 为 token 硬顶(默认 null = 无限);budget.spent() / budget.remaining() 读实时消耗;耗尽后再发 agent() 抛错。
  • 并发:引擎 Semaphore 默认许可 3DEFAULT_MAX_CONCURRENCY),可经 Workflow 工具的 maxConcurrency 入参 per-run 覆盖(钳到 [1, MAX_CONCURRENCY_CAP=16])。
  • 错误:脚本语法/meta 错 → parseScript 即时返错不进后台agent 抛错 → kind:'dead'nullworkflow 继续(parallel/pipeline 容错);WorkflowAbortedErrorkilled

九、文件索引

文件 职责
src/workflow/wiring.ts Workflow 工具装配(createWorkflowToolCore
src/workflow/service.ts WorkflowService 门面
src/workflow/ports.ts 端口聚合(createWorkflowPorts
src/workflow/registry.ts AgentAdapterRegistry + 默认后端
src/workflow/backends/claudeCodeBackend.ts 深度后端 AgentAdapter
src/workflow/hostHandle.ts 不透明 host 句柄(buildHostBundle
src/workflow/progress/bus.ts 进度事件总线
src/workflow/progress/store.ts 进度 reduceragentId 关联)
src/workflow/panel/*.tsx /workflows 双栏面板
src/workflow/namedWorkflowCommands.ts /<name> 命令发现
src/workflow/WorkflowPermissionRequest.tsx 启动权限 UI
src/skills/bundled/ultracode.ts /ultracode 知识 skill
src/tools.ts:152-153,254 工具注册
src/commands.ts:95-97,392 /workflows 命令注册
packages/workflow-engine/ 引擎包hooks / journal / budget / 并发)