---
title: "03 · 怎么记住你的习惯"
description: "上下文是一次性的，关机就清空。Claude Code 怎么跨会话记住你的项目、习惯、偏好？答案是双轨记忆——你写的 CLAUDE.md 持久指令 + 它自己写的 Auto Memory 工作笔记。"
canonical: "https://xiangyugongzuoliu.com/tag/claude-code"
verifiedAt: "2026-05-08"
---

上一篇我们聊了上下文——一张很大但会清空的桌子。Aaron当时的第一个念头是：那每次启动 Claude Code，它岂不是什么都不记得？翻文档发现 Anthropic 给的方案比想象中精妙——**两套记忆并行**，一套你写、一套它写，把每天都是第一天这个问题彻底解决了。——Aaron

> [!NOTE]
> **这一篇用 13 分钟换什么**：上一篇 [02](/docs/claude-code/understanding/02-context-window) 拆了上下文窗口——会话级、会清空。这一篇拆**跨会话**的记忆系统：你写给 Claude 的项目指令（CLAUDE.md）+ Claude 自己积累的工作笔记（Auto Memory）。理解了双轨设计，你才能判断什么信息该写哪、写多少、放哪一层。

## 1. 一个新员工的麻烦

假设你雇了一个超级聪明的助手。什么都会，反应飞快，解决问题一流。

但他每天早上来上班，**不记得昨天发生过什么**。

你得重新告诉他：项目用的是 Next.js，数据库是 PostgreSQL，代码风格遵循这套规范，构建命令是 `pnpm build`，部署走 Vercel，CI 在 GitHub Actions 里……

第一天你觉得还行。第二天开始烦了。第三天你想辞退他。

这就是上一篇结尾提到的问题：上下文窗口是一次性的，会话结束就清空。如果 Claude Code 只有上下文，**每次启动它对你的项目一无所知**——你得反复解释技术栈、构建命令、代码规范、架构决策……这些解释本身还要占上下文空间，挤掉了本来可以用来做正事的位置。

**换个设定**：同样这个助手，但桌上放着一本你写好的手册——《新员工必读》。每天来上班先翻一遍，五分钟后进入状态。**你再也不需要重复解释任何事**。

这本手册就是 Claude Code 的 **CLAUDE.md**。

## 2. 一份手册，先解决最痛的问题

CLAUDE.md 是一个普通的 Markdown 文件，任何文本编辑器都能打开。

每次 Claude Code 启动，它做的第一件事就是读这个文件。读完之后，文件内容变成这次会话的背景信息——Claude 回答你的每个问题时，都**知道**手册里写的东西。

那应该写什么？想象你给一个聪明但对你的项目一无所知的新同事写一份备忘录。你不会写公司全部历史，不会贴 500 行源代码，不会把所有制度从头抄一遍。你只会写他**上班第一天最需要知道的那些事**。

具体三类：

- **这是什么（WHAT）**：项目一句话介绍、技术栈、核心目录结构
- **为什么这样设计（WHY）**：关键架构决策（如选 Next.js 因为需要 SSR）—— 这类信息 Claude 从代码里看不出来，必须你告诉它
- **怎么操作（HOW）**：构建命令、测试命令、部署流程

> [!WARNING]
> **200 行预算**：官方建议 CLAUDE.md 控制在 **200 行以内**。文件越长，消耗的上下文越多，Claude 对指令的遵循度也会下降。内容多时用 `@import` 引用外部文件，或拆到 `.claude/rules/` 子目录（按文件路径 glob 加载）。

## 3. 一份手册不够：4 层 scope

如果记忆只有一个 CLAUDE.md，你很快会碰到一个具体的麻烦：**个人偏好和项目规范混在一起**。

你喜欢中文回复——这是个人偏好，跟项目无关。
项目用 TypeScript——这是项目规范，跟你个人无关。

在多个项目之间切换时，个人偏好每个项目都要写一遍？团队多个人时，每人偏好都要写进项目 CLAUDE.md？

显然得**分层**。Anthropic 的方案是 **4 层 scope**，按位置自动判断属于哪一层：

```files
📦 4 层 scope/
  ① Managed policy（系统级，最高优先）/
    macOS · /Library/Application Support/ClaudeCode/CLAUDE.md
    Linux · /etc/claude-code/CLAUDE.md
    Windows · C:\Program Files\ClaudeCode\CLAUDE.md
  ② Project（项目级，团队共享）/
    ./CLAUDE.md（项目根，提交 git）
    ./.claude/CLAUDE.md（同上，子目录形式）
  ③ User（用户级，跨所有项目）/
    ~/.claude/CLAUDE.md
  ④ Local（本地级，个人项目偏好）/
    ./CLAUDE.local.md（必须 .gitignore）
```

每一层各管各的，按官方加载顺序拼起来：

```mermaid
sequenceDiagram
    participant CWD as 你的工作目录
    participant Claude as Claude Code 启动
    participant Ctx as 上下文窗口

    Claude->>CWD: 从项目根往上一路走
    CWD-->>Claude: 找到所有 CLAUDE.md / CLAUDE.local.md
    Claude->>Ctx: ① Managed policy（系统级）注入
    Claude->>Ctx: ② Project（项目根 ./CLAUDE.md）注入
    Claude->>Ctx: ③ User（~/.claude/CLAUDE.md）注入
    Claude->>Ctx: ④ Local（./CLAUDE.local.md）注入
    Note over Ctx: 离工作目录越近的越晚注入<br/>越容易影响最终行为
    Claude->>Ctx: 也加载 MEMORY.md 前 200 行
    Note over Ctx: Auto Memory 索引（详见 §5）
```

**加载机制底层**：Claude Code 从工作目录**往上**逐层查找 CLAUDE.md，**全部拼接**注入上下文（不是覆盖）。同目录下 CLAUDE.local.md 接在 CLAUDE.md 之后。子目录的 CLAUDE.md 只在 Claude 实际读取那个目录下的文件时**按需加载**。详见[官方加载顺序文档](https://code.claude.com/docs/en/memory#how-claude-md-files-load)。

日常使用中，**你只需要关注两个文件**：

- `~/.claude/CLAUDE.md` —— 你的个人偏好（跨项目）
- `项目根/CLAUDE.md` —— 项目规范（团队共享，进 git）

**为什么是"全部拼接"而不是"覆盖"**：覆盖会让最深一层的 CLAUDE.md 干掉所有上层规则——团队规范被个人偏好覆盖、个人偏好被本地实验覆盖，工程上不可控。拼接的代价是**所有层加起来不能太长**——如果 4 层都写满 200 行，启动注入 800 行，主对话桌子被规则文件占掉一大半。这就是为什么"克制"是 CLAUDE.md 的核心写作原则。

**新手最常见的写法误区**：把项目结构（目录树 / 文件列表）、依赖列表（package.json 内容）、Git 历史 / Commit 说明都抄进 CLAUDE.md。这些信息**代码里有**，每次会话再注入一遍 = 浪费 token。Claude 需要时直接读就行——它在你电脑上（[01 篇](/docs/claude-code/understanding/01-what-is-claude-code) 拆过）。

到这里手册系统已经很完整了。但还有一类信息，手册装不下。

## 4. AI 还得自己记笔记

CLAUDE.md 解决了一个问题：**你把规则写下来，Claude 每次启动都看得见**。

但工作中还有一些东西不太适合写进正式手册。

比如你纠正了 Claude 一次：测试不要 mock 数据库，用真实数据库。这条信息很有价值——下次写测试时应该记住。但它不是项目规范，不太适合写进 CLAUDE.md（团队 review 时也奇怪）。

再比如 Claude 在帮你调试时发现，某类错误的根因总是缓存没清。这是经验教训，对未来有用，但你不会主动写进手册。

这就是 **Auto Memory** 的角色。

**通俗讲**：CLAUDE.md 是你写的**员工手册**，Auto Memory 是员工自己带的**工作笔记本**。手册写公司规章，笔记本记工作中积累的经验教训。**你不需要告诉它什么时候该记——它自己判断**。

Auto Memory 是 Claude Code 自己维护的项目笔记系统（v2.1.59+ 默认开启）。你什么都不用做——Claude 在对话中**自动识别**哪些信息值得记住，分类存到持久文件里。下次启动新会话时，这些笔记自动可用。

存放位置：

```files
~/.claude/projects/<项目标识>/memory//
  MEMORY.md（索引，启动加载前 200 行 / 25KB）
  debugging.md（按需加载）
  patterns.md（按需加载）
  ...（其它主题文件）
```

`<项目标识>` 由 Claude Code 根据 git 仓库自动推导——同一个仓库的不同 worktree、子目录共享同一份 Auto Memory。Auto Memory **机器本地**（不跨机同步）。

> [!WARNING]
> **200 行 / 25KB 加载上限**：启动时只加载 `MEMORY.md` 的前 **200 行或 25KB**（取较小）。超过部分不进入会话起点，但 Claude 在工作中可以**按需读取** topic 文件（`debugging.md` 等）。这是为了避免笔记把工作台从一开始就铺满。

## 5. 怎么判断什么放哪？

现在两套系统都清楚了。判断标准很简单——这条信息是**规则**还是**经验**？还是**Claude 直接看代码就能知道**？

<details>
<summary>📜 规则 → CLAUDE.md</summary>

**特征**：必须遵守的、每次都需要的、应该共享给团队的。

**典型内容**：

- 技术栈声明（用 TypeScript / Next.js / PostgreSQL）
- 构建测试命令（`pnpm build` / `pnpm test`）
- 代码规范（缩进 / 命名 / 文件组织）
- 架构约定（API 在 `src/api/handlers/` 下）
- 业务领域规则（订单状态机 / 权限边界）

**写进哪一层**：

- 团队共享 → `项目根/CLAUDE.md`（提交 git）
- 个人跨项目偏好 → `~/.claude/CLAUDE.md`
- 个人项目偏好 → `./CLAUDE.local.md`（加 `.gitignore`）

**什么时候开始写**：

- Claude 第二次犯同一个错误
- 代码 review 指出 Claude 本应知道的项目规则
- 你反复在对话里解释同一个流程
- 新团队成员需要同样的上下文才能上手

</details>

<details>
<summary>💡 经验 → Auto Memory</summary>

**特征**：有用但非强制的、在工作中自然积累的、个人化或机器本地的。

**典型内容**：

- 你的纠正反馈（不要 mock 数据库 / 用 pnpm 不要 npm）
- 调试中发现的规律（这类报错根因总是缓存没清）
- 项目临时状态（这周冻结主分支 / X 服务停机维护）
- 某个文件 / 函数的非显然约定（看起来像 X 但实际是 Y）
- 偶发但重要的环境差异（CI 跟本地行为不同）

**怎么写**：

- 你不用主动写——Claude 自己判断写什么
- 想主动添加：直接告诉 Claude 比如**以后都用 pnpm 不要 npm**，它会自动写进 Auto Memory
- 想编辑：用 `/memory` 命令打开

**怎么查**：

- `/memory` 列出所有当前会话加载的指令文件
- 直接打开 `~/.claude/projects/<项目>/memory/` 看 markdown

</details>

<details>
<summary>🔍 代码里有 → 不存</summary>

**特征**：Claude 随时能从项目代码 / 文件 / Git 历史读到的事实。

**典型内容**：

- 文件结构 / 目录组织（`ls` 就能看）
- 函数签名 / 类定义（`grep` 就能看）
- 历史变更 / 谁改了什么（`git log` 就能看）
- package.json 的依赖列表（直接 `cat` 就行）
- README 已经写过的内容

**为什么不存**：

- 重复存 = 浪费上下文 token + 容易跟代码不同步
- Claude 需要时直接读就行——它在你电脑上（[01 篇拆过](/docs/claude-code/understanding/01-what-is-claude-code)）
- 信息源唯一才不会自相矛盾

**反模式**：把 README 内容复制进 CLAUDE.md / 把目录结构 ASCII 树写进 CLAUDE.md / 把测试用例列表写进 CLAUDE.md。

</details>

> [!TIP]
> **速记**：**每次都需要 → CLAUDE.md**。**工作中发现的 → Auto Memory**。**代码里有的 → 不存**。

**3 个判断练习** —— 下面三句话分别该放哪里？读完答案再看你判断对了几个：

> **场景 A**：项目用 Next.js 14 + TypeScript + Prisma，所有 API 必须返回 `{ data, error }` 格式。
>
> **场景 B**：你昨天发现 Claude 总是把测试 mock 数据库——你纠正后说"以后所有测试都连真实测试库"。
>
> **场景 C**：项目源码结构（`src/app/` / `src/components/` / `src/api/handlers/` ...）。

<details>
<summary>📌 看答案</summary>

- **A → 项目根 `CLAUDE.md`**：是项目级长期规范，每个团队成员都需要，进 git 共享。
- **B → Auto Memory**（自动记忆）：是工作中积累的纠正反馈，不需要正式写进项目规范，Claude 自己会记到 `~/.claude/projects/<项目>/memory/`。
- **C → 不存**：源码结构 `ls` 就能看到，写进 CLAUDE.md = 浪费 token + 跟代码不同步（重构后 CLAUDE.md 容易忘改）。

判断诀窍——问自己：
1. 这条信息**每次会话**都要进上下文吗？是 → CLAUDE.md。
2. 这条信息是**工作中临时发现的纠正**？是 → Auto Memory（让 Claude 自己记）。
3. 这条信息**代码里 / `ls` / `git log` 能直接读到**？是 → 不存。

</details>

## 6. 完整的画面

把前面所有内容串起来，Claude Code 启动时的信息架构是这样的：

| 时机 | 自动加载 | 来源 |
|------|---------|------|
| **会话开始** | 系统提示（内置） | Claude Code 自己 |
| **会话开始** | CLAUDE.md（4 层全量拼接） | 你写的 |
| **会话开始** | MEMORY.md 前 200 行 / 25KB | Claude 自己写的 |
| **工作进行中** | 你和 Claude 的对话、读取的文件、命令输出 | 实时累积进上下文窗口 |
| **工作进行中** | Claude 自动写 Auto Memory（识别值得记的信息）| Claude 决策 |
| **工作进行中** | 子目录 CLAUDE.md / `.claude/rules/*.md` 按 glob 命中 | 按需加载 |
| **会话结束** | 上下文清空 | —— |
| **下次启动** | CLAUDE.md + MEMORY.md 还在 | 跨会话保留 |

> [!NOTE]
> **底层逻辑**：两套记忆系统的设计**对应了两种信息天然属性**——**每次对话都需要知道的**（CLAUDE.md）和**在工作中自然积累的**（Auto Memory）。把所有信息都塞进 CLAUDE.md 等于文件膨胀 + 团队 review 噪音；让 AI 自己积累而不留人写规则的口子，团队会失去显式约定。**两套必须并存**。

## 7. 排障：Claude 不听 CLAUDE.md 怎么办

CLAUDE.md 是**上下文**不是**强制配置**。Claude 会读它、尝试遵守，但**不保证严格服从**——尤其是模糊或冲突的指令。

<details>
<summary>排障 1 · 用 /memory 检查到底加载了哪些文件</summary>

`/memory` 命令列出当前会话所有已加载的 CLAUDE.md / CLAUDE.local.md / `.claude/rules/*.md`。

如果你的指令文件**没出现在列表里** → Claude 根本没看到。

常见原因：
- 文件不在工作目录的祖先链上
- 子目录 CLAUDE.md（只在 Claude 读子目录文件时按需加载）
- 用了 `--add-dir` 但没设 `CLAUDE_CODE_ADDITIONAL_DIRECTORIES_CLAUDE_MD=1`

</details>

<details>
<summary>排障 2 · 让指令更具体</summary>

`格式化代码` ❌ → `用 2 空格缩进` ✅
`测试改动` ❌ → `提交前跑 pnpm test` ✅
`保持文件组织` ❌ → `API 处理器在 src/api/handlers/` ✅

模糊的话 Claude 会自由发挥，**具体到能验证的程度**才能稳定遵循。

</details>

<details>
<summary>排障 3 · 文件超过 200 行</summary>

文件越长，消耗上下文越多，对指令的遵循度反而下降。

**解法**：

- **路径范围规则** → 拆到 `.claude/rules/` 加 `paths: [...]` frontmatter，只在 Claude 处理匹配文件时加载
- **拆分多文件** → 用 `@path/to/sub.md` import（注意：import 的内容仍然占上下文 token，只是组织上分开）
- **剔除可推断的内容** → 文件结构 / 函数签名等代码里有的，删掉

</details>

<details>
<summary>排障 4 · 多个 CLAUDE.md 互相冲突</summary>

monorepo / 大型项目里，祖先目录的 CLAUDE.md 可能跟当前项目的指令矛盾。Claude 会**任意挑一个**，行为不稳定。

**解法**：

- 用 `/memory` 看所有加载的文件
- 找到冲突指令，统一表述
- 不需要的祖先文件用 `claudeMdExcludes` 设置排除

</details>

<details>
<summary>排障 5 · /compact 后指令好像没了</summary>

项目根 CLAUDE.md **会** 在 `/compact` 后被重新注入。
子目录 CLAUDE.md **不会**自动重新注入，下次 Claude 读子目录文件时才会重新加载。

如果 `/compact` 后指令丢了 → 大概率是你**只在对话里口头给过**的指令，没写进文件。**写进 CLAUDE.md 才能跨 compact 持久**。

</details>

## 8. 检验你真懂了吗

费曼说，检验你是不是真的理解一件事，试试能不能解释给朋友听。

| # | 试着用自己的话回答 | 对应章节 |
|:-:|------|------|
| 1 | 有人说 Claude Code 记忆力很好什么都能记住——你能解释为什么这说法不准确？它有几种记忆，各自的特点？ | §1 + §6 |
| 2 | CLAUDE.md 为什么建议控制在 200 行以内？背后的原理是什么？超过会怎样？ | §2 + 排障 3 |
| 3 | **动手题** ⭐：打开你当前项目的 `CLAUDE.md`（如果没有，新建一个）。**删掉**所有"`ls` / `git log` / `cat package.json` 能查到的内容"——目录结构、依赖列表、Git 历史描述等。剩下的就是真正"每次会话都要进上下文"的项目规范。如果剩不到 50 行，证明你以前在 CLAUDE.md 里塞了太多 Claude 自己能查的事实。| §5 |

> [!TIP]
> **过关标准**：能用一句话说清——**Claude Code 的跨会话记忆是双轨的：你写的 CLAUDE.md（4 层 scope，规则）+ 它写的 Auto Memory（项目本地，经验）；代码里有的事实不重复存。**

<details id="glossary">
<summary>📖 本篇术语速查表</summary>

| 英文 / 缩写 | 中文 | 一句话解释 |
|-------------|------|-----------|
| CLAUDE.md | 项目记忆文件 | 你写的持久指令，每次启动自动读，Markdown 格式 |
| `~/.claude/CLAUDE.md` | 用户级记忆 | 跨所有项目的个人偏好 |
| `./CLAUDE.local.md` | 本地级记忆 | 当前项目的个人偏好（必须加 `.gitignore`）|
| Managed policy | 系统级策略 | IT/DevOps 部署的全公司强制指令 |
| `.claude/rules/` | 规则目录 | 大项目下按主题拆分的指令文件，支持 `paths:` glob 过滤 |
| `@path/to/file` | import 语法 | CLAUDE.md 引用其它文件，递归最多 5 层 |
| Auto Memory | 自动记忆 | Claude 自己维护的项目本地笔记系统（v2.1.59+ 默认开启）|
| MEMORY.md | 自动记忆主文件 | Auto Memory 索引，启动加载前 200 行 / 25KB |
| `/memory` | 记忆查看命令 | 列出当前会话已加载的所有指令文件 |
| `claudeMdExcludes` | 排除设置 | settings 里指定不加载某些 CLAUDE.md（monorepo 场景）|
| `CLAUDE_CODE_DISABLE_AUTO_MEMORY` | 环境变量 | 设为 `1` 关闭 Auto Memory |

</details>

## 官方资料

- [How Claude remembers your project](https://code.claude.com/docs/en/memory)
- [Explore the .claude directory](https://code.claude.com/docs/en/claude-directory)

## 接下来去哪

<Cards>
  <Card title="➡️ 04 · 怎么和 AI 说话" href="/docs/claude-code/understanding/04-prompting">
    有了记忆，还得会说话。提示词不是模板游戏，是信息密度游戏——目标 / 上下文 / 边界 / 验收 4 件套。
  </Card>
  <Card title="06 · 把重复的话写成文件（可跳读）" href="/docs/claude-code/understanding/06-command-files">
    规则之外还有工作流。Skills 是把多步流程沉淀成可复用单元——记忆系统的进化形态。
  </Card>
  <Card title="02 · 一次能看多少代码（上一篇）" href="/docs/claude-code/understanding/02-context-window">
    复习一下：上下文是会话级的工作台。本篇的双轨记忆就是为了解决**每次对话都需要知道的**那部分。
  </Card>
</Cards>

不用按顺序全读。挑你最好奇的那条线走就行。
