Checkpoints
快照与回退——让探索和迭代变得安全可控
大胆尝试,随时回退 — 不再害怕改坏代码不敢大胆试
你有没有发现,想试一个新方案但怕改坏了回不去?
想试新方案
你想给 API 加个 Redis 缓存层。改了 8 个文件后,发现这个方案跟现有架构不兼容。撤回 8 个文件的修改,比重新写还痛苦。
重构到一半
把认证模块从 Session 迁移到 JWT。改到一半发现 OAuth 集成被弄坏了。代码处于半成品状态,前进也不是,后退也不是。
想比较方案
两种实现思路都想试试。但试完一个想试另一个时,代码已经被改得面目全非,回不到起点了。
三个概念
Checkpoint、Rewind、Branch Point
Checkpoint是当前对话状态的完整快照,包含所有消息、文件修改、工具使用历史和会话上下文。
说白了,它就是一个"游戏存档"——你玩到某个关键节点,存一下。后面走错了路,读档回去就行。这个比喻只是为了帮你建立直观感受。实际上,Checkpoint 保存的是对话历史和文件状态的元数据,而不是文件内容的完整拷贝——恢复时它会重放操作历史来还原状态。
| 概念 | 说明 |
|---|---|
| Checkpoint | 保存消息、文件和上下文的对话快照 |
| Rewind | 回到之前的 checkpoint,丢弃之后的更改 |
| Branch Point | 从同一个 checkpoint 出发,探索多个方案 |
如何回退
两种方式打开 Checkpoint 浏览器
快捷键
按两次 Esc(Esc + Esc)打开 checkpoint 浏览界面。
Slash Command
$ /rewind
# 或别名
$ /checkpoint
每个 Checkpoint 显示什么
打开 checkpoint 浏览器后,你会看到每个快照包含四项信息:创建时间、被修改的文件、对话中的消息数量、使用过的工具。这些信息帮你快速判断哪个节点值得回退。
Rewind 的 5 个选项
| 选项 | 效果 |
|---|---|
| 恢复代码和对话 | 文件和消息都恢复到该 checkpoint |
| 恢复对话 | 只回退消息,保留当前代码 |
| 恢复代码 | 只回退文件修改,保留完整对话 |
| 从这里开始总结 | 把后续对话压缩成摘要,原始消息仍保留在记录中 |
| 算了 | 取消,返回当前状态 |
总结压缩
长对话的"减肥"工具——不丢结论,只减噪音
当你经过 20 多条消息的调试和探索后,对话已经很长了。这时你可以用"从这里开始总结"来压缩对话——它会把从该 checkpoint 到现在的所有消息压缩成一段 AI 生成的摘要。
# 场景:长调试会话后压缩上下文
用户: [经过 20 多条消息的调试和探索]
[按 Esc+Esc,选择较早的 checkpoint,选择"从这里开始总结"]
[可选:提供指令,如"重点保留我们尝试过什么,以及什么有效"]
Claude: [生成从该点开始的对话总结]
[原始消息仍保留在记录里,不会丢失]
[总结替换当前可见对话,减少上下文窗口占用]
用户: "现在继续推进那个有效的方案"
三个要点
- 原始消息不丢失——它们仍在记录中,只是不可见了
- 可以指定摘要重点——告诉 Claude 聚焦什么主题
- 释放上下文窗口——长对话不再挤占 AI 的工作记忆
什么时候用
- 经过长时间调试,对话已经很长
- 探索了多个方向,想压缩成结论
- 回退前想保留之前的发现,而非直接丢弃
分支探索
保存 → 试方案 A → Rewind → 试方案 B → 比较
# 场景:给 API 加缓存层
用户: "我们给 API 加一个缓存层吧"
Claude: 我会为你的 API 端点添加 Redis 缓存……
[在 checkpoint A 处做出修改]
用户: "其实我们先试试内存缓存"
Claude: 我会 rewind 回去,探索另一种方案……
[用户按 Esc+Esc,回退到 checkpoint A]
[在 checkpoint B 处实现内存缓存]
用户: "现在我可以比较两种方案了"
安全重构
当前状态 → checkpoint → 开始重构 → 运行测试 → 失败则 Rewind
# 场景:重构认证模块
用户: "把认证模块重构成 JWT"
Claude: 我会重构认证模块……
[做出大量修改]
用户: "等等,这把 OAuth 集成弄坏了。我们回去。"
Claude: 我来帮你回退到重构之前……
[用户按 Esc+Esc,选择重构前的 checkpoint]
用户: "这次我们试一个更保守的方案"
Claude: [基于回退后的状态,逐步重构]
性能优化
同一起点出发,试 3 种策略,组合后提升 79%
# 起点:API 响应时间 450ms
用户: "我们来优化 API 响应时间"
[Checkpoint "Baseline" 自动创建]
# --- 第一轮:Redis 缓存 ---
Claude: 我来加数据库查询缓存…… [实现 Redis 缓存]
用户: 运行性能测试
Claude: 结果:280ms(提升 38%)
# --- Rewind 回 Baseline,试第二种 ---
用户: [按 Esc+Esc,选择 Baseline]
用户: 改试数据库查询优化
Claude: [添加索引,优化 N+1 查询]
用户: 运行性能测试
Claude: 结果:180ms(提升 60%)← 最优
# --- Rewind 回 Baseline,试第三种 ---
用户: [按 Esc+Esc,选择 Baseline]
用户: 尝试响应压缩和 CDN
Claude: [实现 gzip + CDN]
用户: 运行性能测试
Claude: 结果:320ms(提升 29%)
# --- 回到最优方案,叠加缓存 ---
用户: 查询优化最好。回到那个版本,再加上 Redis 缓存。
Claude: [在优化查询之上添加 Redis 缓存]
Claude: 结果:95ms(提升 79%)
三种策略对比
| 策略 | 响应时间 | 提升 |
|---|---|---|
| Redis 缓存 | 280ms | 38% |
| 查询优化 | 180ms | 60% |
| 压缩 + CDN | 320ms | 29% |
| 查询优化 + 缓存 | 95ms | 79% |
关键思路
- 同一起点(Baseline)出发,分别测试 3 种策略
找到最优解后,回到该检查点叠加第二种优化——组合效果远超单独使用任何一种。这种"试 → 比 → 叠加"的模式,只有检查点才能低成本实现。
调试会话
多个假设逐一排除——内存泄漏排查实录
# 起点:应用存在内存泄漏
用户: "应用里有内存泄漏"
[Checkpoint "Before debugging" 自动创建]
# --- 假设 1:事件监听器 ---
用户: 我觉得问题在事件监听器里
Claude: [修复事件监听器清理逻辑]
用户: 运行内存分析器
Claude: ❌ 仍然在泄漏——不是事件监听器的问题
# --- Rewind,试假设 2 ---
用户: [按 Esc+Esc,选择 "Before debugging"]
用户: 也许是数据库连接的问题?
Claude: [实现连接池修复]
用户: 运行内存分析器
Claude: ❌ 还是在泄漏——也不是连接的问题
# --- Rewind,试假设 3 ---
用户: [按 Esc+Esc,选择 "Before debugging"]
用户: 检查一下有没有循环引用
Claude: [找到并修复缓存中的循环引用]
用户: 运行内存分析器
Claude: ✅ 内存泄漏修复了!
假设驱动的调试模式
- 提出假设 → 实现修复 → 验证结果
- 假设失败 → Rewind 回起点 → 换下一个假设
- 每次回到同一个检查点,确保代码状态干净
为什么检查点关键
传统调试中,每个失败的修复都会污染代码状态——你得手动撤销才能试下一个假设。有了检查点,每次回退都是完整、干净的,不存在"改了 A 又忘了改回 B"的风险。
安全试验
激进改动不怕错——试了不行就回退
# 场景:尝试函数式风格改写
用户: "我们试着把它改写成函数式风格"
[检查点在提示前自动创建]
Claude: [执行实验性修改——重写核心逻辑为纯函数]
Claude: [移除可变状态,改用不可变数据流]
用户: 运行测试
Claude: ❌ 12 个测试失败,类型推断出了问题
用户: 测试失败了。我们回退吧。
[用户按 Esc+Esc,回退到实验前的检查点]
Claude: 我已经回退这些更改了。我们试另一个方案。
何时该回退
这些信号出现时,通常就该考虑 rewind 了
方向变复杂了
当前方案开始变复杂,而且你还没确定方向。这说明你可能走偏了——回退到上一个"干净"状态,换个思路重新来。
测试刚失败
问题大概率就是最近一两步引入的。别在错误的基础上继续改——回退到测试通过的那一步,从那里重新出发。
想比较两种实现
你觉得当前方案可以,但又想试另一种。先记住当前方案的效果,rewind 回去试新方案,最后对比选择。
想要一个干净起点
探索了半天方向不明确。回退到一个已知的"好状态",重新规划路线,比在混乱中继续摸索更高效。
与 Git 互补
Checkpoints 和 Git 是互补的,不是替代关系
Checkpoints
- 会话级快照,自动创建
- 适合快速试错和方案比较
- 跨会话保留,30 天后自动清理
- 仅当前用户可见,不共享
Git
- 代码级版本控制,需手动 commit
- 适合长期保存和团队协作
- 永久保留(除非手动删除)
- 可共享,团队协作基础
推荐用法
- ✅ 用 Checkpoints 快速试错、比较方案
- ✅ 找到最佳方案后,提交到 Git
- ✅ 关键节点手动 commit 到 Git 保存
- ✅ 长会话用"总结"保持可管理
避免的做法
- ❌ 只依赖 Checkpoints 保存代码
- ❌ 指望 Checkpoints 跟踪外部文件变化
- ❌ 把 Checkpoints 当成 Git commit 的替代品
局限性
Checkpoints 很强,但它不是万能的
不是版本控制系统
Checkpoints 适合会话内的快速回退和方案探索,但它不能替代 Git。需要长期保存、可审计、可共享的改动,仍然应该使用 git commit。
30 天自动清理
旧检查点最多保留 30 天,之后自动清理。如果你有一个月前的探索记录想保留,关键结果必须手动提交到 Git。
不跟踪外部变化
检查点只记录 Claude Code 会话中的操作。你在会话外用编辑器改的文件、用终端跑的命令,检查点无法感知。
仅当前用户可见
检查点是个人会话快照,不能共享给团队成员。团队协作请用 Git,检查点只负责帮你快速试错。
配置与保留
自动保存、跨会话持久化、可关闭
自动机制
每次用户输入都会自动创建 checkpoint,无需手动操作。你只管做事,该存的时候它会自动存。这些快照会跨会话保留——即使你关掉 Claude Code,下次打开时仍然可以回到之前的节点。
旧 checkpoint 最多保留 30 天,之后自动清理,避免存储无限增长。
可配置项
如果你不需要自动 checkpoint,可以在设置中关闭:
{
"autoCheckpoint": false
}
默认值是 true。关闭后,Claude Code 不再自动创建快照,你需要手动管理状态。
排错指南
找不到 Checkpoints
症状:按 Esc+Esc 后没有看到任何快照。
检查:确认你的 Claude Code 版本是否支持 checkpoints;检查 autoCheckpoint 设置是否被关闭了;试试重新打开会话。
Rewind 失败
症状:选择 checkpoint 后回退操作失败。
检查:确认选择的是一个有效 checkpoint;查看是否有文件系统或权限限制;试试先单独恢复代码或对话,不要同时恢复两者。
回退太频繁
症状:每次小改动都 rewind,浪费大量时间。
修复:只在关键转折点回退。小修改直接撤销就好,不需要 checkpoint。
改动太多才回退
症状:改了 20 个文件才想起来可以回退,回退代价太大。
修复:养成习惯:每完成一个"可验证的阶段"就确认一下。如果这个阶段结果不对,立刻 rewind。
只依赖 Checkpoints
症状:从来不手动 git commit,全指望 checkpoints 保存代码。
修复:Checkpoints 30 天后自动清理。关键代码必须手动 commit 到 Git。
回退后忘了之前试过什么
症状:rewind 了但忘了之前的方案,又重复探索了一遍。
修复:在 Rewind 时选择"从这里开始总结"——它会压缩后续对话成摘要,保留关键结论但不占空间。
动手练习
设计一个"三段式 Checkpoint"策略
不用真的去改代码,只设计分段策略——每个阶段什么时候打点、验证什么、什么情况下 rewind。
- 每个阶段的创建时机
- 每个阶段的验证标准
- 什么情况下需要 rewind
参考答案
开始前
✅ 原有测试通过
提取接口后
✅ 编译通过
替换实现后
✅ 测试全部通过
| 阶段 | 目标 | 验证标准 | Rewind 条件 |
|---|---|---|---|
| 1 → 2 | 提取 AuthProvider 接口 | 编译通过,无报错 | 编译失败或引入新错误 |
| 2 → 3 | 实现 JWTAuthProvider | 原有测试全部通过 | 任何原有测试失败 |
| 3 → 完成 | 添加 JWT 专属测试 | 新旧测试全部通过 | 新测试无法通过 |
本章回顾
到这里,你已经能
- 说清 Checkpoint 与 Rewind 的用途
- 知道触发时机和访问方式
- 设计分段式 Checkpoint 策略
- 理解与 Git 的互补关系
- 掌握分支探索和安全重构两种模式
它和前后章节的关系
- Hooks — 在 checkpoint 前后自动做质量检查
- Plugins — 插件工作流中的安全试错
- Checkpoints — 让探索更安全的快照机制
- Advanced Features — 规划模式 + checkpoints 的系统化组合
延伸阅读
继续本课程
- 下一章:Advanced Features — 规划模式 + checkpoints 的系统化组合
- CLI — 通过命令行控制 checkpoint 行为
示例文件 (点击查看完整内容)
08-checkpoints/
└── checkpoint-examples.md
更多实战示例
- checkpoint-examples.md — 7 个完整工作流示例
- 数据库迁移(直接迁移 vs 双写模式)
- UI/UX 迭代(三种布局比较,最终组合方案)
- API 设计演进(REST vs GraphQL 来回比较)
- 配置管理(环境变量 vs YAML 配置文件)
- 测试策略(单元测试 → 集成测试 → E2E 渐进构建)
外部资源
- Claude Code 官方检查点文档
- 根目录中文指南
- Advanced Features 指南 — 规划模式与检查点的高级组合
本章源文件
08-checkpoints/README.md— 完整说明文档08-checkpoints/checkpoint-examples.md— 实战示例集合