22 篇(core-data-structures 18、postmortem 3、rfc/README)译文按 v4 基线重出;机械核对零异常;rfc/README.zh 页内锚点按门禁规则改回 英文侧锚名。
5.0 KiB
工作流
English | 中文
工作流 seam:一个 agent(智能体)运行由模型编写的编排脚本(SCRIPT),扇出 subagent。与 subagent 一样,它是一项可选能力,不属于 agent loop(智能体循环)主干,因此其词汇定义在此处而非 core.md。与 subagent 注册表不同,它采用 bash 形态:每个上下文只有一个引擎实现提供 ctx.workflows;没有命名提供方注册表(第二个引擎是插件替换,而非共存)。
接口:dsh-workflow(ctx.workflows + 下文词汇)。实现是 dsh-workflow-workerthread(一个 node:worker_threads 引擎:每次运行一个 worker,脚本的 vm 上下文在其中执行);面向模型的消费方是 dsh-tool-workflow。提案与设计动机见动态工作流 RFC。
源码:packages/workflow/workflow/src/types.ts
启动请求
调用方启动一次运行时提交的内容。工具层从模型的 { script, meta, args } 调用加上发起调用的 agent 构建此请求;meta 和 args 是纯 JSON 数据(引擎在任何代码执行之前对 meta 做形状校验,不通过则立即报错:永远不会为了获取 meta 而执行脚本文本)。parent 是必填项:脚本 spawn 的每个子 agent 都归属于它(cwd、血统与深度通过 subagent seam 传递)。
interface WorkflowStartRequest {
script: string
meta: WorkflowMeta
args?: unknown
parent: Agent
signal?: AbortSignal
}
工作流的身份标识:WorkflowMeta
作为数据附在启动请求上的身份块(工具的 meta 参数;字段词汇与 Claude Code 动态工作流的 meta 块一致)。phases 仅用于进度展示:phase() 调用与标题匹配,供观察者使用;不暗示任何执行结构。
interface WorkflowMeta {
name: string
description: string
whenToUse?: string
phases?: WorkflowPhase[]
}
终态结果:WorkflowResult
一次运行的结果,由 WorkflowRun.result resolve。value 是脚本的物化返回值——纯宿主域 JSON 数据(脚本无返回值时为 null)——仅在 completed 时有意义。stopReason 是封闭联合类型(引擎所有;消费方可穷举):completed | cancelled | error。非 completed 的原因在 error 中携带失败信息,消费方将其映射为 isError 工具结果,而非把部分输出当作成功上报。
interface WorkflowResult {
value: unknown
stopReason: WorkflowStopReason
error?: string
agentsStarted: number
}
活跃运行:WorkflowRun
脚本执行期间消费方持有的句柄。消费方 await result,可中途 cancel,且必须在每条路径上 dispose。result 不会 reject:脚本失败以 stopReason: 'error' resolve;一旦运行被取消,即使脚本本身永不 settle,它也会在引擎的有界宽限期内 settle(引擎强制以 cancelled settle;worker-thread 引擎随后终止脚本的 worker),因此消费方 await result 不会在取消后卡死。dispose() = cancel + 有界 settle + 子 agent 静默;它不会因脚本卡死而挂起。
interface WorkflowRun {
readonly id: WorkflowRunId
readonly meta: WorkflowMeta
readonly result: Promise<WorkflowResult>
cancel(reason?: string): void
dispose(): Promise<void>
}
失败纪律:WorkflowError.fatal
脚本内部的钩子误用:错误参数、未知或延迟的 agent() 选项、超出结构化输出子集的 schema、触发的上限、seam 启动失败、取消,都会抛出 fatal: true 的 WorkflowError。parallel()/pipeline() 组合器对 fatal 错误直接重新抛出,而非将该项映射为 null:一个拼写错误的选项必须让脚本大声失败,绝不能消融为看似普通子 agent 失败的结果。逐项的 null 保留给子运行失败(非 completed 的 stop reason)和阶段内的普通脚本错误。
事件
workflow/* 事件(workflow/start、workflow/phase、workflow/log、workflow/agent-start、workflow/agent-end、workflow/end,见事件目录)是仅供观察的 emit,携带数据快照:每个 payload 以 WorkflowRunInfo(id + meta)开头,而非活跃的 WorkflowRun,因此订阅者无法获得 cancel/dispose;workflow/end 刻意省略 result value(观察结果的监听器不得收到调用方 result 的可变别名)。每次 emit 对每个监听器隔离:抛出异常的订阅者被记录日志但不传播,不会饿死在它之后注册的监听器;每个监听器收到自己的 payload 克隆,因此修改它既不会损坏引擎也不会影响其他监听器。这种隔离方式与 subagent/start/subagent/end 一致。