# 管理上下文与会话：让它一直清醒

> 会话越聊越长，Claude 开始忘约定？这一课教你看清和清理上下文，用 --continue、--resume 恢复会话，用检查点回退，并判断何时该开新会话、何时交给子智能体。

- 网址：https://coding.chengyu.dev/learn/claude-code/context/
- 学习路径：Claude Code 精通
- 预计用时：18 分钟；核实日期：2026-10-25
- 官方来源：[Manage sessions（Claude Code 官方文档）](https://code.claude.com/docs/en/sessions)，[Checkpointing（Claude Code 官方文档）](https://code.claude.com/docs/en/checkpointing)，[Explore the context window（Claude Code 官方文档）](https://code.claude.com/docs/en/context-window)，[Best practices for Claude Code（Claude Code 官方文档）](https://code.claude.com/docs/en/best-practices)，[Interactive mode（Claude Code 官方文档）](https://code.claude.com/docs/en/interactive-mode)，[CLI reference（Claude Code 官方文档）](https://code.claude.com/docs/en/cli-reference)

## 学习目标

- 能用 /context 判断上下文被什么占满，并选择 /clear、/compact 或 /btw 处理
- 能用 --continue、--resume、/rename、/branch 管理和恢复会话
- 能用 Esc Esc 或 /rewind 回退代码和对话，并说出检查点的限制
- 能判断什么时候该开新会话，什么时候该把探索交给子智能体

一个很常见的下午：你在同一个会话里先修了支付回调的 bug，接着调了首页样式，又让它分析了一份 2 万行的 Nginx 日志，最后回来继续改支付逻辑。这时它开始忘记你上午说的「金额用分存」，还把早就否掉的方案又提了一遍。

不是它变笨了。官方最佳实践里反复强调一点：**上下文窗口是最需要管理的资源，窗口越满，模型表现越差**。这一课讲怎么看清它、清理它、在多个会话之间来回切换，以及改坏了怎么退回去。

## 先看清：上下文里装了什么

输入 `/context`，Claude Code 会用一张彩色网格展示当前上下文的占用情况，按类别列出各部分占多少（例如记忆文件、Skill 列表、对话消息），列出这次加载了哪些 CLAUDE.md 和自动记忆文件，并给出优化建议，比如哪些工具占用过大、记忆文件是否臃肿。加上 `all` 参数可以展开全部明细。

快满时，Claude Code 会自动压缩：先清理较早的工具输出，必要时把对话总结成摘要。你可以在 CLAUDE.md 里写一节 Compact Instructions，告诉它压缩时优先保留什么（第 2 课的示例里有）。

自动压缩之后，哪些东西还在？官方列得很细，记住几条关键的：

| 内容 | 压缩之后 |
|---|---|
| 项目根目录的 CLAUDE.md、自动记忆 | 从磁盘重新读入，不会丢 |
| 子目录 CLAUDE.md、带 paths 的路径规则 | 等再次读到匹配文件时重新加载 |
| 读过或改过的文件 | 重新读入最近修改的最多 5 个，太大的只留路径 |
| 已调用的 Skill 正文 | 重新附上，但每个最多保留开头 5000 token |
| 只在聊天里说过的约定 | 进入摘要，可能被简化或丢失 |

所以，只在对话里交代过一次的规则最危险。要长期遵守的，写进 CLAUDE.md。

## 三个日常命令：/clear、/compact、/btw

| 命令 | 做什么 | 什么时候用 |
|---|---|---|
| `/clear` | 开始一段上下文为空的新对话（别名 `/reset`、`/new`） | 切换到不相关的新任务 |
| `/compact [指令]` | 把目前的对话总结成摘要，替换掉原有历史 | 任务还没完，但对话太长 |
| `/btw 问题` | 问一个旁路问题，答案不进入对话历史 | 临时确认一个细节，不想污染上下文 |

几点细节：

- `/clear` 不会删掉旧对话，它被保存下来了，之后可以用 `/resume` 找回。写成 `/clear 支付回调排查`，还能给刚离开的那段对话起个名字。
- `/compact` 可以带重点，比如 `/compact 只保留支付回调的修改和测试命令`。比让它自动压缩时去猜什么重要更可控。
- `/btw` 只根据已有上下文回答，不能读文件或跑命令，即使 Claude 正在干活也能用，不打断主任务。
- 想压缩一部分而不是全部，可以打开 `/rewind`，选中某条消息后用「从这里开始总结」或「总结到这里为止」。

## 恢复会话：关了终端也能接着干

会话会持续保存在本地 `~/.claude/projects/` 下的 JSONL 文件里，退出或 `/clear` 之后都能回来：

```text
# 接着干当前目录里最近的一次会话
$ claude --continue
# 打开会话选择器，从列表里挑
$ claude --resume
# 启动时就给会话起名，之后按名字恢复
$ claude -n refund-review
$ claude --resume refund-review
# 恢复时复制一份新会话，原会话保持不动
$ claude --continue --fork-session
> /rename 退款审核重构
> /branch 试试乐观锁方案
# 在会话里切换到另一个会话
> /resume
```

`--continue` 可简写为 `-c`，`--resume` 可简写为 `-r`。会话选择器里，`Space` 预览内容，`Ctrl+R` 重命名，`Ctrl+B` 只看当前 git 分支的会话，`Ctrl+W` 扩大到同一仓库的所有 worktree，`Ctrl+A` 扩大到本机所有项目。

官方的建议是**把会话当分支来管**：每条工作线一个会话，起一个像 `refund-review` 这样能看懂的名字。`/branch` 会复制当前对话并切进去，原对话原样保留，适合「换个思路试试，但不想丢掉现在这条路」的时候。

有两点要注意：恢复的是对话历史，不是所有启动参数。如果原来用了 `--add-dir`、`--mcp-config`、`--settings` 等参数，恢复时要重新带上；写在 settings.json 里的配置则会自动重新读取。另外，同一个会话不分叉就同时在两个终端里恢复，两边的消息会交错写进同一份记录，容易乱。

## 回退：检查点是你的后悔药

每次你发送一条开启新一轮的消息，Claude Code 都会自动创建一个检查点（checkpoint），记录 Claude 用文件编辑工具改动前的文件状态。输入框为空时连按两下 `Esc`，或者输入 `/rewind`（别名 `/checkpoint`、`/undo`），就能打开回退菜单。选中一条历史消息后可以：

- **恢复代码和对话**：两者都回到那个时间点；
- **只恢复对话**：对话回去，代码保持现状；
- **只恢复代码**：代码回去，对话保留，方便你告诉它「刚才那个方案不行」；
- **从这里开始总结 / 总结到这里为止**：压缩部分对话，腾出空间。

检查点随会话保存，关掉终端再 `--resume` 回来依然能用；每个会话保留最近 100 个检查点的快照。

但它有明确的边界，必须记住：

- **Bash 命令的改动基本不追踪。** 只被 `rm`、`mv`、脚本改过的文件，回退时不会恢复；
- **子智能体的编辑通常不会恢复**，后台运行的分叉 Skill 也是如此；
- **你在编辑器里手动改的、其他会话改的**，都不在追踪范围内；
- **数据库、接口调用、部署这些外部操作**，完全无法回退。

所以检查点只是会话级的快速后悔药，**不能代替 git**。动大手术前先提交一次，是最便宜的保险。

> 小测：Claude 用 Bash 执行了 rm -rf dist/legacy 删掉了一个你从没让它编辑过的目录，你发现后立刻打开 /rewind 选择「恢复代码」。结果会怎样？

## 什么时候该开新会话

满足下面任何一条，就别硬撑了：

- **要做的事和刚才无关。** 修完 bug 去写文档，直接 `/clear`；
- **同一个问题你已经纠正它两次以上。** 官方原话的意思是：上下文里已经堆满了失败的尝试，带着这些包袱继续，不如清空后用一个更具体的提示词重来；
- **它开始忘记你说过的约定**，或者 `/context` 显示对话消息占了大头；
- **调研和方案已经完成，准备动手实现。** 让它把方案写进一个文件（比如 `SPEC.md`），开新会话照着实现，上下文干净、目标清楚。

开新会话之前，最好先让它留一份交接记录，这样新会话不必从头再读一遍：

**清空上下文前写交接记录**

```text
我准备用 /clear 开始新会话。在那之前，请把当前进展整理到项目根目录的 HANDOFF.md（覆盖旧内容），包括：
1. 这次任务的目标，以及我中途补充的约束和偏好；
2. 已完成的改动：改了哪些文件、每个文件改了什么、为什么；
3. 试过但被否掉的方案，以及否掉的原因；
4. 还没完成的事项，按优先级排序；
5. 验证用的命令和当前结果。

只写事实，控制在 60 行以内。写完后告诉我文件路径，不要做其他修改。
```

新会话里一句「先读 HANDOFF.md，然后继续第 4 条里的第一项」就能接上。

## 用子智能体隔离探索

还有一种情况：任务本身没变，但中间需要做大量调研，比如「搞清楚项目里所有调用旧版短信 SDK 的地方」。让主会话自己去读几十个文件，读到的内容会全部留在你的上下文里。

更好的做法是交给子智能体（subagent）。子智能体在自己独立的上下文窗口里工作，读多少文件都不占你的空间，结束后只把摘要带回来。Claude Code 内置的 Explore 子智能体就是只读的，专门用来搜索和理解代码库。你只需要在提示词里明确说：

```text
用子智能体调查项目里所有调用旧版短信 SDK（sms-legacy）的地方，
按模块列出文件路径、调用方式和是否有重试逻辑，只把汇总结果告诉我。
```

另外，`/subtask 任务描述` 会派出一个继承当前完整对话的后台子智能体，你继续手头的事，它做完后把结果送回来。怎么自定义子智能体、怎么并行开发，见第 8 课[子智能体与并行](/learn/claude-code/subagents-parallel/)。

> 小测：你正在调一个复杂的 bug，上下文已经很长，突然想确认「刚才那个配置文件叫什么名字」。最合适的做法是？

- [ ] 在一个进行中的会话里运行 `/context`，找出占用最大的类别
- [ ] 用 `claude -n 名字` 启动一个会话，退出后用 `claude --resume 名字` 恢复
- [ ] 让 Claude 改一个文件，然后按两下 `Esc` 用「只恢复代码」退回去
- [ ] 试一次 `/btw`，确认它的回答没有出现在对话历史里
- [ ] 用上面的提示词写一份 HANDOFF.md，`/clear` 后让新会话接着做
- [ ] 让 Claude「用子智能体调查」一个跨多文件的问题，对比主会话上下文的变化
