发布时间:
目录
一、两套记忆机制,怎么选 #
每次会话 Claude 都是"失忆"状态,跨会话传知识靠这两样东西:
| CLAUDE.md | 自动记忆(Auto Memory) | |
|---|---|---|
| 谁写 | 你 | Claude 自己 |
| 写什么 | 指令和规则 | 经验、偏好、纠正记录 |
| 作用范围 | 项目 / 用户 / 组织 | 按仓库区分,跨 worktree 共享 |
| 加载时机 | 每次会话 | 每次会话(索引前 200 行或 25KB) |
| 典型内容 | 构建命令、编码规范、项目结构 | 你的偏好、你纠正过的地方、代码里看不出来的背景 |
选择原则:想约束 Claude 的行为 → 写 CLAUDE.md;想让它记住你的习惯和纠正 → 用自动记忆,它会自己记。
⚠️ CLAUDE.md 只是"塞进上下文的参考",不是强制配置。想真正拦住某个动作(比如禁止直接 push 到 main),要用 PreToolUse hook。
二、CLAUDE.md:放哪、写什么、怎么写 #
2.1 什么内容值得写进去 #
判断标准很简单:那些你每次都要重复解释的东西。
出现下面情况就该补进 CLAUDE.md:
- Claude 第二次在同一个地方犯错
- 代码评审时发现"这个仓库的人本来就知道"的事
- 你在这次会话里又重复了上次的口头纠正
- 新同事上手也需要知道的背景
反过来说:
2.2 四个作用域(加载顺序从宽到窄) #
| 作用域 | 位置 | 放什么 | 谁能看到 |
|---|---|---|---|
| 托管策略 | macOS /Library/Application Support/ClaudeCode/CLAUDE.mdLinux/WSL /etc/claude-code/CLAUDE.mdWindows C:\Program Files\ClaudeCode\CLAUDE.md |
IT/DevOps 下发的公司规范 | 全组织 |
| 用户指令 | ~/.claude/CLAUDE.md |
你个人的通用偏好 | 只有你(所有项目) |
| 项目指令 | ./CLAUDE.md 或 ./.claude/CLAUDE.md |
团队共享的项目约定 | 通过 Git 共享的同事 |
| 本地指令 | ./CLAUDE.local.md |
项目内的个人笔记(加进 .gitignore) |
只有你(当前项目) |
加载规则:
- 从当前工作目录往上逐层加载,所有文件会拼在一起,不会互相覆盖;越靠近工作目录的越晚读到(优先级更高)。
- 同一个目录里
CLAUDE.local.md排在CLAUDE.md后面,也就是你的个人笔记最后生效。 - 子目录里的 CLAUDE.md 不在启动时加载,而是等 Claude 真正读写该目录的文件时才按需加载。
- 想跳过不相关的(比如 monorepo 里别的团队的),用
claudeMdExcludes设置按路径排除。
2.3 怎么写才有效 #
Claude 把 CLAUDE.md 当上下文读,不会"照章办事"。越具体越好:
| ❌ 别这么写 | ✅ 这么写 |
|---|---|
| 正确格式化代码 | 使用 2 空格缩进 |
| 测试你的更改 | 提交前运行 npm test |
| 保持文件有组织 | API 处理器都在 src/api/handlers/ |
另外三条经验:
- 短:单个文件控制在 200 行以内。越长的文件越费 context,遵守度也越低。
- 有结构:用 Markdown 标题和列表分组,比大段文字更容易被遵循。
- 不打架:两个文件对同一件事给出相反说法时,Claude 可能随便挑一个。定期跑
/doctor prompt-audit查过时、失效、互相冲突的指令(它会先给报告,你确认后才改)。
2.4 确认和初始化 #
/init—— 让 Claude 分析代码库,自动生成一版 CLAUDE.md(构建命令、测试方式、项目约定)。已存在时它会提改进建议而不是覆盖。CLAUDE_CODE_NEW_INIT=1—— 开启/init的交互式多阶段流程(会先出提案再写文件),顺便生成 skill 和 hook。/context all—— 确认文件到底加载了没有,看 Memory files 那一栏(普通/context在全屏模式下会折叠这个列表)。
三、导入其他文件:@path #
CLAUDE.md 里可以用 @路径 把别的文件内容拉进来一起加载:
See @README for project overview and @package.json for available npm commands.
# Additional Instructions
- git workflow @docs/git-instructions.md
要点:
- 相对路径以引用它的那个文件为基准,不是当前工作目录;也支持绝对路径。
- 最多递归导入 4 层。
- 路径里有空格要转义:
- API conventions @Design\ Docs/api-conventions.md。 - 想只是提到某个文件名而不导入,用反引号包起来:
`@README`。 CLAUDE.local.md用来放不想提交到 Git 的个人偏好,自动忽略版。- 外部导入审批:导入路径跑出工作目录时(比如
~/.claude/my-project-instructions.md),Claude Code 第一次会弹窗列出让你批准;拒绝后该导入保持禁用且不再询问。
四、用 .claude/rules/ 拆分规则 #
项目大了就把规则拆成多个文件,一个文件讲一件事:
your-project/
├── .claude/
│ ├── CLAUDE.md # 主说明
│ └── rules/
│ ├── code-style.md # 代码风格
│ ├── testing.md # 测试约定
│ └── security.md # 安全要求
路径限定规则(按需加载,最省 context) #
在规则文件顶部加 paths frontmatter,这条规则就只在 Claude 碰到匹配文件时才加载:
---
paths:
- "src/api/**/*.ts"
---https
# API 开发规则
- 所有接口都要做入参校验
- 使用统一错误响应格式
glob 写法速查:
| 模式 | 匹配 |
|---|---|
**/*.ts |
任意层级的 .ts |
src/**/* |
src/ 下全部 |
*.md |
任意层级的 .md |
/*.md |
只匹配基准目录根下的 .md(不含子目录) |
src/components/*.tsx |
只匹配 src/components/ 下的 .tsx(不含子目录) |
- 可以写多个模式,也可以用大括号一次匹配多个扩展名:
src/**/*.{ts,tsx}。 paths是规则里唯一被读取的字段,其他字段会被忽略;YAML 解析失败时规则照常加载,只是没有paths限定(用claude --debug看错误)。- 规则的加载时机和它绑定的文件相关:Claude 用 Read/Write/Edit 打开匹配文件时加载;用
cat、head这类 Bash 命令查看匹配文件也算。
用户级规则 #
~/.claude/rules/ 下的规则对这台机器上的所有项目生效,适合放非项目特定的个人偏好。它先于项目规则加载;两者冲突时 Claude 可能听任其一,所以要保持一致。
跨项目共享规则 #
.claude/rules/ 支持符号链接,可以把一套规则链到多个项目:
ln -s ~/shared-claude-rules .claude/rules/shared
ln -s ~/company-standards/security.md .claude/rules/security.md
- 链接目标是工作目录外的路径时,算外部导入,需要你在弹窗里批准一次。
- 指向网络路径(UNC 共享、
/net等)的链接不会加载(避免访问远程主机)。 - Windows 上更推荐用
@AGENTS.md导入而不是符号链接:建链接要管理员权限或开发者模式,而且 Git 默认会把链接检出成普通文本。
五、AGENTS.md:兼容别的工具写的说明 #
如果仓库已经给 Cursor、Cline 等工具准备了 AGENTS.md,Claude Code 可以直接用。
默认规则很简单:只要工作目录或其上层存在 CLAUDE.md 或 CLAUDE.local.md,Claude 就只读 CLAUDE.md,不读 AGENTS.md。
(~/.claude/CLAUDE.md、托管 CLAUDE.md 和 .claude/rules/ 不算在内,它们不会顶掉 AGENTS.md。)
想改行为,在会话里 /config 打开设置面板,改 项目说明(Project instructions):
| 取值 | Claude 读取什么 |
|---|---|
claude-md-or-agents-md |
默认值。有 CLAUDE.md 就读它,没有才读 AGENTS.md |
claude-md-and-agents-md |
两个都读,每个目录里 CLAUDE.md 在前、AGENTS.md 在后(不会重复读) |
claude-md |
只读 CLAUDE.md |
managed-only |
只读组织的托管 CLAUDE.md + 启动时的自动记忆,其余全部排除 |
也可以写进设置文件:
{
"pluginConfigs": {
"cc-plugin-agents-md@builtin": {
"options": { "instructionFiles": "claude-md-and-agents-md" }
}
}
}
让两个工具共用一个文件 #
Claude 不直接读 AGENTS.md 时,在旁边的 CLAUDE.md 里写一行导入即可:
@AGENTS.md
## Claude Code
Use plan mode for changes under `src/billing/`.
Claude 先读导入的 AGENTS.md,再读后面的 Claude 专属说明。
也可以直接 ln -s AGENTS.md CLAUDE.md,但注意:Claude 能通过链接读到内容,Edit/Write 工具却拒绝经符号链接写入,也就是改不了目标 AGENTS.md。
和 CLAUDE.md 的区别 #
CLAUDE.md |
通过设置读入的 AGENTS.md |
|
|---|---|---|
InstructionsLoaded hook |
会触发 | 不触发(但被 CLAUDE.md 导入/链接的仍会触发) |
--add-dir 加进来的目录 |
里面的 CLAUDE.md 会加载 | 里面的 AGENTS.md 不加载 |
| 导入工作目录外的文件 | 需要你批准 | 已批准过就直接加载,不提示 |
从别的工具迁移 #
/init会读取其他工具的说明并合并进生成的 CLAUDE.md:Cursor 的.cursor/rules/、.cursorrules,Copilot 的.github/copilot-instructions.md;设了CLAUDE_CODE_NEW_INIT=1后还会读AGENTS.md、.devin/rules/、.windsurf/rules/、.windsurfrules、.clinerules。/import可以把别的 Agent 的配置一次性搬进来(说明文件、MCP 服务器、命令、子代理、skill)。
六、自动记忆:让 Claude 自己记 #
记什么 #
Claude 工作时会主动存笔记,用 frontmatter 里的 type 字段区分:
| type | 内容 |
|---|---|
user |
你的角色、专业背景、工作偏好 |
feedback |
你给它的纠正,以及你认可的做法 |
project |
在做什么、截止时间、代码和 git 历史里看不出来的决策 |
reference |
项目外的资料位置(问题追踪系统、看板等) |
它不会记这些:能从代码里推导出来的(架构、文件路径、调试补丁),以及 CLAUDE.md 里已经写过的。
它也不是每轮都写——只有判断"以后还用得上"才记。
开关 #
- 会话里
/memory里直接开关,写入用户设置~/.claude/settings.json的autoMemoryEnabled。 - 单个项目关掉:在该项目设置里写
{"autoMemoryEnabled": false}。 - 环境变量关掉:
CLAUDE_CODE_DISABLE_AUTO_MEMORY=1。 - 后台会话(agent view、由另一个 Claude Code 会话启动的会话)可以关但开不了,需要在终端直接跑
claude才能重新打开。
存哪儿 #
每个仓库一个目录:~/.claude/projects/<项目路径>/memory/
~/.claude/projects//memory/
├── MEMORY.md # 索引,每条记忆一行,每次会话都加载
├── user_role.md # 一条记忆一个文件
├── feedback_testing.md
└── ... # Claude 自己建的主题文件
<项目路径>来自 git 仓库根,同一仓库的所有 worktree 和子目录共用这一个目录;不在 git 仓库里就用项目根目录。MEMORY.md是索引,Claude 用它记录有哪些记忆;具体内容放在各个主题文件里。- 主题文件启动时不加载,Claude 需要时才用文件工具按需读取。
- 完全在本机,不跨机器、也不跨云环境同步。
- 记忆文件不受
cleanupPeriodDays清理,你或 Claude 改了才会变。
索引的容量限制 #
MEMORY.md的前 200 行或前 25KB(谁先到算谁)在每次对话开始时加载,超出的部分启动时不加载。- 接近上限时,Claude Code 会提醒 Claude 精简:每条只留一行,细节挪到主题文件。
- 写超了也不报错,但下次加载时超出部分会被丢弃——所以别让索引无限膨胀。
- 这个限制只针对
MEMORY.md。启动时加载的 CLAUDE.md 只要不超过 4 MiB 就是全文加载,超过则整个跳过。
其他 #
- 主对话的自动记忆不会进子代理(
fork除外,它继承父对话)。子代理自己的记忆(子代理定义里的memory字段)是独立目录。 - Claude 写带 YAML frontmatter 的记忆文件时,会在
modified字段记 ISO 8601 时间戳,方便判断记忆新旧。 - 自动记忆就是纯 Markdown,随时可以自己编辑或删除,运行
/memory浏览。
七、上下文自动压缩(Auto-compact) #
上下文窗口快满时,Claude Code 会自动把前面的对话摘要化,腾出空间继续往下做,效果等同于自动执行了一次 /compact。记忆文件不受影响——它们在磁盘上,压缩完照样能读。
开关 #
| 方式 | 做法 |
|---|---|
| 设置项 | autoCompactEnabled,默认 true(/config 里显示为 "Auto-compact") |
| 环境变量 | DISABLE_AUTO_COMPACT=1 彻底关掉 |
压缩窗口(阈值) #
autoCompactWindow 决定"涨到多少 token 就压缩",单位是 token,取值 100000–1000000,也可以写 "auto" 表示按当前模型自动取。
四个地方可以配:
{
"autoCompactEnabled": true,
// 全局默认值
"autoCompactWindow": 200000,
// 按模型单独设(键名用模型的规范名,日期版 / [1m] / Bedrock / Vertex 写法都能匹配)
"models": {
"claude-sonnet-4-6": { "autoCompactWindow": "auto" }
}
}
- 环境变量:
CLAUDE_CODE_AUTO_COMPACT_WINDOW /autocompact命令会把当前值保存到按模型的那一档里- 子代理:在 agent 定义里写
autoCompactWindow,只能把继承来的窗口调低,不能调高
窗口调得比模型实际支持的大 → 压缩触发得太晚,容易先撞上硬上限;调得太小 → 频繁摘要,丢失细节。
查看与手动压缩 #
/context里能看到当前状态:Auto-compact window是阈值,Autocompact buffer是压缩时保留的余量。- 想立刻手动压缩一次:
/compact。
压缩之后还剩什么 #
| 内容 | 压缩后 |
|---|---|
项目根目录的 CLAUDE.md |
✅ 保留——Claude 会从磁盘重新读一遍再注入 |
子目录里的嵌套 CLAUDE.md |
🔄 按需重新加载 |
带 paths: 的路径限定规则 |
🔄 按需重新加载 |
| 只在对话里说过一次的指令 | ❌ 没了——想留住就写进 CLAUDE.md |
| 自动记忆文件 | ✅ 不受影响(在磁盘上) |
八、Auto mode(自动权限模式) #
普通权限模式下,每次 Claude 要做有风险的操作都会弹窗问你。Auto mode 把这个判断交给一个分类器:它审这次调用该不该放行,把不可逆、破坏性、指向外部环境的操作拦下来。
它怎么工作 #
- 分类器在服务端运行,只看这一次调用的参数。
deny规则和显式ask规则在分类器之前判定,始终优先——你的规则不会被它覆盖。- 命中安全清单的操作(比如 acceptEdits 模式本来就允许的)直接跳过分类器。
- 内置规则按类别分组(源码管理、网络、云存储等),可以在
/config里删掉某一条内置规则,也可以加自己的。 - 状态栏会显示
auto mode on;用 Shift+Tab 在权限模式之间切换,启动时也可以claude --permission-mode auto。
让它懂你的环境 #
/auto-mode-setup 是一个向导:它会读这个项目、你最近的 Claude 会话记录,以及(可选)shell 历史和其他仓库,分析出你的实际环境,生成一份"环境说明"写进设置:
{
"autoMode": {
"environment": [
"Source control: github.example.com/acme-corp and all repos under it",
"Trusted cloud buckets: s3://acme-build-artifacts",
"Trusted internal domains: *.corp.example.com"
]
}
}
分类器也会读取和 Claude 相同的 CLAUDE.md 内容当作规则依据——所以 CLAUDE.md 里写清楚"这个仓库可以推 feature 分支",比在别处重复描述更省事。
关掉它 #
任何一层设置里出现下面这个值,auto mode 就被关掉(托管策略优先级最高):
{
"disableAutoMode": "disable"
}
什么情况下它不介入,直接问你 #
| 情况 | 提示 |
|---|---|
| 对话太长,分类器判断不了 | Run /compact to shorten the conversation——先压缩再来 |
| hook 或插件在分类器审查之后改了这次调用 | 无法审查,改为询问 |
| 调用被改到没法向分类器完整描述 | 改为询问 |
和 CLAUDE.md、hook 的分工 #
三层互补,别混着用:
| 机制 | 管什么 | 强制性 |
|---|---|---|
| CLAUDE.md | 告诉 Claude 该怎么做 | 上下文,不是硬约束 |
| Auto mode | 替人决定这次操作要不要批准 | 由分类器判断,可被 deny/ask 规则覆盖 |
| Hook | 到点必执行的动作 | 硬执行,不看 Claude 怎么想 |
九、故障排查 #
Claude 不听我的 CLAUDE.md #
先记住一件事:CLAUDE.md 的内容是作为用户消息、在系统提示词之后传入的,不是系统提示词的一部分。Claude 会读、会尽量照做,但没有硬保证。
排查顺序:
/context all→ 看 Memory files 里有没有那个文件。不在列表里 = Claude 根本看不到它。- 子目录里的 CLAUDE.md 不在 Memory files 里是正常的(按需加载),加载时终端会打印一行
Loaded <路径>。 - 检查文件是不是放错了层级(对照 2.2)。
- 把指令改得更具体("2 空格缩进"优于"格式规范")。
- 查互相冲突的指令(两个文件对同一件事说法不同)。
- 如果你的 CLAUDE.md 定了提交或 PR 规则,可能和 Claude Code 自带的行为指南打架——用
includeGitInstructions关掉内置的,用attribution设好署名。
指令必须"在某个时点执行"(每次提交前、每次改完文件后),就写成 hook:hook 在固定生命周期节点执行 shell 命令,不依赖 Claude 的判断。
我的 AGENTS.md 没被加载 #
按顺序查:
- 工作目录或其上层有没有
CLAUDE.md、.claude/CLAUDE.md、CLAUDE.local.md(~/.claude/CLAUDE.md不算)——有就默认不读 AGENTS.md。 /config里 项目说明 是不是设成了claude-md或managed-only;如果连这个选项都看不到,说明当前会话不支持 AGENTS.md。- 确认版本足够新:
claude --version。
实在读不到,就在 AGENTS.md 旁边放一个 CLAUDE.md 写上 @AGENTS.md。
我不知道自动记忆存了什么 #
/memory → 选自动记忆文件夹,里面全是 Markdown,直接读、直接改、直接删。
我的 CLAUDE.md 太大了 #
- 超过 200 行会明显吃 context 并降低遵守度;超过 4 MiB Claude Code 直接跳过不加载。
- 拆成 路径限定规则,只在碰到相关文件时加载。
@导入只能帮你整理,不能减少 context——导入的文件和导入它的 CLAUDE.md 一起加载。/doctor会帮你挑出可以删的部分(能从代码推导的目录结构、依赖清单、架构概述等)。- 启动时和
/status都会对超长的文件给出警告。
Claude 只读到了子目录 CLAUDE.md 的前半截 #
按需加载的文件有单文件大小上限,超了 Claude 只拿到开头部分(后面附了提示,让它用 Read 工具读剩余内容):
| 上下文窗口 | 单文件上限 |
|---|---|
| 200K | 40,000 字符 |
| 1M(Claude Opus 4.6 / Sonnet 4.6) | 200,000 字符 |
| 1M(更新的模型) | 150,000 字符 |
用 wc -m path/to/CLAUDE.md 数字符数,超了就精简,或者拆成多个规则文件(每个单独计算上限)。
/compact 之后指令好像丢了 #
- 项目根目录的 CLAUDE.md 会保留:压缩后 Claude 会从磁盘重新读一遍并注入会话。
- 子目录的嵌套 CLAUDE.md、带
paths:的规则会按需重新加载。 - 只在对话里说过一次的指令不会保留 —— 想持久化就写进 CLAUDE.md。
压缩什么时候触发、阈值怎么调,见 七、上下文自动压缩。