将 feat/sdk-backend 分支中 workflow 相关的 20 个 commit 压缩为单 commit: - 工作流引擎核心:phase / agent / parallel / pipeline 编排原语(packages/workflow-engine/) - /workflows 面板:三区焦点布局(顶部 run tabs + 左侧 phase 侧栏 + 右侧 agent 列表) - /ultracode skill:多 agent workflow 编排入口 - 进度存储 / journal / notification 系统 - WorkflowService 生命周期管理 + SentryErrorBoundary - 脚本沙箱:禁用 dynamic import()、JSON args 防御性归一化 - journal 与 named-workflow 路径统一在 projectRoot - 错误处理:parallel/pipeline hooks 错误日志、failure routing、semaphore abort - workflow 工具升级为 core 工具 + PascalCase 命名 Co-Authored-By: glm-5.1 <zai-org@claude-code-best.win>
11 KiB
WORKFLOW_SCRIPTS — 确定性多 agent 工作流编排
Feature Flag:
FEATURE_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-codeAgentAdapter 接入当前会话体系(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 |
AgentAdapter:按 agentType/model 解析会话体系,跑真实子 agent,结构化输出 |
| Host 句柄 | src/workflow/hostHandle.ts |
buildHostBundle() 不透明包装 toolUseContext/canUseTool/parentMessage |
| 进度总线 | src/workflow/progress/bus.ts |
基于 Set 的进度事件发射 |
| 进度状态 | src/workflow/progress/store.ts |
reducer:按 agentId 精确关联 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 知识 skill(registerBundledSkill) |
三、编排原语
workflow 脚本内可用的钩子(语义详见引擎包 engine/hooks.ts):
| 原语 | 语义 |
|---|---|
agent(prompt, opts?) |
派发一个子 agent;返回最终文本,或(带 opts.schema)结构化对象。opts:model / agentType / label / phase / schema |
parallel([() => …]) |
并发跑 thunk 数组,barrier(等全部完成);单项抛错 → 该项 null,其余保留 |
pipeline(items, s1, s2, …) |
每个 item 链式过各 stage;item 间无 barrier,stage 内顺序;单 item 某 stage 抛错 → 该 item null |
phase(title) |
标记阶段(面板按此分组展示) |
log(msg) |
进度日志(面板展示,无状态变更) |
workflow(name | { scriptPath }, args?) |
嵌套一层子 workflow(仅允许一层) |
硬限:单次 parallel/pipeline ≤ MAX_ITEMS_PER_CALL(4096);单 workflow 总 agent ≤ MAX_TOTAL_AGENTS(1000);并发 cap = min(16, cores - 2)。
四、编写 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 模块:
- 禁
import:agent/parallel/pipeline/phase/log/workflow与args/budget是注入的形参,直接用。 - 禁 TS 语法:不要类型注解(
x: number)、interface、enum、as、泛型。引擎不转译,即便文件是.ts也会原样报语法错。 - 只允许一处
export const meta = {...}(引擎正则提取剥离);不要export其他、不要export default。 - 顶层
return返回结果。
确定性约束(违反则 resume 失效):
- 禁
Date.now()/Math.random()/ 无参new Date()(沙箱强制抛错)。需时间戳/随机种子经args传入。 export const meta = { ... }必须是纯字面量(无变量、函数调用、模板插值)——加载期求值,否则抛ScriptError。
五、Workflow 工具
模型通过 Workflow 工具启动 workflow(input 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.phases,store 落地 declaredPhases,面板 mergePhases 合并。useSyncExternalStore 订阅 WorkflowService,稳定快照,无变更不重渲染。
七、/ultracode skill
/ultracode(src/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.jsonl。resumeFromRunId重放 journal,已完成agent()秒回缓存结果。 - budget:
budget.total为 token 硬顶(默认null= 无限);budget.spent()/budget.remaining()读实时消耗;耗尽后再发agent()抛错。 - 并发:引擎
Semaphore(min(16, cores - 2))限制同时运行的 agent 数。 - 错误:脚本语法/meta 错 →
parseScript即时返错(不进后台);agent 抛错 →kind:'dead'→null,workflow 继续(parallel/pipeline容错);WorkflowAbortedError→killed。
九、文件索引
| 文件 | 职责 |
|---|---|
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 |
进度 reducer(agentId 关联) |
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 / 并发) |