前言¶
DSH(DeepSeek Harness)的理念是「一切皆插件」。做智能体开发时常见这样一个需求:会话聊了几轮发现走偏了,希望回到之前某一轮重来,而不是整个会话作废。QinLuza/dsh-rollback-visual 就是冲着这个需求做的 /rollback 插件仓库:后端用 fork 子会话实现回滚,前端尝试把回滚锚点可视化到轨迹视图里。
先说结论:这个仓库已经废弃,不要再用了。原因有两个:一是对话回退方向,官方 DSH 已自带 fork/分支功能,这里属于重复造轮子;二是前端可视化采用的 DOM 注入方案有根本问题,已放弃。仓库现在仅作踩坑存档保留,不再维护,替代项目是 QinLuza/dsh-file-undo。
下面按仓库现状介绍:后端三件套做了什么、命令怎么用、前端方案为什么被放弃,以及现在还能从里面拿到什么。
仓库现状¶
- 已废弃,不再维护。package.json 中版本为
0.0.1,private: true,许可证 MIT。 - 后端三件套实现的 fork 子会话回滚当时已可用,但方向被官方自带功能覆盖。
- 前端可视化(DOM 注入)已放弃。
- 保留内容:
docs/踩过的雷.md记录了 10 个雷,供后续 DSH 插件开发避坑。
回滚是怎么设计的¶
先交代模型:回滚 = 在会话事件日志里选一个边界 seq,fork 出一个子会话。源会话历史不变,子会话从边界处开始新时间线;成功后在会话列表切到新子会话继续,源会话保留原样,可随时切回。
具体分三块。
checkpoint 锚点¶
每轮(turn)结束自动追加一条 rollback/checkpoint 事件,记录 turn 号和边界 seq。有了锚点,回退时按「第几轮」选即可,不用记 seq。不想要锚点,配置 checkpoints: false 可以关掉。
fork 回滚与事务标记¶
回滚在边界处派生子会话,源会话留下成对的 rollback/start → rollback/end 事务标记。标记成功、失败都闭合,没有悬空括号;全部落盘,可重放。
边界验证¶
非法边界一律拒绝,包括五种情况:越界、落在 open turn 内、落在 compaction 区间内、agent 忙碌(busy)、信号中止(cancelled)。失败时返回人类可读原因:busy、boundary、cancelled、persistence。
安装与加载¶
仓库分两部分,装法不同。先说后端三件套:timeline-rollback / rollback-basic / command-rollback,源码与构建配置不在本仓库,在 QinLuza/deepseek-harness-research 的 feat/timeline-rollback 分支。加载方式:
1、在 profile 的 cordis.patch.yml 中 insert rollback-basic 与 command-rollback 两条;
2、timeline-rollback 是 Service Definition,作为依赖自动引入,不要单独加载。
经过上面的步骤,后端三件套会随 profile 加载。前端插件就是本仓库,两步:
pnpm build
dsh plugin --profile web add .
先用 pnpm build 构建,再用 dsh plugin 把当前目录加进 web profile。
提醒:插件以当前 dsh 进程权限运行,安装前应检查源码与许可证(本仓库为 MIT)。本仓库已不再维护,以上仅作存档记录。
命令用法¶
在 GUI 输入框输入,或 CLI 环境执行:
| 命令 | 作用 |
|---|---|
/rollback |
显示用法 + 当前会话所有 checkpoint 锚点列表 |
/rollback checkpoint |
回退到最近一个锚点 |
/rollback checkpoint:<turn> |
回退到指定 turn 的锚点 |
/rollback <seq> |
精确回退到指定事件 seq(高级用法,易错) |
一个实际例子:
/rollback
→ turn 3 -> seq 47
→ turn 7 -> seq 120
/rollback checkpoint:3
→ Rolled back to seq 47 — new child session rollback-xxxx.
/rollback 先列出所有锚点;/rollback checkpoint:3 回到第 3 轮对应的边界 seq 47,生成新的子会话 rollback-xxxx。
两条约束要记住:
- 回滚只 fork 会话历史,工作区 / 沙箱文件不会回退;
- 回滚必须在轮次之间进行:agent 空闲、边界落在 turn 结束处。
前端可视化:为什么放弃¶
渲染层采用 MutationObserver 做 DOM 注入,这个方案有根本问题,已放弃,不再重构,完整踩坑记录见 docs/踩过的雷.md。
数据层是写对了的:src/client/anchors.ts 里的 conversationEvents / conversationViews 定义可复用。路线图中原计划把渲染层重构为轨迹原生节点,未完成。
适用场景与注意¶
- 实际需要回退对话:直接用官方 DSH 自带的 fork/分支功能,不要装这个仓库;
- 需要撤销 agent 的文件操作:用替代项目
QinLuza/dsh-file-undo,操作级回退,/undo恢复到操作前; - 想给 DSH 写插件、尤其是要在前端注入 UI:先读
docs/踩过的雷.md,10 个雷是现成的避坑材料; - 想研究 fork 回滚、事务标记、边界验证的实现:后端源码在
QinLuza/deepseek-harness-research的feat/timeline-rollback分支。
注意本仓库不再维护,不要在生产环境依赖它。
结尾¶
dsh-rollback-visual 的后端三件套验证了 fork 子会话回滚可行,前端 DOM 注入则留下了一份反面教材。仓库的使命已经结束,剩下的价值在踩坑记录、可复用的数据层和替代项目。
- GitHub:https://github.com/QinLuza/dsh-rollback-visual
- 社区目录页:https://www.skillhub.cn/plugins/QinLuza/dsh-rollback-visual
社区目录为独立站点,与 DeepSeek / 幻方无官方从属关系。