# dsh-dcp 压缩处理流(Compression Flow) > 本文说明 dsh-dcp 插件对“压缩上下文”的完整处理逻辑,包括模型调用、 > 校验、checkpoint 注入、inline cleanup、模型可见语义、审计与恢复。 > 协议细则见 [docs/PROTOCOL.md](./PROTOCOL.md),统计口径见 > [docs/STATS.md](./STATS.md)。 ## 1. 目标 dsh-dcp 的目标是:在 dsh 的模型可见上下文演化过程中,把**已经闭合、 不再需要逐字保留的旧对话区间**替换为一个**包含完整技术摘要的标准 checkpoint**, 从而降低后续请求的 token 用量,同时不破坏 dsh 的请求不变式: ```text llm/stream 的 options.messages === session.deriveMessages() ``` 插件不在请求时临时改写模型消息;一切压缩结果都先成为已落库的 surface 事件。 ## 2. 核心概念 | 概念 | 说明 | | ---------------- | --------------------------------------------------------------- | | `mNNNN` | 日志化 boundary marker,模型可见的边界引用 | | `bN` | 一个 DCP checkpoint,也是可引用的活跃边界 | | `range` | half-open 区间 `[startRef, endRef)` | | `topic` | 压缩区间短标题,用于人类阅读和统计 | | `summary` | 模型提供的完整技术正文 | | `checkpoint` | 替换原区间后的标准 `user/message` | | `inline cleanup` | 同一步把 assistant 消息中的 summary 参数清理为 `[stored in bN]` | | `shadowed` | 被压缩区间遮蔽的原始 surface 节点 | ### 2.1 边界标记 每个 step 入口,插件追加: ```xml ``` - 引用按 surface position 解析,不按 seq 数值大小。 - range 是 half-open,`endRef` 本身不被压缩。 - 陈旧/无效引用 fail closed,不扩大范围。 - 被原生 compaction 吸收后,会追加 alias 以保持旧引用可解析。 ## 3. compress 工具调用 模型调用: ```json { "topic": "初始仓库检查", "content": [ { "startRef": "m0001", "endRef": "m0004", "summary": "这里是完整技术正文,而不是指针式占位。" } ] } ``` 一次调用可以包含多个不重叠 range,每个 range 独立事务。 ### 3.1 输入校验 - `topic` 非空且 ≤ 200 字符。 - `content` 非空数组,数量 ≤ `maxRangesPerCall`。 - 每个 range 的 `startRef` / `endRef` 必须存在且合法。 - ranges 必须按 surface 顺序且互不重叠。 - range 两侧 cuts 必须工具配对平衡。 - range 不得进入最近 `retainRecentTurns` 个 turn。 - range 不得包含当前 compress 调用。 - range 不得包含硬保护内容(instructions / snapshot)。 - 净节省必须 ≥ `minNetSavingsTokens`。 - `summary` 必须: - 非空; - ≤ 8000 字符; - 不以内嵌 `[bN]` 块引用前缀开头; - 是实际技术正文,不是 `[stored in bN]` 这类指针占位。 ## 4. 压缩事务与 checkpoint 注入 每个 range 独立记录以下日志序列: ```text compaction/start → compaction/summary → user/message (checkpoint,surface replace) → compaction/end ``` 其中: - `compaction/summary` 保存 `shadowedSeqs`、`shadowedTokenCount` 和摘要; - `user/message` 使用标准 surface replace 替换原区间; - `sourceEventSeqs` 记录被遮蔽的全部 surface 节点; - `compaction/end` 关闭该笔事务。 ### 4.1 checkpoint 文本格式 ```text [Compressed conversation section] <完整技术正文> (可选:受保护内容附录,原样保留) b1 ``` 要点: - blockRef 只通过 `` 表达; - summary 正文中不携带 `[bN]` 前缀; - 受保护内容(用户消息、``、受保护工具、来源附录等)以附录形式保留; - checkpoint 是模型后续读到的**权威摘要**。 ## 5. inline cleanup 模型调用 `compress` 时,assistant 消息中通常包含一大段内联 summary。 压缩提交后,插件在同一步把该 assistant 消息里的 tool-call `summary` 字段改为: ```text [stored in bN] ``` ### 5.1 为什么需要 - 避免同一份完整摘要同时出现在“checkpoint”和“旧 assistant 参数”中; - 保留 assistant 消息、tool-call id、message id 不变; - 原始完整参数仍保留在 `tool/call` 的 raw log 中,形成审计链。 ### 5.2 模型可见语义(重要) 压缩成功后,模型后续看到的上下文包含: 1. **checkpoint `user/message`**:完整技术正文,权威内容; 2. **assistant 消息中的工具调用参数**:`[stored in bN]`,这只是清理标记; 3. **tool result**:报告压缩消息数和生成 blockRef,并明确说明完整摘要保存在 checkpoint 中。 因此: ```text [stored in bN] ≠ 原始 summary [stored in bN] ≠ 数据丢失 checkpoint = 完整摘要唯一权威位置 ``` 模型不应因为看到自己被改写后的 tool-call 参数,就误以为提交了占位符。 ## 6. 多 range 与部分失败 - 一次 `compress` 可以携带多个 range; - 每个 range 独立提交; - 批内后续 range 在提交时按当前 surface 重新解析; - 某个 range 失败只进入 `failed`,不伪造跨 range 原子性; - tool result 会列出成功 blocks 和失败 ranges。 ## 7. 持久化与恢复 - 原始 session 日志永不删除; - checkpoint 是标准 `user/message`,可被 dsh 持久化、重启、投影; - DCP 状态可以从日志冷重放:`reduceDcpState()`; - 被原生 compaction 吸收或再次压缩的 `bN` 通过 membership 重分类; - 支持 `show`、semantic expansion、recompress 等只读/恢复路径。 ## 8. 常见误读与防护 | 误读 | 实际情况 | 防护 | | ---------------------------------------------------- | --------------------------------------- | ------------------------------------ | | 认为 `[stored in bN]` 是提交的 summary | 只是 inline cleanup 标记 | 工具结果 + 系统提示 + 本文档明确说明 | | 认为 checkpoint 没有注入上下文 | checkpoint 是 surface `user/message` | 日志顺序 + deriveMessages 不变式 | | 认为摘要开头必须写 `[bN]` | blockRef 只能由 `` 表达 | schema 拒绝 + checkpoint 构造剥离 | | 认为多个 range 必须分多次调用 | 一次调用可携带多个 range | 工具描述 + 系统提示 + 示例 | | 把 `compaction/summary` 的 token 与 prune token 混算 | 两者口径不同 | `docs/STATS.md` 明确区分 | ## 9. 一句话总结 > dsh-dcp 的压缩 = 把一段闭合历史替换成包含完整技术摘要的标准 checkpoint, > 同时把模型原始 inline summary 参数清理为 `[stored in bN]` 审计标记。 > 完整摘要的权威位置是 checkpoint `user/message`。