Claude Code 的项目记忆由两条互补轨道组成:人工编写的 CLAUDE.md 给出”应当遵守”的规则,auto memory 让 Claude 自己在每次会话中沉淀”踩过的坑”。两套机制都在会话开始时被读入上下文,但作用域、写入者、典型内容差异显著,理解这两条轨道的边界是让项目上下文真正跨会话保留的关键。2025 年起,CLAUDE.md 已支持六级作用域与路径级规则,可与多个 Agent 工具共享。
(项目背景:在 monorepo 里维护公共指令时,常遇到”刚加的规则下次又丢”的痛点。Claude Code 把规则拆成”人写”与”机写”两轨,再配合 .claude/rules/ 做路径级裁剪,终于让”小修改”在几个月内不再被重置。)
一、双轨记忆的总体结构
Claude Code 的每次会话都从一个全新上下文窗口启动,本身不具备跨会话记忆能力。所有跨会话知识都必须通过外部文件注入。官方文档把这两类机制统称为”两个互补的记忆系统”:CLAUDE.md 提供人工编辑的规则,auto memory 由 Claude 在运行中追加。
| 维度 | CLAUDE.md | 自动记忆 |
|---|---|---|
| 写入者 | 项目维护者本人 | Claude 自己 |
| 典型内容 | 编码规范、构建命令、必守规则 | 调试踩坑、依赖约束、用户偏好 |
| 作用域 | 项目 / 用户 / 组织 / 本地 | 仓库级别,可跨 worktree 共享 |
| 加载时机 | 每次会话启动全量 | 每次会话启动前 200 行或 25KB |
| 强制方式 | 上下文提示(非强约束) | 上下文提示(非强约束) |
注意”非强约束”这四个字。两者都是”建议给模型参考”的提示,不是 PostToolUse 那种拦截式钩子。真正要强制某条规则必须用 PreToolUse hook 在工具调用前阻断,单纯写进 CLAUDE.md 只是提高模型注意力的手段。
二、CLAUDE.md 的六级作用域
CLAUDE.md 不是单一文件,而是一组按目录层级组织的指令文件。Claude Code 启动时从工作目录向上回溯,把沿途所有命中文件全部读入。官方列出了五个层级的标准位置,再加上 .claude/rules/ 这条按路径裁剪的辅助层。
| 作用域 | 路径示例 | 共享范围 |
|---|---|---|
| Managed policy | /etc/claude-code/CLAUDE.md | 组织内全部用户 |
| User | ~/.claude/CLAUDE.md | 当前用户全部项目 |
| Project | ./CLAUDE.md 或 ./.claude/CLAUDE.md | 团队通过 Git 共享 |
| Local | ./CLAUDE.local.md | 当前项目单人(须 .gitignore) |
| Project rules | ./.claude/rules/*.md | 团队通过 Git 共享 |
| Auto memory | ~/.claude/projects/ |
当前用户全部 worktree |
上下级之间是”叠加”而非”覆盖”——项目级文件会出现在用户级之后,作用是补充而非替换。对于 monorepo,更稳妥的写法是项目根放总纲,再用 .claude/rules/ 给子目录或文件类型做精细约束。
2.1 路径级规则:把”何时生效”写清楚
.claude/rules/ 目录下每个 .md 是一份”作用域规则”,可以前置 YAML 头限制只对某些文件类型或路径生效。例如”所有 src/api/ 下的 TypeScript 文件必须用 2 空格缩进”。这条规则只在 Claude 真正打开匹配文件时才会被读入,未匹配的会话不会浪费上下文。
---
paths:
- "src/api/**/*.ts"
- "src/api/**/*.tsx"
---
# API 层编码规范
- 缩进统一 2 空格
- 错误必须经过统一 errorHandler 包装
- 新增接口需在 docs/api.md 同步登记
规则文件前有这一段声明,解决了”通用 CLAUDE.md 越写越长”的常见问题。官方建议每个 CLAUDE.md 文件控制在 200 行内,长出来就拆到路径级规则里去。
2.2 @ 导入与 AGENTS.md 互通
很多仓库已经存在给其他 Agent 工具使用的 AGENTS.md。Claude Code 不直接读 AGENTS.md,但支持用 @ 语法把它导入项目 CLAUDE.md,使两套工具读同一份事实。最大导入深度是 4 跳,文件可递归引用但不能形成环。
# CLAUDE.md 片段
通用 Agent 规则 @AGENTS.md
Claude 专属行为
- Plan Mode 必须在 src/billing/ 下使用
- 长任务前先 /compact
导入文件同样在启动时全量读入,超长引用会反噬上下文窗口。给外部 README 写引用时,记得用反引号包住 @README,否则会被当作导入语法解析。
三、auto memory 的写入与检索
auto memory 由 Claude 在会话中通过标准文件编辑工具写入本地目录,典型路径是 ~/.claude/projects/<repo>/memory/,再围绕一个 MEMORY.md 索引文件组织内容。官方将其分为四类:user(用户偏好)、feedback(被纠正的偏好)、project(项目特征)、reference(外部资料)。
写入策略与一般 Agent 的向量记忆差异明显:Claude Code 不做 embedding 检索,而是每轮让一个较小的模型从候选文件里挑”本次对话用得到的 5 个文件”读入上下文。这种”小模型 per-turn 选文件”的策略源自 Anthropic 公开的 Claude Agent SDK 设计原则,强调透明、可解释、低维护成本。
auto memory 写入流程(伪代码)
1. 上一轮产生 user 反馈("不要在这里用 export default")
2. 反思:这是偏好还是项目约定?
3. 写入 ~/.claude/projects/<repo>/memory/feedback.md
4. 更新 MEMORY.md 索引,加入一行摘要
5. 下次会话首轮被读入
3.1 与通用 Agent Memory 的差异
把 Claude Code 的记忆与常见 Agent 框架(LangChain、CrewAI、AutoGen 等)放在一起比较,差异集中在存储形态、检索方式、跨工具可移植性三个维度。
| 维度 | Claude Code | 通用 Agent Memory(典型方案) |
|---|---|---|
| 存储形态 | 纯 Markdown 文件 | 向量库 + 结构化记录混合 |
| 检索方式 | 小模型每轮挑选文件 | 语义检索 + 关键词检索 |
| 嵌入成本 | 无 | 需要 embedding 模型 |
| 跨工具可移植 | 通过 @AGENTS.md 导入 | 需导出/导入 schema |
| 维护成本 | 文件可读,diff 友好 | 向量库 schema 演进困难 |
对项目维护者而言,Claude Code 的优势是”会写 Git diff 就会审记忆”。劣势是文件规模膨胀后没有自动去重,200 行上限是条隐形的硬约束。
四、让规则真正生效的实操步骤
把”什么写哪里”想清楚再下笔,比反复改 CLAUDE.md 更省时间。
- 把”每次会话都要用”的硬规则放 ./CLAUDE.md;
- 个人调试沙箱与本地 URL 放 ./CLAUDE.local.md 并加入 .gitignore;
- 编码风格、子目录约定放 .claude/rules/ 配 paths 字段;
- 团队代码规范、组织级安全策略走 managed policy;
- 调试踩坑、用户偏好让 Claude 自己写 auto memory;
- /init 命令生成初版 CLAUDE.md,再人工补全它发现不了的约束。
跑通这条流水线后,会发现”为什么又忘了”这种问题大幅减少,团队成员拉一份新仓库也能立刻进入节奏。
常见问题(FAQ)
Q1:CLAUDE.md 写得太长会怎么样?
加载时占据更多上下文窗口,模型对每条规则的注意力都会下降,超过 200 行建议拆到 .claude/rules/。
Q2:如何阻止 Claude 违反 CLAUDE.md 中的规则?
CLAUDE.md 只是上下文提示,强制阻断必须用 PreToolUse hook 在工具调用前拦截。
Q3:auto memory 的内容会跨仓库串味吗?
不会,auto memory 存放在 ~/.claude/projects/