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 状态

  1. goal 的续跑:goal-round-driver 监听 agent/* 事件——一个 turn 结束后若 goal 未完成,它通过 agent 事件发起下一个轮次(05 页 turn-stopping 的「数据决定」之外的另一条续跑通道)。goal 是「同会话目标」,与 subagent 的「另开会话」相对。
  2. plan 是日志化的状态:进入计划模式 = 一个可回放的持久状态切换。PlanModeController 通过 tools + systemPrompt 注入切换模型的行为面(计划工具集 + 计划提示词)。
  3. 命令与工具双入口:用户 /goal(命令,23 页的旁路)与模型 tool-goal(工具)都能操作目标——同一能力、两个入口,这是 dsh 的常见形态。

§4关键代码

packages/plan/plan-mode/src/index.ts计划模式控制器202-203
202export class PlanModeController extends Service {
203  static inject = ['tools', 'systemPrompt']
packages/goal/goal-round-driver/src/index.tsgoal 续跑的三依赖19
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 = 另开会话。选错机制是常见设计错误——判断标准是「结果是否要留在当前日志里」。