S5.4.1 Task 5.4

保存、压缩、恢复:/compact 的三步工作流

/compact 命令压缩对话历史以释放上下文空间。它是延长长会话的主要工具——让会话能继续超过上下文本该填满并开始退化的点。但它有一个代价:compact 是有损的。

压缩前:src/auth/middleware.ts:45 → validateToken()。压缩后:“认证模块”和”一个验证函数”。压缩把具体细节摘要成了笼统描述。

解决方案是三步工作流:保存发现到 scratchpad 文件,压缩对话,恢复发现(通过读取 scratchpad)。

为什么 /compact 是有损的

/compact 通过摘要对话历史来减少上下文。摘要的本质就是用概括替代具体。文件路径变成”auth 模块”。函数签名变成”一个验证函数”。行号完全消失。压缩后的历史保留了叙述(“我们研究了认证”)但丢掉了精度(“文件 X,行 Y,函数 Z”)。

这不是 bug。这是压缩固有的权衡。问题在于你是提前做好准备,还是事后措手不及。

三个步骤

步骤 1:保存

运行 /compact 之前,把所有关键发现写入 scratchpad 文件:

Claude, write our current findings to findings.md:
- src/auth/middleware.ts:45 → validateToken() checks JWT expiry
- src/db/pool.ts:8 → connection pool max=20, timeout=5000ms
- Bug: src/api/orders.ts:112 — race condition on concurrent updates
- Architecture: auth middleware wraps all /api/* routes

大约 30 秒。信息现在在磁盘上,不受任何上下文操作影响。

步骤 2:压缩

运行 /compact。对话历史被压缩,上下文空间释放。对话中的具体引用可能被摘要掉。这是预期中的——scratchpad 里有。

步骤 3:恢复

压缩后,读取 scratchpad:

Read findings.md to restore our exploration context.

代理现在恢复了关键细节到工作上下文中,同时有了释放的空间继续探索。

数据:30 秒节省 8 分钟

跨探索会话的对照比较:

指标不带 scratchpad 的 compact带 scratchpad 的 compact
具体引用丢失40%3%
返工(重新发现信息)会话时间的 25%会话时间的 2%
平均每次会话返工时间8 分钟约 0
压缩前保存时间030 秒

保存到 scratchpad 的 30 秒投入几乎消除了压缩后的所有信息丢失。3% 的残余丢失代表边缘情况——没有显式保存到文件的发现。

为什么”重新 Grep 一下就行”不管用

常见反对意见:“如果 compact 丢了文件路径,我再 Grep 搜一下就好了。“对简单文本模式这行得通,但很多探索发现不是靠搜索能重新发现的:

  • 架构理解 — “auth 中间件包装所有 /api/* 路由并委托给服务特定的 handler”来自读取多个文件并推理整个流程,不是来自某个可搜索的字符串。
  • 跨文件依赖映射 — 知道模块 A 通过间接导入链依赖模块 B 需要追踪多次 Read 操作。
  • Bug 分析 — “并发订单更新的竞态条件,因为 read-check-write 序列不是原子的”是读代码后的结论,不是任何文件中的字符串。

Grep 恢复字符串。Scratchpad 恢复理解。当你的发现来自对多个文件的推理而非模式匹配时,这个区别很重要。

长会话中的多次 Compact 循环

超长会话(60+ 分钟)通常需要 2-3 次 compact 操作。每次 compact 前只保存并覆盖 scratchpad 会丢失早期发现。正确做法:增量追加

Scratchpad 文件在会话中持续增长:

  1. 循环 1:探索 auth → 保存 auth 发现到 scratchpad → compact → 读取 scratchpad
  2. 循环 2:探索数据库 → 追加 DB 发现到 scratchpad → compact → 读取 scratchpad
  3. 循环 3:探索 API → 追加 API 发现到 scratchpad → compact → 读取 scratchpad

循环 3 之后,scratchpad 包含三个探索阶段的所有发现。每次 compact 可能都单独丢了一些细节,但磁盘上的 scratchpad 累积了一切。每次 compact 后读取它就能恢复全貌。

每次覆盖 scratchpad(而不是追加)会丢弃早期发现。第一阶段探索中的架构决策在实施阶段和最新发现一样关键。

什么时候 Compact 不是正确的工具

/compact 解决的是上下文满了的问题,不是上下文复杂度的问题。两种不该用它的情况:

定时压缩。 有人提议:每 10 次工具调用就运行 /compact,主动管理。问题是:compact 是有损的,定时使用会在可能还需要的近期上下文被用到之前就把它扔掉。更好的主动上下文管理方式包括使用 Explore 子代理做隔离发现(子代理的上下文是独立的,主上下文保持干净)或把工作拆成有范围的子任务。

作为 scratchpad 持久化的替代品。 有些开发者运行 compact 然后听天由命。每次 compact 40% 的引用丢失率,一个会话中运行 3 次会复合损失——关键的早期发现到第三次循环时可能完全消失。Compact 是上下文管理工具,不是持久化工具。持久化是 scratchpad 的工作。

工作阶段转换

保存-压缩-恢复工作流在阶段边界处特别有价值:从探索转向实施,从访谈模式转向编码,从研究转向综合。

一个开发者使用访谈模式通过提问发现了 20+ 个需求。在转向实施前,把所有需求写入 scratchpad 文件。如果实施阶段需要 /compact(很可能——实施会因为文件读取和编辑产生大量上下文),需求在文件中存活。实施阶段可以在任何时候读取 scratchpad 访问完整的需求列表,不管经历了多少次 compact。

没有 scratchpad,实施阶段的一次 compact 就可能把”用 RFC 5322 正则验证邮箱格式,拒绝一次性域名”变成”邮箱验证”。


一句话总结: 运行 /compact 前始终把发现写入文件——compact 释放空间但丢失细节,scratchpad 确保重要的东西不会消失。