Volume 2 · Chapter 24
目标与计划:跨轮次的持续任务与日志化的计划模式
目标(goal)是「同会话的持续任务」:agent 一轮做不完,goal 驱动它继续。计划(plan)是把「计划模式」做成持久状态:计划文档、审批、切换回执行模式,全部是可回放的状态。
(卷一连接点) 05 页 turn 循环 + agent/* 事件续跑 · 06 页 SessionEventMap 扩展
→
本域:goal / goal-round-driver / command-goal / tool-goal / plan-mode / plan
→
(回心脏) goal 续跑经 agent/* 事件回到 kick/turn
示例本次示例:一个跨 turn 的目标
示例轨迹 24-1 · goal 驱动的续跑
# 用户:/goal "把这个目录的所有 TODO 修完" # command-goal 注册目标(commands 旁路,23 页) # 一个 turn 修完 3 个 TODO,还剩 2 个 → turn 以 completed 关闭(05 页) # goal-round-driver(inject=['agents','goals','sessions']): # 监听 agent/* 事件 → 检查 goal 状态(sessions 读日志判断完成度) # → 未完成 → 经 agent 事件发起下一个 turn(续跑) # → 直到 5 个 TODO 全修完 → goal 完成 → 不再续跑 # 全程不需要用户再输入——goal 是「持续任务」,跨多个 turn
来源:24 页 §3 + goal-round-driver/src/index.ts:19
示例轨迹 24-2 · 计划模式的切换
# 用户:/plan "重构认证模块" # PlanModeController(plan-mode/src/index.ts:202): # 切换工具面(tools:计划专用工具集) # 切换提示词面(systemPrompt:计划模式指引) # 状态落盘(logged state)→ 可回放 # 模型产出计划文档 → 用户批准 → 切回执行模式 # 注意:loop 没改一行(05 页)——换的是模型看到的东西(12/14 页)
来源:24 页 §3-4 + 12/14 页的注入面
§1挂载条目
goal → @deepseek-ai/dsh-goal(1291 行)——目标注册表goal-round-driver → dsh-goal-round-driver——把 goal 转成轮次command-goal → dsh-command-goal(226 行)——/goal 命令tool-goal → dsh-tool-goal——模型操作目标的工具plan-mode → dsh-plan-mode——计划模式(PlanModeController,202 行)
§2包文件地图
| 包 | 规模 | 角色 |
|---|---|---|
packages/goal/goal/ | 7 文件 / 1291 行 | 目标能力:static inject = ['agents'](src/index.ts:184)——目标生命周期与续跑 |
packages/goal/goal-round-driver/ | — | inject = ['agents', 'goals', 'sessions'](src/index.ts:19)——把 goal 驱动的续跑接到 agent 事件上 |
packages/plan/plan-mode/ | — | PlanModeController extends Service(src/index.ts:202),static inject = ['tools', 'systemPrompt'](203 行)——计划模式的工具与提示词切换 |
packages/plan/plan/ | — | plan 状态本身(logged state,见 §3) |
§3机制:goal 轮驱动与 plan 状态
- goal 的续跑:goal-round-driver 监听
agent/*事件——一个 turn 结束后若 goal 未完成,它通过 agent 事件发起下一个轮次(05 页 turn-stopping 的「数据决定」之外的另一条续跑通道)。goal 是「同会话目标」,与 subagent 的「另开会话」相对。 - plan 是日志化的状态:进入计划模式 = 一个可回放的持久状态切换。PlanModeController 通过 tools + systemPrompt 注入切换模型的行为面(计划工具集 + 计划提示词)。
- 命令与工具双入口:用户
/goal(命令,23 页的旁路)与模型 tool-goal(工具)都能操作目标——同一能力、两个入口,这是 dsh 的常见形态。
§4关键代码
202export class PlanModeController extends Service {
203 static inject = ['tools', 'systemPrompt']
19export const inject = ['agents', 'goals', 'sessions']
202-203
plan 模式 = 换工具面 + 换提示词面——它不碰 loop(05 页),只改「模型看到什么」(12 页的 systemPrompt 层与 14 页的 registry)。这是「插件不动循环」原则的标准示范。
19
goal-round-driver 的依赖面:agents(听事件/发起轮次)+ goals(状态)+ sessions(读日志判断完成度)。它站在心脏(05 页)的旁边驱动它。
§5易错点
「模型可见 ⟺ 已记录」对 plan 同样适用:计划状态必须可回放——所以 plan 是 logged state(进 SessionEventMap),不是内存变量。切换模式但没落盘 = 重启后模型行为与日志不一致。
goal 与 subagent 的分界:goal = 同会话的持续任务(22 页的对面);subagent = 另开会话。选错机制是常见设计错误——判断标准是「结果是否要留在当前日志里」。