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

72 lines
5.0 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 工作流
[English](workflow.md) | 中文
工作流 seam由 agent智能体运行一段模型编写的编排脚本SCRIPT向外扇出 subagent。与 [subagent](subagent.md) 一样,它是**一项可选能力**,不属于 agent loop智能体循环主干因此其词汇定义在此而非 [core.md](core.md) 中。与 subagent 注册表不同,它采用 bash 形态:每个上下文只有一个引擎实现提供 `ctx.workflows`;没有命名提供方注册表(第二个引擎是插件替换,而非共存)。
接口:[dsh-workflow](../../packages/workflow/workflow)`ctx.workflows` + 下文词汇)。实现为 [dsh-workflow-workerthread](../../packages/workflow/workflow-workerthread)(基于 `node:worker_threads` 的引擎:每次运行一个 worker脚本的 vm 上下文在其中执行);面向模型的消费方是 [dsh-tool-workflow](../../packages/workflow/tool-workflow)。提案与设计理由见[动态工作流 RFC](../rfc/implemented/feature/2026-07-05-dynamic-workflows.md)。
源码:[`packages/workflow/workflow/src/types.ts`](../../packages/workflow/workflow/src/types.ts)
## 启动请求
调用方启动一次运行时发出的请求。工具层根据模型的 `{ script, meta, args }` 调用加上发起调用的 agent 构建此请求;`meta``args` 是纯 JSON 数据(引擎在任何代码运行之前对 `meta` 做形状校验,不通过则大声拒绝——永远不会为了获取 meta 而执行脚本文本)。`parent` 是必需的:脚本 spawn 的每个子 agent 都归属于它cwd、血统和深度通过 [subagent seam](subagent.md) 流转)。
```ts type-equiv
interface WorkflowStartRequest {
script: string
meta: WorkflowMeta
args?: unknown
parent: Agent
signal?: AbortSignal
}
```
## 工作流的身份标识:`WorkflowMeta`
作为数据附在启动请求上的身份块(工具的 `meta` 参数;字段词汇与 Claude Code 动态工作流的 meta 块一致)。`phases` 仅为进度词汇:`phase()` 调用与标题匹配供观察者使用;不暗示任何执行结构。
```ts type-equiv
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` 工具结果,而非把部分输出当作成功上报。
```ts type-equiv
interface WorkflowResult {
value: unknown
stopReason: WorkflowStopReason
error?: string
agentsStarted: number
}
```
## 活跃运行:`WorkflowRun`
脚本执行期间消费方持有的句柄。消费方 await `result`,可在运行中途 `cancel`,且必须在每条路径上调用 `dispose`。`result` 不会 reject脚本失败以 `stopReason: 'error'` resolve一旦运行被取消即使脚本本身永不 settle它也会在引擎的有界宽限期内 settle引擎强制以 `cancelled` settleworker-thread 引擎随后终止脚本的 worker因此消费方 await `result` 不会在取消后永远卡住。`dispose()` = cancel + 有界 settle + 子 agent 静默;它不会因脚本卡死而挂起。
```ts type-equiv
interface WorkflowRun {
readonly id: WorkflowRunId
readonly meta: WorkflowMeta
readonly result: Promise<WorkflowResult>
cancel(reason?: string): void
dispose(): Promise<void>
}
```
## 失败纪律:`WorkflowError.fatal`
脚本内部的钩子误用——错误参数、未知或延迟的 `agent()` 选项、超出[结构化输出子集](../../packages/core/tools/README.md)的 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`——见[事件目录](../cordis-catalog/events.md))是**仅供观察**的 emit携带数据快照每个 payload 以 `WorkflowRunInfo`id + meta开头从不暴露活跃的 `WorkflowRun`,因此订阅者无法获得 `cancel`/`dispose``workflow/end` 刻意省略 result value观察结果的监听器不得收到调用方 result 的可变别名)。每次 emit 对每个监听器隔离:抛异常的订阅者被记录但不传播,不会饿死其后注册的监听器;每个监听器收到自己的 payload 克隆,因此修改它既不会损坏引擎也不会影响其他监听器。这种隔离与 `subagent/start`/`subagent/end` 一致。