跳到主要内容
路径工作流

工作流与 Ralph

DSH 把"多个 Agent 协作"做成两个模型可用的工具:

工具用途
workflow跑一段 JS 编排脚本,扇出多个子 Agent,返回脚本最终值
ralph对同一个不可变目标,每次起一个全新 Agent 迭代执行

两者的差异在心智模型:workflow 是"你写脚本、脚本编排一批 agent";Ralph 是"目标不变、每轮换一个全新 agent 继续推进"。

workflow 工具

@deepseek-ai/dsh-tool-workflow 跑一个模型写的 JS 编排脚本(fan out subagents),本质是宿主把脚本交给 ctx.workflowEngine seam 执行,引擎(dsh-workflow-worker-thread)决定如何隔离与执行。

运行约束:当前 dsh-workflow-worker-thread 每次运行都会创建一个 worker thread,没有池化或跨运行缓存;node:vm 只提供执行环境,不是安全隔离边界。处理不可信脚本应使用独立进程或容器。

模型看到的三个参数:

meta 必填身份数据: { name, description, phases? }
script 必填纯 JS 函数体(顶层 await;不要 export const meta)
args 可选 JSON,作为 args 全局暴露给脚本

脚本里可用的编排 hook(agent/pipeline/parallel/phase/log),全部返回 JSON 可序列化值。规则:

  • 显式请求才用:只在用户明确要"工作流 / 大规模多 Agent 编排"时用
  • 一两个委派优先用普通的 subagent 调用,不要上 workflow
  • WorkflowStartRequest = { meta, script, args, subagentProvider?, maxTotalAgents?, parent, signal? }
  • 一个 WorkflowResult = { value, stopReason, error?, agentsStarted };value 是纯 JSON 或 null
  • 运行是 holder-owned,必须 dispose();引擎插件卸载只阻止新开始,不撤销已接受的运行

一段最小脚本

// 这就是 tool 的 script 参数(Plain JS,顶层 await)
async function main(args) {
const items = await parallel([
() => agent('抓取 A 站', {label:'A'}),
() => agent('抓取 B 站', {label:'B'}),
() => agent('抓取 C 站', {label:'C'}),
])
return items.filter(Boolean)
}

脚本本身可以是 return main(args) 的顶层脚本体。运行时 agent() 返回子 Agent 的最终文本(或按 opts.schema 验证后的对象),错败的子 Agent 返回 null(.filter(Boolean) 去空)。

生命周期与错误

  • start() 同步拒绝畸形 meta / 不可解析脚本 / 不可用 provider / 超限的请求:在 run 存在之前
  • WorkflowRun.result 永不复现拒绝:执行失败 resolve 成 stopReason:'error',取消 resolve 成 cancelled(引擎有界宽限内)
  • exec.signal 桥接到 run.cancel()(含已先中止的情况)
  • completed 的停因映射成 isError(从不大包小包地当成功)
  • 根传输(ex. exec.parent 缺失)会把 run 投影到调用 agent 的 Session

Ralph 循环

@deepseek-ai/dsh-tool-ralph 是模型面向的 fresh-agent iterative loop,基于 workflow + subagent seam:对同一个不可变客观目标,每轮开一个没有继承父会话上下文的全新子 Agent,共享工作区作为长期记忆,只有有界的结构化报告跨轮。适合"目标稳定、需要反复试错推进"的长任务。

某一轮子 Agent 失败会让 Ralph 作为工作流错误结束,不重试该轮;取消同样是错误,部分报告不算成功结果。

用法基本是"只在一个目标上跑几轮,每轮新 agent 独立推进"。它把"下一轮从上一轮学到什么"交给工作区 + 结构化报告,而不是对话上下文。

什么时候用哪个

场景
一次并行拆解(抓多个源、审计多个文件)workflow
用户明确要多 agent 编排/大 fan-outworkflow
一个稳定目标、反复换新 agent 推进ralph
一两个独立子任务普通 subagent(别上 workflow)

验证

# 会话里看 workflow 记录(run-start/成员/run-end)
zstdcat ~/.dsh/sessions/*/*/session.jsonl.zstd | grep -E 'workflow|"run/' | head

下一步