avatar


2.Memory

简介

回忆一下,最早我们使用Cursor,每开一个新会话都要重新灌输一遍项目背景,一遍又一遍的重复目录职责,技术选型等。
我们可能会把这些写到一个文档中,这样可以复制粘贴给Cursor,或者让Cursor去读这份文档。

现在,ClaudeCode帮我们把这部分自动化了,并帮我们做了更精细的管理。

这就是本章的主题,记忆(Memory)。

官方文档:https://code.claude.com/docs/en/memory

记忆的三种形态

按"谁写、什么时候加载"划分,ClaudeCode的记忆有三种形态。

CLAUDE.md是我们写给Claude的项目手册。
规则文件(Rules)也是我们写的,但可以按路径条件加载。
自动记忆(Auto Memory)是Claude写给自己的笔记。

形态 谁写 位置 加载时机
CLAUDE.md 我们写给Claude 企业、用户、项目等多个层级 启动时注入;子目录的按需
规则文件 我们写给Claude .claude/rules/*.md~/.claude/rules/ 未声明paths的启动时加载;声明了paths的在Claude读取匹配文件时加载
自动记忆 Claude写给自己 ~/.claude/projects/<project>/memory/ 启动时加载MEMORY.md的前200行或25KB

三者解决同一个问题的三个侧面:CLAUDE.md承载稳定的事实与约定;规则文件把只与部分代码相关的规范从常驻上下文中拆出去;自动记忆让Claude把会话中学到的经验沉淀下来,不必每次重新踩坑。

CLAUDE.md

多个层级的CLAUDE.md

CLAUDE.md不止一个,ClaudeCode启动时会从多个层级收集:

层级 位置 作用范围 说明
企业策略 Linux/WSL为/etc/claude-code/CLAUDE.md,macOS为/Library/Application Support/ClaudeCode/CLAUDE.md,Windows为C:\Program Files\ClaudeCode\CLAUDE.md 组织内所有开发者 IT统一管理,无法被排除
用户 ~/.claude/CLAUDE.md 该用户的所有项目 跨项目的个人偏好
项目 ./CLAUDE.md./.claude/CLAUDE.md 当前项目 提交进版本库,团队共享
项目本地 ./CLAUDE.local.md 当前项目,仅本机 个人补充,加入.gitignore
子目录 ./src/CLAUDE.md 对应子目录 按需加载,Claude访问该目录下的文件时才注入

加载顺序的规则有:

  1. 目录树方向上,从文件系统根一路加载到当前工作目录,离工作目录越近的越靠后;
  2. 同一目录内,CLAUDE.md先于CLAUDE.local.md

子目录一级的CLAUDE.md有两点需要注意:

  1. 前四级都在启动时注入,子目录一级的CLAUDE.md是例外。如果Claude没有实际访问该目录下的文件,它就不会被加载。
  2. /compact压缩上下文之后,子目录一级的CLAUDE.md不会自动重新注入。

怎么写CLAUDE.md

不写废话

判断一条信息该不该进CLAUDE.md,标准只有一个: 这是不是Claude无法自行推断、而做错了会有实际代价的事实。
例如:

  • 构建与测试命令、目录职责、接口约定、"用什么、不用什么"的技术选型,属于该写的。
  • 通用编程常识和项目背景故事属于不该写的,Claude要么本来就知道,要么不需要知道。
  • "第一步做什么、第二步做什么"式的操作流程也不该写,这是工作流,只在特定任务时才有用,不该常驻在每一次会话里。
    这类按需加载的操作流程属于Skill(技能),是下一章《3.Skills》要解决的问题。

注意篇幅

CLAUDE.md的每个字都会出现在每一次会话的上下文里,写它的心态应该更接近写配置文件,而不是写文档。
超过两百行的CLAUDE.md不仅消耗更多token,还可能降低遵守率,内容越多,单条指令被严格执行的概率越低。

只是指导不是约束

CLAUDE.md是上下文,不是规则引擎。它写的是"希望Claude怎么做",Claude绝大多数时候会照做,但这终究是模型的判断,没有百分之百的保证。

所以别指望CLAUDE.md兜底那些"绝不能出错"的事,按需要多强的保证来选机制:

  • 允许偶尔偏差的行为习惯与约定,写进CLAUDE.md——软约束,靠模型自觉。
  • 绝不许碰的红线(哪些命令、哪些操作禁止执行),用settings.json的权限规则挡住——由ClaudeCode在工具调用前直接拦截,不经过模型判断。
  • 必须每次都发生的动作(比如每次编辑后自动格式化、提交前必跑检查),交给Hook(钩子),在特定事件上确定性触发,同样不依赖模型自觉,见《5.Hooks》

例子

一份短而事实型的项目级CLAUDE.md大致长这样:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 项目约定

## 常用命令

- 构建:`npm run build`,产物输出到`dist/`
- 测试:`npm test`,提交前必须全部通过
- 本地启动:`npm run dev`,监听3000端口

## 代码约定

- TypeScript严格模式,2空格缩进,Prettier统一格式化
- API统一返回`{ success, data, error }`结构

## 架构

- 架构说明见 @docs/architecture.md

每一行都在陈述事实,没有解释,没有寒暄。

导入语法

如何导入其他文件

在上文示例最后一行的@docs/architecture.md用到了导入语法。

CLAUDE.md里可以用@路径引用其他文件,被引用文件的内容会一并加载。

示例代码:

1
2
3
4
@docs/setup.md         # 相对路径,相对于导入文件所在目录
@~/.claude/shared.md # 绝对路径,~表示主目录
概览见 @README,环境搭建见 @docs/setup.md。
`@README` # 反引号包裹时不导入,保留字面文本

四条规则:

  1. 相对路径相对于导入文件所在目录解析,也支持绝对路径与~
  2. 导入可以递归,被导入的文件里还可以再写@,最大深度4跳。
  3. Markdown代码块与代码跨度内的@路径会被跳过,不触发导入;想在正文里字面展示一个@路径,用反引号包裹即可。
  4. 被导入的文件同样在启动时完整加载。

导入只是组织上清晰 不是上下文节省

注意:导入不节省token。把一大份CLAUDE.md拆成主文件加若干@导入,得到的是组织上的清晰,不是上下文上的节省,所有被导入的内容仍会在启动时全部注入。

规则文件

什么是规则文件

CLAUDE.md的内容对所有任务无差别常驻,但很多规则只与一部分代码相关:API设计规范只在改接口时有用,测试规范只在写测试时有用。

规则文件解决这个问题。在项目的.claude/rules/目录(或用户级的~/.claude/rules/)下放置多个Markdown文件,每个文件在YAML front matter的paths字段里声明自己关心的路径。

示例代码(.claude/rules/api-design.md):

1
2
3
4
5
6
7
8
9
10
---
paths:
- "src/api/**/*.ts"
- "lib/**/*.{ts,tsx}"
---

# API设计规范

- 校验所有输入
- 错误响应使用统一格式

触发机制

规则文件加载与否,取决于有没有声明paths

  • 声明了paths:只在Claude读取到匹配的文件时才加载,而不是每次工具调用都注入。
  • 没声明paths:启动时就加载,与拆成多个文件的CLAUDE.md没有区别,照样常驻每一次会话。

所以规则文件的价值全在paths上。
与其把两百行各领域规范一股脑塞进CLAUDE.md常驻,不如让每份规范只在相关文件被触碰时才出现。
这才是"减少启动常驻"的正解。

自动记忆

自动记忆:Claude在工作中把学到的东西写成笔记,留给未来会话中的自己。

它的位置在~/.claude/projects/<project>/memory/目录(<project>由git仓库路径派生,非git项目则按项目根目录路径派生),核心文件是MEMORY.md,此外还有Claude按主题拆分的独立文件。每次会话启动时,MEMORY.md的前200行或25KB会被自动加载。里面沉淀的往往是踩坑经验:某个脚本的隐藏前提、某份文档与实际行为的出入。

需要注意的是:

  1. 自动记忆是机器本地的,不跨机器、不跨云环境同步。
  2. 同一项目的多个worktree共享同一个memory目录。

自动记忆和CLAUDE.md的关系可以这样理解:前者是Claude的草稿本,后者是我们的定稿。自动记忆里长期有效的结论,值得经我们审核后升格写进项目CLAUDE.md——后者进版本库、随团队共享,前者只留在本机。

自动记忆默认开启,要关闭它有三种方式:在/memory面板里切换、把配置字段autoMemoryEnabled设为false,或设环境变量CLAUDE_CODE_DISABLE_AUTO_MEMORY=1

命令和配置

命令

/init

分析当前代码库,生成一份初始CLAUDE.md;已存在则给出改进建议。还能识别AGENTS.md.cursorrules等其他工具的规则文件并合并。

默认是一次性流程:扫一遍代码库、识别命令与约定,直接写出CLAUDE.md

设置环境变量CLAUDE_CODE_NEW_INIT=1后,变成交互式的多阶段流程:

  1. 先问你要生成什么(CLAUDE.md、Skills、Hooks);
  2. 派子代理探查代码库;
  3. 遇到信息缺口反问你;
  4. 给出可审阅的方案,确认后才落盘。

/add-dir

把工作目录之外的目录临时加进当前会话,让Claude能读写那里的文件。

默认只给文件访问权限,不会加载那些目录里的记忆文件(CLAUDE.md.claude/CLAUDE.md、规则文件、CLAUDE.local.md)。要连记忆一起加载,需把环境变量CLAUDE_CODE_ADDITIONAL_DIRECTORIES_CLAUDE_MD=1设上。

/compact

压缩当前上下文以腾出空间。它对记忆有个影响:压缩后项目根的CLAUDE.md会从磁盘重新注入,子目录一级的CLAUDE.md则不会自动回来(前文「多个层级的CLAUDE.md」已说明)。

配置

配置字段如下,写在settings.json中(claudeMd仅用于managed-settings.json),其层级与优先级见《1.Start》

字段 类型 默认值 说明
autoMemoryEnabled boolean true 启用或禁用自动记忆
autoMemoryDirectory string ~/.claude/projects/<project>/memory/ 自定义自动记忆的存储位置
claudeMdExcludes string[] [] 用glob模式排除特定的记忆文件(CLAUDE.md、规则文件),模式匹配的是绝对路径,对企业策略层无效
claudeMd string managed-settings.json中直接内嵌CLAUDE.md内容

示例代码(.claude/settings.local.json,排除遗留目录里的记忆文件):

1
2
3
4
5
6
{
"claudeMdExcludes": [
"**/legacy/CLAUDE.md",
"**/other-team/.claude/rules/**"
]
}
文章作者: Kaka Wan Yifan
文章链接: https://kakawanyifan.com/12802
版权声明: 本博客所有文章版权为文章作者所有,未经书面许可,任何机构和个人不得以任何形式转载、摘编或复制。

留言板