每次与 Claude Code 开始一段新对话,它都像一位初次见面的同事------对之前的合作毫无印象。这在开发中会带来困扰:明明上次已经教过它项目的构建命令,这次又得重复一遍。
为了解决这个问题,Claude Code 内置了两套记忆系统。一套是开发者主动撰写的说明书,另一套是 Claude 自己默默积累的笔记。两者各司其职,配合起来能让协作体验大幅提升。

两种记忆,两种分工
Claude Code 的两套记忆机制并不冲突,而是互补的:
| 特性 | CLAUDE.md 文件 | 自动记忆(Auto Memory) |
|---|---|---|
| 谁来写 | 开发者 | Claude 自己 |
| 内容是什么 | 指令和规则 | 学习到的模式和偏好 |
| 作用范围 | 项目、用户或整个组织 | 每个工作树(git 仓库) |
| 加载时机 | 每次会话开始 | 每次会话开始(前 200 行或 25KB) |
| 典型用途 | 代码规范、工作流程、架构说明 | 构建命令、调试技巧、偏好习惯 |
简单来说:想明确告诉 Claude 怎么做事,就用 CLAUDE.md;想让 Claude 从纠正中自己学东西,交给自动记忆就好。
CLAUDE.md:开发者写给 Claude 的说明书
CLAUDE.md 是纯文本的 Markdown 文件,放在项目的特定位置,Claude 在每次会话启动时都会读取。它就像一份放在办公桌上的项目手册,随时可以翻阅。
放在哪里最合适
不同位置的 CLAUDE.md 有不同的影响范围,越具体的位置优先级越高:
| 作用范围 | 存放路径 | 用途举例 |
|---|---|---|
| 组织级策略 | macOS: /Library/Application Support/ClaudeCode/CLAUDE.md Linux/WSL: /etc/claude-code/CLAUDE.md Windows: C:\Program Files\ClaudeCode\CLAUDE.md |
公司级编码标准、安全策略 |
| 项目指令 | ./CLAUDE.md 或 ./.claude/CLAUDE.md |
项目架构、团队工作流 |
| 用户指令 | ~/.claude/CLAUDE.md |
个人代码风格偏好、工具习惯 |
当 Claude 在某个目录下工作时,它会沿着目录树向上查找,加载沿途遇到的 CLAUDE.md。比如在 foo/bar/ 目录下启动,就会同时加载 foo/bar/CLAUDE.md 和 foo/CLAUDE.md。子目录中的 CLAUDE.md 不会在启动时全部加载,而是在 Claude 实际读取那些目录里的文件时才按需载入。
如何写出一份好用的 CLAUDE.md
运行 /init 命令可以让 Claude 自动分析代码库,生成一份起步用的 CLAUDE.md。如果设置环境变量 CLAUDE_CODE_NEW_INIT=true,还会进入交互式流程,让 Claude 先探索项目、提出疑问,最后给出一个可预览的方案再写入文件。
但自动生成只是起点。真正好用的指令需要遵循几个原则:
控制长度 。每个 CLAUDE.md 文件最好控制在 200 行以内。太长的文件会占用大量上下文,反而让 Claude 难以遵循。如果内容实在很多,可以拆分成多个文件,通过导入或 .claude/rules/ 来组织。
结构清晰。使用 Markdown 标题和列表来分组。Claude 扫描结构的方式和人类读者差不多------有组织的章节比一大段文字更容易被准确理解。
指令要具体。模糊的表述效果很差。对比一下:
- 差:"代码要写得规范"
- 好:"使用 2 个空格缩进"
- 差:"提交前测试一下"
- 好:"提交前运行
npm test" - 差:"文件要放对地方"
- 好:"API 处理器放在
src/api/handlers/目录下"
避免矛盾 。如果两个规则相互冲突,Claude 可能会随意选择一个。定期检查各个 CLAUDE.md 文件、子目录里的指令以及 .claude/rules/ 下的规则,删掉过时或冲突的内容。在大型 monorepo 中,可以用 claudeMdExcludes 设置跳过其他团队不相关的 CLAUDE.md。
导入其他文件
CLAUDE.md 支持 @路径 语法导入外部文件。比如在文件中写上:
plain
参见 @README 了解项目概览,@package.json 查看可用命令
# 额外说明
- git 工作流参见 @docs/git-instructions.md
导入的文件会在启动时被展开并加载到上下文中,支持递归导入,最深五层。相对路径是相对于当前文件所在目录。
对于不想提交到仓库的个人偏好,可以导入用户目录下的文件:
plain
# 个人偏好
- @~/.claude/my-project-instructions.md
第一次遇到外部导入时,Claude Code 会弹出一个对话框列出所有要导入的文件,需要用户确认。如果拒绝了,导入就会保持禁用状态,且不再弹出提示。
关于 AGENTS.md 的说明
Claude Code 读取的是 CLAUDE.md,而不是其他工具常用的 AGENTS.md。如果仓库里已经有 AGENTS.md 文件,可以创建一个 CLAUDE.md,在里面用 @AGENTS.md 把它导入进来。这样两个工具就能共享同一份指令,不用重复维护。还可以在导入语句后面继续追加 Claude Code 特有的说明。
注释的妙用
CLAUDE.md 文件中的块级 HTML 注释(<!-- 维护者笔记 -->)在注入上下文之前会被自动剥离。这意味着可以用注释给人类维护者留下说明,而不会消耗宝贵的上下文 token。代码块内部的注释则会被保留。如果直接用 Read 工具打开 CLAUDE.md 文件,注释仍然是可见的。
加载额外目录的 CLAUDE.md
通过 --add-dir 参数可以让 Claude 访问主工作目录之外的其他目录。默认情况下,这些额外目录中的 CLAUDE.md 不会被加载。如果想一并加载,可以设置环境变量:
bash
CLAUDE_CODE_ADDITIONAL_DIRECTORIES_CLAUDE_MD=1 claude --add-dir ../shared-config
用 .claude/rules/ 组织更复杂的规则
当项目变得庞大,把所有指令塞进一个 CLAUDE.md 会很难维护。.claude/rules/ 目录提供了更灵活的方案。
基本用法
在项目根目录下创建 .claude/rules/,然后往里面放 Markdown 文件。每个文件聚焦一个主题,文件名要有描述性,比如 testing.md、api-design.md。可以再用子目录进一步分类:
plain
your-project/
├── .claude/
│ ├── CLAUDE.md
│ └── rules/
│ ├── code-style.md
│ ├── testing.md
│ ├── security.md
│ └── frontend/
│ └── react-patterns.md
所有 .md 文件都会被递归发现。不带 paths 前置信息的规则文件会在启动时加载,优先级和 .claude/CLAUDE.md 相同。
路径特定的规则
通过 YAML 前置信息中的 paths 字段,可以让规则只对特定文件生效:
markdown
---
paths:
- "src/api/**/*.ts"
---
# API 开发规则
- 所有 API 端点必须包含输入验证
- 使用标准错误响应格式
- 包含 OpenAPI 文档注释
没有 paths 字段的规则会无条件加载。路径规则会在 Claude 读取匹配的文件时触发,而不是每次工具调用都检查。
paths 字段支持 glob 模式:
| 模式 | 匹配内容 |
|---|---|
**/*.ts |
任意目录下的所有 TypeScript 文件 |
src/**/* |
src 目录下的所有文件 |
*.md |
项目根目录下的 Markdown 文件 |
src/components/*.tsx |
特定目录下的 React 组件 |
还可以用花括号扩展一次匹配多个扩展名:
yaml
paths:
- "src/**/*.{ts,tsx}"
- "lib/**/*.ts"
用符号链接共享规则
.claude/rules/ 支持符号链接,因此可以维护一套公共规则库,然后在多个项目中通过链接引用。循环链接会被自动检测并妥善处理。
示例:
bash
ln -s ~/shared-claude-rules .claude/rules/shared
ln -s ~/company-standards/security.md .claude/rules/security.md
用户级规则
放在 ~/.claude/rules/ 目录下的规则会应用到本机的所有项目。适合存放不依赖具体项目的个人偏好:
plain
~/.claude/rules/
├── preferences.md
└── workflows.md
用户级规则在项目规则之前加载,因此项目规则拥有更高的优先级。
团队大规模使用时的管理
当组织内有多名开发者使用 Claude Code 时,集中管理指令就变得很重要。
部署组织级 CLAUDE.md
可以在每台机器上放置一个由 IT 或运维团队管理的 CLAUDE.md 文件,位置如下:
- macOS:
/Library/Application Support/ClaudeCode/CLAUDE.md - Linux / WSL:
/etc/claude-code/CLAUDE.md - Windows:
C:\Program Files\ClaudeCode\CLAUDE.md
这个文件无法被个人设置排除,适合存放公司编码标准、安全策略等必须遵守的指导。通过 MDM、组策略或 Ansible 等工具可以批量分发到所有开发者机器。
需要注意的是,组织级 CLAUDE.md 与管理设置(managed settings)各司其职:
| 需求 | 配置位置 |
|---|---|
| 禁止特定工具、命令或路径 | 管理设置:permissions.deny |
| 强制沙箱隔离 | 管理设置:sandbox.enabled |
| 环境变量和 API 路由 | 管理设置:env |
| 代码风格和质量指南 | 组织级 CLAUDE.md |
| 数据处理和合规提醒 | 组织级 CLAUDE.md |
| 对 Claude 的行为指导 | 组织级 CLAUDE.md |
管理设置是由客户端强制执行的技术手段,而 CLAUDE.md 是指导性内容。
排除特定的 CLAUDE.md 文件
在大型 monorepo 中,父目录里可能有其他团队的 CLAUDE.md 包含不相关的指令。通过 claudeMdExcludes 设置可以跳过特定文件或目录:
json
{
"claudeMdExcludes": [
"**/monorepo/CLAUDE.md",
"/home/user/monorepo/other-team/.claude/rules/**"
]
}
这个配置可以放在 .claude/settings.local.json 中,保持本地化。排除规则支持 glob 模式匹配绝对路径,不同配置层的数组会合并。但组织级策略的 CLAUDE.md 无法被排除。
自动记忆:Claude 给自己做的笔记
如果说 CLAUDE.md 是开发者给 Claude 的"操作手册",那自动记忆就是 Claude 自己记的"工作日志"。
自动记忆功能让 Claude 能够跨会话积累经验,而开发者完全不需要手动写任何东西。Claude 在工作的过程中会自己决定什么值得记住------可能是某个项目的构建命令、一次调试中的关键发现、代码风格的偏好,或者常用的工作流程。它不会每个会话都记录,只会在判断某条信息对未来对话有用时才保存。
这个功能需要 Claude Code 2.1.59 或更高版本,可以用 claude --version 检查。
开启与关闭
自动记忆默认是开启的。在会话中输入 /memory 可以打开记忆面板,通过开关来控制。也可以在项目设置中明确禁用:
json
{
"autoMemoryEnabled": false
}
或者通过环境变量:CLAUDE_CODE_DISABLE_AUTO_MEMORY=1
存在哪里
每个项目(基于 git 仓库)拥有独立的内存目录:~/.claude/projects/<项目>/memory/。同一个仓库的所有工作树和子目录共享这个目录。如果不在 git 仓库中,则使用项目根目录。
目录结构大致如下:
plain
~/.claude/projects/<项目>/memory/
├── MEMORY.md # 索引文件,每次会话加载
├── debugging.md # 调试模式的详细笔记
├── api-conventions.md # API 设计决策
└── ... # 其他 Claude 创建的主题文件
MEMORY.md 扮演着索引的角色,记录每个主题存放在哪个文件里。Claude 在会话过程中会读写这些文件。
如果需要改变存储位置,可以在用户或本地设置中指定:
json
{
"autoMemoryDirectory": "~/my-custom-memory-dir"
}
注意这个设置不能放在项目级别的 .claude/settings.json 中,这是为了防止共享项目将自动记忆重定向到敏感位置。
工作机制
每次会话开始时,MEMORY.md 的前 200 行(或前 25KB,取较小者)会被加载到上下文中。超出这个阈值的内容不会在启动时加载,这迫使 MEMORY.md 保持精简------Claude 会把详细内容挪到单独的主题文件里。
这个加载限制只针对 MEMORY.md。CLAUDE.md 文件无论多长都会完整加载,但如前所述,较短的 CLAUDE.md 通常效果更好。
像 debugging.md 这样的主题文件不会在启动时加载。当 Claude 需要这些信息时,它会用常规的文件工具按需读取。
当界面显示"Writing memory"或"Recalled memory"时,就表示 Claude 正在更新或读取内存目录中的文件。
查看和编辑记忆
所有自动记忆文件都是纯文本的 Markdown,可以随时手动编辑或删除。在会话中运行 /memory 命令,会列出当前会话加载的所有 CLAUDE.md 和规则文件,并提供开关自动记忆的选项以及打开内存文件夹的链接。选中任意文件就可以在编辑器中打开。
如果想主动让 Claude 记住某件事,可以直接说"记住,这个项目总是用 pnpm 而不是 npm",或者"记住 API 测试需要本地 Redis 实例"。Claude 会把它保存到自动记忆中。如果想添加到 CLAUDE.md 里,可以明确告诉 Claude"把这个加到 CLAUDE.md",或者通过 /memory 手动编辑。
常见问题排查
Claude 不遵循 CLAUDE.md 里的指令
CLAUDE.md 的内容是以用户消息的形式(在系统提示之后)传递给 Claude 的,而不是作为系统提示本身。Claude 会尝试遵循,但对于模糊或矛盾的指令无法保证严格遵从。
排查步骤:
- 运行
/memory确认文件确实被加载了。如果文件不在列表里,Claude 根本看不到它。 - 检查文件是否放在了正确的位置(参考前面的位置表格)。
- 让指令更具体。"使用 2 个空格缩进"比"把代码格式弄好"有效得多。
- 检查多个 CLAUDE.md 文件之间是否有冲突。
- 对于那些希望放在系统提示级别的指令,可以用
--append-system-prompt参数,但这个参数每次调用都要带上,更适合脚本和自动化场景。 - 使用 InstructionsLoaded 钩子来记录哪些指令文件被加载、何时加载、为什么加载,这对调试路径规则或子目录中的懒加载文件很有帮助。
不知道自动记忆保存了什么
运行 /memory,选择自动记忆文件夹,就可以浏览 Claude 保存的所有内容。一切都是纯文本,可以阅读、编辑或删除。
CLAUDE.md 文件太大了
超过 200 行的文件会占用更多上下文,降低遵循程度。可以把详细内容移到单独的文件中,通过 @路径 导入,或者拆分成多个 .claude/rules/ 文件。
执行 /compact 后指令好像丢失了
/compact 后,Claude 会从磁盘重新读取 CLAUDE.md 并重新注入到会话中。如果一个指令在压缩后消失了,说明它只是在之前的对话中被口头提过,并没有写进 CLAUDE.md。把它加到 CLAUDE.md 里就能跨会话持久保留。
相关资源
除了记忆机制,Claude Code 还有几个相关的功能值得了解:
- Skills(技能):打包可重复的工作流,按需加载,不占用常驻上下文
- Settings(设置):通过配置文件精细控制 Claude Code 的行为
- 会话管理:管理上下文、恢复对话、运行并行会话
- 子代理记忆:子代理也可以维护自己的自动记忆
理解了这两套记忆系统------开发者主动编写的 CLAUDE.md 和 Claude 自行积累的自动记忆------就能让每次对话站在之前的基础上继续前进,而不是每次都从零开始。