description: "worker-thread 工作流引擎:在宿主事件循环之外执行由模型编写的编排脚本,供选择或配置执行隔离的用户与维护者阅读。"
English | 中文
dsh-workflow-worker-thread 以每次运行一个 Node worker thread 的方式实现工作流引擎:编排脚本在一个全新 worker 内执行,其 agent() 调用通过带类型的宿主/worker 协议触达宿主 subagent。同步脚本循环不会阻塞 harness 事件循环,忽略取消的脚本可以连同其 worker 一起终止。这种隔离只是 containment(隔离),不是安全边界——由模型编写的脚本与模型已有的 bash 访问具有相同的信任前提,逃逸 node:vm 上下文即可重新取得 worker 的进程权限。挂载本引擎即为 ctx.workflowEngine 提供具体实现;与 dsh-tool-workflow 一起加载的组合会把 workflow 工具交给模型。
当组合需要工作流能力时挂载本引擎:每个编排脚本都在独立 worker thread 中、宿主事件循环之外运行,已发布组合中的 workflow 与 ralph 工具都在其上执行。不要把它当作真正不可信脚本的沙箱——恶意代码需要独立进程或容器引擎。
加载本引擎即注册 ctx.workflowEngine;在其上添加 dsh-tool-workflow 会把 workflow 工具交给模型。每个配置字段都是可选的:
- name: '@deepseek-ai/dsh-workflow-worker-thread'
- name: '@deepseek-ai/dsh-tool-workflow'
| 字段 | 默认值 | 含义 |
|---|---|---|
provider |
spawn |
agent() 调用使用的宿主侧 subagent 提供方。 |
maxConcurrentAgents |
0 |
并发 agent() 上限;0 会根据可用 CPU 并行度解析。 |
maxTotalAgents |
1000 |
一次运行最多启动的 agent() 调用总数——失控循环的后备闸。 |
maxItemsPerCall |
4096 |
一次 parallel() 或 pipeline() 调用接受的条目数。 |
syncTimeoutMs |
5000 |
脚本最初同步片段的 VM 超时时间,单位为毫秒。 |
disposeGraceMs |
5000 |
强制结算与终止 worker 前的期限;同时约束 dispose()。 |
负责该引擎的消费方可以为一次运行设置 WorkflowStartRequest.subagentProvider 与 WorkflowStartRequest.maxTotalAgents——这是引擎级策略,不是脚本钩子;普通 workflow 工具两者都不设置,单次运行的子 agent 总数上限可以降低、但绝不能提高已配置的上限。生成的配置目录是每个受支持字段的穷尽式真源。
运行启动后,脚本正文在 worker 中以顶层 await 执行,并可使用钩子 agent()、parallel()、pipeline()、phase() 与 log();meta 与 args 以普通 JSON 数据到达,绝不作为代码求值。每次 agent() 调用都会在配置的提供方下启动一个宿主侧 subagent,并以运行的父级作为每个子 agent 的父级。运行以脚本的最终 JSON 值结算;普通子 agent 失败会把 agent() 兑现为 null,由脚本处理。
格式错误的 meta 块、无法解析的正文、不可用的提供方路由或高于上限的单次运行上限,都会在 worker 存在之前被同步拒绝,调用方因此看到违规清单并可以修正调用。执行期间,钩子误用与超出上限会用致命工作流错误终止脚本。取消是有界的:忽略取消的脚本会在 disposeGraceMs 后被强制以 cancelled 结算,其 worker 被终止。
脚本的 CPU 工作与同步自旋不会占用宿主事件循环,worker.terminate() 为 dispose(资源释放)提供真实的最终停止手段,worker 以清理后的环境启动——只注入平台临时路径以及(源码模式下)TSX_TSCONFIG_PATH——因此环境凭据不会通过 process.env 跨越边界。宿主/worker 消息使用结构化克隆数据,并在脚本边界执行普通 JSON 校验。
以上都不是安全边界:有意不注入 timer、文件系统 API 或 Node 全局变量,但逃逸代码仍可以 worker 的进程权限触达 Node。
当引擎级契约不够用时阅读以下页面。它们从 seam 契约逐步进入面向模型的消费方与设计决策。
ctx.workflowEngine 背后的运行与结果词汇。脚本每次调用 agent(),都会把提示词原样发送给 subagent 提供方,并附带可选模型或结构化输出 schema。每个子 agent 看到该提供方自己的上下文;phase 与 log 叙述只留在观察器事件中。
可能需要为许多独立子 agent 上下文支付 token,数量受 maxConcurrentAgents、maxTotalAgents 与 maxItemsPerCall 限制;这些上下文绝不会直接加入父级历史。
与父级请求缓存及同级子 agent 相互独立。每个子 agent 只能在其自身提供方、模型、提示词与 schema 下复用逐字节相同的前缀;其后续历史仅追加增长。
通过 dsh-tool-workflow,成功结果只会在该消费方的包装层中公开实体化的最终 JSON 值与子 agent 数量。本引擎提供稳定错误,包括 workflow script does not parse: <error>、invalid meta: <violations>、agent() requires a non-empty prompt string、agent() could not start a child: <error> 与 child agent run failed: <error>,以及其精确的 parallel()、pipeline()、phase()、选项、schema 与 JSON 边界校验消息。中间子 agent 输出可供脚本使用,但不提供给父模型。
本引擎不会直接向父级添加 token。最终结果大小由工具消费方限制,并保留到压缩(compaction)为止。
仅追加;新增可见内容位于可复用请求前缀之后,不会使现有 KV Cache 条目失效。
这些限制说明本引擎何时不合适,或何时需要特别的运维注意。它们是当前约束,不是任务积压。
node:vm 并取得 worker 的进程权限;不可信代码部署需要独立进程或容器引擎。agentsStarted 不包括因并发限制仍在 worker 侧排队、且在强制终止后无法得知的调用。instanceof Error——工作流作者必须根据 name 与 code 等稳定字段分支。