Skip to content

03.4 压缩 Compact 与会话续航

会话越长越笨是必然的。这一章讲怎么延缓它,以及什么时候该果断重开。

读完你能做什么:让一个复杂任务跨越 100 轮对话仍然保持质量。


一、三个"清理"命令的区别

命令保留什么丢弃什么什么时候用
/compact对话摘要 + 项目记忆详细的历史消息同一个任务但上下文快满了
/clear项目记忆(CLAUDE.md)全部对话历史切换到不相关的新任务
/rewind到指定检查点的状态该点之后的对话和/或代码改动走错方向要回退

决策树

text
你还在做同一个任务吗?
├─ 是 → 上下文压力大吗?
│        ├─ 是 → /compact
│        └─ 否 → 继续
└─ 否 → 新任务和旧任务有关联吗?
         ├─ 有 → /compact 后继续
         └─ 无 → /clear

二、/compact 的幸存规则

这是最需要精确掌握的部分 —— 压缩后什么会留下,什么会消失。

2.1 会幸存的

内容机制
项目根目录的 CLAUDE.md压缩后从磁盘重新读取并重新注入
.claude/rules/ 中的无条件规则同上
系统提示词不参与压缩
MCP 工具定义不参与压缩
对话的摘要由模型生成,保留主要脉络

2.2 会丢失或退化的

内容后果
子目录中的嵌套 CLAUDE.md不会自动重新注入,要等下次读该目录文件时才重新加载
你在对话中口头说的规则可能被摘要成一句模糊的话,丧失具体性
读过的文件的完整内容变成"读过 xxx 文件"的描述,细节丢失
工具调用的详细输出大幅压缩
早期讨论的细节权衡只保留结论,理由可能丢失

2.3 压缩前的必做动作

/compact 之前,把口头约定固化下来。

text
> 在压缩之前,把我们本次会话确定的所有约束和决策,
  追加到 CLAUDE.md 的「本次重构约定」小节里。
  包括:
  - 我们决定不动 legacy 目录的理由
  - 命名约定(xxxHandler 而不是 xxxController)
  - 已经确认过的三个不能改的接口

  写完后再执行 /compact

这样这些内容会以 CLAUDE.md 的形式幸存,而不是被摘要成一句「用户提出了一些约定」。

2.4 引导压缩

/compact 可以带参数,指示保留重点:

text
> /compact 重点保留:已完成的改动清单、剩余待办事项、
  三个不能修改的接口签名。可以丢弃前期的方案讨论过程。

三、检查点与回退(Checkpointing)

3.1 /rewind 的三种模式

text
> /rewind

会让你选择回退范围:

模式效果
只回退对话代码改动保留,对话回到之前
只回退代码对话保留,文件恢复到之前状态
两者都回退完整回到检查点

别名:/checkpoint/undo

3.2 什么时候用 rewind 而不是"让它改回来"

text
❌ 「刚才那个改动不对,改回去」
   → 它可能改不干净;而且错误的方案仍留在上下文里持续干扰

✅ /rewind 到改动之前
   → 代码和上下文一起干净

判据:如果错误的尝试污染了上下文(模型现在同时"知道"两个矛盾的方案),用 rewind。如果只是一个局部小错,让它改就行。

3.3 主动创建检查点的习惯

在做危险操作之前:

bash
# 用 git 做外部检查点(最可靠)
git add -A && git commit -m "checkpoint: 开始重构对账模块前"

# 或者用 worktree 完全隔离
claude -w refactor-reconcile

Worktree 的好处:实验完全隔离在另一个目录,失败了直接删掉,主工作区毫发无损。见 06.7 Worktrees 与并行开发


四、长任务的会话续航策略

4.1 策略:外部状态文件

这是跨越 100 轮对话的核心技巧 —— 把任务状态写到文件里,而不是留在上下文里。

markdown
<!-- PROGRESS.md,放在项目根目录 -->
# 对账模块重构 · 进度

## 已完成
- [x] 抽出 ReconciliationEngine 接口(commit a3f2c1)
- [x] 迁移 alipay 适配器(commit 7b9e40)
- [x] 迁移 wechat 适配器(commit 2c1d88)

## 进行中
- [ ] 迁移 unionpay 适配器
      当前卡点:unionpay 的回调格式与其他渠道不同,需要额外的字段映射层

## 待办
- [ ] 迁移剩余 9 个渠道
- [ ] 删除旧的 ReconciliationService
- [ ] 补充集成测试

## 关键约定(不要违反)
1. 不修改 src/legacy/ 下任何文件
2. 每个渠道迁移必须独立可上线、独立可回滚
3. 金额一律 BigDecimal
4. 接口 IPaymentCallback 的签名不能改(有外部系统依赖)

## 已知坑
- alipay 的 SDK 在并发下有线程安全问题,不要在 static 字段里缓存 client
- 测试环境的 unionpay mock 服务经常挂,跑测试前先 curl 检查

CLAUDE.md 里加一句:

markdown
## 当前任务
正在进行对账模块重构。开始工作前先读 `PROGRESS.md` 了解进度,
完成任何一步后立即更新它。

效果:即使 /clear 完全清空对话,新会话读一下 PROGRESS.md 就能接着干。

4.2 策略:按子任务开新会话

bash
# 每个渠道一个独立会话,每个会话都很短
claude -n "migrate-unionpay" "根据 PROGRESS.md,完成 unionpay 渠道的迁移"
claude -n "migrate-jd" "根据 PROGRESS.md,完成 jd 渠道的迁移"

-n 给会话命名,之后可以精确恢复:

bash
claude --resume migrate-unionpay

4.3 策略:Auto Memory

Claude Code 的自动记忆会跨会话保留学到的东西(构建命令、调试经验、你的偏好)。

text
> /memory

可以查看和编辑。存储位置:

bash
~/.claude/projects/<project>/memory/
├── MEMORY.md          # 索引,每次会话加载前 200 行 / 25KB
├── debugging.md       # 详细笔记,按需加载
└── ...

注意MEMORY.md 有 200 行 / 25KB 的加载上限,超出部分会被丢弃。让它保持索引性质,详细内容放到主题文件里。

关闭自动记忆:

json
{
  "autoMemoryEnabled": false
}

或环境变量 CLAUDE_CODE_DISABLE_AUTO_MEMORY=1


五、上下文变笨的早期信号

学会识别这些信号,在质量崩塌前干预:

信号含义
开始重复之前说过的话它在"回顾"上下文,说明检索变困难
格式漂移(不再遵守你定的输出格式)格式约束的权重被稀释
忘记早期约束(又开始用 double 了)早期指令衰减
反复问你已经回答过的问题检索失败
响应明显变慢上下文长度导致的延迟
开始给出泛泛而谈的答案具体信息被噪音淹没

看到任意两条同时出现,立刻 /context 检查占用,准备压缩。


六、一份长任务的标准操作流程

text
【开始】
1. 建 PROGRESS.md,写清目标、约束、验收标准
2. 在 CLAUDE.md 里加一句「先读 PROGRESS.md」
3. git commit 作为起始检查点

【每完成一个子任务】
4. 更新 PROGRESS.md
5. git commit
6. 检查 /context,占用 > 60% 就准备压缩

【压缩前】
7. 把口头约定写进 CLAUDE.md 或 PROGRESS.md
8. /compact 并指定保留重点

【走错方向时】
9. /rewind 到检查点(而不是让它改回来)

【切换到不相关的任务】
10. /clear(不是 /compact)

【每天结束】
11. 确保 PROGRESS.md 反映真实状态
12. 明天从新会话开始,读 PROGRESS.md 即可续上

延伸阅读

基于 VitePress 构建 · 内容采用原作者授权