这是什么
长会话里,DSH 会把早期历史压成一条摘要。压一次没事,压三次之后—— 「当初为什么否决了方案 A」、「那个参数定的是 0.75 还是 0.8」、「测试到底跑没跑过」—— 这些细节就都没了。模型甚至会推翻自己刚才确认过的结论。
cairn 是登山者在无路高原上堆的石堆路标:沿途堆几块石头,后人循石而行。
本插件让模型在里程碑处堆一块路标:写下当前目标、已定结论、否决过的方案、 待办与证据。插件把它存进自己的目录,并在每次压缩后重新注入系统提示词—— 压缩冲不走一块放在提示词里的石头。
它解决什么
| 你遇到的 | 没有 cairn | 有 cairn |
|---|---|---|
| 压缩后模型否认刚才的结论 | 「我没说过要改配置」 | 从检查点读到,直接接着做 |
| 反复讨论已经否决的方案 | 重新提议方案 A | 读到「A 已否决,原因是 X」 |
| 忘了测试跑没跑过 | 重跑一遍或凭空声称通过 | 从 Evidence 里读到原始输出要点 |
| 新会话接手同一件事 | 从零开始问你要做什么 | 摘要卡片自动带上前情 |
四档注入策略(这是省 token 的关键)
插件不是把检查点无脑塞进每一轮。它先判断这份检查点和当前会话的关系:
| 情形 | 注入什么 | 实测体积 |
|---|---|---|
| 同一会话 | 全文(≤12000 字符) | 起 240 字符 |
| 跨会话、7 天内、主题相关 | 摘要卡片(≤900 字符) | 约 175 字符 |
| 跨会话、过期或主题不相关 | 一行指针 | 约 95 字符 |
| 还没有检查点 | 什么都不注入 | 0 字符 |
所以:不相干的历史不会占你的上下文。只有当你要接着做同一件事时,它才出现。
「主题相关」靠你写检查点时给的一句
topic和几个keywords判断。 这两个字段务必写,否则跨会话时只会给你一行提示。
三个工具
| 工具 | 作用 |
|---|---|
checkpoint_write |
写下/更新检查点(旧的一代自动归档,保留最近 20 代) |
checkpoint_read |
读回全文,或按关键词过滤行 |
context_status |
看真实 token 占用、窗口、以及这份检查点为什么被注入/没被注入 |
另有一个 context_compact:在支持压缩服务的环境里预约一次主动压缩
(若宿主的压缩服务不在插件所在的平面,它只落盘、不压缩,并如实告知)。
什么时候写检查点:插件会主动提醒
这不是「靠模型自觉」的插件。 除了把纪律写进提示词,它还在四个时机主动介入:
① 上下文越线提醒(自动注入,最直接的一种)
插件每步测量真实占用,跨越档位时主动向会话注入一条提醒(同一档位只提醒一次,不刷屏):
| 档位 | 触发阈值 | 注入的提醒 |
|---|---|---|
warm |
占用 ≥ 窗口 50% | 「已过半。先调用 checkpoint_write 落盘,再调用 context_compact」 |
near |
占用 ≥ 80% | 「接近上限。立刻更新检查点」 |
over |
占用 ≥ 90% | 「已越过安全线。立即更新检查点」 |
这条提醒是插件推给模型的,不需要模型先想起自己该写。
② 常驻的提示词段(每一轮都在)
只要本会话已有检查点,系统提示词里就常驻一段规则:
- 本段是本会话的权威副本;与项目文档或 repo 冲突时以 repo 为准,其余以本段为准。
- 顺序:上下文紧张时先
checkpoint_write落盘,再context_compact。
模型不需要"记得"这个约定,它每轮都能读到。
③ 随包分发的 skill(声明式触发条件)
插件自带一份 context-checkpoint 技能,明确列出四类触发事件:
| 触发 | 说明 |
|---|---|
| 明确压力信号 | 系统或用户告知上下文将尽(最高可信) |
| 里程碑 | 根因找到 / 方案确定 / 模块改完 / 测试通过 / 用户确认一条决策 |
| 压缩后对账 | 首次观察到新的 <compacted-summary> |
| 应急补救 | 已出现溢出类报错 |
④ 压缩后的唤醒消息
压缩执行完后,插件会主动注入一条后续消息,告诉模型「检查点已落盘、历史已压缩, 直接接着做,不要重述已完成的工作」——避免压缩后模型从零开始。
仍然需要人管的部分:如果你的任务是「纯增量、从不到 50% 也从不压缩」, 上述提醒都不会触发。这类场景建议在
AGENTS.md里写一条里程碑纪律 (例如「每个模块改完调用一次checkpoint_write」),把它变成固定动作。
安装
dsh plugin --profile desktop add dsh-flashback
装好重启 DSH 即可。
需要 DSH
0.2.x。插件不修改你的cordis.patch.yml,也不写settings.yaml; 卸载后随插件目录一起消失。
数据存在哪
全部在插件自己的目录里,你的工作区一个文件都不会多。
<DSH_HOME>/plugins/dsh-flashback/data/
├── checkpoints/<工作区标识>/
│ ├── current.md 当前活跃副本
│ ├── current.meta.json 代际/时间/主题/关键词
│ └── gen-NNN.md 旧代际(保留 20 份)
├── active-variant.lock 运行时锁(多包共存时决定谁生效)
├── tmp/ 原子写中转(正常为空)
└── logs/
为什么写插件自己的目录,而不是工作区里:
- 不扰乱工作区的文件结构 —— 装个插件不该让你的目录多出东西来;
- 检查点不随项目走 —— 它是本地的工作状态,不必进版本库、也不必同步给同事;
- 不依赖工作区的写入权限 —— 有些环境下工作区是只读的,或对子目录有额外限制。
与 DSH 压缩机制的关系
DSH 的压缩是有损的:它把一段历史折成一条摘要,细节按设计被丢弃, 而且会要求模型「丢掉过时信息」。压得越多,衰减越重。
cairn 不去改压缩本身,也不跟它抢活。它做的是:
把「压缩碰不到的地方」当成权威副本。
具体是 systemPrompt.section —— DSH 的系统提示词首节点永不参与压缩。
检查点放在那里,所以它能跨越任意多次压缩。
配置
插件没有必须手改的配置。可调项集中在 data/ 与工具参数里:
| 项 | 默认 | 说明 |
|---|---|---|
| 单份检查点写入上限 | 60000 字符 | 超出直接拒绝,不静默截断 |
| 单份检查点注入上限 | 12000 字符 | 超出截断并提示,仍可用 checkpoint_read 取全文 |
| 保留代际数 | 20 | 超出删最旧 |
| 跨会话卡片有效期 | 7 天 | 超过只给一行指针 |
| 落盘新鲜度窗口 | 10 分钟 | 超过则 context_compact 拒绝预约 |
已知限制
- 不会自动总结你的对话。插件负责在合适的时机提醒并落盘,但"写什么"由模型判断;
想让它在项目里程碑处固定动作,可在
AGENTS.md里加一条纪律 (例如「每个模块改完调用checkpoint_write」)。 - 跨会话相关性的判断是关键词级的,不是语义 embedding。 误判方向刻意保守:宁可只给一行提示(你自己去读),也不给全文(白烧 token)。
- 主动压缩可能不可用。取决于你的 DSH 装配,插件可能拿不到压缩服务; 此时它只负责落盘与重注入(核心能力不受影响),DSH 自带的自动压缩照常工作。
- 同一份数据目录只允许一个实例生效。插件用
data/下的一个锁文件做仲裁; 两个 DSH 实例指向同一个插件目录时,后到的会休眠。
兼容的 DSH 版本
- 目标:DSH 0.2.x(
0.2.1-rc.5实测) - 零外部依赖:只
importnode:*与包内相对模块,因此不受官方包版本升级影响 - 不依赖
schemastery/zod等第三方库
许可
MIT
Copyright (c) 2026 Saretheya · 基于 Leafstory 的 context-checkpoint(MIT)继续开发
No comments yet. Be the first to write one.