Claude Code 会话恢复后丢失先前工作记忆 —— 排查与修复

恢复 Claude Code 会话却像全新开始 —— 计划没了、决定没了、未完成的重构也没了。从快照范围、压缩、记忆分层定位问题。

合上电脑。第二天 claude --resume(或者你常用的恢复流程)把会话弹出来。看上去还是同一段对话 —— 工具调用历史看得见,计划也在。但你刚说”继续”,Claude 就问这是什么项目、把昨天读过的文件重新读一遍、把你下午 5 点明确否决的设计又重新提一次。会话恢复给的是”看上去连续”,不是”实际连续”。底层上,恢复能保住的是可见的对话记录,但模型工作上下文里那些东西 —— 隐式摘要、工具结果的记忆、推导出来的决策 —— 都是从头重建的,而且重建得不一定准。

常见原因

按影响排序。

1. 自动压缩把工作上下文丢了

长会话会被压缩:较早的轮次被摘要,原文丢弃。你恢复时只剩摘要。细节没了 —— “我们决定不用 Redis”变成一句话备注,能不能再被注入到下次上下文都不一定。

怎么判断:对话记录里出现 [summarized] 标记,或者较早的轮次明显被截断;你记得做过的决策在可见历史里找不到。

2. 恢复只载入消息历史,不载入工具结果

部分恢复流程保留用户/助手文本,但把工具结果块(文件内容、命令输出)丢掉以省 token。下一轮 Claude 知道自己”读过 foo.ts”,但实际没 foo.ts 的内容了。

怎么判断:Claude 立刻重新读昨天读过的同一批文件;尽管可见历史还在,输入字节计数从头算。

3. 两次会话之间 CLAUDE.md 或 settings 改了

如果你在两次会话之间改了 CLAUDE.md 或 .claude/settings.json,恢复出的上下文仍带着旧规则,但系统提示带的是新规则。行为不一致。

怎么判断:与关机前行为不同 —— 包管理器换了、测试命令换了等等。

4. 恢复时工作目录变了

claude --resume 找到的是会话文件,但 cwd 决定哪份 CLAUDE.md、哪个 .claude/、哪些文件路径有效。你从不同的 shell 位置恢复,记录里的相对路径就不再指向同一批文件。

怎么判断:昨天能用的路径今天 Claude 说”文件不存在”,或者相对路径下读到的是另一个文件。

5. 子代理 / Task 结果本就是临时的

Task 工具子代理产生的结果会被插进当时的父对话。父对话一被摘要,子代理的发现就被压缩成一句话。原始细节不可恢复。

怎么判断:你记得某次子代理跑出来的深度调研结论;恢复后只剩一句简短提及。

6. 会话文件本身是另一个版本

Claude Code 升级后,旧会话文件可能部分不兼容。技术上 resume 成功,但部分字段加载失败。

怎么判断:昨天同一份文件能 resume,今天不行,中间你升级了 Claude Code。

7. 计划 / TodoWrite 列表存在另一个未持久化的存储里

如果你用的规划工具把状态维护在对话之外,那个存储可能只在本地、现在空了。可见的计划项消失。

怎么判断:本来有 12 项 checklist;恢复后 TodoWrite 列表 0 项,但对话历史里提到过。

开始前

  • 看两次会话之间隔了多久(越久,压缩风险越大)。
  • 找一个具体的”丢失记忆”样例 —— 某条本应延续的决定或任务。
  • 看你在上一次会话之后是否升级了 Claude Code 或改了配置。
  • 想清楚你真正要什么:完整的状态延续,还是够用就行?

需要收集的信息

  • 会话文件路径(常见在 ~/.claude/sessions/ 或类似目录 —— 看 claude --debug)。
  • 会话文件大小(wc -c)。
  • 是否触发过压缩(文件或调试日志里搜 compacted)。
  • 现在的 Claude Code 版本 vs 原会话开始时的版本。
  • 任何外部状态文件(TodoWrite 存储、agent.log)是否还配套。

一步步修复

按 ROI 排序 —— 最便宜的先做。

第 1 步:用一条”当前状态”消息重新打底

任何 resume 都适用的 90 秒解法:

Quick context dump before we continue:

Project: <name>
Goal of this session: <goal>
Where we left off: <specific step or file>
Decisions already made (do not re-propose):
- <decision 1>
- <decision 2>
Files in scope: <list>
Next concrete step: <action>

花你 60 秒,省下一小时的重新推导。

第 2 步:动手前先让 Claude 读对的文件

主动重新读关键文件:

Read these files to refresh context:
- src/auth/login.ts (the one we are refactoring)
- src/auth/login.test.ts (the test we are keeping green)
- docs/architecture.md (the constraints)
Then summarize back to me what you understand. Do not act until I confirm.

这样把完整内容塞进当前上下文,不只是摘要。

第 3 步:在仓库里维护一份会话状态文件

留一份 .claude/session-notes.md(或类似),记录决策、待解决问题、当前步骤。每天关之前更新它。下次 resume:

Read .claude/session-notes.md and recap to me before doing anything else.

这份文件存在于对话之外,因此能跨过压缩存活。

第 4 步:从正确的 cwd 恢复

cd ~/projects/myrepo
claude --resume <session-id>

每次都核对 cwd 跟原会话一致。确认:

What is your current working directory? Print it.

第 5 步:重新同步当前 CLAUDE.md

恢复后:

Please re-read CLAUDE.md from disk and acknowledge any changes since the last loaded version. Treat the current file as authoritative.

强制 Claude 拿到两次会话之间的改动。

第 6 步:接受 resume 有边界;大动作开新会话

跨多天工作,别指望 resume 能扛过 1-2 次关开循环。改用这套流程:

  1. 每天结束写一份”当前状态”笔记进仓库。
  2. 第二天用 claude(不用 --resume)开新会话。
  3. 开场一句”Read .claude/session-notes.md and continue”。

新会话有干净的上下文窗口、没有压缩历史负债。

第 7 步:超长项目,把计划外化

仓库里搞一份 PLAN.md:

# Refactor auth to async/await

## Completed
- [x] login.ts converted
- [x] signup.ts converted
- [x] login.test.ts updated

## In progress
- [ ] reset-password.ts (started, partial)

## Not started
- [ ] sso.ts
- [ ] mfa.ts

## Decisions
- Using axios for HTTP, not fetch (team preference)
- No new dependencies allowed

计划不存在对话里,存在 git 里,每次会话都读它。

验证

  • 新一次 resume + 重新打底之后,让 Claude 复述当前步骤和决策,跟你写下的核对。
  • 跑下一步具体动作,确认它没重做已完成的工作。
  • 打开会话文件,确认大小合理(如有压缩事件能看到)。
  • 用 1-2 天对比”resume 一直续”和”新会话+笔记”,大多数场景后者赢。

长期预防

  • 状态外化。任何需要存活超过 24 小时的东西都该在仓库的文件里,而不是对话里。
  • 把 resume 当作一日工具。跨天工作直接靠笔记重启。
  • CLAUDE.md 和 PLAN.md 随用随改,不要等到一天结束才更新。
  • 关键决定在对话里加显式标记(“DECISION: using axios, not fetch”),压缩中更容易保留。
  • 一天结束前提交在制品;diff 本身也是一种记忆辅助。
  • 相关上下文丢失模式见 Claude Code 上下文损坏Claude Code 输出被上下文截断
  • 定期审计 ~/.claude/sessions/,旧的删掉 —— 从旧文件 resume 比新开更麻烦。

常见坑

  • 相信 --resume 会”完整记忆地”接着上次 —— 不会。
  • 把整套计划放对话里(“这是 30 个步骤”),而不是放文件里。
  • 恢复后立刻甩一句模糊指令(“继续”) —— Claude 压缩之后压根不知道这是什么意思。
  • 两次会话之间改了 CLAUDE.md,但没让恢复出来的 Claude 重读。
  • 把子代理结论当作持久信息;它们不是。
  • --resume 前忘了 cd 到正确目录;cwd 解析规则见 Claude Code 项目 CLAUDE.md 未加载
  • 工作日中间升级了 Claude Code,然后周一发现周五的会话恢复不干净。

FAQ

Q: 有没有设置可以关掉压缩?

基本没有。长会话能存在,就是因为有压缩。修复思路是”把需要存活的部分外化”,而不是”跟压缩对抗”。

Q: --resume 会重载工具结果吗?

它载入的是消息历史。工具结果块为省 token 可能被换成摘要。工具结果按”临时”处理。

Q: 一个会话现实里能跑多久 resume 才不可靠?

我们的经验:活跃使用 8-12 小时,或约 3 次关开循环。超出之后,新会话+笔记更可靠。

Q: 关之前能把会话导出到磁盘吗?

可以 —— 从 ~/.claude/sessions/ 复制文件,或者你的 CLI 支持就用 export 命令。审计用得上,但从导出的副本 resume 受同样的压缩限制。

Q: 为什么 Claude 有时会问我昨天就答过的问题?

答案被压缩掉了。要么在新轮次再答一次,要么先从笔记里把答案捞出来再让 Claude 继续。

标签: #Claude Code #session #memory #排查 #context