← 返回博客

    AGENTS.md vs CLAUDE.md

    “AGENTS.md vs CLAUDE.md” 背后的问题通常不是理论题。一个团队用了 Claude Code 六个月。有一份 CLAUDE.md,大体能用。然后 Codex 进入 workflow,或者 Cursor 开始读 AGENTS.md,或者 contractor 用了另一个 coding agent。突然团队有两个 rule files,三种关于哪个文件是 canonical 的意见,还有越来越高的风险:同一个 repo,不同 agent 收到不同 instructions。

    短答案是:如果你跑的是 multi-agent codebase,通常两个都要有。不是因为 duplication 好。duplication 很糟。你需要两个,是因为不同 tool-specific harness 会发现不同文件,而 harness 读到哪个文件,哪个文件就会塑造 session。设计问题不是假装一个文件能服务所有 tool。设计问题是怎样让两个文件不漂。

    AGENTS.md 是 OpenAI Codex 的主要 instruction file。当前 Codex docs 描述了 global 和 project AGENTS.md discovery,包括 override files 和 fallback filenames。CLAUDE.md 是 Claude Code 的主要 project memory file。两者都是 markdown instruction files。两者都承载 project rules、commands、style、operational constraints。两者自己都不执行任何东西。它们都在 CI、hooks、permissions、reviews 上面。

    危险做法是把它们当竞争对手。它们其实是接入不同 harness 的 adapters。你的工作是决定 source of truth 在哪里。

    你需要两个吗?

    如果是只用一个 tool 的个人项目,也许不用。如果你只用 Claude Code,一份 project CLAUDE.md 加 global CLAUDE.md 可能够了。如果你只用 Codex,AGENTS.md 可能够了。第二个没有 tool 会读的文件,只是另一个会腐烂的地方。

    但如果是团队,或者 repo 会被多个 agents 碰到,那就需要两个。原因是每个 agent 的 discovery behavior 都重要。如果 Codex 读 AGENTS.md,Claude Code 读 CLAUDE.md,那么只存在一个文件里的规则,就只对一个 agent 存在。这就是 Codex 用 npm、Claude 用 pnpm 的来源。这就是一个 agent 开 PR,另一个直接 push 的来源。这也是 “agent behavior” 变成抽奖的来源。

    修法不是盲目 copy-paste。copy-paste 给你第一天好看,第三个月难受。修法是明确选择下面三种模式之一。

    模式一:AGENTS.md canonical,CLAUDE.md pointer

    这个模式里,AGENTS.md 是 source of truth。CLAUDE.md 要么是 symlink,要么是很小的 pointer。

    symlink 版本:

    CLAUDE.md -> AGENTS.md
    

    pointer 版本:

    # CLAUDE.md
    
    This project uses AGENTS.md as the canonical agent instruction file.
    Read AGENTS.md before making changes. Tool-specific Claude Code notes live below.
    
    ## Claude Code notes
    - Use project-local skills under .claude/skills/ when the user invokes them.
    - Hooks are configured in .claude/settings.json.
    

    这是新项目里最干净的模式。AGENTS.md 这个名字更 tool-neutral,而且 Codex 把它当 first-class project instruction file。它也很适合更开放的 agent harness 方向:一个 repo-level instruction file,多个 tools 都能理解,tool-specific 细节留在薄 adapter 里。

    优点:一个 canonical file,漂移少,review 容易,Codex 和其他 AGENTS.md-aware tools onboarding 更简单。文件名写的是 “agents”,不是某个 vendor。

    缺点:Claude Code 用户可能期待 CLAUDE.md 里有丰富内容,如果 tooling 没清楚展示 pointer,他们可能会错过。symlink 在 Windows 或某些 tooling 里会麻烦。Claude Code-specific behavior 仍然需要位置,通常是 .claude/settings.json.claude/skills/,或者 CLAUDE.md 里的短 section。

    这是我对新项目的默认建议。

    模式二:parallel files,但显式声明 overrides

    这个模式里,AGENTS.md 和 CLAUDE.md 都是真文件。大多数规则相同。差异是故意的,并且写明。

    AGENTS.md 例子:

    # AGENTS.md
    
    ## Project rules
    - Use npm. package-lock.json is canonical.
    - Run npm run build before opening a PR.
    - Do not edit dist/ by hand.
    
    ## Codex-specific notes
    - Nested AGENTS.override.md files may narrow rules for subdirectories.
    - When instructions conflict, the closer directory wins.
    

    CLAUDE.md 例子:

    # CLAUDE.md
    
    This file mirrors AGENTS.md for Claude Code.
    
    ## Project rules
    - Use npm. package-lock.json is canonical.
    - Run npm run build before opening a PR.
    - Do not edit dist/ by hand.
    
    ## Claude Code-specific notes
    - Project hooks live in .claude/settings.json.
    - Workflow-specific rules live in .claude/skills/.
    - Overrides AGENTS.md only for Claude Code hook and skill behavior.
    

    这是已有团队最务实的模式。你已经有一份有意义的 CLAUDE.md。你加 AGENTS.md,但不强行做高风险重写。关键纪律是给差异贴标签。如果 CLAUDE.md 有 AGENTS.md 里没有的规则,文件应该写清楚:这是 Claude-specific,还是一个等着爆的 drift bug。

    优点:所有 tools 都能用,尊重已有 Claude Code setup,避免 symlink portability 问题,也给每个 harness 留下自己的 semantics 空间。

    缺点:维护成本更高。每个 cross-agent rule change 都要碰两个文件。reviewer 必须学会问:“另一个文件也改了吗?” 如果不用 lint 或 test,文件会悄悄分叉。

    这是我对成熟 Claude Code repo 加 Codex 时的建议。

    模式三:CLAUDE.md canonical,AGENTS.md generated

    这个模式里,已有 CLAUDE.md 继续做 source of truth,AGENTS.md 从它生成。

    一个简单 generated AGENTS.md 可能长这样:

    # AGENTS.md
    
    Generated from CLAUDE.md. Do not edit by hand.
    
    ## Shared project rules
    ...
    
    ## Codex-specific notes
    - Codex reads AGENTS.md files from global and project scopes.
    - If this generated file is stale, run npm run sync-agent-docs.
    

    当公司已经有几百个 repo 标准化在 CLAUDE.md 上时,这可以是正确桥接方式。它避免 big-bang migration。它也让 review 更容易,因为 generated file 不应该接受手改。

    优点:扰动小,source of truth 清楚,可以机械化铺到很多 repo,保护已有 Claude Code 习惯。

    缺点:generation scripts 变成 harness 的一部分,也要维护。它可能隐藏 AGENTS.md 和 CLAUDE.md 的 discovery semantics 差异。如果 generator 太天真,就会把 Claude-specific instructions 复制给 Codex,而那些 instructions 并不适用。

    这是过渡模式,不是我会为新 repo 选择的终点。

    两边都该有的内容

    Cross-agent rules 应该在 canonical source 里,也应该进入每个 tool 会读的 adapter file。例子:

    - Package manager and install command.
    - Build, lint, test, and typecheck commands.
    - Branching and PR policy.
    - Dependency policy.
    - Generated-file policy.
    - Security and secret-handling rules.
    - Architecture boundaries.
    - Source-of-truth docs.
    

    这些不是 Claude rules,也不是 Codex rules。它们是 project rules。如果它们按 agent 不同而不同,你大概率有 bug。

    留在 tool-specific 的内容

    Tool mechanics 不应该硬塞进 shared section。Claude Code hooks 属于 Claude Code config。Claude Code skills 属于 .claude/skills/。Codex-specific override behavior、fallback filenames、CODEX_HOMEproject_doc_max_bytes 属于 AGENTS.md 或 Codex config references。Cursor rule globs 属于 .cursor/rules

    判断很简单:如果规则描述的是项目,就共享。如果规则描述的是某个 harness 怎样发现、加载、scope 或执行 instructions,就保持 tool-specific。

    我的建议

    新项目,把 AGENTS.md 设为 canonical。CLAUDE.md 保持 pointer,加最小的 Claude-specific section。这样你有一个 tool-neutral root file,也能把 cross-agent rules 放在一个地方。

    已有 Claude Code 项目,先用 parallel files with declared overrides。不要在知道真实分歧前花一周设计 generator。加 AGENTS.md,镜像 shared rules,标出 Claude-specific 部分,然后观察一个月 diff。如果 drift 变痛,再迁到 canonical AGENTS.md 或 generator。

    错误不在于选了“错”的文件。错误是让关系保持隐式。两个 instruction files 没有声明 source of truth,就是 split-brain harness。

    怎样让它们保持诚实

    一旦两个文件都存在,就把它们当成一个 surface review。package-manager policy 的改动应该碰两个文件,或者解释为什么不用。CLAUDE.md 里新增 rule 应该标成 Claude-specific,或者复制到 AGENTS.md。AGENTS.md 里新增 rule,也要在 merge 前对照 CLAUDE.md。

    AgentLint 在这里有用,因为它把 instruction files 当作 harness 的一部分,而不是孤立 markdown。它能在差异变成不同 agent behavior 之前,抓到冲突、过期引用、模糊规则、缺少执行,以及 cross-file drift。

    相关文章