AGENTSMD-Codex

时间:2026-07-04 08:56:41 来源:互联网

在开发工作中,针对AI编程工具Codex的指令编排常因细节疏忽而效率折损。以AGENTS.md文件为例,若不掌握其准确的撰写与加载规则,极易陷入指令被忽略的困境。本文将完整解析该文件从发现机制到落地写法的全流程,帮助读者避免常见陷阱,建立规范的开工流程。

11 · 项目说明书 AGENTS.md:把规矩焊进 Codex 的开工流程

分享一个我刚接触Codex时犯下的低级错误。

去年我将一个Node项目交给Codex,并在根目录清晰写下AGENTS.md,首行即注明“本项目用pnpm,禁用npm”。结果它依然执行npm install。起初我以为是文件未被读取,恼怒地将规则重复三次并加粗标注,但问题依旧。

经过数小时排查才发现,文件确实被读取,但关键指令被埋在约第140行。在此之前,我填充了大量公司介绍、产品路线图及技术选型背景,累计超过百行。当Codex读到“禁用npm”时,注意力早已被前文内容稀释。核心问题不在于工具不听话,而在于我将唯一有效的规则嵌入了一堆无用信息中。

AGENTS.md 对Codex而言,等同于 CLAUDE.md之于Claude Code,只是文件名不同。然而Codex的发现机制、覆写规则与字节限制自成体系,存在多处容易踩坑的细节。本文将连同“该写什么、不该写什么”一并讲清。

通过本篇内容,你将掌握:Codex发现AGENTS.md的完整链条(全局层→项目层→合并顺序),以及冲突时的优先级规则;AGENTS.override.md 这个Claude Code不具备的“临时盖章”机制及其适用场景;一份“该写vs不该写”的清单,避免重蹈“140行无人听”的覆辙;修改文件名(project_doc_fallback_filenames)、调整字节上限(project_doc_max_bytes)的官方用法;以及一套可实操的流程,验证Codex是否真正读取了指令。

注意:本篇只聚焦AGENTS.md这一个文件的编写与加载。容易混淆的“记忆(Memories)”机制(本地自动回忆层,默认关闭)已在[02 核心概念]中说明。请记住:真正需要每次生效的团队规则,务必写入AGENTS.md,而非依赖记忆功能。


01 先搞懂:AGENTS.md 是 Codex 开工前的「交接清单」

先给出结论:AGENTS.md 是你向Codex提供的一组持久化指令。它会在每次启动、执行任务前被读取,作为该项目的背景信息加载到上下文中。

为什么需要它?因为Codex每开启一轮操作(每轮即每个会话周期,按官方术语,TUI中通常每启动一个会话算一轮)都从空白状态开始。上一轮你反复强调的“使用pnpm、不要修改legacy/目录、按此方式运行测试”,这一轮它完全不记得。如果没有AGENTS.md,你每次都必须重新解释一遍。

类比:交接班的工作清单。工厂实行三班倒,上一班下班前会在墙上的白板上写明关键事项——这台机器有故障需注意、这批材料需先质检、紧急联系人是谁。下一班接班后,按照白板指示操作即可,无需将上一班人员召回口述。AGENTS.md 就是Codex的“交接板”,并且它每次接班前都会优先查看这块板。

(请注意,此处未使用“入职手册”这一比喻,因为[02]中已用过多。使用“交接清单”更贴切:它强调“每一轮开工都重读”,而非“入职当天看一次”。)

哪些情况下应该向文件中添加内容?以下是几个典型的判断信号:Codex第二次重复同一个错误——说明该规则需固化,不应再第三次口头纠正;你发现自己在当前会话中重复输入上一轮已写过的一次性更正指令;代码审查发现,Codex本该早就知晓代码库的某项约定;新团队成员(或三个月后的你自己)需要相同的背景信息才能快速上手。

我最常用的方式,[02]中已提及,这里再次强调:将其作为反馈回路。当Codex对你的代码库做出错误假设时,不要仅在对话中纠正(那是一次性的,下一轮它会再次忘记),直接让它将该修正写入AGENTS.md。我曾调优一个Python项目两周,AGENTS.md 从空白增长到约二十行,全部是它踩过的坑,被我抓住后自己记录下来的。如今新会话基本不再重复犯错。


02 发现链条:Codex 是怎么找到这些文件的

AGENTS.md 并非单一文件,它可以放置在多个层级,作用范围由大到小。Codex启动时会将这些文件串联成一条“指令链”。本节将拆解这条链路——这也是与Claude Code差异最大的部分,需仔细理解。

根据官方文档,Codex构建指令链分两步进行(每轮构建一次,TUI中通常每启动一个会话构建一次):第一步,全局层(Global scope)。在Codex主目录(默认~/.codex,除非你设置了CODEX_HOME环境变量)中,Codex首先检查是否存在AGENTS.override.md。如果存在,则使用它;否则才读取AGENTS.md。这一层只选取第一个非空文件,不会同时读取两个。第二步,项目层(Project scope)。从项目根目录(通常是Git根)开始,沿路径向当前所在目录逐级下降。沿途每个目录中,Codex按此顺序筛选:先查AGENTS.override.md,再查AGENTS.md,最后查project_doc_fallback_filenames中你自定义的备选文件名。每个目录最多只取一个文件。第三步,合并(Merge order)。Codex将从根到叶找到的所有文件按顺序拼接,中间用空行隔开。越靠近当前目录的文件,由于排在拼接结果越靠后,优先级越高,可以覆盖前面的内容。

为便于理解,请看下图:

AGENTS.md 三层发现链:机器级 ~/.codex/(override 优先)→ 项目层 Git 根逐级累加 → 拼成指令链

这张图展示了整条链路:先在全局层二选一,再到项目层逐级各选一个,最后从根到叶拼接——离你越近的文件,在拼接结果中位置越靠后,优先级越高。

这里有两个关键点,均来自官方文档,需牢记:第一,是“拼接”而非“覆盖”。全局文件和项目文件同时生效,不存在“写了项目级,全局级就失效”的情况。它们全部进入上下文,后面的文件不会完全替换前面的,仅当条目冲突时,以靠后(更近)的文件为准。第二,更近的规则胜出。例如,全局AGENTS.md 规定“字符串用单引号”,项目根AGENTS.md 规定“用双引号”。由于项目根离当前目录更近、排位更靠后,因此双引号规则胜出。简言之,项目规则可以覆盖个人偏好,这正是团队协作所需要的。

类比:导航地图的三层缩放。全国地图提供大方向(全局层),城市地图显示城区路线(项目根),小区门口的指示牌告诉你最后几步如何走(子目录)。三层同时有效,信息互不删除。一旦小区门口的指示牌与大地图冲突,以现场最近的那块牌子为准——它最贴近你当前所处的位置。AGENTS.md的这条链正是遵循“越靠近当前位置越具体,冲突时越优先”的逻辑。

AGENTS.md 三层发现链、就近优先

这张图将三层从上到下叠加展示:全局层(~/.codex/)、仓库根、子目录依次拼接,三层同时生效。右侧的“优先级”轴提示:越靠近当前目录的层级,在拼接结果中排位越靠后,冲突时优先级越高,即“就近覆盖”。


03 AGENTS.override.md:Claude Code 没有的「临时盖章」

上一节反复出现一个名称——AGENTS.override.md。这是Claude Code所不具备的,属于Codex的独特设计,需要单独说明。

首先明确它解决的问题。设想你的~/.codex/AGENTS.md 中保存了一套团队共用的全局约定,日常使用正常。但今天你承接了一个临时任务,需要完全替换这套全局指导,又不想删除原文件(否则日后还需重写)。如何处理?

类比:在文件上盖一张“以此为准”的便签。原合同存放在抽屉中,你并未撕毁;只是临时贴了一张便签条,写明“本月按此新条款执行”。任务完成后,揭下便签,原合同自动恢复生效。AGENTS.override.md 就是这张便签——它存在时,同级的AGENTS.md 被整体跳过;将其删除后,原文件立即恢复使用。

官方给出的两个典型场景:全局临时覆写:在~/.codex/AGENTS.override.md 中编写一套临时全局指导,原~/.codex/AGENTS.md 保持不动。任务完成后删除override文件,共享的那份即恢复。子目录特殊规则:某子目录的团队需要一套与外部完全不同的规则。例如,支付服务目录services/payments/,放置一份AGENTS.override.md

# services/payments/AGENTS.override.md ## 支付服务规则 - 用 `make test-payments` 替代 `npm test`- 轮换 API Key 前必须先通知安全频道

放置此override文件后,该目录中同级的AGENTS.md(如果有)将被跳过。Codex在此目录工作时,只认override中的指令。

这里需要厘清一个新手易混淆的点:override与“覆盖整条链”并非同一概念。它存在的含义是:同级的AGENTS.md(以及备选文件名)被跳过,这一层只认override文件。但这并不意味着“全链路只听我一个”。整条链的拼接规则和就近优先规则照常执行。我第一次使用时就理解错误,以为在子目录放置override文件可以屏蔽全局文件,结果全局约定依然生效。后来查阅官方文档才明白,它只在自己所在层级进行二选一。

另外,override还有一个排查神器级的用法:如果Codex突然出现一条你从未写过的奇怪指令,第一步应顺着目录树向上排查,连同~/.codex,检查是否存在隐藏的AGENTS.override.md。将其重命名或删除,即可回退到常规AGENTS.md。官方排查清单中专门列出了这一条。


04 该写什么 vs 不该写什么

这一节是全篇的核心,也是开头所述“140行无人听”问题的解药。AGENTS.md 写不好,九成原因在于“该写的没写清,不该写的塞太多”。

先谈该写的内容:一句话概括——写“Codex在每一轮中都应保持的事实”。具体分为以下五类:

类别

具体写什么

例子

项目概述

一句话说明项目性质

“基于 FastAPI 的订单管理后端”

技术栈

语言、框架、数据库、关键工具

“Python 3.11 / PostgreSQL / pytest”

常用命令

测试、构建、检查/lint的运行方式

npm run lint 、make test-payments

代码约定

风格、命名、必须遵守的写法

“函数必须有类型注解”“字符串用双引号”

明确的“不要做”

雷区、禁改文件、必须先确认的操作

“禁改 migrations/ 已有文件”“新增生产依赖前先确认”

其中常用命令是被参考最频繁的内容:Codex在执行测试、提交PR前会优先来此查找命令,避免自行猜测或用错。官方示例AGENTS.md 中的第一条就是命令:“提 PR 前运行 npm run lint ”。禁止清单则是防止它“聪明但闯祸”的护栏:哪些目录是遗留代码、只读不改,哪个操作在修改前必须先询问。

再说“不该写”的内容,这是新手翻车的重灾区,也是我亲身踩过的坑:长篇大论的背景:公司介绍、产品愿景、技术选型的历史渊源——Codex编写代码用不上,不仅占用上下文空间,还会稀释真正有用的规则(参考我开头的140行案例)。过时信息:更换了包管理器但未更新AGENTS.md,其中仍写着npm,结果反而误导它。看代码就能知道的内容:不要重复描述目录结构中每个文件的用途,不要将ESLint/Prettier已定义的代码风格照抄一遍。Codex能自行读取代码,重复描述只会浪费空间。

官方对“别写太大”给出了硬性约束,但与Claude Code不同——Claude Code以行数为限制(建议200行内),Codex则以字节为限制:Codex会跳过空文件,当拼接后的总大小达到project_doc_max_bytes 限制(默认32 KiB)时,停止继续添加文件。

注意这句话包含两层含义:一是默认上限为32 KiB,超过则截断(甚至整个文件被排除);二是该上限计算的是合并后的总和,即全局+项目+子目录相加的总大小。因此,如果一份文件写得过长,可能导致后面更重要的文件被排除在窗口之外。官方建议:如果遇到上限问题,要么调高project_doc_max_bytes,要么将指令分散到多级子目录中(这与[04 计费]中提到的“AGENTS.md 瘦身+按子目录分层”以节省token的思路一致)。

这里有一个实用的方法:在写入每一条内容前,先自问一句:“Codex通过看代码能否自己推导出这条规则?如果能,就删除。”仅仅依靠这一准则,就能将一份接手项目的AGENTS.md 从一百多行缩减到几十行,留下的都是它无法推导的硬性约束。经过裁剪后,它使用错误包管理器的次数明显减少。


05 两个旋钮:改文件名、调字节上限

大多数情况下,使用默认的AGENTS.md 即可满足需求。但在两种特定场景下,需要调整配置。本节介绍两个位于~/.codex/config.toml(Codex的用户级配置文件)中的设置项。

旋钮一:让 Codex 认你已有的文件名

假设你的仓库中已有一份TEAM_GUIDE.md,整个团队一直将其作为规范文档使用。你不想再创建一份AGENTS.md 重复内容,希望Codex直接将TEAM_GUIDE.md 视为指令文件读取。此时可以使用project_doc_fallback_filenames(备选文件名)配置:

# ~/.codex/config.tomlproject_doc_fallback_filenames = ["TEAM_GUIDE.md", ".agents.md"]

添加此配置后,Codex在每个目录中的文件选择顺序变为:AGENTS.override.mdAGENTS.mdTEAM_GUIDE.md.agents.md,并选取第一个存在(且非空)的文件。

旋钮二:合并内容被截断了,调高上限

上一节提到默认上限为32 KiB。如果你的指令确实超出该范围,且暂时不想拆分文件,可以将project_doc_max_bytes 调大:

# ~/.codex/config.tomlproject_doc_max_bytes = 65536

这样就将上限提升到64 KiB,能够容纳更多合并指令后才触及上限。不过需要提醒一句:这只是治标之策。如果内容确实有用,调高上限是可行的;但更多情况下,触碰32 KiB上限是一个信号,提示你“该精简内容了”或“该按子目录拆分文件了”,而不是“该将上限上调”。我个人的偏好是优先拆分文件,其次删除冗余内容,实在无法拆分时才考虑调高上限。

两个旋钮的适用场景对比如下:

project_doc_fallback_filenames 加上它的名字


06 动手:给玩具项目配一份合格的 AGENTS.md 并验证加载

理论讲解之后需要进行实践。下面通过一个最小项目,完整走一遍“创建文件→书写规则→验证Codex是否读取”的流程。按照步骤操作,几分钟即可完成。

第一步:创建玩具项目并初始化Git

mkdir agents-md-democd agents-md-demogit init

预期结果:在agents-md-demo 目录中出现一个.git 目录。Git初始化是为了让Codex能够将此处识别为“项目根”(它通常以Git根目录为起点向下扫描),同时也便于将AGENTS.md 纳入版本控制,实现团队共享。

第二步:手写一份精简的项目级AGENTS.md

使用你习惯的编辑器,在项目根目录中新建AGENTS.md,并粘贴以下内容(注意,文件只有寥寥数行——这正是优秀AGENTS.md 应有的篇幅):

# agents-md-demo — 一个演示用的最小项目 只有用来演示 AGENTS.md 怎么写,没有真实业务逻辑。 ## 常用命令 - `npm test` —— 运行测试 ## 编程约定 - 所有函数必须有类型注解- 字符串一律用双引号 ## 注意事项 - 不要新增任何生产依赖,需要时先问我

预期结果:项目根目录下出现AGENTS.md,内容就是以上几部分。全文仅十几行——请记住这个篇幅,真实项目也应避免失控膨胀。

第三步:让 Codex 复述它读到的指令

官方提供了一种非常直接的验证方法——让Codex将当前生效的指令总结出来。在项目目录中运行:

codex --ask-for-approval never "Summarize the current instructions."

预期结果:Codex在执行操作前,会回显你刚刚写下的几条指令(命令、类型注解、双引号、不添加依赖)。只要它能够复述出这些内容,就说明这份AGENTS.md 在当前轮次中确实被载入了上下文。

第四步(进阶)验证子目录覆写的“就近优先”效果

如果你希望亲眼验证“越近越管用”的规则,可以再执行一步。在项目中创建一个子目录,并放置一份仅覆盖一条命令的override文件:

mkdir -p services/payments

services/payments/AGENTS.override.md 中写入:

# services/payments/AGENTS.override.md ## 支付服务规则 - 用 `make test-payments` 替代 `npm test`

然后从该子目录的视角启动Codex,让它报告加载了哪些指令来源:

codex --cd services/payments --ask-for-approval never "List the instruction sources you loaded."

预期结果:根据官方描述,Codex会依次列出——首先是全局文件(如果你的~/.codex 中存在),然后是仓库根的AGENTS.md,最后是支付服务目录的override文件。并且,该层的测试命令将以override中的make test-payments 为准,根目录中的npm test 命令在该子目录中被覆盖。这就是“就近优先”规则的直观体现。


07 小结

通过本篇内容,你已经掌握了AGENTS.md 这个“Codex项目说明书”的完整知识体系,包括其发现机制与落地写法:每轮开工前必读的交接清单,功能与CLAUDE.md类似但文件名不同;全局层(~/.codex/)与项目层(Git根+子目录)构成级联发现逻辑,就近优先;override文件提供临时替代机制,便于在不影响原文件的情况下切换指令;应写入项目概述、技术栈、常用命令、代码约定与禁止清单五类核心信息,避免冗余背景与过时内容;可通过调整备选文件名(project_doc_fallback_filenames)与字节上限(project_doc_max_bytes)两个配置项满足特定需求;利用“Summarize the current instructions”命令即可实时验证指令是否被加载。

现在,你应该具备以下能力:判断一条信息是否应写入AGENTS.md、以及应放置在哪个层级;理解多层文件冲突时的胜负规则;使用AGENTS.override.md 临时更换指导内容,而不删除原文件;在遇到字节上限时,判断是应该精简内容还是调高上限;通过一句验证命令确认Codex是否成功读取指令。总之,你已经能够编写一份Codex真正愿意执行、而非像当年我那样写下140行却无人理睬的AGENTS.md了。


下一篇将介绍“斜杠命令与快捷键”——在本篇中,你已经多次在命令行中敲击codex ...,那么进入会话之后呢?以/开头的斜杠命令能让你即时切换模式、清空上下文、查看状态,配合几个实用的快捷键,操作效率将大幅提升。留一个思考题:本篇让Codex“记住规则”依靠的是写入文件,那么如果希望在会话中临时改变它的行为,又不想修改AGENTS.md,猜猜应该使用什么方法?