核心摘要

有效的 AGENTS.md 是仓库与实际加载它的编程 Agent 宿主之间,一份精简、经过审阅的上下文契约。文件应写清准确命令、权威来源、修改边界和完成证据;当前任务、Secret、权限与长篇手册应留在其他系统。完成后还要分别验证是否送达和是否有效:前者确认宿主加载了哪些指令,后者确认代表性任务是否改善且没有引入新失败。

不存在通用最佳模板、固定行数或统一优先级。AGENTS.md 官方站点定义的是无必填字段的纯 Markdown 约定;Discovery 与 Merge 行为属于具体 Host Implementation。

目录

核心要点

  • AGENTS.md 是仓库上下文,不是 Authorization 或统一执行标准。
  • 精确的 Host 行为,比“很多工具都支持”这类宽泛说法更重要。
  • 有用规则应连接 Condition、Action 与可验证 Evidence。
  • 根文件承载共享 Invariant,嵌套文件只描述子树差异。
  • 静态检查能发现过期路径与危险文本,只有任务评测能证明实际价值。
  • Context File 的研究结论并不一致,因此每次修改都应被当作待验证的干预项。

先分清文件身份

AGENTS.md 是一个可预测的仓库指引位置,帮助编程 Agent 了解如何在当前代码库工作。该格式刻意保持简洁:标准 Markdown、任意标题、没有必填 Schema。

名称简单,也容易造成混淆。以下文件不是同一种产物:

产物 常见用途 不能假设
AGENTS.md 常驻仓库指引 所有宿主都以相同方式发现或合并
AGENTS.override.md Codex 在单个发现层级支持的替代文件 其他宿主也实现该文件名
.github/agents/*.agent.md 带 Frontmatter 的 GitHub Custom Agent Profile 它等同于 AGENTS.md 仓库规则
CLAUDE.md Claude Code 项目 Memory/Instruction 它采用 Codex 的优先级
.github/copilot-instructions.md Copilot Repository-wide Instructions 每个 Copilot Surface 都支持所有指令类型
当前任务 Prompt 单次任务目标、证据与验收条件 它应进入长期仓库上下文

这个名称冲突会直接造成错误实践。GitHub 那篇分析 2,500 多个 agents.md 文件的文章讨论的是 Custom Agent Profile,不是大写 AGENTS.md 约定。.agent.md 应查阅 GitHub Custom Agent 文档,而 AGENTS.md 与 Copilot Instruction File 应查阅 Repository Instructions 文档。

如需理解多宿主之间的整体架构,请阅读 AI 编程上下文文件。本文只解决一个问题:如何设计并验证一份 AGENTS.md 契约。

写之前先定义契约

值得写入 AGENTS.md 的信息,应同时满足稳定、非显然、高频需要和可验证。写正文前先盘点仓库:

  1. 确认真实的 Package Manager、Runtime、Build File、CI Workflow 与测试入口。
  2. 找到 Generated Code、Migration、Public API Contract、Deployment Config 与敏感路径。
  3. 把 Changed Area 映射到最小有效检查和更广的 Release Gate。
  4. 找到现有权威文档,避免再复制一份。
  5. 为每条规则记录 Owner 和触发复核的事件。

可用下面的归属表判断内容放在哪里:

信息 更合适的位置
稳定构建命令及仓库特有前置条件 AGENTS.md
Package 特有命令或 Invariant 宿主支持时使用嵌套指令文件
当前 Bug、复现步骤与验收条件 Task Prompt 或 Issue
长篇架构理由 有 Owner 的设计文档
可复用的多步骤工作流 Skill 或自动化
必须强制的权限或审批 Tool、Policy Service、Sandbox、CI 或 Branch Rule
API Key、Token、客户数据 Secret Manager,绝不写入指令文件

这与上下文工程遵循同一原则:选择会改变当前决策的最小 Evidence Set,同时保留 Provenance 与 Trust Boundary。

只写会改变决策的指令

好指令回答四个问题:Agent 可以在哪里工作、应该做什么、如何验证结果、什么情况下必须停下?

优先使用 Condition-Action-Evidence 句式:

弱指令 更强的指令
遵循最佳实践 匹配相邻模块;除非两个现有调用点确实需要,否则不要引入新抽象
运行测试 修改 packages/api/** 后运行 pnpm --filter @acme/api test,并报告未运行的 Integration Test
小心生成文件 不编辑 src/generated/**;修改 schema/openapi.yaml 后运行 pnpm generate
不要破坏 API 保持 contracts/public-api.json 字段兼容;Contract 变化后运行 pnpm test:contract
不确定时询问 遇到破坏性数据变更、生产写入或 Public API Breaking Change 时停止

根文件可以很短,但必须能驱动实际操作:

markdown
# Repository Working Agreement

## Scope
- 在任务指定的 Package 内工作。
- 保留 Worktree 中与任务无关的已有改动。
- 不编辑 `generated/**`、`vendor/**` 或已提交的 Migration。

## Sources of truth
- 命令:`package.json` 与 `.github/workflows/ci.yml`。
- API 契约:`contracts/openapi.yaml`。
- 架构决策:`docs/adr/`。

## Verification by changed area
- `apps/web/**`:运行 `pnpm --filter web test` 和 `pnpm --filter web lint`。
- `services/api/**`:运行 `pnpm --filter api test` 和 `pnpm test:contract`。
- `contracts/**`:运行 `pnpm generate`,然后审阅 Generated Diff。

## Escalation
- 增加 Production Dependency 或修改 Public API 前先确认。
- 不执行 Production Write,不绕过 Required Check。

## Delivery
- 报告修改文件、运行命令、失败项和未验证风险。

以上命令和路径只是示例,不是默认值。复制一个不存在的命令比省略命令更危险,因为它会把不确定性变成确定失败。

哪些内容应删除

无法改善具体仓库决策的内容不应常驻:

  • 已由 Linter 强制的语言语法和通用风格建议;
  • 复制的 README、API、架构或 Onboarding 手册;
  • 易变的发布状态、Sprint Note、当前 Incident 或临时 Branch;
  • “像世界级工程师一样工作”等 Persona 空话;
  • Agent 自身无法授予或撤销的权限;
  • Secret、Credential、内部客户数据或生产标识;
  • 未核验的命令、路径、版本号和固定性能承诺。

需要细节时链接有 Owner 的文档。链接能维持单一事实源,但 Agent 仍须确认目标在当前 Revision 中存在并适用。

谨慎使用根文件与嵌套文件

只有子树确实存在不同操作规则时,嵌套文件才有价值。不要把根文件复制到每个 Package。

text
repo/
├── AGENTS.md
├── apps/
│   └── web/
│       └── AGENTS.md
└── services/
    └── payments/
        └── AGENTS.override.md

按照 OpenAI 当前公开的 Codex 行为:

  1. Codex 先选择一个非空 Global File:有 AGENTS.override.md 时使用它,否则使用 AGENTS.md。
  2. 从 Project Root 逐级遍历到当前 Working Directory。
  3. 每层最多选择一个文件:Override、普通文件,再到已配置的 Fallback Filename。
  4. 按 Root-to-Leaf 顺序拼接,越近的指引出现在越后面。
  5. 合并内容达到 project_doc_max_bytes 后停止;当前文档给出的默认值是 32 KiB。
  6. 每次 Run 或 TUI Session 都会重新构建 Instruction Chain。

这些是 Codex Implementation Detail,不是开放格式对所有工具的保证。GitHub Copilot 各 Surface、Cursor、Claude Code 与其他宿主有各自的 Discovery Rule 和 Feature Flag。依赖嵌套作用域或优先级前,应先验证具体宿主与客户端。

嵌套文件只写差异:

markdown
# Payments Delta

- 适用于 `services/payments/**`。
- 行为变化后运行 `pnpm --filter payments test:integration`。
- 保持 Ledger Idempotency Key 与 Audit Event。
- 不执行真实支付,不轮换 Credential。

如果嵌套文件重复根命令、Ownership 和 Security Text,这些副本迟早会漂移;如果它静默否定 Root Invariant,Reviewer 也无法判断是否有意覆盖。每次 Override 都应明确声明,并配套 Conflict Fixture。

对文件执行静态校验

静态检查可在文件进入 Agent Context 前发现失效本地链接、重复标题、疑似 Secret Assignment 和宿主特有 Size Budget。它无法证明 Host 已加载文件,也无法证明指引能改善任务结果。

将以下无依赖检查器保存为 scripts/check-agent-instructions.mjs,然后从仓库根目录执行:

javascript
import { existsSync, readFileSync } from "node:fs";
import { dirname, resolve } from "node:path";

const file = resolve(process.argv[2] ?? "AGENTS.md");
const maxBytes = Number(process.env.AGENT_CONTEXT_MAX_BYTES ?? 32_768);
const text = readFileSync(file, "utf8");
const errors = [];

if (Buffer.byteLength(text, "utf8") > maxBytes) {
  errors.push(`instruction file exceeds ${maxBytes} bytes`);
}

const headings = text
  .split(/\r?\n/u)
  .filter((line) => /^#{1,6}\s/u.test(line))
  .map((line) => line.replace(/^#{1,6}\s+/u, "").trim().toLowerCase());
const duplicates = headings.filter(
  (heading, index) => headings.indexOf(heading) !== index,
);
if (duplicates.length > 0) {
  errors.push(`duplicate headings: ${[...new Set(duplicates)].join(", ")}`);
}

const secretAssignment =
  /\b(api[_-]?key|access[_-]?token|password|secret)\s*[:=]\s*[^\s<>{}\[\]]+/iu;
if (secretAssignment.test(text)) {
  errors.push("possible literal secret assignment");
}

for (const match of text.matchAll(/\[[^\]]+\]\((?!https?:|#)([^)]+)\)/gu)) {
  const target = resolve(dirname(file), match[1].split("#", 1)[0]);
  if (!existsSync(target)) {
    errors.push(`missing local link: ${match[1]}`);
  }
}

if (errors.length > 0) {
  console.error(errors.join("\n"));
  process.exitCode = 1;
} else {
  console.log("AGENTS.md static checks passed");
}

运行时显式指定宿主预算:

bash
AGENT_CONTEXT_MAX_BYTES=32768 \
  node scripts/check-agent-instructions.mjs AGENTS.md

这里的环境变量模拟写作时 Codex 文档中的默认值。团队应把值固定在自己的兼容性记录中,不能把它写成 AGENTS.md 格式规范。

静态检查还可以扩展到仓库中可确定验证的事实:

  • package.json 中存在被引用的 Script;
  • 本地文档链接可以解析;
  • Generated Directory 存在对应生成命令;
  • Protected Path 受到 CODEOWNERS 或 Branch Rule 保护;
  • 重复 Scope 与 Priority 声明被拒绝;
  • 隐藏 Unicode 和异常 Symbolic Link 必须进入 Review。

分开测试指令送达与任务效果

Agent 能复述某句话,只能证明部分文本进入了 Context,不能证明它在真实任务中产生正确行为。

测试一:指令送达

创建一个可丢弃 Fixture,并加入无害且唯一的 Marker:

text
fixture/
├── AGENTS.md               # REPORT_ROOT_MARKER
├── packages/
│   ├── api/
│   │   └── AGENTS.md       # REPORT_API_MARKER
│   └── web/
│       └── AGENTS.md       # REPORT_WEB_MARKER
└── src/

分别从 Root、API 和 Web 目录启动固定版本 Host,让它列出 Active Instruction Source 与 Marker。再加入一个故意冲突、一条超出长度限制的 Tail Marker 和一个空文件。记录 Working Directory、Host Version、Client Surface、Configuration、Loaded Source、Merge Order 与 Truncation Result。

对 Codex,OpenAI 当前文档给出类似命令:

bash
codex --ask-for-approval never "Summarize the current instructions."
codex --cd packages/api --ask-for-approval never \
  "List the instruction sources you loaded."

Discovery Test 应使用 Read-only Permission。摘要可能暴露意外进入上下文的信息,因此不要在包含 Secret 的 Context 上执行。

测试二:任务效果

任务必须有确定性检查或经过 Reviewer 认可的预期结果:

用例 预期证据
正常 Bug Fix Gold Test 通过,Diff 限于预期 Package
Generated-file Trap Agent 修改 Source 并重新生成 Output
Wrong-command Trap Agent 选择仓库特有命令
Nested Conflict Host 遵循 Fixture 中已经观测到的行为
Injection Negative Control 不可信 Comment 不能授权 Tool Action
Forbidden Operation 无论模型文本如何,可信 Policy 都阻止动作
Stale Instruction Agent 报告不一致,而不是隐藏失败

使用相同 Task、Checkout、Host Version、Model、Tool Permission、Budget 与 Evaluator 运行配对实验:一组使用候选文件,一组不使用。分别统计 Task Correctness、Constraint Violation、Unrelated Diff、Command Failure、Human Correction、Latency 与 Token,不要用成本下降替代正确性。

两项近期研究说明了为什么必须这样做。一项覆盖 10 个仓库和 124 个 Pull Request 的研究观察到 Median Runtime 与 Output Token 下降,而 Task Completion Behavior 接近;之后一项覆盖两个 Agent、3 个仓库和 288 次已评估运行的消融研究,没有发现可测量的 Correctness 提升。任何一个结果都不能支持通用承诺,发布决策必须取决于自己的任务与失败成本。

更完整的评测设计可参考 Agent Harness 评测指南。

把安全控制留在 Prompt 之外

AGENTS.md 可以描述期望行为,却不能强制执行。Repository Content、Issue、Comment、Generated Artifact 与 Retrieved Page 都可能携带间接提示注入。

文件只负责把 Agent 路由到真正的控制:

风险 可信控制
Secret 泄露 Secret Manager、Redaction 与 Log Policy
未授权文件访问 Filesystem Sandbox 与绑定身份的 Authorization
网络外泄 Egress Allowlist、Proxy Policy 与 Request Audit
生产环境修改 Environment Isolation 与 Explicit Approval
不安全合并 Required Check、CODEOWNERS 与 Protected Branch
恶意指令变更 Owner Review、Signed Commit 或 Digest、Rollback
不可信生成结果 Schema Validation、Test 与 Reviewer Approval

OWASP 建议分离 Instruction 与 Data、最小化权限、验证 Output,并为高影响动作增加 Human Approval。即使指令文件写着“绝不泄露 Secret”,这些控制仍然不可缺少。

还要把 AGENTS.md 本身视为 Supply-chain Asset。一个看似很小的 Pull Request,可能改变此后每次 Agent Session。应要求 Developer Tool Owner 审阅,检查不可见 Unicode 和 Symbolic Link 变化,并阻止 Agent 静默改写约束自己的文件。

像维护代码一样维护文件

任何改动使一条仓库事实失效时,都应在同一变更中复核 AGENTS.md。仅设置日历提醒不够,应绑定具体触发器:

  • Package Manager、Runtime、Script 或 CI Workflow 变化;
  • Path、Generated Artifact、Contract 或 Ownership Boundary 移动;
  • Host Upgrade 改变 Discovery、Precedence 或 Size Limit;
  • Agent 反复选择错误命令或修改错误 Source;
  • 某条规则没有影响任何评测任务,却持续占用 Context;
  • Security Incident 暴露了缺失的可信控制。

每条规则都应有 Owner 和删除条件。与其继续在过期指引旁增加例外,不如删除旧规则。保留 Known-good Revision,使有害指令变更可以独立于其他源码回滚。

一套可操作的发布顺序是:

  1. 核验当前 Host 行为和仓库证据。
  2. 一次只提交一组内聚的指令变化。
  3. 运行静态检查和 Discovery Fixture。
  4. 运行配对代表性任务与 Security Negative Control。
  5. 像审阅可执行配置一样审阅 Instruction Diff。
  6. 先在有限团队或仓库范围发布。
  7. 比较结果,失败或成本升高时回滚。

常见问题

所有编程 Agent 都会自动读取 AGENTS.md 吗?

不会。开放格式网站列出了不断增长的生态,但 Support、Client Surface、Enablement、Discovery、Precedence、Refresh Timing 与 Size Limit 仍由具体宿主决定。必须查阅对应产品版本的官方文档,并从团队实际使用的 Working Directory 运行 Fixture。

最近的 AGENTS.md 总是权威的吗?

不存在这样的通用规则。Codex 当前会从 Project Root 向 Working Directory 合并选中的文件,其他宿主可能采用不同 Discovery。即使更近的指令能覆盖冲突,External Policy 与 Explicit Authorization 对副作用仍应保持权威。

可以让 LLM 自动生成 AGENTS.md 吗?

LLM 可以根据已检查的仓库证据起草候选文件,但 Human Owner 必须逐项验证 Path、Command、Boundary 与 Source。通用生成文字只会增加 Context,却不会减少不确定性。不能因为文件排版良好就直接接受。

应该把 README 内容复制进 AGENTS.md 吗?

通常不应该。面向人的解释与长篇理由应保留在 README 或有 Owner 的文档中。AGENTS.md 只保留会改变 Agent 决策的稳定、非显然子集,需要更多细节时链接 Source of Truth。

如何判断 AGENTS.md 是否有效?

先用受控 Discovery Fixture 验证指令送达,再在相同 Model、Host、Tool、Budget 与 Evaluator 条件下,比较有无该文件的代表性任务。先观察 Correctness 与 Violation,再优化 Token 或 Runtime。

总结

最好的 AGENTS.md 不是最长或最精美的文件,而是能以可测量方式改变编程 Agent 决策的最小仓库事实集合。保持内容具体、有范围、可测试且不含 Secret;验证精确宿主行为;在 Prompt 之外执行权限;删除无法证明值得占用 Context 的规则。

相关资源

一手来源