Claude Code 如何记住项目:两种记忆机制全解析

每次与 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.mdfoo/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.mdapi-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.mdCLAUDE.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 会尝试遵循,但对于模糊或矛盾的指令无法保证严格遵从。

排查步骤:

  1. 运行 /memory 确认文件确实被加载了。如果文件不在列表里,Claude 根本看不到它。
  2. 检查文件是否放在了正确的位置(参考前面的位置表格)。
  3. 让指令更具体。"使用 2 个空格缩进"比"把代码格式弄好"有效得多。
  4. 检查多个 CLAUDE.md 文件之间是否有冲突。
  5. 对于那些希望放在系统提示级别的指令,可以用 --append-system-prompt 参数,但这个参数每次调用都要带上,更适合脚本和自动化场景。
  6. 使用 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 自行积累的自动记忆------就能让每次对话站在之前的基础上继续前进,而不是每次都从零开始。

相关推荐
oscar9991 天前
探秘Claude Code的“.claude”目录:那些藏在背后的配置与记忆
memory·配置·rule·claude code·sikil
UWA11 天前
如何降低Animator的调用次数
性能优化·memory·游戏开发·animation
self-motivation14 天前
openclaw架构分析(三) -------------- memory实现分析
agent·memory·rag
roamingcode2 个月前
Cursor-memory-cli 自动化记忆提取的完整实现
运维·自动化·agent·memory·cursor·持久化记忆
roamingcode2 个月前
Cursor Memory 实战:如何终结 AI 助手的“金鱼记忆”
人工智能·agent·memory·cursor·会话记忆提取
wangmengxxw2 个月前
SpringAi-memory
人工智能·大模型·memory·springai
cr72582 个月前
使用 seekdb + PowerMem 构建多模态智能记忆系统 MemBox
ai·memory
M宝可梦2 个月前
Engram: DeepSeek最新工作解读
transformer·memory·hash·moe·记忆·deepseek·engram
UWA2 个月前
如何使Bloom只局部地作用于特效以提高性能
memory·rendering