AGENTS.md 规范
项目级 agent 指令的事实标准——60k+ 项目采用;Codex 原生实现最完整,CC 仅经 import 桥接
AGENTS.md 规范
结论
AGENTS.md 是项目级 agent 指令的事实标准("README for agents"):纯 Markdown、零必填字段、嵌套时"离被改文件最近者胜,用户 prompt 压倒一切",已被 60k+ 开源项目和 26+ 工具采纳,2025-12 起由 Linux Foundation 旗下 AAIF 托管 [一手文档]。两大 runtime 的态度截然不同:Codex 原生实现且工程上最完整——agents_md.rs 做项目根发现(默认 .git 标记)、根到 cwd 链式拼接、32KiB 预算、AGENTS.override.md 本地覆盖、~/.codex/AGENTS.md 全局层 [一手源码];CC 完全不读 AGENTS.md,官方路径是在 CLAUDE.md 中写 @AGENTS.md import 或建符号链接 [一手文档]。Harness 应把 AGENTS.md 当作唯一的"真源"指令文件,CLAUDE.md 退化为一行桥接。
研究问题
- 规范本身规定了什么、没规定什么(格式、发现、嵌套、优先级)?
- Codex 的 project_doc 实现细节:发现算法、预算、覆盖机制、多层来源如何拼接?
- CC 到底读不读 AGENTS.md?官方推荐的共存方案是什么?
- 嵌套 AGENTS.md 的语义在"规范"与"实现"之间有什么落差?
规范要点(agents.md,2026-06-11 访问)
[一手文档]
- 格式:纯标准 Markdown,"No required fields"——"Use any headings you like; the agent simply parses the text you provide"。常见小节:项目概览、构建/测试命令、代码风格、安全注意事项。
- 嵌套与优先级:"the closest AGENTS.md to the edited file wins; explicit user chat prompts override everything"。monorepo 可在子包放置嵌套 AGENTS.md。
- 采纳面:60,000+ 开源项目;官网列出 26 个集成方,含 OpenAI Codex、Google Jules、Gemini CLI、Aider、goose、opencode、Zed、Warp、VS Code、Devin、Windsurf、Cursor、JetBrains Junie、GitHub Copilot、Amp、Factory、RooCode 等。列表中没有 Claude Code。
- 治理:"AGENTS.md is now stewarded by the Agentic AI Foundation under the Linux Foundation"(OpenAI 于 2025-12-09 捐入)。
规范刻意"薄":它只定义文件名、位置语义和优先级惯例,把发现算法、token 预算、多文件合并策略全部留给实现。这正是下文 CC/Codex 差异的来源。
各 Agent 设计与实现
Claude Code
CC 不原生读取 AGENTS.md。claude-code-docs/docs/memory.md:125 [一手文档]:
"Claude Code reads
CLAUDE.md, notAGENTS.md. If your repository already usesAGENTS.mdfor other coding agents, create aCLAUDE.mdthat imports it..."
官方给出三条桥接路径:
- import:CLAUDE.md 内写
@AGENTS.md,会话启动时展开加载(import 可递归,最大 4 跳;外部 import 首次需用户批准)。 - 符号链接:
ln -s AGENTS.md CLAUDE.md(Windows 需管理员/开发者模式,故文档建议用 import)。 - /init 吸收:在已有 AGENTS.md 的仓库跑
/init,会读取它并把相关内容并入生成的 CLAUDE.md(同时还读.cursorrules、.devin/rules/、.windsurfrules)。
CC 自有指令体系的加载语义(对比用):managed policy → ~/.claude/CLAUDE.md → ./CLAUDE.md 或 ./.claude/CLAUDE.md → CLAUDE.local.md;cwd 之上的祖先链启动时全量加载,子目录的 CLAUDE.md 在 Claude 读到该目录文件时按需加载;另有 .claude/rules/ 支持 path-scoped 规则、claudeMdExcludes 排除 monorepo 噪音 [一手文档:memory.md]。CC 的体系功能上是 AGENTS.md 的超集(imports、路径作用域、排除),但格式私有。
Codex CLI
codex-rs/core/src/agents_md.rs(AgentsMdManager)[一手源码],实现要点:
- 项目根发现:从 cwd 向上走,命中
project_root_markers即为项目根;默认标记.git,可配置;空列表禁用向上遍历;找不到标记则只看 cwd(文件头注释 +agents_md_paths())。不会越过项目根继续向上。 - 收集顺序:项目根 → cwd 的每一级目录各取一个文件,按"根在前、cwd 在后"的顺序拼接(
search_dirs构造后dirs.reverse())。 - 候选文件名:每级目录按优先级尝试
AGENTS.override.md→AGENTS.md→project_doc_fallback_filenames配置的回退名(默认空列表),取第一个命中(candidate_filenames())。AGENTS.override.md是本地覆盖机制——同目录下它存在则正篇被跳过。 - 预算:总量受
project_doc_max_bytes限制,默认 32 KiB(config_toml.rs:68:DEFAULT_PROJECT_DOC_MAX_BYTES: usize = 32 * 1024),超出截断并打 warning;设 0 则完全禁用。 - 全局层:
$CODEX_HOME/AGENTS.override.md或AGENTS.md(即~/.codex/AGENTS.md)作为用户级指令(load_global_instructions),与项目层之间用分隔符\n\n--- project-doc ---\n\n拼接,提示模型"workspace 作用域指令从这里开始"。 - 来源追踪:每段指令带
InstructionProvenance(User/Project/Internal),UI 可展示指令来自哪个文件。 - 子目录嵌套(规范的"closest wins"):启动时只加载"祖先链",不会扫描 cwd 之下的子目录。子目录 AGENTS.md 由实验特性
child_agents_md(Feature::ChildAgentsMd,Stage::UnderDevelopment,默认关闭 [一手源码:features/src/lib.rs:870])处理:开启后注入一段系统提示(prompts/templates/agents/hierarchical.md),告诉模型"每个 AGENTS.md 管辖其所在目录及全部子目录;冲突时更深者胜;system/developer/user 直接指令压倒任何 AGENTS.md"——即把"closest wins"交给模型在运行中自行发现与遵守,而非 harness 预加载。
差异矩阵
| 维度 | Claude Code | Codex CLI |
|---|---|---|
| 原生读 AGENTS.md | 否(仅 @AGENTS.md import / symlink / /init 吸收) | 是(默认行为) |
| 真源文件 | CLAUDE.md(私有格式) | AGENTS.md(标准) |
| 全局用户层 | ~/.claude/CLAUDE.md | ~/.codex/AGENTS.md(支持 .override) |
| 祖先链加载 | cwd 之上的 CLAUDE.md 启动时全量加载 | 项目根(.git 标记)→ cwd 链式拼接,不越过根 |
| 子目录嵌套 | 子目录 CLAUDE.md 按需加载(读到该目录文件时) | child_agents_md 实验特性,经系统提示让模型自行遵守 |
| 本地覆盖 | CLAUDE.local.md(gitignore) | AGENTS.override.md(同目录优先于正篇) |
| 大小控制 | 软约束(文档建议 <200 行) | 硬预算 32 KiB(project_doc_max_bytes),超出截断 |
| 模块化 | @import(4 跳)、.claude/rules/ path-scoped | 无(单文件拼接) |
| 优先级声明 | 文档建议层级 | 注入提示明确"prompt > 深层 > 浅层" |
最小复现
# Codex:验证发现算法与预算(源码级)
sed -n '1,16p' codex/codex-rs/core/src/agents_md.rs # 文件头注释 = 算法规范
grep -n "DEFAULT_PROJECT_DOC_MAX_BYTES" codex/codex-rs/config/src/config_toml.rs
# → pub const DEFAULT_PROJECT_DOC_MAX_BYTES: usize = 32 * 1024;
# Codex:行为级复现(需 codex 二进制)
mkdir -p /tmp/repo/sub && cd /tmp/repo && git init -q
echo "ROOT RULE" > AGENTS.md && echo "SUB RULE" > sub/AGENTS.md
cd sub && codex "what project instructions do you see?"
# 预期:ROOT RULE 与 SUB RULE 均出现(根→cwd 链式拼接)
# CC:验证桥接路径
cat > CLAUDE.md <<'EOF'
@AGENTS.md
EOF
claude "summarize your project instructions"
# 预期:AGENTS.md 内容经 import 进入上下文Harness 接入建议(Yoda 实践)
- AGENTS.md 是唯一真源。Yoda 的"项目指令"编辑器直接读写 AGENTS.md;检测到用户使用 CC 时,自动生成(或修复)只含
@AGENTS.md一行 + Claude 专属附注的 CLAUDE.md。不要双写两份内容——会漂移。 - 生成时遵守最小公分母:不依赖 CC 的 import/rules 语法写"标准内容",Claude 专属内容(如
.claude/rules/)放桥接文件之后,保证 Codex/Gemini CLI/Zed 读到的部分自包含。 - 尊重 32 KiB 预算:Yoda 若做指令聚合/生成,按 Codex 的 32 KiB 上限校验总量并提示用户拆分——CC 虽无硬限制,但其文档同样建议 <200 行/文件。
- 嵌套语义不要赌:规范说"closest wins",但 Codex 默认根本不加载子目录文件(实验特性才覆盖)。Yoda 在 monorepo 中应把关键规则提升到祖先链上(根或包目录在 cwd 路径上),而不是指望 agent 主动发现旁支子目录的 AGENTS.md。
- 迁移路径:存量 CLAUDE.md 项目 → 重命名为 AGENTS.md + 写桥接 CLAUDE.md;可参考 Codex
external-agent-migration的做法(它把 CC 配置整体导入)验证无损。
失效条件
- CC 原生支持 AGENTS.md(changelog 出现相关条目)——本章核心差异翻转,桥接建议作废
- Codex
child_agents_md特性转正/默认开启——嵌套语义从"提示驱动"变为产品行为,矩阵需更新 -
DEFAULT_PROJECT_DOC_MAX_BYTES调整或 AGENTS.md 规范增加 size/格式约束——预算建议需复核 - AAIF 给 AGENTS.md 增加规范性发现算法(目前留白)——"实现差异"一节需重写
- CC 的
.claude/rules/或 imports 语法被 AGENTS.md 规范吸收——模块化对比失效
参考资料
(访问日期均为 2026-06-11)
- AGENTS.md 官网/规范:https://agents.md/ [一手文档]
- Linux Foundation:AGENTS.md 捐入 AAIF(2025-12-09):https://www.linuxfoundation.org/press/linux-foundation-announces-the-formation-of-the-agentic-ai-foundation
- CC memory 文档(AGENTS.md 小节):https://code.claude.com/docs/en/memory ;本地镜像
claude-code-docs/docs/memory.md:123-143[一手文档] - Codex 实现:
codex/codex-rs/core/src/agents_md.rs(发现/拼接/预算)、codex/codex-rs/config/src/config_toml.rs:68(32 KiB 默认值)、codex/codex-rs/prompts/templates/agents/hierarchical.md(嵌套语义提示)、codex/codex-rs/features/src/lib.rs:870(child_agents_md 默认关闭) [一手源码] - CC 重构源码
/init对 AGENTS.md 的读取:claude-code-source-code/src_2026-03-31/commands/init.ts[一手源码]