Volume 2 · Chapter 25
工作流与任务:多代理编排与后台作业
工作流(workflow)是确定性编排多代理的引擎——fan-out、pipeline、循环由一段脚本控制,不是模型驱动。任务(jobs)是后台长作业:tool-bash 的后台命令(17 页)就落在这里。加上 todo 工具(模型的持久待办快照),构成本章的三个「时间维度」。
(卷一连接点) 22 页 subagent(workflow 的底层)· 17 页 tool-bash 后台路径(jobs)
→
本域:workflow / workflow-worker-thread / tool-workflow / jobs-local / tool-jobs / tool-todo
→
(回心脏) workflow 的 agent 池与 jobs 的结果都回到会话日志
示例本次示例:后台任务与 todo
示例轨迹 25-1 · bash 后台命令 → jobs
# 模型:bash({command:'npm test', background:true})
# 17 页 354 行 ctx.get('jobs') 有值 → 370 行 ctx.shell.start(...)
# → ShellProcess → background.ts 的 processOutcome → jobs-local 注册任务
# 模型:tool-jobs 查看 → "任务 j1 运行中"
# 测试跑完 → 任务 outcome:completed → 模型再查 → 结果文本
# 整个过程模型的 turn 不阻塞——jobs 是「时间上外挂」的作业
来源:17 页 354-370 行 + 25 页 jobs-local
示例轨迹 25-2 · todo/write 与模型的关系
# 模型修 TODO 时调用 todo_write({ todos:[{content:'修 auth', status:'in_progress'},...] })
# 落盘:{ "type":"todo/write", "seq":N, "data":{ "todos":[...] } }
# 关键:todo/write 是 log-only(06 页 SurfaceEventType 只有三个类型)
# → 不进 deriveMessages → 模型下一请求看不到它(除非 UI 注入)
# UI 显示待办列表(全量快照,最新写入胜出)
# 模型靠「自己调用时的最新快照」管理——不是持久记忆
来源:25 页 §3 + 06 页 todo/write 的 JSDoc
§1挂载条目
workflow-ptc → dsh-workflow-ptc——PTC 运行时里的工作流引擎(0.1.6 起,取代原 worker-thread 实现)tool-workflow → dsh-tool-workflow——模型发起工作流的工具jobs → dsh-jobs-local(534 行)——本地后台作业注册表tool-jobs → dsh-tool-jobs(432 行)——模型查看/停止后台作业tool-todo → dsh-tool-todo(384 行)——todo/write 事件(06 页 SessionEventMap 的 log-only 事件)schedule → dsh-schedule(2140 行,可选挂载)——定时任务
§2包文件地图
| 包 | 规模 | 角色 |
|---|---|---|
packages/workflow/workflow/ | 4 文件 / 519 行 | Service Definition:WorkflowEngine extends Service(src/index.ts:157)——脚本引擎契约 |
packages/workflow/workflow-ptc/ | 9 文件 / 1321 行 | Provider:static inject = ['subagents', 'ptcRuntime', 'sandboxPolicy'](src/index.ts:103)——0.1.6 起在沙箱化的 PTC 运行时里执行编排脚本(原本是 worker 线程),经 subagent(22 页)派生代理 |
packages/workflow/tool-workflow/ | — | Consumer:inject = ['tools', 'workflowEngine', 'systemPrompt'](src/index.ts:30) |
packages/jobs/jobs-local/ | 1 文件 / 534 行 | 后台作业的本地实现 |
packages/todo/tool-todo/ | 4 文件 / 384 行 | todo/write 的写入工具(全量快照、last-write-wins) |
§3机制:脚本编排 vs 后台作业
- workflow = 确定性编排:脚本(fan-out/pipeline/loop)决定哪些 agent 何时跑——这与主循环的「模型决策」正交。引擎在 PTC 运行时(沙箱化的脚本执行环境)里执行,底层代理来自 subagent seam(22 页的复用)。
- jobs = 后台作业:tool-bash 的
start把 ShellProcess 适配成 jobs 任务(processOutcome,0.1.6 起拆到tool-bash/src/background.ts)——模型随时用 tool-jobs 查看/停止。 - todo = 模型自己的待办:
todo/write是全量快照、最新写入胜出的 log-only 事件(06 页 types.ts 的 JSDoc 原话)——不进派生历史,仅 UI 使用。
§4关键代码
157export abstract class WorkflowEngine extends Service {
102class PtcWorkflowEngine extends WorkflowEngine {
103 static inject = ['subagents', 'ptcRuntime', 'sandboxPolicy']0.1.6:多了运行时与沙箱策略
157
workflow 的 Definition 与 compaction/subagent 同构——但它的「能力」是编排脚本,不是模型能力。
102-103
依赖 subagents 是关键:工作流不自己造 agent,它编排 22 页 seam 提供的 agent——seam 复用链:workflow → subagents → agents(05 页)。0.1.6 起又多两个依赖:ptcRuntime(脚本在哪跑)与 sandboxPolicy(以什么权限跑)。编排脚本从「worker 线程」搬进了「沙箱化的 PTC 运行时」——脚本是模型写的,它该和工具执行受同一套沙箱约束。
§5易错点
todo/write 是 log-only(06 页 SurfaceEventType 只有四个消息生产类型,todo 不在其中)——它永不下发模型,只是 UI 状态。若误以为模型能看到 todo,会写出模型从不知情的工具。
jobs 的存活边界在 17 页提过:后台进程的 teardown 归 subprocess disposal——jobs 只是「查看/停止」的窗口,不拥有进程。