Claude Code 宣布支持 AGENTS.md 的当天,我删掉了全局的 ~/.claude/CLAUDE.md。
之后整整一周,我写在全局配置里的规则在 Claude Code 里一条都没生效。没有报错,没有提示,Claude 照常干活,只是不再知道那些规则。
问题出在一个词上:公告里说的「folder」。
我当时是怎么配置的
我同时用 Claude Code 和 Codex,希望两边共用一份全局规则。原来的做法是:
- 规则写在
~/.claude/AGENTS.md ~/.codex/AGENTS.md软链到这个文件~/.claude/CLAUDE.md里只有一行@AGENTS.md,把它引入给 Claude Code
这是 Claude Code 不认识 AGENTS.md 时的标准做法,一直工作正常。
9 月 19 日,Claude Code 团队的 Thariq 发了一条推文:
We’re adding support for AGENTS.md to Claude Code.
Starting today in version 2.1.277, if there is no CLAUDE.md in a folder, Claude will check for and use AGENTS.md.
我的理解是:~/.claude 也是一个 folder,里面只要没有 CLAUDE.md,Claude 就会去读 AGENTS.md。那个只写了一行 @AGENTS.md 的 CLAUDE.md 已经是多余的中间层,删掉,单一数据源更干净。
我还在 AGENTS.md 开头留了一行注释:
<!-- 单一数据源:Claude Code 原生支持无 CLAUDE.md 时回退读 AGENTS.md,故不再用 ~/.claude/CLAUDE.md 做 @AGENTS.md 引入 -->
这行注释本身就是错的。
删文件、写注释,都是我让 Claude Code 做的。当时用的是 还是 Opus 5,Opus 5.5 要到 9 月 22 日才发布,而 Opus 5 发布后的口碑普遍不好。它照着我的理解改完了配置,没有指出这个理解有问题。
怎么发现的
一周后,我在一个博客项目里整理配置,发现一件事:会话开始时加载进来的只有项目的 CLAUDE.md 和记忆文件,全局 AGENTS.md 里的 GitHub 双账号规则、本地 Postgres 端口约定,都不在上下文里。
为了排除「是不是 Claude 没注意到」,我用 claude -p 起一个全新会话,禁用读文件的工具,让它只凭启动时加载的内容回答:
claude -p "不要读取任何文件,不要调用工具。只根据你启动时上下文里已加载的指令回答:有没有关于 GitHub 双账号或本地 Postgres 端口的规则?有就原样引用一句,没有就回答『没有』。" --disallowedTools "Read,Bash,Grep,Glob"
两种配置各跑一次:
~/.claude 的状态 |
结果 |
|---|---|
只有 AGENTS.md |
「没有」 |
CLAUDE.md 里写一行 @AGENTS.md |
原样引用了两条规则 |
Claude Code 版本是 2.1.283,满足 2.1.277 的要求,不是版本问题。只有 AGENTS.md 时,它确实读不到。
原因:「folder」指的是项目目录链
推文里的「a folder」没有限定范围。真正的范围写在官方文档和 mod 源码里。
官方文档
Claude Code 的 memory 文档对 AGENTS.md 的定位是项目说明:
Claude Code can read
AGENTS.mdas your project instructions, so a repository already set up for other coding agents works without adding aCLAUDE.md…
读取范围是工作目录及其上级目录:
By default, Claude reads
AGENTS.mdonly when you have noCLAUDE.mdin your working directory or above it.At session start: every
AGENTS.mdand.claude/AGENTS.mdin your working directory and the directories above it.
而用户级文件的位置表里,全局配置只有一个:
User instructions:
~/.claude/CLAUDE.md
整篇文档没有出现过 ~/.claude/AGENTS.md。
mod 源码
Thariq 在推文下面补充说,AGENTS.md 支持是基于 Claude Code mods 实现的内置 mod,源码在 anthropics/claude-code/mods/agents-md。
README 的「What it hooks」一节,第 94 行描述了它在每轮组装上下文时做的事:
walks
$.fs.ancestorsfor theAGENTS.mdfiles above the working directory and answers them asprojectinstruction files
从工作目录往上逐级找 AGENTS.md,找到的当作 project 类型加载。
我的工作目录是 ~/Documents/myblog/techblog,往上依次是 ~/Documents/myblog、~/Documents、~、/。这条路径不经过 ~/.claude。
用户级的 ~/.claude/CLAUDE.md 是 Claude Code 按固定路径单独加载的,不在这次逐级查找里。mod 只接管了项目目录链这一条路径,用户级没有对应的 AGENTS.md 版本。
推文里说的「在 /config 里切换」,对应的是 /config 中的 Project instructions 这一项,也就是 mod 唯一的配置项 instructionFiles:
设置项的名字就叫「Project instructions」,默认值的说明里,主语也是「a project」(a project with no … gets its AGENTS.md files instead)。四个选项管的都是项目说明,即使切到 claude-md-and-agents-md,多读的也只是项目链上的 AGENTS.md。
正确的配置
用户级仍然用引入的方式:
# ~/.claude/CLAUDE.md
@AGENTS.md
~/.claude/AGENTS.md:放全部规则~/.codex/AGENTS.md:软链到上面的文件~/.claude/CLAUDE.md:只有一行@AGENTS.md
文档里「Remove an earlier AGENTS.md workaround」一节确实教人删掉旧的 @AGENTS.md 引入,但它针对的是项目里的 CLAUDE.md。项目级现在有原生支持,用户级从来没有。所以全局这一行引入不是过时写法,而是目前唯一的办法。
把加载模型补全
这次踩坑,根源是我脑子里只有一张模糊的图:「Claude Code 会读一些 CLAUDE.md」。把 memory 文档从头读完,完整的图是这样的:
| 层级 | 位置 | 什么时候进上下文 | 谁写 |
|---|---|---|---|
| 组织策略 | macOS 上是 /Library/Application Support/ClaudeCode/CLAUDE.md |
启动时,个人设置排除不掉 | IT / 运维 |
| 用户级 | ~/.claude/CLAUDE.md、~/.claude/rules/*.md |
启动时 | 你 |
| 项目级 | 工作目录及每一级上级目录的 CLAUDE.md、.claude/CLAUDE.md(都没有时回退到 AGENTS.md),以及项目的 .claude/rules/*.md |
启动时 | 团队,进版本库 |
| 本地级 | 同一条目录链上的 CLAUDE.local.md |
启动时 | 你,加进 .gitignore |
| 子目录 | 工作目录下层的 CLAUDE.md / CLAUDE.local.md,带 paths 的 rules |
Claude 读到对应文件时 | 同项目级 |
| 自动记忆 | ~/.claude/projects/<project>/memory/MEMORY.md |
启动时,只读前 200 行或 25KB | Claude |
| 记忆主题文件 | 同一目录下的其他 .md |
Claude 需要时自己去读 | Claude |
表里藏着几件比「有哪些文件」更值得注意的事。
三种加载方式,AGENTS.md 只接进了一种
这些文件按三种方式进入上下文:
- 固定路径:组织策略、
~/.claude/CLAUDE.md、~/.claude/rules/。不管在哪个目录启动,都去同一个位置读 - 目录链:从工作目录往上一直走到根目录,沿途的
CLAUDE.md、.claude/CLAUDE.md、CLAUDE.local.md - 按需:子目录的 CLAUDE.md、带
paths的 rules、记忆主题文件,碰到相关文件才加载
AGENTS.md 回退只挂在目录链上,而用户级走的是固定路径。我的坑就落在这两条路径的缝隙里。
反过来,家目录 ~ 本身在目录链上。~/CLAUDE.md 不是用户级配置,而是家目录下每个项目都会读到的「项目级」文件。按文档的判定规则,工作目录或任一上级目录只要有 CLAUDE.md,就不读 AGENTS.md。所以一个 ~/CLAUDE.md,会让家目录下所有仓库的 AGENTS.md 回退一起失效。~/.claude/CLAUDE.md 反而不参与这个判定,能和项目的 AGENTS.md 同时加载。
拼接,不是覆盖
所有找到的文件都拼进上下文,谁也不覆盖谁。顺序是组织策略、用户级、项目级;目录链上从根目录往下读到工作目录,同一级目录里 CLAUDE.local.md 接在 CLAUDE.md 后面。
「项目规则覆盖全局规则」是个很自然的直觉,但它是错的。后读的只是位置靠后,不是优先级更高。文档对冲突的描述是:
if a user rule and a project rule conflict, Claude may follow either one
两条规则打架时,Claude 可能随便挑一条。必须保证的行为不该靠 CLAUDE.md 的先后顺序,而应该交给 hook 或 settings 里的 permissions,这两个由客户端执行,不依赖 Claude 的判断。
CLAUDE.local.md:私人补丁,也是 AGENTS.md 的开关
CLAUDE.local.md 放在项目根目录,写只和自己有关的东西,比如本机的测试地址、个人习惯,加进 .gitignore 不提交。它和 CLAUDE.md 一样加载,排在同级 CLAUDE.md 后面。
它有两个不太显眼的副作用。
第一,它算作 CLAUDE.md。一个只靠 AGENTS.md 的仓库,你加一个 CLAUDE.local.md 记私人笔记,Claude 就不再读 AGENTS.md 了。和我遇到的一样,这也是静默的。文档给的解法是把 Project instructions 设成 claude-md-and-agents-md。
第二,它被 gitignore,所以只存在于创建它的那个 worktree。多个 worktree 要共用个人说明,文档建议在 CLAUDE.md 里引入家目录下的文件,比如 @~/.claude/my-project-instructions.md。
自动记忆:Claude 的笔记,不是你的规则
自动记忆和前面几层性质不同。前面的都是你写给 Claude 的指令,自动记忆是 Claude 写给自己的笔记:
- 按 user、feedback、project、reference 四类记录。你对 Claude 说「记住……」,存进的是这里,不是 CLAUDE.md
- 按 git 仓库划分,同一仓库的子目录和 worktree 共用一份;只存在本机,不跨机器同步
- 启动时只加载
MEMORY.md这个索引的前 200 行或 25KB,超出的部分直接丢掉;具体内容在主题文件里,Claude 判断需要时才去读 - 不会传给 subagent(fork 出来的除外)
- CLAUDE.md 里已经写了的,它不会重复记
所以它适合放纠正和偏好,不适合放必须每次生效的规则:索引可能被截断,主题文件读不读取决于 Claude 自己,换一台机器就没有了。一条规则如果漏掉会出事,就应该写进 CLAUDE.md。
公告是摘要,文档才是规格
这次踩坑,推文本身没说错,只是省略了范围。「in a folder」对大多数人的用法(在仓库根目录放一个 AGENTS.md)是准确的,偏偏我的用法落在了省略掉的那部分。
更麻烦的是失败方式:静默。Claude Code 不会提示「你的全局 AGENTS.md 没被加载」,它只是少知道一些事,然后照常回答。规则失效和规则被遵守,从外面看不出区别。
以后看到类似的功能公告,我会先做两件事再动配置:
- 用
/context看 Memory files 列表,确认实际加载了哪些文件(/memory列出的是所有可能的位置,包括还不存在的文件) - 找到文档里描述范围的那一段,而不是只看公告
关于
关注我获取更多资讯