阅读,与值得关注的内容Readance

Claude Code 终于读 AGENTS.md 了,但先别急着删 symlink

4667 个赞、361 条评论、等了 13 个月,换来的是一行 changelog。这行字里有个反直觉的优先级规则,以及一个它压根没解决的问题。

✿ ✿ ✿

开篇

先看三个数。

4667 —— 这是 anthropics/claude-code 仓库里 issue #6235 收到的点赞数,诉求只有一句:让 Claude Code 读 AGENTS.md。它是这个仓库历史上最多人投票的 issue。

2026-08-17 —— 这个 issue 被关闭的日期。状态标的是 completed,回复是两句话,内容是"你可以用 import 或者 symlink 绕一下"。

2026-09-18 —— 一个月零一天之后,Claude Code 2.1.277 发布,changelog 里多了一行:

Added AGENTS.md support: in a project with no CLAUDE.md, Claude Code reads AGENTS.md instead; change it under "Project instructions" in /config (not yet on Bedrock, Vertex or Foundry)

Hacker News 上那条帖子底下最高频的一句话是 "Time to delete the symlinks"。我第一反应也是这个 —— 我自己那台机器上有十几个仓库里躺着 ln -s AGENTS.md CLAUDE.md,删起来挺爽。

然后我去把文档和 release notes 挨个读了一遍,把 symlink 又放回去了。

等了13个月的一行changelog

等了13个月的一行changelog

✿ ✿ ✿

这行字里藏着一个反直觉的规则

大多数人看到"支持 AGENTS.md 了",脑子里默认的模型是合并:两个文件都读,冲突时谁更具体听谁的。

不是这样。

实际规则是互斥项目里只要有 CLAUDE.md,AGENTS.md 就被完全忽略,哪怕它明明躺在旁边

为什么要做成互斥而不是合并?说实话这个选择有它的道理 —— 不这么做的话,所有已经精心调过 CLAUDE.md 的仓库,会在升级到 2.1.277 的那一刻凭空多出来一份没人审过的上下文。Anthropic 选了"不惊动任何人"这条路。

但它带来一个非常实际的后果:你以为的"顺手加一个 AGENTS.md 给同事的 Codex 用",在你自己的 Claude Code 会话里是彻底隐形的。

真正的判定链是这样的:

  1. 01
    Claude Code 从工作目录往上走,找 CLAUDE.md.claude/CLAUDE.mdCLAUDE.local.md 这三个文件
  2. 02
    三个里只要命中任何一个,流程结束,AGENTS.md 不看
  3. 03
    三个全都没有,才去读 AGENTS.md

注意第 1 条的措辞。~/.claude/CLAUDE.md(你的全局配置)、组织托管的 CLAUDE.md、.claude/rules/ 下的规则文件,这些不参与这个判定 —— 它们继续跟 AGENTS.md 并排加载,互不影响。

我卡在这儿好一会儿。因为我的全局 ~/.claude/CLAUDE.md 是个几百行的大文件,我一度以为它会把所有项目的 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,回到 2.1.276 的行为
`managed-only`
只读组织托管的 CLAUDE.md 和 auto memory

我给自己切到了 claude-md-and-agents-md。理由很简单:我的 CLAUDE.md 里有一半内容是 Claude 专属的 —— skill 路由表、subagent 派发规则、@ 引用的上下文加载指令 —— 这些搬到 AGENTS.md 里,Codex 读到只会困惑。而另一半(build 命令、测试怎么跑、哪些目录不许碰)本来就该是所有 agent 共享的。

两个都读,各写各的,是目前最省心的分法。

这个值有个设计细节值得说一下:==仓库自己的 .claude/settings.json 设不了它==。只能写在你的用户设置里、用 --settings 传、或者由组织的托管设置强制。

为什么?因为这是"策略"不是"配置"。如果允许 checkin 进仓库的文件决定 agent 怎么加载指令,那我 clone 一个陌生仓库,它就能悄悄把我的指令加载方式改掉。这条边界画得很对。

还有一类情况是你压根看不到这个选项

  •  
    版本低于 2.1.277
  •  
    会话没从 Anthropic 拉 feature flag —— 走 Bedrock、Vertex、Foundry 或者第三方 provider,或者你关了遥测
  •  
    刚装完 / 刚升级完的第一次会话
  •  
    你设了 disableAllHooks 或 allowManagedHooksOnly
  •  
    你禁用了内置的 agents-md 插件

前面四条里随便中一条,/config 里就没有 Project instructions 这一项。这时候老老实实用 @AGENTS.md import。

四种模式对照

四种模式对照

✿ ✿ ✿

先别删 symlink:三个坑

这一节是我把 symlink 放回去的原因。

坑一:从子目录启动时,import 不展开。

这是个已经被维护者复现确认的 bug(issue #78697)。场景:你在 monorepo 根目录放了一个 CLAUDE.md,里面就一行 @AGENTS.md。然后你 cd packages/api && claude

根目录那个 CLAUDE.md 会作为 ancestor 文件被加载,它自己的正文老老实实到了上下文里 —— 但那一行 import 没有展开

你的会话拿到的"项目指令"全文,就是指向一个从来没被加载过的文件的一行字。没有任何警告。 有人在 2.1.235 到 2.1.274 之间持续记日志,12 次注入里 12 次都没展开。

symlink 不走 import 展开这条路,读文件直接跟着链接走,所以它不受这个 bug 影响。

坑二:Windows 上的假 symlink,静默失效。

git 用 mode 120000 存 symlink。而 core.symlinks=false —— Git for Windows 安装时不主动勾就是这个默认 —— 会把它 checkout 成一个普通文本文件,内容就是链接目标那个词。

于是你的 Windows 同事拿到一个 9 个字节的 CLAUDE.md,全文内容是 AGENTS.md 这一个单词。没有 @,所以不是 import,就是一个孤零零的词。

Claude Code 会毫无怨言地加载它。所有规则全丢,git 不报警,Claude Code 也不报警。

这个坑比第一个阴险得多,因为它只在别人的机器上发作。

坑三:Edit / Write 工具拒绝写穿 symlink。

这个是有意为之(issue #66559 里维护者在 2.1.234 确认过),目的是防止一次写入被悄悄重定向到另一个文件。副作用是 Claude 想改 CLAUDE.md 的时候会先失败一次,然后自己反应过来去改 AGENTS.md。

想省掉那次失败,在 AGENTS.md 里加一行:"对 agent 指令的修改一律写进 AGENTS.md。"读不受影响。

三个坑的示意

三个坑的示意

✿ ✿ ✿

最扎心的一条:skills 还是不认

HN 那个帖子里,在一片"终于可以删 symlink 了"中间,有条评论被顶得很高:

Note that this does not include .agents/skills. Argh.

还有一条更直接:

Don't get too excited, Claude code still won't detect skills on .agents/skills.

这话说到点子上了。instruction 文件只是这件事的第一层。skills、subagents、commands、hooks —— 这些还是全部住在 .claude/ 底下。一个团队要在 Codex 和 Claude Code 之间共享一个仓库,改完 instruction 文件之后,还得一个目录一个目录地继续 symlink。

有人在帖子里贴了个 git hook 兜底,我试了,能用:

mkdir -p ~/.githooks git config --global core.hooksPath ~/.githooks  cat > ~/.githooks/post-checkout <<'EOF' #!/usr/bin/env bash if [ -d .agents/skills ] && [ ! -e .claude/skills ]; then     mkdir -p .claude     ln -s ../.agents/skills .claude/skills fi EOF  chmod +x ~/.githooks/post-checkout

每次 checkout 自动补 symlink。治标,但省心。

说句公道话 —— 这次更新其实比"读个文件"要重。AGENTS.md 支持是作为 Claude Code 第一个原生 mod 实现的。mod 是 Anthropic 还没正式发布的机制,用来改 harness 本身:在模型开始干活之前,改变上下文是怎么被拼起来的。Thariq Shihipar 把这个 mod 的源码和文档都公开了。

换句话说,这次真正值得关注的不是"它读了 AGENTS.md",而是"指令加载这一层现在是可替换的代码了"。

instruction只是第一层

instruction只是第一层

✿ ✿ ✿

怎么确认它真的加载了

这一步是我觉得最多人会跳过的。

/context。会话里跑一下,看 Memory files 那一段里有没有你的文件。

文件系统上的东西和 Claude 上下文里的东西是两回事。symlink 建好了不代表加载了,import 写对了不代表展开了 —— 前面那三个坑,全都能通过这一条命令看出来。

要长期留证据的话,用 InstructionsLoaded hook(2.1.69 就有了)。它会为每个 instruction 文件触发一次,带一个 load_reason

  •  session_start
  •  nested_traversal
  •  path_glob_match
  •  include
  •  compact

通过 import 进来的 AGENTS.md,load_reason 是 include,并且带一个指向那个 CLAUDE.md 的 parent_file_path。记一周日志,如果从子目录启动的会话从来没出现过 include 这条,那你就是撞上 #78697 了。

顺便提醒一句:/import 不是桥接,是一次性拷贝。拷完你手上就是两份会各自漂移的文件,而这恰恰是 AGENTS.md 当初想解决的问题。用它迁移一次,然后把拷过来的那块替换成 @AGENTS.md

用/context验证加载

用/context验证加载

✿ ✿ ✿

扯远一点:你写进去的东西,可能在帮倒忙

写到这儿我本来想收尾了,但有组数据我觉得比这次更新本身更值得看。

苏黎世联邦理工做过一次评测:4 个 coding agent(Claude Code、Codex、Qwen Code),138 个真实任务。结论有点扎人:

  •  LLM 自动生成
    的 context 文件:成功率 下降 0.5~2%,推理成本 上升 20~23%。8 个测试配置里有 5 个,"有自动生成的文件"比"完全没有文件"更差
  •  人手写
    的文件:成功率提升约 4%
  •  
    那个每个自动生成的文件都会写的 "codebase overview",没用 —— 它没让 agent 更快找到相关文件,很多时候反而多走了几步

最能说明问题的是那个反向实验:研究者把仓库里所有文档都删掉之后,LLM 生成的 context 文件突然有用了(+2.7%)。意思很清楚 —— 它平时只是在复述 agent 本来就能自己从 README 里读到的东西。

另一项效率研究给了正面的例子:只保留三类内容(编码约定、架构、项目描述)的精简 AGENTS.md,中位墙钟时间降了 28%,输出 token 降了 16%

还有 MSR '26 对 10000 个仓库的调查,三个数:

只有 5% 的仓库有任何 context 文件;AGENTS.md 平均 142 行一半的 AGENTS.md 创建之后再也没被提交过。

一半。写完就扔。

这组数据放在一起看有点讽刺:我们为了"让 Claude Code 读到这个文件"吵了 13 个月、写了 361 条评论、发明了三种 workaround,而文件里装的东西有一半从第一天起就在过期。

三组研究数据

三组研究数据

我自己也中招。我的某个项目的 CLAUDE.md 里,到现在还写着一个三个月前就换掉的包管理器。Claude 每次都老老实实按那个写,我每次都手动改回来,改了大概二十次才意识到问题在文件里而不是在模型里。

✿ ✿ ✿

写在最后

如果你今天只做一件事,我建议是这个:

打开你最近在用的那个项目,跑 /context,看一眼 Memory files 里到底加载了什么。

大概率会有惊喜 —— 可能是一个你以为在生效但根本没加载的文件,也可能是一个三个月前的旧约定还在悄悄影响每一次输出。

至于 symlink 到底删不删?分情况。单包仓库、大家都从根目录启动,删了没问题,切 claude-md-and-agents-md 然后两边各写各的。monorepo、或者团队里有 Windows 机器,这事儿就先留着别动。

这个功能等了 13 个月。再多花十分钟确认它在你这儿真的生效,不亏。

前往微信阅读全文

内容来自公众号,可前往微信查看原文。

查看作者的更多文章 →