Workflow
模型编排多阶段子代理流水线。
workflow 脚本 = 阶段 + 并行 + 屏障。
问题
一个任务天然分成多块独立工作:"先审计 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/workflow 与 docs/subsystems/workflow.md 的核查。DSH 的动态工作流族:
| 包 | 角色 |
|---|---|
workflow |
工作流执行与生命周期事件(ctx.workflowEngine) |
workflow-worker-thread |
在 worker 线程执行工作流脚本 |
tool-workflow |
通用工作流执行工具 |
tool-ralph |
固定策略的 fresh-agent Ralph 循环工具 |
你的三个原语(agent/pipeline/parallel)正是 tool-workflow 暴露给模型的钩子(外加 phase、log、schema 校验、meta 声明)。生产差异:
- 隔离:worker 线程隔离执行与主事件循环——但不是安全边界(脚本仍能调用子代理做危险事)。
- 校验:模型提交的脚本经过严格 schema 校验(错误的钩子用法、未知选项、超出并发上限直接报错杀死脚本——不会静默降级)。
- Ralph 变体:
tool-ralph是固定策略的"fresh-agent 循环"——每轮全新子代理、共享工作区为长期记忆,用于需要新鲜视角反复冲击同一目标的场景。
一句话:工作流把"编排多子代理"从手工劳动变成模型可编程的一次性脚本。你写的三个原语,就是 DSH 工作流引擎的模型可见面。