AGENTS.md:给 AI 写一份项目说明书

问题
你有没有这种经历:每次让 AI 帮你写代码,它都用错缩进、选错框架、命名风格跟你项目格格不入?你纠正一次,下次对话它又忘了。
很多时候,问题只是 AI 没拿到项目上下文。它不知道你用 4 空格还是 Tab,不知道 commit message 用中文还是英文,也不知道测试跑在 Jest 还是 Vitest 上。
AGENTS.md 就是解决这个问题的。
它是什么
AGENTS.md 是放在项目根目录的 Markdown 文件。支持它的 AI 编码助手会在开始工作前读取它,并把里面的内容当作项目规则。
可以把它当作写给 AI 的 README:README 面向人,AGENTS.md 面向助手。
它正在成为跨工具通用的约定。不同工具也可能使用别的文件名,例如 Cursor 的 .cursorrules、Claude Code 的 CLAUDE.md。
里面写什么
它没有固定模板,通常会写这些内容:
项目概述:一两句话说清楚这是什么项目、用什么技术栈。
编码规范:缩进、命名、文件组织、import 顺序。你团队 code review 时反复提的那些东西。
工作流约定:分支策略、commit message 格式、PR 描述模板、测试要求。
架构边界:哪些模块不能动、哪些目录放什么、依赖方向是什么。
禁止事项:不要用的库、不要碰的文件、不要引入的模式。
常用命令:怎么跑测试、怎么构建、怎么部署。
一个真实例子
# AGENTS.md
## 项目概述
这是一个 Astro 5 静态博客,部署在 Cloudflare Pages。
纯静态输出,不使用任何客户端 JS 框架。
## 编码规范
- 使用 2 空格缩进
- 组件用 PascalCase,文件名用 kebab-case
- CSS 写在 .astro 文件的 <style> 标签里,不单独建文件
- 不使用 Tailwind,不使用 CSS-in-JS
## 内容规范
- 博文放在 src/content/blog/,格式为 Markdown
- frontmatter 必须包含 title、date(ISO 8601 带时间)、description
- 中英文之间加空格
## 工作流
- 每篇文章写完后执行 astro build 验证
- 部署命令:wrangler pages deploy dist --project-name ohmyself-blog
- commit message 用英文,格式:type: description
## 禁止
- 不要引入 React/Vue/Svelte 等客户端框架
- 不要使用 localStorage 或任何浏览器存储 API
- 不要修改 public/ 下已有的图片文件
内容不用复杂。助手读到这份文件后,就能按这些规则工作。
怎么写好它
几条经验:
写规则,不写教程。 不用解释什么是 Git,直接写“commit message 用 conventional commits 格式”。
写例外,不写常识。 “请使用 linter”没必要反复写;如果项目禁用了某条规则,就该写出来。
写约束,不写偏好。 “不要用 any 类型”是约束。“我觉得 TypeScript 比 JavaScript 好”不是。
保持更新。 项目演进后,AGENTS.md 也要跟着改。过时的规则反而容易把助手带偏。
尽量短。 规则太长,真正重要的约束更容易被埋住。
和 README 的区别
README 面向开发者,通常介绍项目和参与方式。AGENTS.md 面向 AI,重点是可执行的约束。
README 可以有历史背景、设计理念、感谢名单。AGENTS.md 只要可执行的规则。
两者可以共存。AGENTS.md 开头可以写“项目介绍见 README.md”,后面只列规则。
进阶用法
分层放置。 根目录放全局规则,子目录放局部规则。比如 src/api/AGENTS.md 里写 API 层的特殊约定,AI 进入那个目录时会同时读取两份。
配合 CI 检查。 把 AGENTS.md 里的规则同步到 ESLint/Prettier 配置里。AI 遵守规则,CI 验证规则,双保险。
版本控制。 AGENTS.md 应该进 Git。它和代码一样是项目的一部分,改动应该有 review。
最后
AGENTS.md 的作用,是把那些平时默认、却没写下来的项目规则放到明面上。
先写一份基础版。以后需要补充,就在遇到同类问题时加一条。
如果你已经在用 AI 编码工具,可以从一个十来行的 AGENTS.md 开始。