Agent 配置最危险的不是写错,是你以为它生效了:从 Claude Code 的 AGENTS.md 说起

Claude Code 支持 AGENTS.md 后,我删掉了 ~/.claude/CLAUDE.md,全局规则随即静默失效了一周。复盘下来,这不只是我理解错了:Claude Code 默认把 CLAUDE.md 和 AGENTS.md 当成「或」,沿目录链往上只要碰到一份 CLAUDE.md,AGENTS.md 就整份不读;开关在 /config 里,却只认个人设置;全局规则也只有 ~/.claude/CLAUDE.md 一个入口。本文用可复现的实验讲清这些规则,以及怎么用 /context all 和禁用工具的探针确认 Agent 实际读到了什么。

我最近发现,我电脑上的一份 Agent 全局配置,整整失效了一周。

期间 Claude Code 照常工作,规则文件好好地待在原来的位置,一个字都没少。它只是没被读进去。

事情的起点,是 Claude Code 新增了对 AGENTS.md 的支持。

我同时用 Claude Code 和 Codex,一直让两边共用一份全局规则:~/.claude/AGENTS.md 是实际文件,~/.codex/AGENTS.md 软链过去,Claude Code 这边靠 ~/.claude/CLAUDE.md 里一行 @AGENTS.md 把它引进来。

看到 Claude Code 原生支持 AGENTS.md,我以为中间这层已经多余,就让 Claude 把 ~/.claude/CLAUDE.md 删了。

它照做了,还在 AGENTS.md 开头留了一行注释,解释为什么不再需要那个文件。

整个过程没有一条报错或警告。几天后我整理另一个项目的配置,才发现 Claude Code 启动时根本没加载那份全局规则。

一开始我以为是自己理解错了,改回来就完事。后来为我又补了几组实验,发现问题不止于此:就算什么都没理解错,Claude Code 的默认规则也可能让你的 AGENTS.md 悄悄停止生效。

多一个文件,规则就没了

先看一个最小的实验。

新建一个空目录,里面只有一个 AGENTS.md,写一句话:

这个项目的暗号是:蓝鲸。回答结尾加一个 🐋。

暗号是我编的,只存在于这份文件里。Claude 答得出来,就说明它读到了。

然后在这个目录里问 Claude:

claude -p "这个项目的暗号是什么?只回答暗号本身,不知道就只回答:没有" --disallowedTools Read Bash Grep Glob --strict-mcp-config

它答:蓝鲸 🐋。

只有 AGENTS.md 时,Claude 答出了暗号「蓝鲸 🐋」

接着在旁边新建一个 CLAUDE.md,只写一句给自己看的笔记,和暗号毫无关系:

echo '# 给自己的笔记:周五前清理测试数据' > CLAUDE.md

同样的问题再问一遍,它说:没有。

新建 CLAUDE.md 后再问,Claude 回答「没有」,而 AGENTS.md 内容一字未变

AGENTS.md 一个字都没动,Claude 就是不读了。

默认规则:「或」,而且一路往上找

这是 Claude Code 的默认行为。

9 月 19 日,Claude Code 团队的 Thariq 发推宣布支持 AGENTS.md,原话是:

Starting today in version 2.1.277, if there is no CLAUDE.md in a folder, Claude will check for and use AGENTS.md.

Thariq 宣布 Claude Code 支持 AGENTS.md 的推文,下方回复说明它基于 Claude Code mods 实现

要紧的是前半句的条件:没有 CLAUDE.md。默认设置下,CLAUDE.md 和 AGENTS.md 是「或」的关系,有 CLAUDE.md 就读 CLAUDE.md,没有才轮到 AGENTS.md。在 Claude Code 里,AGENTS.md 是个备胎。

「有没有 CLAUDE.md」查的范围,也比我原先以为的大。memory 文档写的是:

By default, Claude reads AGENTS.md only when you have no CLAUDE.md in your working directory or above it.

「or above it」意味着 Claude 会从你启动的目录开始,一层层往上查,一直查到文件系统根,而不是停在 git 仓库根。路上只要碰到下面任何一种,整条链上的 AGENTS.md 就都不读了:

  • CLAUDE.md
  • .claude/CLAUDE.md
  • CLAUDE.local.md

我实测过:在 git 仓库外面的上级目录放一份 CLAUDE.md,里面子项目的 AGENTS.md 就不再加载,去掉之后恢复。

有两个例外不挡路:全局的 ~/.claude/CLAUDE.md 不算在这条链上;指向不存在文件的断链 CLAUDE.md 也不算。

你多半没想挡掉谁

建这些文件的时候,你多半没想过要挡掉谁。按文档的规则,下面这些很普通的操作都会让 AGENTS.md 失效。

团队仓库里,用 Codex 的同事维护了一份 AGENTS.md。你用 Claude Code,顺手加了一份 CLAUDE.md 放自己的约定。从这一刻起,你的 Claude 就不读团队那份了,你们俩可能都不知道。

或者你只想放点本地配置,建了个 CLAUDE.local.md。名字听起来像「补充」,效果和 CLAUDE.md 一样,一个原本只靠 AGENTS.md 的项目,从此只剩你的本地笔记。

影响最大的是在 home 目录放一份 ~/CLAUDE.md,想让所有项目都用上。home 目录在几乎所有项目的目录链上,这一份文件等于告诉 Claude:home 目录下每个仓库都已经有 CLAUDE.md 了。于是所有项目里的 AGENTS.md 一起失效。它和全局规则 ~/.claude/CLAUDE.md 只差一个 .claude/,效果完全相反。

开关在 /config 里,但只管你自己

「或」可以改。打开 /config,找到 Project instructions,有四个选项:

/config 中 Project instructions 的四个选项,默认是 claude-md-or-agents-md

选项 含义
claude-md-or-agents-md(默认) 或:链上有 CLAUDE.md 就不读 AGENTS.md
claude-md-and-agents-md 和:两份一起加载
claude-md 只用 CLAUDE.md,AGENTS.md 一律不读
managed-only 只认组织统一下发的规则

如果你同时用好几个 AI 编程工具,或者团队里有人不用 Claude Code,改成「和」就行。我在前面那个暗号目录里切到 claude-md-and-agents-md,CLAUDE.md 还在,再问一次,它又答出了「蓝鲸 🐋」。

改完要开新会话。我在同一个会话里切过去再看,加载的还是原来那几份文件。

这个开关还只认个人设置:~/.claude/settings.json、--settings,或者组织下发的 managed settings。我把「和」写进项目的 .claude/settings.json 试过,探针照样答「没有」。

这就带来一个尴尬的局面。同一个仓库,你改成了「和」,同事还是默认的「或」,代码和 AGENTS.md 都一样,你们俩的 Claude 读进去的规则却不一样。这个差异不在仓库里,code review 看不到。

全局规则:同名,不同门

回到我自己踩的那个坑。

项目规则之外,全局规则是另一套逻辑。Codex 的全局规则是 ~/.codex/AGENTS.md;Claude Code 的全局规则只有一个入口:~/.claude/CLAUDE.md,不管在哪个目录启动都会加载。memory 文档里从来没有出现过 ~/.claude/AGENTS.md 这个位置。

Codex Claude Code(默认设置)
全局指令文件 ~/.codex/AGENTS.md ~/.claude/CLAUDE.md
项目内的 AGENTS.md 怎么找 从项目根(通常是 git 根)往下走到当前目录 从当前目录往上,一直走到文件系统根
AGENTS.md 的定位 指令文件本身 链上没有 CLAUDE.md 时的回退

我当时的推理是:~/.claude 也是一个 folder,里面没有 CLAUDE.md,那 Claude 应该会读里面的 AGENTS.md。但这个功能的实现,是一个内置在 anthropics/claude-code/mods/agents-md 的 mod,README 第 94 行写着它做的事:

walks $.fs.ancestors for the AGENTS.md files above the working directory and answers them as project instruction files

它只沿工作目录往上找,找到的都算项目说明。我的工作目录是 ~/Documents/myblog/techblog,往上是 ~/Documents/myblog、~/Documents、~、/,这条路不经过 ~/.claude。

不过删掉 ~/.claude/CLAUDE.md 之后,那份 ~/.claude/AGENTS.md 也不是彻底没人读,它是降了级。我分别在几个目录里用 /context all 看过:

  • home 目录下、链上没有 CLAUDE.md 的项目:它会被加载,但标签是 Project,是沿目录链顺路捡到的
  • home 目录下、链上有 CLAUDE.md 的项目:不加载,被挡住了
  • home 目录外,比如 /tmp:不加载

它从到哪都生效的全局规则,变成了只在部分项目里碰巧生效的项目规则。这比彻底失效还难发现,因为你挑个目录测一下,它看起来是好的。

把 ~/.claude/CLAUDE.md 直接改名成 AGENTS.md,也是这个结果。

想和 Codex 共用一份全局规则,目前还得用老办法:

# ~/.claude/CLAUDE.md
@AGENTS.md

~/.claude 目录下 AGENTS.md 和 CLAUDE.md 两个文件并存

加回这一行之后,在任何目录启动,~/.claude/AGENTS.md 都会以 User 身份加载;在 home 目录下的项目里也不会被重复读一次,文档说明会跳过已经加载过的 AGENTS.md。

文档里「Remove an earlier AGENTS.md workaround」一节确实教人删掉旧的 @AGENTS.md 引入,但针对的是项目里的 CLAUDE.md。用户级从来没有原生支持,这一行引入是目前唯一的办法。

Agent 会把错误固化下来

回头看那次改动,最值得警惕的不是删了一个文件,而是 Claude 留下的那行注释:

<!-- 单一数据源:Claude Code 原生支持无 CLAUDE.md 时回退读 AGENTS.md,故不再用 ~/.claude/CLAUDE.md 做 @AGENTS.md 引入 -->

删文件是我的主意,Claude 照着我的理解改完了配置,没有指出这个理解有问题,还把理由写得清清楚楚。

以前手动改错配置,链条是这样的:

理解错 → 改错 → 过几天发现

现在多了一环:

人产生错误理解
      ↓
Agent 执行
      ↓
Agent 写注释解释这个错误
      ↓
以后的人 / Agent 看到注释
      ↓
继续相信这个错误

错误的源头在我,但 Agent 把它从一个念头变成了系统里的一段「文档」。

还有个讽刺的细节:指令文件里的 HTML 注释,加载进上下文时会被去掉。这行注释影响不到 Claude 启动时看到的内容,能看到它的只有打开文件的人,和用工具去读文件的 Agent,而事后会去检查配置的,恰好就是这两类。一周后如果我没有先去查加载列表,而是先读到这行注释,我大概率会信。

AI 把配置改错不算什么,改错之后还能配上一段像模像样的理由,这才麻烦。

别问它,看它

那怎么知道 Claude 这一轮到底读了什么?

最直觉的做法是直接问:「你知道这条规则吗?」但 Claude 手里有读文件的工具,它可以当场把文件打开看一眼,再告诉你知道。这只证明文件还在,证明不了启动时规则进了上下文。你以为在查上下文,其实查的还是文件。

我现在分两步确认。

第一步看 /context all,这一轮加载了哪些指令文件,都列在 Memory files 里,还标着是 User 还是 Project。all 不能省,只输 /context 的话,Memory files 只显示一个文件数。

还是那个暗号目录,CLAUDE.md 和 AGENTS.md 都在。设置为「和」时,列出 4 个文件:

「和」模式下 /context all 的 Memory files:两份全局文件,加上项目里的 CLAUDE.md 和 AGENTS.md

改回默认的「或」,开新会话,项目里的 AGENTS.md 那一行就没了:

「或」模式下 /context all 的 Memory files 只剩 3 个文件,项目 AGENTS.md 不在其中

不要拿 /memory 代替。它列的是所有可能的位置,包括根本没加载、甚至还不存在的文件。

第二步用禁用工具的探针。从目标文件里挑一条别处没有的规则,开一个全新会话,禁掉读文件的工具再问,写法和开头那条命令一样:

claude -p "不要读取任何文件。只根据你启动时上下文里已加载的指令回答:有没有关于 GitHub 双账号或本地 Postgres 端口的规则?有就原样引用一句,没有就回答『没有』。" --disallowedTools Read Bash Grep Glob --strict-mcp-config

它只能靠已经进了上下文的东西回答。答得出来,规则才算真进去了。--strict-mcp-config 让这次调用不加载任何 MCP,避免连接器在回答后面追加无关提示。

我用这条探针测自己的全局规则,结果是:

~/.claude 的状态 在博客目录里问
只有 AGENTS.md 「没有」
CLAUDE.md 里写一行 @AGENTS.md 原样引用了两条规则

几个 Agent 共用的文件,要每个 Agent 分别验证。Codex 读到了,不代表 Claude Code 也读到了。

顺带一提,自动记忆是 Claude 自己维护的项目笔记,不是你写给它的硬规则,需要每次生效的东西还是放在指令文件里。

文中的加载行为基于 Claude Code 2.1.283 和 2026 年 9 月的官方文档,后续版本可能变化。

AGENTS.md 统一了名字,没有统一生效规则

AGENTS.md 让不同 coding agent 共享指令方便了一点,但它统一的只是文件名。全局规则放哪、从哪一层开始找、谁会挡掉谁、每个人的开关怎么设,这些各家都不一样,AGENTS.md 标准本身也没规定全局文件放在哪。Codex 从项目根往下找,Claude Code 从当前目录往上找,同一个文件名底下是两套逻辑。

而这些规则失效时通常不报错。装好 Claude Code 直接用,默认值已经替你决定了读哪份规则。不配置,也是一种配置,只是做决定的不是你。

以前配软件,文件写对了基本就行。Agent 多了一层:文件写对了,它还不一定读到。前一个问题查文件,后一个问题得查上下文,我现在会刻意把两件事分开查。

这次我只是少了几条工作习惯,一周都没察觉。要是那份规则里写的是安全限制、部署流程,或者禁止某个危险操作,一周可就太长了。

AI 让改配置越来越便宜,理解错了马上就能改过去,还附带一段解释。所以现在给 Agent 加规则之前,我会先想清楚它该影响哪个 Agent、哪个项目、哪个目录,改完再用上面两步确认一遍。在那之前,我不认为这条规则已经生效。

关于

关注我获取更多资讯

月球基地博客公众号二维码,扫码关注获取更多 AI 与编程资讯
📢 公众号
月球基地博客作者个人微信二维码,扫码交流 AI 与编程话题
💬 个人号
使用 Hugo 构建
主题 Stack 由 Jimmy 设计