Files
deepseek-harness/docs/core-data-structures/workflow.zh.md
Ziya 5270dcd61d docs(i18n): core-data-structures and postmortem batch — 22 bilingual pairs
core-data-structures 18 篇(core.md 因超长仍在产出、随后补)、
postmortem 3 篇与 RFC 前门 README 配对;流水线 + 二遍校验产出。
生成文件 docs/rfc/INDEX.md(gen-rfc-index 产物)列入排除。中文侧
页内锚点统一指向英文侧锚名,满足配对门禁的链接目标一致规则。
2026-07-15 23:11:25 -07:00

5.0 KiB
Raw Blame History

工作流

English | 中文

工作流 seam由 agent智能体运行一段模型编写的编排脚本SCRIPT向外扇出 subagent。与 subagent 一样,它是一项可选能力,不属于 agent loop智能体循环主干因此其词汇定义在此而非 core.md 中。与 subagent 注册表不同,它采用 bash 形态:每个上下文只有一个引擎实现提供 ctx.workflows;没有命名提供方注册表(第二个引擎是插件替换,而非共存)。

接口:dsh-workflowctx.workflows + 下文词汇)。实现为 dsh-workflow-workerthread(基于 node:worker_threads 的引擎:每次运行一个 worker脚本的 vm 上下文在其中执行);面向模型的消费方是 dsh-tool-workflow。提案与设计理由见动态工作流 RFC

源码:packages/workflow/workflow/src/types.ts

启动请求

调用方启动一次运行时发出的请求。工具层根据模型的 { script, meta, args } 调用加上发起调用的 agent 构建此请求;metaargs 是纯 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,且必须在每条路径上调用 disposeresult 不会 reject脚本失败以 stopReason: 'error' resolve一旦运行被取消即使脚本本身永不 settle它也会在引擎的有界宽限期内 settle引擎强制以 cancelled settleworker-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: trueWorkflowErrorparallel()/pipeline() 组合器对 fatal 错误执行重新抛出,而非将该项映射为 null:一个拼写错误的选项必须大声杀死脚本,绝不能消融为看似普通子 agent 失败的东西。逐项的 null 保留给子运行失败(非 completed 的 stop reason和阶段内的普通脚本错误。

事件

workflow/* 事件(workflow/startworkflow/phaseworkflow/logworkflow/agent-startworkflow/agent-endworkflow/end——见事件目录)是仅供观察的 emit携带数据快照每个 payload 以 WorkflowRunInfoid + meta开头从不暴露活跃的 WorkflowRun,因此订阅者无法获得 cancel/disposeworkflow/end 刻意省略 result value观察结果的监听器不得收到调用方 result 的可变别名)。每次 emit 对每个监听器隔离:抛异常的订阅者被记录但不传播,不会饿死其后注册的监听器;每个监听器收到自己的 payload 克隆,因此修改它既不会损坏引擎也不会影响其他监听器。这种隔离与 subagent/start/subagent/end 一致。