CLAUDE.md 记忆体系:项目级/用户级/自动记忆怎么组织
两套记忆,各管一头
Claude Code 每个会话都从空白上下文开始。跨会话留知识靠两套机制:CLAUDE.md 文件——你写给 Claude 的持久指令;自动记忆(auto memory)——Claude 自己记的笔记。官方文档有个很清醒的定位:这些是上下文,不是强制配置。想让某个动作无论如何都执行或禁止,得用 hook(硬约束);CLAUDE.md 是软引导,写得越具体越容易被遵守。
| CLAUDE.md | 自动记忆 | |
|---|---|---|
| 谁来写 | 你 | Claude |
| 内容 | 指令和规则 | 经验和偏好 |
| 作用域 | 项目 / 用户 / 组织 | 按仓库,worktree 共享 |
| 载入 | 每次会话全量 | 每次会话载 MEMORY.md 前 200 行或 25KB |
| 典型用途 | 构建命令、规范、架构 | 你的纠正、偏好、代码里看不出来的背景 |
CLAUDE.md 的四个层级
CLAUDE.md 可以放好几个位置,作用域从大到小:
| 层级 | 位置 | 给谁用 |
|---|---|---|
| 组织策略 | /Library/Application Support/ClaudeCode/CLAUDE.md(macOS)等系统路径 |
全公司,IT 统一下发 |
| 用户级 | ~/.claude/CLAUDE.md |
你个人的全部项目 |
| 项目级 | 项目根 ./CLAUDE.md 或 ./.claude/CLAUDE.md |
团队共享,进版本库 |
| 本地级 | ./CLAUDE.local.md |
只你自己,加进 .gitignore |
理解两件事就掌握了这套体系。第一,加载顺序:从宽到窄依次载入、拼接而非覆盖——用户级的先读,项目级的后读,离你启动目录越近的越靠后。第二,子目录懒加载:当前目录及所有上级目录的 CLAUDE.md 启动时就读;子目录里的要等 Claude 实际读写那个目录的文件时才载入。monorepo 里的团队就是靠这个机制让各目录自带各自的规矩。
打个比方:CLAUDE.md 的层级像公司的规章制度体系——宪法(组织级)、个人工作习惯(用户级)、项目组守则(项目级)、你自己的便利贴(本地级),一级比一级具体。
什么样的内容值得写进去
一个实用的判断标准:同一件事你会向 Claude 解释第二遍,就该进 CLAUDE.md。包括:
- 构建和测试命令("跑
npm test,别用 vitest 直接跑"); - 代码约定("缩进两格""API 处理器放
src/api/handlers/"); - 哪些目录不能动、有哪些历史包袱;
- 新同事入职也需要知道的背景。
反过来,多步骤流程、只针对某类文件的操作,别塞 CLAUDE.md——前者该做成 skill,后者该做成路径作用域规则(下面讲)。
写法上有条黄金法则:写可验证的具体指令,不写正确的废话。"格式规范"是废话,"缩进两格"是指令。目标控制每个文件 200 行以内——更长的文件吃上下文还降低遵守率。
# 本项目约定
## 构建
- 跑测试:npm test(不要直接用 vitest,包装脚本里有环境初始化)
- 类型检查:npm run typecheck
## 规则
- 所有 API 端点必须有输入校验,错误响应用统一的 ErrorResponse 格式
- src/legacy/ 目录是待下线的旧系统,不要修改也不要在其中新增文件
- 提交信息用中文,遵循 conventional commits 前缀
## 上下文
- 数据库迁移只能追加,禁止修改已发布的迁移文件
@导入 与 rules 目录
CLAUDE.md 支持 @路径 导入语法,被导入的文件在启动时展开加载(最多递归四层)。想让 README、package.json 也进上下文,一行搞定:
见 @README 了解项目概况,可用脚本见 @package.json。
要提一个 @ 路径但不想导入它,用反引号包起来即可。另外把指令按主题拆进 .claude/rules/ 目录,每个文件一个话题,还能用 paths 前置元数据限定作用范围:
---
paths:
- "src/api/**/*.ts"
---
# API 开发规则
- 所有端点必须包含输入校验
- 使用标准错误响应格式
带 paths 的规则只在 Claude 碰到匹配文件时载入——这是省上下文的神器:安全规范只在改安全相关代码时占用注意力,平时一 token 不花。没有 paths 的规则每会话加载,优先级与 .claude/CLAUDE.md 相同。
已有 AGENTS.md 的仓库不用另建文件:Claude Code 能直接读它当项目指令(也可在 CLAUDE.md 里 @AGENTS.md 导入实现多工具共用一份)。
自动记忆:Claude 自己的笔记本
自动记忆默认开启,存储在 ~/.claude/projects/<项目>/memory/,结构是一个 MEMORY.md 索引加若干主题文件。它记四类内容,以 type 字段区分:你的角色和偏好(user)、你给过的纠正(feedback)、代码里看不出来的项目背景(project)、外部资源的位置(reference)。能从代码推导出来的东西它会主动跳过。
用 /memory 命令可以浏览、编辑这些文件——都是明文 markdown,随时可改可删。想让 Claude 记住什么,直接说"记住:我们的 API 测试需要本地 Redis",它就写进去了;想加到 CLAUDE.md 则明确说"把这条加到 CLAUDE.md"。
同仓库的所有 worktree 共享一份自动记忆(按 git 仓库定位),但不跨机器同步。MEMORY.md 只载前 200 行或 25KB,所以索引保持每条一行,细节让它放主题文件里。
一份从零到成熟的维护节奏
CLAUDE.md 不是写完就完的文件,它有生命周期。给你一份我团队实践出来的节奏:
第 0 天:/init 生成初稿,人工删掉它从代码就能推出来的部分(目录结构、依赖清单——这些占上下文却没增量价值),只留坑、理由和与默认行为不同的约定。
第 1 周:每次你纠正 Claude 第二遍时,当场说"把这条加进 CLAUDE.md"。一周下来积累的往往就是最宝贵的五到十条。
每月:跑一次 /doctor prompt-audit,清过时条目。项目变了规范也要跟着变,过时指令比没有指令更糟——它会让 Claude 在新场景里用旧行为。
团队场景:约定"改了规范就同步改 CLAUDE.md"作为 code review 检查项之一。这个文件是代码库的一部分,理应和代码走同样的评审流程。
CLAUDE.md 反模式清单
写了这么多项目,最常见的失败模式集中在这几条:
- 百科全书式:把项目所有背景塞进一个文件,300 行起步。结果是没有一条被认真遵守。处方:拆 rules、砍到 200 行以内;
- 教程式:写"请先阅读 README,然后理解架构,再开始工作"。Claude 不会执行你的仪式感,直接写结论;
- 命令冲突式:项目 CLAUDE.md 说用 pnpm,你的用户级 CLAUDE.md 说用 npm。两个都会被加载,Claude 随机听一边。处方:用户级只放跨项目通用偏好;
- 愿望式:"写出高质量代码""注意性能"。无法验证的指令等于不存在;
- 翻译式:把团队文档原样 @ 导入五份。@ 导入不省上下文——展开加载的内容和写在正文里一样大。只导入真正每会话需要的。
排障:写了不生效怎么办
第一步永远是 /context:在 Memory files 清单里确认你的文件真的载入了。没在清单里的文件,Claude 根本看不见。然后按这个顺序查:
- 文件放对位置了吗?(子目录的要等按需加载)
- 指令够具体吗?("缩进两格"好过"格式规范")
- 多个文件之间互相矛盾吗?(矛盾时 Claude 随机选一边)
- 是不是该用硬约束?(必须在固定时机执行的事写成 hook)
可以跑 /doctor prompt-audit 让 Claude 自己审计指令文件,找出过时、冲突、引用不存在的命令等问题。项目根的 CLAUDE.md 在压缩后会从磁盘重新注入,所以"压缩后指令丢了"通常是因为指令只在对话里说过——老规矩:要持久的,进文件。
本章由 WorkBuddy 原创整理,事实性内容参考 Claude Code 官方文档。
