[控场AI]
· 6 分钟阅读· 3,168 字

AGENTS.md 与 AI 上下文之争:FAF 如何定义项目事实

AGENTS.md 与 AI 上下文之争:FAF 如何定义项目事实

AI 编程代理的指令文件正收敛于 AGENTS.md,但项目定义需由结构化的 project.faf 承担。

文章记录了开发者 Wolfe-Jam 构建 FAF 项目时的思考与实践。行业最终选择了 `AGENTS.md` 作为所有编程代理共同读取的指令文件,并推动其成为开放标准。但作者指出,`AGENTS.md` 只是“指令”,无法回答“项目究竟是什么”。为此提出 `project.faf`:一个位于仓库根目录、与 `package.json` 并肩的 YAML 文件,用于保存有来源的“可验证事实”,如目标、技术栈与用户。文章引用 2026 年 arXiv 研究说明:上下文文件平均增加超 20% 推理成本,却未提升任务成功率,仓库概览类内容尤其无益。由此分出事实与指令的边界,并给出仓库上下文状态的四级阶梯。核心结论是:指令文件会改变名称与厂商,但底层事实来源应保持稳定。

一场与 Codex 的争论

开发者 Wolfe-Jam 在构建 FAF 项目时,曾与 OpenAI 的 Codex 发生过一场争论。当时 Claude 有 CLAUDE.md,Gemini 有 GEMINI.md,但 OpenAI 没有 CODEX.md,只有 AGENTS.md。Codex 坚称它"有上下文",而开发者认为它没有,于是干脆停用了 Codex。

后来行业做出了选择。AGENTS.md 成为所有编程代理都会读取的文件,覆盖 Codex、Cursor、Copilot、Windsurf、Amp、Devin。OpenAI 在 2025 年 12 月将其捐赠给 Linux 基金会的 Agentic AI 基金会,使其成为开放标准。

据 rss 来源报道,转折点来自 Svelte 社区一位开发者的提问:"这不就是 AGENTS.md 做的事吗?"开发者重新审视后终于醒悟——争论的焦点从来不是哪个文件胜出,而是 Markdown 无法表达的东西:项目究竟是什么。

AGENTS.md 是目前业界事实上的标准文件,放置在代码仓库根目录,用于向各类 AI 编程代理(Coding Agent)传达项目指令、约定与工作方式。它由 OpenAI 于 2025 年推动标准化,并在同年 12 月捐赠给 Linux 基金会旗下的 Agentic AI 基金会,成为一个中立的开放规范。其设计初衷是提供一个厂商无关的入口:无论你使用 Codex、Cursor、GitHub Copilot、Windsurf 还是 Devin,代理都会优先读取该文件,从而避免每个工具各搞一套专属配置(如 CLAUDE.md、.cursorrules)。这种“单一入口、多方兼容”的模式降低了迁移成本,但也带来一个被广泛忽视的问题:它是一个纯文本的 Markdown 文件,只能容纳自然语言指令。

定义与指令的边界

AGENTS.md 本质上是给代理的指南:如何构建、如何测试、约定是什么、什么不要碰。它是指令,而且做得很好。但指令需要一个"关于什么"的对象,这正是 Markdown 没能提供的。

于是出现了这条分界线:

  • FAF 定义。AGENTS.md 指令。AI 编码。

project.faf 是一个位于仓库根目录的小型 YAML 文件,它与 package.json 并肩而立。开发者用一组目录结构说明这种关系:

project/
├── AGENTS.md        ← 代理遵循此文件
├── package.json     ← npm 读取此文件
├── project.faf      ← AI 读取此文件
├── README.md        ← 人类阅读此文件
└── src/

project.faf 保存的是事实:目标、技术栈、用户是谁、是什么、为什么。每条事实都是经过验证的"可验证事实",只能来自两个地方——仓库本身(faf auto 读取运行时、构建、CI、托管信息),或者人(通过 faf go 写入或批准代码无法展示的目标和用户信息)。任何猜测都不被允许,像 tbd 这样的占位符会被视为空值,因为它没有来源。

事实与指令分离的实证依据

这个区分比听起来更重要。据 2026 年一项名为《Evaluating AGENTS.md: Are Repository-Level Context Files Helpful for Coding Agents?》的研究(Gloaguen 等人,arXiv 2602.11988)发现:提供上下文文件通常不会提升任务成功率,反而平均增加超过 20% 的推理成本,无论是 LLM 生成的文件还是开发者提交的文件都是如此。

研究建议:只把它们用于非标准内容,其他任何东西在依赖之前都要先评估。研究最新版本还补充了一个关键发现:上下文文件中的指令被很好地遵循,但仓库概览——"尽管很流行且被模型提供商推荐"——却没有帮助。

作者的解读是:概览本质上只是更多的散文,而散文可能过时、不具体或自相矛盾,代理无法分辨。因此 FAF 不写概览,而是把定义留在 project.faf 中,让每条事实都有来源,而进入 AGENTS.md 的是命令、护栏和技术栈——代理可以运行或检查的东西。该研究测试的是 Markdown 上下文文件,展示了散文的局限性,但结构化数据(YAML 中的模式)并不在其中,作者认为这是下一步该测试的方向。

“推理成本”在此语境下指的是代理为完成任务所消耗的 token 总量。上下文文件中的每一段文字都会在每次调用时被注入模型的上下文窗口,因此文件越长、越详尽,代理为同一次任务付出的 token 就越多,而 token 直接对应金钱与时间开销。该研究的核心发现是:这些额外的 token 并没有换来更高的任务成功率,反而拉高了成本。这被称为“上下文税”——你以为在给代理帮忙,实际上只是让它读了更多无助于执行的散文。尤其值得注意的是,模型对指令性语句(如“运行 npm test”)遵循度较高,但对描述性概览(如“本项目是一个高性能的分布式系统”)几乎无法验证真伪,只能照单全收,一旦概览过时便可能误导决策。

仓库的四级阶梯

据此,任何仓库的上下文状态都可以分为四级:

级别状态后果
NONE没有 AGENTS.md,代理靠猜每次会话都从空白开始
GOOD有任意 AGENTS.md会悄悄过时
BETTER带有受管块的 AGENTS.md:精简、最新、可检查块中的事实在仓库中没有来源
BESTBETTER 加上仓库中的 project.faf:块背后的来源,以及应用类型和人类上下文事实与指令保持同步

大多数仓库停留在第一列。到达 GOOD 只需要一个文件。BEST 才是事实不再漂移的状态,因为它们在一个地方定义,每个指令文件都指回同一来源。

两大阵营的汇合

最令作者欣喜的是行业趋势的收敛。2025 年 9 月,Claude Code 也开始读取 AGENTS.md——在一个没有 CLAUDE.md 的项目中,它会转而使用 AGENTS.md。作者曾经纠结的"两大阵营"已经会师。

这恰恰印证了核心观点:负责指令的文件会不断改变名称、厂商和规则,但底层的事实不会变。定义一次事实,让每个指令文件——AGENTS.md、CLAUDE.md、GEMINI.md、.cursorrules——都指回同一来源。

如何尝试

开发者提供了两条命令来体验这套工作流:

npx faf-cli auto
npx faf-cli export --agents

第二条命令会写出标准的、符合规范的 Markdown 文件,而非 FAF 方言。在其中,FAF 管理一个事实块,包含设置命令、构建命令、如何运行测试、文件位置、护栏和技术栈。你手写的其他内容会被保留。当事实改变时,再次运行同一命令,块会从源重写,从而避免漂移。

项目仓库位于 github.com/Wolfe-Jam/faf-cli。作者的建议是:完成后问问你的代理这个项目是什么,它不必再猜测。

分享:

相关推荐