Workflow

模型编排多阶段子代理流水线。

workflow 脚本 = 阶段 + 并行 + 屏障。

90 行1 个工具

问题

一个任务天然分成多块独立工作:"先审计 40 个文件,再按结果分类,再写修复方案。"用 s06 的子代理一个个跑?串行太慢;手动并行?你写不出编排。

编排本身应该可编程:模型写一段"工作流脚本"(阶段、并行、屏障),harness 在受控环境里执行它,把子代理当作流水线里的工人。脚本是一次性的——由模型针对当前任务生成,跑完即弃。

解决方案

工作流脚本语言(最小的):

  • agent(prompt):跑一个子代理,返回其最终文本;
  • pipeline(items, ...stages):每个 item 依次经过多个阶段,阶段间无屏障
  • parallel(thunks):并发执行多个函数,等全部完成(屏障)。
async function runWorkflow(script) {
  // 在受控环境(如 worker)中执行脚本
  const fn = new Function("agent", "pipeline", "parallel", "log", `return (async () => { ${script} })()`);
  return await fn(agent, pipeline, parallel, log);
}

async function agent(prompt) {
  const result = await agentLoop(prompt, { tools: CHILD_TOOLS });
  return result;
}

async function pipeline(items, ...stages) {
  let current = items;
  for (const stage of stages) {
    current = await Promise.all(current.map((item, i) => stage(current[i], item, i).catch(() => null)));
  }
  return current;
}

async function parallel(thunks) {
  return Promise.all(thunks.map((t) => t().catch(() => null)));
}

工作原理

第 1 步:模型用 workflow 工具提交一段脚本。示例——审计 3 个文件并汇总:

const files = ["a.ts", "b.ts", "c.ts"];
const results = await pipeline(
  files,
  async (_, file) => await agent(`审计 ${file},找出问题`),           // 阶段 1:并行审计
  async (prev) => await agent(`把这份审计结果整理成报告:${prev}`)   // 阶段 2:逐项整理
);
return JSON.stringify(results);

第 2 步:执行环境受控——脚本在 worker 线程里跑,不阻塞主循环;每次 agent() 调用一个子代理,结果结构化返回。

第 3 步:脚本结束时返回 JSON,模型读取结果继续。工作流是模型的一次性编排——它不需要"学会"平台,只需要知道三个原语。

阶段间无屏障是性能关键:pipeline 让每个 item 立即进入下一阶段,而不是等整批。只有 parallel 显式要求屏障(当阶段需要全部先前结果时)。

试一下

运行 s16:

  • 用 pipeline 对 3 个文件并行审计再汇总——比较与串行 s06 的速度
  • 故意让某个子代理失败——观察 .catch(() => null) 让该 item 变 null 而不拖垮整批
  • 用 parallel + 屏障实现"两路调研,合并且对比"

观察重点:脚本是模型生成的、一次性的——这与手写固定流水线有何不同?模型能写出正确的工作流脚本吗?

以下内容基于 packages/workflowdocs/subsystems/workflow.md 的核查。DSH 的动态工作流族:

角色
workflow 工作流执行与生命周期事件(ctx.workflowEngine
workflow-worker-thread 在 worker 线程执行工作流脚本
tool-workflow 通用工作流执行工具
tool-ralph 固定策略的 fresh-agent Ralph 循环工具

你的三个原语(agent/pipeline/parallel)正是 tool-workflow 暴露给模型的钩子(外加 phaselog、schema 校验、meta 声明)。生产差异:

  1. 隔离:worker 线程隔离执行与主事件循环——但不是安全边界(脚本仍能调用子代理做危险事)。
  2. 校验:模型提交的脚本经过严格 schema 校验(错误的钩子用法、未知选项、超出并发上限直接报错杀死脚本——不会静默降级)。
  3. Ralph 变体tool-ralph 是固定策略的"fresh-agent 循环"——每轮全新子代理、共享工作区为长期记忆,用于需要新鲜视角反复冲击同一目标的场景。

一句话:工作流把"编排多子代理"从手工劳动变成模型可编程的一次性脚本。你写的三个原语,就是 DSH 工作流引擎的模型可见面。