DSH plugin 与计划模式:plan/mode、待定选择冲刷与 exit_plan_mode
DSH plugin 的计划模式不是权限开关,而是一段记录到日志的逐 agent 协作状态。 它激活时只做一件事:让每个模型请求多一段部署持有的 plan:policy 指引;真正的限制由沙箱与审批各自强制,两者都不读写计划状态。理解这条边界,才能解释两个常被当成 bug 的行为:切换模式后当前轮行为不变(选择要等下一个被接受的轮内 pre-step 才追加),以及非计划模式下 exit_plan_mode 仍然在工具目录里(为了保证进入/离开只改提示词、不改工具清单)。
DSH plugin 计划模式的状态:plan/mode 事件与回放
一句话结论:模式是一个整值替换的日志事件,持久可回放,但从不进入模型对话记录。
- 事件载荷:
plan/mode就是{ active: boolean },整值替换。 - 回放能力:恢复、fork 与压缩都能从日志还原已记录状态与待生效选择。
- 折叠单元:可选的
plan单元折叠已提交模式、命令结算结果与最近一次请求头记录的模式。 - 读取入口:
ctx.planMode通过stateOf()读;注册表、plankey 或turnBoundarykey 缺失时,第一次访问就失败。 - 客户端视图:只接收
{ active, pending }两个字段,不暴露内部折叠细节。
DSH plugin 的待定选择:为什么切换不是立刻生效
一句话结论:所有会话事件都在轮内,选择必须先待定,再由下一个被接受的轮内 pre-step 在派生请求之前追加。
- 待定规则:用户选择保持 pending,直到下一个被接受的轮内 pre-step 追加它,与那个 pre-step 位于哪个轮次无关。
- 不强制续行:选择本身不会逼着 agent 继续,所以在一轮最后一个被接受的 pre-step 之后做的选择,会在之后的轮次追加。
set的返回值:committed(已写入日志)、queued(等待追加)、cancelled(取消了相反方向的待定选择)、noop(已经是该状态)。get的语义:返回已记录状态与可选的待定状态,组装当前步骤时用前者。- 已知限制:轮末之后的选择只存在于进程内,进程在下一个被接受的 pre-step 之前退出就会丢。
DSH plugin 的追加点:agent/pre-step 与一次性通知
一句话结论:唯一追加点是前置注册的 pre-step 监听器;追加失败不能阻塞轮次。
- 监听范围:每个候选请求步骤,包括第 1 轮第 1 步与请求恢复重试。
- 决策顺序:先调用下游监听器,只有下游接受该步骤后才追加。
- 提示词阶段的限制:提示词准入发生在轮次开启之前,无法追加
plan/mode,所以那里的选择由它开启的轮次内第一个被接受的 pre-step 补上。 - 失败处理:追加失败不能阻塞轮次,选择继续等待之后被接受的 pre-step。
- 模型通知:追加时会记录一条插件来源的
user/message,但仅当最近请求头描述的是另一种状态——模型恰好在上下文变化时收到通知,且不会重复。
DSH plugin 的配置与退出:section 与 exit_plan_mode
一句话结论:指引文本由部署提供,缺字段或未知键在加载时就失败;退出工具常驻注册,但只在计划模式内可执行。
- 配置形态:
PlanModeConfig { section: string },缺失、空白、非字符串或未知键都会在加载时失败。 - 渲染位置:激活期间以 order 50 渲染为
plan:policy段落;未激活不贡献文本。 - 退出工具:
exit_plan_mode在非计划模式仍注册,执行会失败;计划模式中要求一份以#标题开头的完整 markdown 计划。 - 评审流程:通过用户交互 seam 呈交;批准返回
{ approved: true }并记录静默的待生效退出。 - 继续规划:是一次携带用户反馈的失败调用,模型据此修订再提交;交互通道缺失或服务重载也会让调用失败,而不是静默离开。
/plan命令:单独的/plan选择计划模式;/plan off选择未激活并取消尚未可见的待定条目;/plan <message>先选模式再通过 steer 作为普通用户消息提交。
DSH plugin 计划模式与沙箱、审批的边界
一句话结论:计划模式管「怎么说」,沙箱与审批管「能不能做」——三者互不读写对方状态。
- 计划模式:软性指引,只影响提示词。
- 沙箱模式:强制进程与文件约束,不读计划状态。
- 审批策略:决定某次操作是否需要用户批准,同样不读计划状态。
- 部署要分开配:想让计划阶段真的更保守,需要同时收紧沙箱与审批,而不是只开计划模式。
- 判据:如果「开了计划模式还是改文件」,那是沙箱/审批没配,不是计划模式失效。
DSH plugin 排查注意事项
一句话结论:计划模式的问题先分「没生效」「没退出」「状态丢失」三类。
- 切了没生效 → 正常,等待下一个被接受的轮内 pre-step;看
set返回的是不是queued。 - 提交了计划还在继续 → 批准是待生效退出,当前工具批次剩余部分仍按计划指引执行。
- 状态丢失 → 选择发生在轮末之后且进程退出,属于已知限制。
plan:policy没出现 → 检查 section 配置与模式是否真的激活。- 以为能限制工具 → 计划模式不限制,去查沙箱与审批。
- 修复状态如实:本文的事件形态、待定规则、追加点与退出流程均取自官方「计划模式」页面与包 README;接口签名与命令行为以该页 Cordis API 与你所用版本为准。
常见问题
DSH plugin 的计划模式是软性指引:激活时每个模型请求多一段部署持有的计划指引,但不限制工具。真正的限制由沙箱模式与审批策略分别强制,两者都不读写计划状态,需要分开配置。
DSH plugin 的选择在轮内是待生效的,要等下一个被接受的轮内 pre-step 才追加,且追加发生在派生请求之前。提示词阶段做的选择无法直接追加,会由它开启的轮次里第一个被接受的 pre-step 补上。
注册一直在,所以工具目录不随模式变化;但 DSH plugin 的 exit_plan_mode 在计划模式之外执行会失败。这样设计是为了让进入与离开计划模式只改变提示词段落,不改变可用工具清单。
DSH plugin 的批准会记录一个静默的待生效退出,由下一个被接受的轮内 pre-step 追加,因此计划指引在当前这批工具调用的剩余部分仍然生效,工具结果本身会报告这次转换。
会,DSH plugin 的这个选择只存在于进程内;如果进程在另一个被接受的轮内 pre-step 之前退出,选择就丢了。跨轮的选择才会立即写入日志。
相关术语
- plan/mode
- plan/mode 是计划模式的会话事件,载荷为 {active: boolean},整值替换、仅记日志。它持久且可回放,但绝不进入模型对话记录。— https://deepseek-harness.github.io/deepseek-harness/reference/subsystems/plan
- 待生效选择(pending)
- 待生效选择是已记录但尚未写入日志的模式切换,会等下一个被接受的轮内 pre-step 在派生请求之前追加。客户端只看到 {active, pending} 两个字段。— https://deepseek-harness.github.io/deepseek-harness/reference/subsystems/plan
- plan:policy
- plan:policy 是计划模式激活期间注入的系统提示词段落,内容是部署配置的 section 文本,按 order 50 渲染。未激活时不贡献任何文本。— https://deepseek-harness.github.io/deepseek-harness/reference/subsystems/plan
- exit_plan_mode
- exit_plan_mode 是稳定注册的退出工具:计划模式中要求一份以 # 标题开头的完整 markdown 计划并提交评审,批准后记录静默的待生效退出。— https://deepseek-harness.github.io/deepseek-harness/reference/subsystems/plan
来源
- DeepSeek Harness 文档 — 计划模式(plan/mode、待生效选择、配置、退出工具与 /plan)· deepseek-harness.github.io
- dsh-plan-mode 包 README(已知限制与延后工作)· deepseek-ai(GitHub)
- DeepSeek Harness 文档 — 系统提示词(plan:policy 段落与装配顺序)· deepseek-harness.github.io