使用Agents.md让AI写代码更可控
目录
- AI Coding遇到的问题
- AGENTS.md是什么
- 什么是AGENTS.md
- 跟 CLAUDE.md 是什么关系
- AGENTS.md层级
- 全局 AGENTS.md
- 项目级 AGENTS.md
- 子目录 AGENTS.md
- AGENTS.override.md
- 一些建议和指南
AI Coding遇到的问题
不知道你有没有这种经历,反正我是遇到过,就是有时候让AI帮我写代码时很多时候不能按照我的想法来,会出现各种各样的问题。比如:
- 他有些模糊的需求不去问你,按照自己的想法去实现了
- 有时候会设计过头,很简单的东西可能做的很复杂,可能因为他太优秀了,想表现吧哈哈
- 可能会修改到其他不需要修改的地方
- 有时候回答你已经完成,但是当你验收的时候,发现还是不对
- 等等各种不如我们愿的问题
然后为了让AI写代码更可控,我们往往需要告诉他更多信息,来规范他的行为,比如告诉他这个项目的哪些目录不要去动,写完代码之后怎么去测试,新增依赖了要先确认等等。这当然是有效的,能提高AI的可控性。但是我好像每次开一个新会话让 Codex 帮改代码,都得重复说一遍"我们项目用 pnpm 不是 npm",“别动 vendor 目录”,“跑测试用 pytest 不是 unittest”?等。说多了烦,不说它又猜不对。
AGENTS.md就是干这个事的。
AGENTS.md是什么
什么是AGENTS.md
简单说,它是一份给 AI 编码助手看的说明书。不是给人看的 README,是专门告诉 Codex、Cursor、Jules 这类 AI 工具"在这个项目里该怎么干活"的文件。你写一次,提交到仓库里,以后每次 AI 启动都会自动读取。
2025 年 5 月前后,各家 AI 编程工具都在解决同一个问题:怎么让 AI 理解你的项目规范。Claude Code 搞了 CLAUDE.md,Cursor 有自己的 rules,Sourcegraph 的 AMP 提议用 AGENT.md(单数)做统一标准,还注册了 agent.md 域名。OpenAI 随后买下了 agents.md 域名,提议用 AGENTS.md(复数)。
最后的结果是,AGENTS.md 成了一个开放格式,由 Linux 基金会下的 Agentic AI Foundation 管理。目前已经有超过 6 万个开源项目在用,支持的工具包括 Codex、Jules、Cursor、Aider、Zed、VS Code、Devin、Windsurf、Gemini CLI、GitHub Copilot 等等,基本覆盖了主流 AI 编程工具。
所以这不是 OpenAI 一家的东西,而是一个事实上的行业标准。
跟 CLAUDE.md 是什么关系
两者解决的问题一样,但范围不同。
CLAUDE.md 是 Claude Code 的专属文件,只有 Claude Code 会读。AGENTS.md 是开放格式,很多工具都认。如果你的仓库里已经有了 AGENTS.md,一般没必要再维护一份内容差不多的 CLAUDE.md。可以这样处理:
@AGENTS.md##ClaudeCode特定指令-使用 plan mode 处理 src/billing/下的改动。让 CLAUDE.md 引用 AGENTS.md,再加上 Claude Code 独有的配置就行了。反过来,如果团队原来只有 CLAUDE.md,想把规则也共享给 Codex 或 Cursor,就把通用部分抽到 AGENTS.md,Claude Code 专属的留在 CLAUDE.md。
AGENTS.md层级
AGENTS.md可以放在不同位置。一般就是分三个层级:
~/.codex/AGENTS.md:全局规则project/AGENTS.md:项目规则project/order/AGENTS.md:子模块规则
他们是合作的关系,不是说有了全局AGENTS.md,项目AGENTS.md就不生效了。
使用的场景也很明确,
- 不管什么项目我都要使用的规则:放全局
- 只在这个仓库要使用:放项目
- 只在某个子目录使用:放子目录
在加载所有的 AGENTS.md 后还会进行合并,从根目录往下拼接,用空行连接。越靠近当前工作目录的文件出现得越晚,优先级也越高——因为模型对上下文末尾的内容更敏感。
所有文件合并后有个大小上限,默认 32 KiB(project_doc_max_bytes)。超了就会被截断。所以别把所有东西都塞进去,后面会讲怎么精简。
举个具体例子。假设你在services/payments/目录下工作,Codex 会依次读取:
~/.codex/AGENTS.md(你的个人全局规则)- 项目根目录的
AGENTS.md(团队共享规则) services/AGENTS.md(如果有的话)services/payments/AGENTS.md(最贴近当前工作,优先级最高)
OpenAI 自己的主仓库里有 88 个 AGENTS.md 文件,分布在不同子目录下。这很能说明大项目确实是很需要分层管理规则的。
全局 AGENTS.md
全局AGENTS.md位于~/.codex/AGENTS.md
他里面写些什么呢?一般是放个人的偏好或者各个项目通用的约束。但是核心就一条:只放 AI 真的会用到的信息。
举一些例子:
- 给核心逻辑打上注释和日志,方便后续理解和排查问题
- 开始写代码前请充分理解现有的代码结构,尽量减少改动,不要过度设计
- 设计重大架构时请先询问确认再执行
- 优先使用项目现有风格
- 充分写测试用例,尤其边界条件,防止出现极端bug
那什么不该写的?核心原则是不写AI已经知道的通识和模糊不清的废话。
举一些例子:
- 保持代码整洁优雅:相当于废话,AI写代码自己会保持好的
- 充分考虑,降低错误率:也是废话,AI写代码不会故意写错,你需要告诉他降低错误率的具体措施
- 遵循 PEP 8 规范:AI会自己按照项目的规范延续写的
记住写的时候不是许愿,而是命令和约束。
还要注意AGENTS.md不是越长越好,尽量控制在 100-200 行以内。超过 300 行后,模型对关键规则的遵循度会明显下降。
如何配置呢?
以Codex为例, 设置 → 个性化 → 自定义指令。你把内容放到自定义指令的输入框里,点击保存就可以了。在7月10号CodeX更新后已经改版被ChatGpt桌面版取代,当然设置的位置是类似的。
注意:AGENTS.md 在会话启动时一次性加载,不是实时配置中心。改了后,当前会话不会自动刷新,必须新开会话或者让他主动读取,才能让新规则生效。
网上盛传Andrej Karpathy 推荐的建议,我们可以作为参考
## Before Writing Code - Read the files you're about to modify. Not skim. Read. - Look at how similar things are done elsewhere in the project. - Check the imports at the top of the file. - Look at the test files. - State your assumptions before coding. - If something is confusing, stop and ask. - Every task should have a clear success criterion before you start writing code. ## Keep Changes Small - Write the minimum amount of code that solves the problem. - "In case we need to" is not a requirement. - Don't touch what you weren't asked to touch. - Match the existing style. - Clean up after yourself, not after others. - Don't reformat. - Can you justify every single changed line? - Don't add dependencies without thinking about it. ## Debugging And Verification - The difference between code that works and code you think works is testing. - Write the test first when fixing bugs. - Run existing tests before and after your changes. - Read the error message. - Reproduce first. - Change one thing at a time. - Don't add workarounds without understanding the root cause. ## Communication And Stop Conditions - Say what you did and why. - Flag concerns. - Be precise about what you're uncertain about. - If you notice a common failure mode, stop and reconsider. - Watch for: Kitchen Sink, Wrong Abstraction, Invisible Decision, Optimistic Path, Knowledge Hallucination, Style Drift, Runaway Refactor.其实主要说了以下几个方面:
- Read Before You Write(开始写前先读上下文):真实项目有自己的项目结构、封装好的工具、测试习惯、命名风格、历史遗留问题等。如果他没有提前读,很可能写出他觉得没问题,但是会影响其他模块,或者写出冗余代码。
- think Before You Code(编码前先思考):这个主要让他需求不清楚时,不要猜。有些需求,比如加缓存、登录验证登,其实可能有很多实现路径。有时候AI会自己选了一个方案,可能到最后执行完了我们才发现方案不合适。
- Goal-Driven Execution(目标驱动执行):即每次行动前要有一个清晰的目标,要求每个任务在开始前都要有清楚的成功标准,写成可验证条件。
Simplicity(最小改动):只改与任务直接相关的代码,使用最小的代码改动来解决问题,除非我们需要;- Surgical Changes(不做顺手改动):不做顺手重构;不要触碰没让你触碰的区域;格式化只限自己改动的区域。
- Dependencies(依赖管理):不要不思考就随意添加依赖,要说明为什么当前依赖不满足需求,
Verification(先复现再修):bug 修复优先写失败测试或给出可复现步骤,主要为了修 bug 之前,先证明 bug 确实存在。不要看到一个报错类型,就立刻生成一个看似合理的修复,真实调试要先读完整错误和堆栈,要复现。- Communication(交流):要详细说明改了什么,为什么这样改,哪里还有不确定,哪些风险需要我知道。
- Stop Conditions(停止条件):失控即停:如果修复开始扩散到多个模块,先暂停,说明原因,重新确认范围。
下面有一份生产级的参考,我们根据自己的需求,做修改使用:
# AGENTS.md 本仓库中 AI 编程助手的协作约定。 当规则冲突时,优先级依次为:用户明确指示 > 本文件 > 现有代码规范 > 你自身的默认行为。 若改动存在风险,或对架构、数据、安全性、对外行为产生实质性影响,请暂停并提问,切勿擅自猜测。 ## 初始准备 每次会话开始前,务必先执行此步骤。 在编写任何代码之前,请根据仓库实际内容构建可用的认知模型: - 阅读 `README`、`CONTRIBUTING` 以及根目录下的 `*.md` 文件,了解项目设置与规范。 - 修改前,先阅读待改文件及其测试。 - 不要凭经验假设技术栈,必须从仓库实际内容中验证。 ## 核心原则 - 以最小改动解决问题。 - 禁止顺手重构、重命名或格式化未触及的代码。 - 确保 diff 中不夹杂无关变更。 - 与周围代码保持一致:命名、结构、错误处理、测试风格。 - 一致性优于个人偏好。 - 优先复用现有的辅助函数、组件和模式,避免新增。 - 不要为尚不存在的场景添加推测性的抽象、配置或错误处理。 - 注释应解释非显而易见的决策,不要复述代码自身已表达的内容。 ## 验证 任务完成前必须执行: - 使用项目定义的命令。优先运行针对性检查,再运行全局检查。 - 运行所涉文件、包或功能的局部测试。 - 然后运行项目定义的全局关卡:lint、类型检查/编译、测试。 - 条件允许时,在本地模拟 CI 流程。 - 不要为了有命令可跑而捏造无关的验证命令。 - 修复由你改动引发的失败。 - 为行为变更添加或更新测试。 - 若因缺少服务、凭证、网络或时间而无法执行某命令,请明确说明。 - 若未实际运行测试,绝不可暗示测试通过。 ## 依赖 - 未经询问,不得添加生产依赖。 - 如需添加,请说明现有工具为何不够用。 - 开发辅助工具的风险较低,但仍需与仓库现有用法保持一致。 - 禁止手动编辑生成文件、第三方代码或锁文件。 - 必须通过项目文档中声明的命令重新生成这些文件及锁文件。 ## 何时暂停并提问 遇到以下情况请暂停并提问: - 添加生产依赖或引入新框架。 - 引入广泛的新抽象。 - 触碰生产数据、schema 或迁移。 - 当任务要求与代码实际情况矛盾时。 - 在多个可行方案中无法明确最佳选择时。 ## 任务反馈 每次任务结束时,请说明: - 按文件列出具体改动。 - 验证方式(包括运行的命令及其结果)。 - 哪些内容未运行及原因。 - 潜在风险或后续待办事项。项目级 AGENTS.md
项目级AGENTS.md一般放在仓库根目录:project/AGENTS.md
这里要写的通常是当前项目息息相关的约束和规则。
比如:
- 启动命令
- 测试命令
- 类型检查命令
- lint 命令
- 项目架构
- 目录结构
- 数据库要求等
另外,ETH Zurich 曾建议,不要让AI帮你写。LLM 自动生成的 AGENTS.md 会让任务成功率下降约 3%,推理成本增加 20%+。而人工编写的文件能让成功率提升约 4%。LLM 生成的版本倾向于重复 README 和 package.json 里已有的信息,冗余内容反而稀释了 Agent 的注意力。
注意我们在写AGENTS.md时不要把你知道的所有好的提示词一股脑全往AGENTS.md里塞。他是一个迭代优化的过程。
这里有一份生产级规则参考,我们根据自己实际的项目情况做修改使用:
# 项目名称 — AI编程 工作指南 > 本文档用于指导AI编程在本项目中的行为。所有规则在会话启动时自动加载。 # 1. 项目概述 **项目目标**:[一句话描述,如:一个面向中小企业的订单管理系统] **核心业务逻辑**: - 用户认证与权限管理(RBAC) - 商品 SKU 管理与库存扣减 - 订单创建、支付、履约全流程 - 消息通知(短信/邮件/站内信) **愿景**:支撑日均 [XX] 万订单,系统可用性 99.95% # 2. 技术栈和环境 | 类别 | 技术选型 | 版本 | 备注 | |------|----------|------|------| | 语言 | Java | 17 | 必须使用 LTS 版本 | | 框架 | Spring Boot | 3.x | 已升级到 Jakarta EE | | ORM | MyBatis Plus | 3.5.x | 使用 Lambda 式查询 | | 数据库 | MySQL | 8.0 | 事务隔离级别 READ-COMMITTED | | 缓存 | Redis | 7.x | 使用 Lettuce 客户端 | | 消息队列 | RocketMQ | 5.x | 事务消息保证最终一致性 | | 依赖管理 | Maven | 3.9+ | — | | 运行环境 | JVM | 17 | 生产环境内存 4GB+ | ## 模块划分 order-service/ ├── order-api/ # API 定义(DTO、Feign 接口) ├── order-common/ # 公共工具类、常量 ├── order-service/ # 核心业务服务(启动入口) └── order-task/ # 定时任务(独立部署) # 3. 代码规范和风格 ## 命名规范 | 类型 | 规范 | 示例 | |------|------|------| | 包名 | 全小写 | `com.example.order.service` | | 类名 | PascalCase | `UserService`、`CreateOrderRequest` | | 接口 | 无前缀 `I` | `PaymentProcessor`(而非 `IPaymentProcessor`) | | 实现类 | 后缀 Impl | `PaymentProcessorImpl` | | 方法/变量 | camelCase | `getUserById` | | 常量 | UPPER_SNAKE_CASE | `MAX_RETRY_COUNT` | | 枚举 | 全大写 | `OrderStatus.PENDING` | | 数据库表名 | snake_case | `order_detail` | | API 路径 | kebab-case | `/api/order-details` | | JSON 字段 | camelCase | `userId` | ## 代码风格 - **缩进**:4 空格(禁止使用 Tab) - **行宽**:120 字符(超行换行,运算符放行首) - **注解风格**:方法注解与签名同行(`@Override` 单独一行) # 4. 开发约定和模式 ## 架构约定 | 层级 | 职责 | 禁止事项 | |------|------|----------| | **Controller** | 参数校验、调用 Service、返回 Result | 禁止编写业务逻辑、禁止直接操作数据库 | | **Service** | 核心业务逻辑、事务管理 | 禁止直接操作 Mapper(通过 Service 调用) | | **Mapper** | 数据访问、SQL 执行 | 禁止编写业务逻辑 | ## 统一响应格式 ```java public class Result<T> { private Integer code; // 0 成功,其他失败 private String message; private T data; } # 5. 数据与迁移 - 将 schema 变更和迁移视为高风险操作。 - 除非任务明确要求,否则不得创建或修改生产环境迁移。 - 在总结中标记破坏性变更,包括删除列、删除行以及不可逆的回填操作。 - 执行破坏性数据变更前,需等待确认。 # 6. 构建、测试和运行 - 构建:mvn clean compile - 打包:mvn clean package -DskipTests=true - 单测:mvn test # 7.禁止事项 - IMPORTANT: 不要修改 prisma/migrations/ 下的文件 - IMPORTANT: 所有数据库改动通过 Flyway Migration 文件子目录 AGENTS.md
子模块可以有自己的AGENTS.md,来做针对当前模块更细的约束。
其位于子目录的根目录下:project/order/AGENTS.md。
比如我在order服务里可能会写:
# orders/AGENTS.md ## 订单服务规则 - 修改订单状态流转或金额计算逻辑时,必须同步更新订单相关测试。 - 禁止记录用户个人身份信息(如姓名、收货地址、联系电话)或订单明细中的敏感内容。 - 修改订单核心逻辑后,运行 `pnpm test orders` 进行验证。一个项目,可能同时有前端、订单、支付、商品等,每个模块的风险点都不一样,所以我们要分开写。
AGENTS.override.md
除了AGENTS.md,还有一个文件名叫AGENTS.override.md
它的优先级比同目录下的AGENTS.md更高。
可能位于如下:
project/ AGENTS.md # 仓库根规则 services/ payments/ AGENTS.md # 会被忽略 AGENTS.override.md # 实际生效 README.md search/ AGENTS.md如果两份同时存在,那么会优先使用AGENTS.override.md,而且会忽略AGENTS.md。
一般用在需要强覆盖的场景。比如:
- 某个子服务有特殊安全规则
- 某个目录禁止修改生成文件
- 某个模块必须用特殊测试命令
- 想临时替换原来的
AGENTS.md行为
一般情况下,用AGENTS.md就够了。
一些建议和指南
- 少写模糊不定和许愿类的规则,多写可检查的动作。
- 根目录只放高频、稳定、通用的规则。低频规则可以采用渐进式披露的方式,拆分到子目录的文档中。
- 不定时维护,根据使用过程出现的问题新增、修改,定时去审查、删除低频没用的规则。
- 最好将文档控制在200行以内,最多不超300行,写的越多AI可能越难遵守指令,只写最重要的。
总结:本文详细介绍了AGENTS.md,他是给 AI编程看的遵守规范。可以分三个层级,全局~/.codex/AGENTS.md放通用偏好;项目repo/AGENTS.md放项目规则;子目录AGENTS.md放子模块规则。长期维护,控制行数。
