07|Checkpoints:为每次实验建立安全存档
理解自动检查点的创建、访问和适用边界。
理解自动检查点的创建、访问和适用边界。
计划像手术前在皮肤上画线:真正价值不是形式,而是在动刀前让错误位置暴露。好计划按可验证结果拆分,并写出未知项与回滚点。
本课交付物
给一个跨三个文件的功能只做计划评审。逐项标注事实、假设、风险、验证命令,故意加入一个错误前提,观察是否能在编码前发现。
核心讲解
Checkpoints 可以让你保存对话状态,并在 Claude Code 会话中回退到之前的时间点。无论你是在探索不同方案、修复错误,还是比较多个实现路径,这个能力都非常有用。
概览
Checkpoints 会保存会话状态,让你可以安全地试验和探索多种方案。它们本质上是当前对话状态的快照,包含:
- 所有已交换的消息
- 已做出的文件修改
- 工具使用历史
- 当前会话上下文
当你在尝试不同实现方式、从错误中恢复,或比较替代方案时,这个功能尤其好用。
核心概念
| 概念 | 说明 |
|---|---|
| Checkpoint | 保存消息、文件和上下文的对话快照 |
| Rewind | 回到之前的 checkpoint,并丢弃之后的更改 |
| Branch Point | 从同一个 checkpoint 出发,探索多个方案 |
访问 Checkpoints
你可以通过两种主要方式访问和管理 checkpoints:
使用键盘快捷键
按两次 Esc(Esc + Esc)打开 checkpoint 界面并浏览已保存的 checkpoints。
使用 Slash Command
使用 /rewind 命令(别名:/checkpoint)快速进入:
# 打开 rewind 界面
/rewind
# 或者使用别名
/checkpoint
Rewind 选项
回退时,你会看到一个包含五个选项的菜单:
- 恢复代码和对话 - 把文件和消息都恢复到那个 checkpoint
- 恢复对话 - 只回退消息,保留当前代码不变
- 恢复代码 - 只回退文件修改,保留完整对话历史
- 从这里开始总结 - 把从这里往后的对话压缩成 AI 生成的摘要,而不是直接丢弃。原始消息仍会保留在记录中。你也可以额外指定摘要应聚焦哪些主题。
- 算了 - 取消并返回当前状态
自动 Checkpoints
Claude Code 会自动为你创建 checkpoints:
- 每次用户提示 - 每次用户输入都会创建一个新 checkpoint
- 持久保存 - checkpoints 会跨会话保留
- 自动清理 - 30 天后自动清理旧 checkpoints
这意味着你随时都可以回到之前的任意节点,从几分钟前到几天前都可以。
使用场景
| 场景 | 工作流 |
|---|---|
| 探索不同方案 | 保存 → 试方案 A → 保存 → Rewind → 试方案 B → 比较 |
| 安全重构 | 保存 → 重构 → 测试 → 如果失败:Rewind |
| A/B 测试 | 保存 → 设计 A → 保存 → Rewind → 设计 B → 比较 |
| 错误恢复 | 发现问题 → Rewind 到最后一个正常状态 |
如何使用 Checkpoints
查看和回退
按两次 Esc,或者使用 /rewind 打开 checkpoint 浏览器。你会看到一个带时间戳的可用 checkpoint 列表。选择任意一个 checkpoint,即可回退到该状态。
Checkpoint 详情
每个 checkpoint 会显示:
- 创建时间
- 被修改的文件
- 对话中的消息数量
- 使用过的工具
实战示例
更多可直接参考的中文示例见 checkpoint-examples.md。
示例 1:探索不同方案
User: 我们给 API 加一个缓存层吧
Claude: 我会为你的 API 端点添加 Redis 缓存……
[在 checkpoint A 处做出修改]
User: 其实我们先试试内存缓存
Claude: 我会 rewind 回去,探索另一种方案……
[用户按下 Esc+Esc 并回退到 checkpoint A]
[在 checkpoint B 处实现内存缓存]
User: 现在我可以比较两种方案了
示例 2:从错误中恢复
User: 把认证模块重构成 JWT
Claude: 我会重构认证模块……
[做出大量修改]
User: 等等,这把 OAuth 集成弄坏了。我们回去。
Claude: 我来帮你回退到重构之前……
[用户按下 Esc+Esc,并选择重构前的 checkpoint]
User: 这次我们试一个更保守的方案
示例 3:安全试验
User: 我们试着把它改写成函数式风格
[在实验前创建 checkpoint]
Claude: [执行实验性修改]
User: 测试失败了。我们回退吧。
[用户按下 Esc+Esc 并回退到 checkpoint]
Claude: 我已经回退这些更改了。我们试另一个方案。
示例 4:分支式探索
User: 我想比较两种数据库设计
[记下 checkpoint,命名为 "Start"]
Claude: 我先实现第一种设计……
[实现 Schema A]
User: 现在让我回去试第二种方案
[用户按下 Esc+Esc 并回退到 "Start"]
Claude: 现在我实现 Schema B……
[实现 Schema B]
User: 太好了,我现在有两个 schema 可以选择
Checkpoint 保留策略
Claude Code 会自动管理你的 checkpoints:
- 每次用户输入都会自动创建 checkpoint
- 旧 checkpoint 最多保留 30 天
- 系统会自动清理,避免存储无限增长
工作流模式
探索时的分支策略
当你在探索多个方案时:
1. 从初始实现开始 → Checkpoint A
2. 尝试方案 1 → Checkpoint B
3. 回退到 Checkpoint A
4. 尝试方案 2 → Checkpoint C
5. 比较 B 和 C 的结果
6. 选择最佳方案并继续
安全重构模式
当你在做大改动时:
1. 当前状态 → Checkpoint(自动)
2. 开始重构
3. 运行测试
4. 如果测试通过 → 继续
5. 如果测试失败 → Rewind 并尝试别的方案
本站实战工作台
计划的价值发生在写代码之前
计划不是把“改文件、跑测试”写成列表。它的价值是提前暴露错误位置、缺失依赖和不可验证的目标。一个可审查计划包含事实来源、仍待确认的假设、按结果拆分的步骤、每步的验证和回滚点。
从影响面开始,而不是从文件名开始
假设要为文章增加草稿状态。先画数据链:数据库字段、写入契约、公开查询过滤、管理端表单、缓存与迁移。若计划只写“修改 schema 和页面”,就漏掉了公开 API 可能展示草稿的安全问题。
管理端输入 → API 校验 → 事务写入 → 缓存失效
↓
公开列表 ← locale + published 过滤 ← 数据库
每个箭头都应该变成一项可验证结果。
标记事实与假设
事实要带路径或查询结果:“Article 查询在 article.service.ts 组装 where。”假设要写出验证动作:“假设现有缓存键不含发布状态;先搜索 generateCacheKey。”计划中未标注的假设最危险,因为审查者会把它当成已知事实。
故意投放一个错误前提
选一个跨三文件的小功能,在任务描述里写入一条可查证的错误,例如“项目使用 Redis 缓存”。只要求计划,不允许编辑。好的 Agent 会检查依赖与实现后指出项目实际使用什么;差的计划会围绕错误前提设计一整套方案。
计划粒度怎样判断
一步应该产出一个可观察状态。太粗的“实现后端”无法审查,太细的“打开文件、移动光标”没有决策价值。合适的粒度类似:新增可回滚迁移并验证状态;扩展写接口且补事务测试;过滤公开读取且覆盖缓存;最后接入双语管理 UI。
高风险步骤旁写回滚:迁移如何撤回、旧客户端是否兼容、发布失败时切回哪一版。低风险样式调整不必伪装成灾难预案。
审查计划的五个问题
范围是否覆盖完整数据链?是否保护旧行为?是否有正常与失败路径?每个测试证明什么?哪一步会产生外部状态?如果回答不出来,计划还没到可以授权的程度。
本课产物
提交 plan-review.md,保留初版、发现的错误前提、修订版和批准理由。不要以“计划已完成”为终点;计划的验收是它能指导后续实施,并在现实反馈变化时允许重规划。