第 1 卷
17|编排机制:模型驱动 Workflow 与固定策略 Ralph
张嘉熙 · DeepSeek Harness 前沿工程实践




你好,我是张嘉熙。
上一讲我们讲了一个 agent 怎么把活横向委派给子 agent 去干。可当活不再是能各自独立干的一批子任务,而是要把多个步骤按特定顺序、并发或循环地串成流程才能干完时,谁来做这
层流程编排、又怎么做?
dsh 内置了两条路:Workflow 让模型现写脚本、自由编排,Ralph 把脚本写死在工具里、模型只传一个目标。两条路都靠同一个编排引擎跑脚本。要看清这一讲的内容,需要回答四个问
题:
编排引擎是什么?
关于环境:本讲机制上新增四个包:@deepseek-ai/dsh-workflow(编排引擎 seam, ctx.workflowEngine)、@deepseek-ai/dsh-workflow-worker-thread(编排
引擎实现)、@deepseek-ai/dsh-tool-workflow + @deepseek-ai/dsh-toolralph(两个面向模型的编排工具)。示例还要子 agent 真去数文件 / 写工作区,得挂
bash 工具链:dsh-subprocess → dsh-subprocess-local → dsh-shell → dsh-bash-local → dsh-shell-env → dsh-tool-bash;联网调真模型要 dsh-
llm-deepseek 及其 peer 依赖 dsh-credentials / dsh-anonymous-user-id / dsh-launch-environment。npm install --legacy-peer-deps 一次装齐。
关于示例:npm run start:ch17:workflow 让模型现场写脚本派子 agent,npm run start:ch17:ralph 让模型传目标跑写死的循环。两个示例都联网调真实模型,先
export DEEPSEEK_API_KEY=... 再跑;模型输出每次不同,所以文档里的输出块都标注为“示例输出”。
编排引擎是什么:编排脚本的执行环境
ctx.workflowEngine(编排引擎)执行编排脚本:吃进脚本,吐出它 return 的值。它下连 ctx.subagents(16 讲讲过,真正启动子 agent);上接 workflow / ralph 两个
面向模型的工具,模型调用它们,它们再把脚本传给引擎。
Workflow 和 Ralph 共用一套引擎,引擎不区分“这是 Workflow 还是 Ralph”,只按 start() 收到的脚本和参数执行、吐返回值,根本不关心脚本是谁写的。两者的差别全在工
具层怎么调 start():Workflow 传模型现写的脚本,Ralph 传写死的 RALPH_SCRIPT。引擎对两者一视同仁,所以一套引擎就够。
编排脚本跑在一个沙箱里:vm 模块造出的一个空 JavaScript 执行环境(里面没有 fs / net / fetch / timers 这些 Node.js 自带能力),所以碰不到文件、网络;注意:这层隔离只
是剥夺了脚本随手能碰的能力、不是安全墙,不等于绝对安全。它和 07 讲的进程沙箱也不是一回事:07 管的是子进程对文件系统的改动,只拦写、不拦读、不管网络;vm 管的是脚本能
原语语义
启动一个子 agent,返回它的最终文本;若带 schema,返 agent(prompt, opts?)
回结构化对象而非纯文本
并发跑一组无参数函数、结果收成数组;像一道屏障,等所 parallel(thunks)
有任务都跑完才继续
把一组条目依次送过若干个阶段函数(前一个阶段的输出传 pipeline(items, ...stages)
给下一个阶段)
给脚本的叙述标一个章节标题;只写进运行事件流、不回喂 phase(title)
给模型,也不派活
给脚本的叙述追加一行文字;同样只写进运行事件流、不回 log(text)
喂给模型,也不派活
其中 agent() 派出去的子 agent 是完整 agent,照样能读写文件、访问网络,只有脚本受限,派出去的子 agent 不受这个限制。
编排引擎对外只有一个入口 start(request),传进去的 request 是这些字段: