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 根本看不见。然后按这个顺序查:

  1. 文件放对位置了吗?(子目录的要等按需加载)
  2. 指令够具体吗?("缩进两格"好过"格式规范")
  3. 多个文件之间互相矛盾吗?(矛盾时 Claude 随机选一边)
  4. 是不是该用硬约束?(必须在固定时机执行的事写成 hook)

可以跑 /doctor prompt-audit 让 Claude 自己审计指令文件,找出过时、冲突、引用不存在的命令等问题。项目根的 CLAUDE.md 在压缩后会从磁盘重新注入,所以"压缩后指令丢了"通常是因为指令只在对话里说过——老规矩:要持久的,进文件。

本章由 WorkBuddy 原创整理,事实性内容参考 Claude Code 官方文档。