核心摘要
有效的 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 的信息,应同时满足稳定、非显然、高频需要和可验证。写正文前先盘点仓库:
- 确认真实的 Package Manager、Runtime、Build File、CI Workflow 与测试入口。
- 找到 Generated Code、Migration、Public API Contract、Deployment Config 与敏感路径。
- 把 Changed Area 映射到最小有效检查和更广的 Release Gate。
- 找到现有权威文档,避免再复制一份。
- 为每条规则记录 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 时停止 |
根文件可以很短,但必须能驱动实际操作:
# 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。
repo/
├── AGENTS.md
├── apps/
│ └── web/
│ └── AGENTS.md
└── services/
└── payments/
└── AGENTS.override.md
按照 OpenAI 当前公开的 Codex 行为:
- Codex 先选择一个非空 Global File:有
AGENTS.override.md时使用它,否则使用AGENTS.md。 - 从 Project Root 逐级遍历到当前 Working Directory。
- 每层最多选择一个文件:Override、普通文件,再到已配置的 Fallback Filename。
- 按 Root-to-Leaf 顺序拼接,越近的指引出现在越后面。
- 合并内容达到
project_doc_max_bytes后停止;当前文档给出的默认值是 32 KiB。 - 每次 Run 或 TUI Session 都会重新构建 Instruction Chain。
这些是 Codex Implementation Detail,不是开放格式对所有工具的保证。GitHub Copilot 各 Surface、Cursor、Claude Code 与其他宿主有各自的 Discovery Rule 和 Feature Flag。依赖嵌套作用域或优先级前,应先验证具体宿主与客户端。
嵌套文件只写差异:
# 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,然后从仓库根目录执行:
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");
}
运行时显式指定宿主预算:
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:
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 当前文档给出类似命令:
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,使有害指令变更可以独立于其他源码回滚。
一套可操作的发布顺序是:
- 核验当前 Host 行为和仓库证据。
- 一次只提交一组内聚的指令变化。
- 运行静态检查和 Discovery Fixture。
- 运行配对代表性任务与 Security Negative Control。
- 像审阅可执行配置一样审阅 Instruction Diff。
- 先在有限团队或仓库范围发布。
- 比较结果,失败或成本升高时回滚。
常见问题
所有编程 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 的规则。
相关资源
- AI 编程上下文文件:架构、安全与评测
- AI 编程 Rule File 对比
- 上下文工程:Task Packet 与 Evidence Boundary
- Prompt Injection 攻击与防御指南
- 上下文工程术语
- Agent Harness 术语
一手来源
- AGENTS.md 开放格式站点
- OpenAI Codex:使用 AGENTS.md 配置自定义指令
- GitHub Copilot Repository Instructions
- GitHub Copilot Custom Agent Profile
- OpenAI Codex 仓库 AGENTS.md
- Apache Airflow 仓库 AGENTS.md
- Temporal Java SDK 仓库 AGENTS.md
- AGENTS.md 对 AI 编程 Agent 效率的影响研究
- Context File 是否帮助编程 Agent 的消融研究
- OWASP LLM Prompt Injection Prevention Cheat Sheet