news 2026/10/21 2:31:46

AGENTS.md 深度解析:给 AI 一份入职手册,让它在你的仓库里少犯错

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
AGENTS.md 深度解析:给 AI 一份入职手册,让它在你的仓库里少犯错

这是「近五年 AI 技术演进」系列深挖的第十篇。上一篇 Skill 解决的是「这一类活按什么方法做」;这一篇解决下一层,也是最后一块拼图:在这个仓库里,具体该守什么规矩。一句话定位:仓库级的项目规则文件,写给 AI 看的 README。全文约 4600 字,含一份 100 行、可直接复制使用的 AGENTS.md 模板,一张三文档对比表和四张原创信息图。

一、AI 很会写代码,但它不知道你们这儿的规矩

先说三个我自己踩过的。

场景一,包管理器。新同事入职第一天会问「装依赖用啥」,你答 pnpm。AI 不问。它看到package.json就默认npm install,于是仓库里多出一个package-lock.json,node_modules被重装了一遍,workspace 的软链断了,另外两个包立刻开始报「找不到模块」。你花了四十分钟才定位到根因是「多了一个锁文件」。

场景二,测试命令。你让它加一个优惠券校验,它写完很自信地说「已添加,运行npm test验证」。你们真正的命令是pnpm test:unit --run,而且得先pnpm dev:db把容器起起来。于是你说「用 pnpm」,它重跑,报环境变量缺失,你再补一句「先起数据库」。三轮对话、四分钟,只为了让 AI 跑对一条你天天在敲的命令。这件事每周发生五次。

场景三,好心办坏事。你让它「把订单状态字段改个名」,它很认真地改了 14 个文件,其中 3 个在packages/shared/dist/里——那是构建产物。合并、CI 构建,产物被覆盖,改动全没了,但它在 PR 里写的是「已完成」。还有更隐蔽的一种:它把.env.example里的示例密钥改成了「更规范」的占位符写法,你本地调试了一下午才发现连不上数据库。

三个场景,同一个病灶:它不是能力不足,是信息缺失。

你脑子里那些「我们这儿一直这么干」——目录怎么分、测试怎么跑、哪些文件是自动生成的、提交信息什么格式——从来没有写在任何它能读到的地方。它每一次都从一个干净的、对你们项目一无所知的房间里开始干活。

大多数团队用三种办法应付,三种都会失败。

第一种,每次在 prompt 里补一句。短期有效,长期必然漂移。同一套交代,今天说三句,明天说五句,后天忘了说「不要动 dist」。而且它只存在于你个人的输入框里,同事用不上。

第二种,写进工具的全局个人规则。这比第一种好,但会跨项目污染:A 项目用 pnpm、B 项目用 uv、C 项目是 Gradle,全局规则里只能写最模糊的那句「请遵循项目现有的技术选型」——等于没写。

第三种,靠 code review 兜。这是最贵的一种。错误已经发生,你要先读 diff 才能发现,而 review 的人也会累。

问题的根子在于,我们把「AI 需要知道的事」当成了一种东西,其实它至少分三层:

知识的类型长什么样该放在哪
这类活怎么做审合同的五步、写周报的口径Skill
这个项目怎么运转目录、命令、禁区、提交格式AGENTS.md
这一次要什么「加个优惠券校验」Prompt

第一层和第三层都有人管,中间那层长期是空白的。AGENTS.md 填的就是这个空。

二、它的本质:一份放在根目录的入职手册

2025 年 8 月,OpenAI 随 Codex 推出 AGENTS.md;9 月,Anthropic 的 Claude Code 跟进兼容;12 月,它被捐入 Linux 基金会下的 AAIF(Agentic AI Foundation);到2026 年 3 月,GitHub 上已有约6 万个仓库放了这份文件。

八个月,从一家公司的内部约定变成跨工具的事实标准。原因不复杂:它的实现成本几乎是零——就是一个文件名。任何工具只要在启动时读一下仓库根目录的同名文件,就兼容了。没有 SDK,没有 schema,没有版本号,没有鉴权。

我更喜欢这个说法:AGENTS.md 是一份入职手册,不是一张工位说明。

新员工第一天到岗,你不会给他讲三小时公司历史,你会递给他一页纸:厕所在哪、代码提交给谁审、周五几点下班、哪台机器不能碰。这一页纸不体现他的专业能力,但决定了他前两周会不会把事搞砸。

AGENTS.md 就是这一页纸。它回答的不是「怎么写好代码」,而是「在我们这儿,代码该往哪儿放、跑起来要敲什么、什么东西碰了会出事」。

这个类比能解释很多细节。为什么它要短?因为入职手册没人读第二遍。为什么它要用祈使句?因为手册是命令,不是散文。为什么它必须写「不要做什么」?因为新人最常犯的错不是不会做,是在不该动的地方动了手。

这里有个关键机制值得单独说:确定性读取。

你在知识库里放一份《项目规范》,AI 未必读得到——检索是概率性的,这次召回,下次可能不召回。AGENTS.md 不是检索,是文件存在就一定被读。它和工具启动绑定,和你今天问什么无关。这个差别看着小,工程上很大:RAG 的失败是静默的(没召回,模型就用常识编),AGENTS.md 的失败是可见的(文件不存在、写错了,当场就能发现)。

第二个关键机制是版本化。它是仓库里的一个文件,所以改规则要走 PR。谁在什么时候、因为什么加了这条,都留得下痕迹。「项目规矩」第一次变成了一件可以 code review 的资产——在此之前,它只存在于老员工的脑子里和聊天记录里。

三、它该写什么:八个板块,一份能直接抄的模板

下面这份模板来自一个真实的混合仓库:微信小程序 + Node BFF + Python 推理服务,pnpm workspace 管前端和 Node,uv 管 Python。你把它换成自己的目录名和命令,今天就能用。

# AGENTS.md ## 1 这是什么 旅拍小程序的服务端仓库。用户上传照片,服务端做人像分割与风格迁移,返回九宫格素材。 monorepo:Node BFF 负责业务与鉴权,Python 服务负责推理。线上跑在微信云托管,2 核 4G。 技术栈:TypeScript 5.6 / Node 22 / Fastify / pnpm 9 workspace / Python 3.12 / FastAPI / uv / PostgreSQL 15 / Redis 7 / Vitest / Pytest / Biome ## 2 目录结构 | 路径 | 放什么 | | --- | --- | | `apps/miniapp` | 小程序前端(Taro + React) | | `apps/bff` | Node BFF,唯一对外 HTTP 入口 | | `services/infer` | Python 推理服务,只被 bff 调用,不对外暴露 | | `packages/shared` | 前后端共享的 TS 类型与常量 | | `packages/ui` | 小程序通用组件 | | `infra/` | 云托管配置、Dockerfile、SQL 迁移 | | `docs/adr` | 架构决策记录,改架构前先读最近三篇 | **生成物,不要手改:** `packages/shared/dist`、`apps/miniapp/src/generated`、 `services/infer/openapi.json`(由脚本从 FastAPI 导出) 新代码落点:业务逻辑进 `apps/bff/src/modules/<domain>/`,一个 domain 一个目录, 内含 `route.ts` / `service.ts` / `repo.ts`。只有跨 domain 复用时,才允许提到 `packages/`。 ## 3 常用命令 包管理器是 **pnpm**,不要用 npm 或 yarn 装依赖——会生成 `package-lock.json`,破坏 workspace 软链。 ```bash pnpm install # 安装依赖 pnpm dev # 起全栈(需 Docker,会拉起 Postgres 与 Redis) pnpm dev:bff # 只起 BFF pnpm typecheck # 全仓类型检查 pnpm lint:fix # Biome 格式化 + 修复(本仓库不用 ESLint / Prettier) pnpm test # 全量单测(Vitest) pnpm test apps/bff/src/modules/order # 只跑一个目录,写完代码优先用这个 pnpm build # 构建 pnpm db:migrate # 迁移,先确认 .env 指向本地库 cd services/infer && uv sync && uv run pytest # Python 服务与测试 ``` **提交前必跑:** `pnpm lint:fix && pnpm typecheck && pnpm test` ## 4 代码规范 - TypeScript `strict` 已开启,禁止 `any`。确实要逃逸用 `unknown` + 类型守卫,并在行尾标 `// FIXME(type)` - 导入顺序:Node 内置 → 第三方 → `@/` 别名 → 相对路径,组间空一行(Biome 自动排,不要手调) - 业务错误抛 `AppError`(`apps/bff/src/lib/errors.ts`),不要 `throw new Error("xxx")` - 日志用 `logger.info({ ... }, "msg")`,禁止 `console.log` - 时间一律 UTC 存储,展示层再转时区 - 金额一律用整数「分」,禁止浮点 ## 5 测试要求 - 改了 `apps/bff/src/modules/**` 的逻辑:必须补或改对应 `*.test.ts`,覆盖成功路径 + 至少一个失败路径 - 改了 `packages/shared` 的类型:跑 `pnpm typecheck`,全仓不得新增报错 - 改了数据库 schema:必须新增 `infra/migrations` 下的迁移文件,**不许修改历史迁移** - 只改文案或样式:可以不补测试,但必须跑 `pnpm lint` ## 6 禁止事项 - **不要编辑任何生成物**(见第 2 节)。要改生成逻辑,改脚本再重跑。 原因:构建时会被覆盖,改动会静默丢失。 - **不要提交 `.env`、`*.pem`、证书**。本地配置写 `.env.local`(已在 `.gitignore`)。 原因:仓库是公开的,泄露一次就要全量轮换密钥。 - **不要升级依赖大版本**。要升先开 issue 说明原因,并作为独立 PR 提交。 原因:大版本升级常带破坏性变更,混在业务 PR 里无法回滚。 - **不要引入 `lodash` / `moment` / `axios`**。仓库已有 `remeda`、`date-fns`、原生 `fetch`。 原因:同一功能三套实现,bundle 会持续变大。 - **不要调整 `apps/miniapp/src/app.config.ts` 里 pages 的顺序**,它决定小程序启动页。 - **不要直接改 `infra/` 下的云托管配置**,改完必须找 @许涛 review。 - **不要跨层调用**:`route.ts` 不能直接访问数据库,必须经 `service.ts`。 原因:repo 层承担了租户隔离,绕过它等于绕过权限。 > 每条后面的「原因」不要删。原因决定了这条规则在什么情况下该被绕过—— > 只给结论不给原因,模型遇到边界情况会自作聪明地犯规。 ## 7 提交与 PR 提交信息用 Conventional Commits:`type(scope): subject` - `type` ∈ `feat` `fix` `refactor` `perf` `test` `docs` `chore` `build` - `scope` 用目录名:`bff` / `infer` / `miniapp` / `shared` / `infra` - 示例:`fix(bff): 订单超时未释放库存` 分支命名:`feat/<issue-id>-<短描述>`,不要直接推 `main`。 PR 描述必须包含三段:改了什么(一句话)、为什么改(关联 issue)、怎么验证的(贴命令或截图)。 ## 8 特殊上下文 - `services/infer` 里的人脸对齐还是去年那版硬编码关键点,已知侧脸会漂。 **不要在这个版本上做优化**,Q4 会换模型。 - `apps/bff` 有两套鉴权中间件:`middleware/auth.ts` 是新版,`auth-legacy.ts` 只服务三个老接口,别删。 - `packages/shared` 的生成脚本依赖 `openapi.json`,顺序错了会生成空类型。 正确顺序:`pnpm gen:openapi && pnpm gen:types`。 - 已知坑:本地 Postgres 15 的时区默认是 UTC+8,和线上不一致,写时间相关测试要显式指定时区。

这份文件一百行出头。它没有一句「请写高质量的代码」,但每一条都能被检查、被执行。

有三个地方最容易写错,值得单独说。

第一,目录结构不标生成物,等于没写。上面第 2 节末尾那三个路径,是整份文件里性价比最高的十几个字。你不写,AI 就会把dist/当成源码认真修改——因为它看起来就是一堆正常的.js文件。

第二,命令要区分「全量」和「单个」。大多数人只写了pnpm test,但 AI 真正需要的是「只跑我刚改的这个模块」——全量测试要跑四分钟,它等不起,于是干脆不跑。给一条能秒回的命令,它才会真的去验证。

第三,禁止事项必须带原因。只写「不要用 axios」,模型在遇到一个 axios 明显更合适的场景时会绕过去,或者给你写一段自己实现的请求封装。写了「仓库已有原生 fetch,同一功能三套实现会让 bundle 持续变大」,它就能自己判断边界。

四、为什么「命令」和「禁止事项」最值钱

八个板块里,这两块的收益占了大部分。原因完全不同。

命令解决的是「猜测」,禁止解决的是「越界」。

先说命令。一条真实的命令,消掉的不只是一次猜测,而是一整串连锁反应:猜错 → 报错 → 你纠正 → 它重试 → 环境不对 → 你再纠正。这个循环平均两到四轮,每轮十几秒到一分钟。命令是文件里唯一「不需要模型理解、照着执行就对了」的部分——它不占认知带宽,没有解释空间,也没有理解偏差。

命令还顺手解决了另一个更隐蔽的问题:验证闭环。AI 能不能自己判断「我改对了」,取决于它有没有一个能跑的验收动作。没有命令,它只能靠读代码自证;有了pnpm test,它可以自己跑、自己看失败、自己改。这一个能力差异,比任何提示词技巧都更能提高一次通过率。

再说禁止。这里要先理解一个前提:模型的默认行为是「尽力满足你的请求」,不是「保护你的仓库」。你说「把状态字段改个名」,它的目标是改名成功,不是「改名过程中不要碰到不该碰的东西」。它没有恶意,它只是没有「你的仓库有边界」这个概念。

所以禁止事项要把边界画出来。我把它归成三类,覆盖了九成事故:

类型典型条目不写的后果
生成物dist/、*.generated.ts、openapi.json改动在下次构建时静默消失
密钥与配置.env、证书、CI 变量、云平台配置泄露,或把线上配置改坏
依赖与全局状态大版本升级、新增同类库、全局单例、数据库 schema破坏性变更混进业务 PR,难以回滚

一条好的禁止事项有三个要素:范围(哪些路径或包)、原因(为什么不能碰)、替代方案(要达成目的该改哪里)。三样缺一样,它就会在边界情况上犯错。

还有个反直觉的经验:写得越具体,模型越愿意遵守;写得越抽象,越容易被忽略。「注意数据安全」这六个字,模型读完没有任何行为变化;「不要提交.env,本地配置写.env.local」,它每次都会照做。抽象规则需要判断力,具体规则只需要记性——而记性这件事,写进文件就解决了。

五、AGENTS.md、README、CLAUDE.md 到底什么关系

这三个文件经常被混为一谈,实际分工很清楚。

README.mdAGENTS.mdCLAUDE.md
读者人:新人、用户、评估者所有支持该约定的 AI 工具Claude Code(工具专属入口)
回答什么这是个什么项目,为什么值得用在这个仓库里该怎么干活与 AGENTS.md 同义
典型内容功能、截图、快速开始、架构图命令、结构、禁区、规范、PR 流程一行 import,或工具专属设置
语气介绍性、说服性祈使句、命令式同 AGENTS.md
长度不限,可以很长100~200 行,一屏读完尽量不超过 50 行
写错的代价没人读完被严格且一致地执行错与 AGENTS.md 分叉,互相矛盾

三个结论。

第一,它们不是三选一。同一个仓库根目录可以同时放着 README 和 AGENTS.md。前者写给还没进来的人,后者写给已经在干活的人——读者不同,内容就不该一样。把 README 复制一份改名叫 AGENTS.md,是这事最常见的失败姿势:README 里那些「为什么选择我们」的段落,对 AI 来说是纯噪声。

第二,CLAUDE.md 是同一份约定的另一个入口。Claude Code 优先读CLAUDE.md,而其他工具读AGENTS.md。正确做法不是写两份,而是让CLAUDE.md只放一行引用,指向AGENTS.md。两份各写一遍的结局一定是分叉:你改了命令,忘了改另一份,然后两个工具开始给出不同的行为。

第三,入口正在收敛。.cursor/rules/、.github/copilot-instructions.md、GEMINI.md,这些名字背后是同一件事。AGENTS.md 之所以能在八个月里覆盖六万个仓库,就是因为它提供了那个公约数:一个文件名,一份 Markdown,零实现成本。

六、写法上的五条纪律

第一,短而具体。目标是一屏读完,200 行以内。超过两屏,模型会开始漏读中间部分——这和长上下文里的「中间遗忘」是同一个现象。AGENTS.md 的价值和长度不成正比,六万个仓库里绝大多数都不到 100 行。

第二,用祈使句。写「用 pnpm 安装依赖」,不写「我们一般会使用 pnpm 来安装依赖」。手册是命令,不是散文;每多一个「一般」「通常」「建议」,就多一个可以商量的余地。

第三,放真实命令,不放描述。写`pnpm test --run`,不写「运行测试套件」。前者可以复制粘贴直接执行,后者需要模型自己翻译成命令——而翻译就会出错。

第四,每条规则要可判定。判断标准只有一句:能不能写个脚本,一跑就知道过没过。「提交信息用 Conventional Commits」可判定;「提交信息要清晰」不可判定,后者不该出现在这里。

第五,随项目演进而更新。改了构建流程、加了新目录,就在同一个 PR 里顺手改它。一条已经不成立的规则,比没有规则更糟——它会带着 AI 稳定地走错。

还有三样东西不要写:公司的愿景与价值观、README 里的营销段落、「代码要优雅、注释要清晰」这类愿望。这些内容占篇幅,改不了任何一次具体决策。

最后补一个结构技巧:monorepo 用嵌套 AGENTS.md。根目录放通用的,services/infer/AGENTS.md放 Python 服务专属的(比如「本目录用 uv,不要用 pip」)。工具读取时遵循就近原则,子目录的规则覆盖根目录的。这样根目录那份能一直保持精简。

七、为什么加了它,一次通过率会明显提高

这不是玄学,有三个具体机制。

第一,砍掉探索回合。AI 干活前要先摸清环境:依赖装了吗、测试怎么跑、这个函数被谁调用。每摸一次就是一轮工具调用。AGENTS.md 把这些前置信息一次给全,省下的不是 token,是**「猜错—报错—重试」的循环**。一次任务从八轮降到三轮,体感上就是「它好像变聪明了」。

第二,压缩选择空间。模型每一步都在做选择:这个文件放哪、这个库用不用、这个函数叫什么。选项越多,选错的概率越高。约定做的事就是把选项砍掉——只剩一个答案的时候,不存在选错。这也解释了为什么「目录结构」那一节的效果常被低估:它决定的不是代码长什么样,而是模型在哪儿落脚。

第三,统一验收标准。有 AGENTS.md 之前,「完成」的定义是「代码写完了」;之后,「完成」的定义是「lint+typecheck+test都过了」。这是从「看起来对」到「可验证对」的转变,也是从「AI 说它做完了」到「AI 证明它做完了」的转变。

但也得说清它解决不了什么,否则会误判。

它不能让需求变清楚。需求本身有歧义时,AGENTS.md 只会让它更自信地做错事——因为它现在有了明确的规矩可以遵守,错得更整齐。

它不能替代架构判断。「这个服务该不该拆」「这个状态该放前端还是后端」,这类问题没有标准答案,写进规则只会变成教条。

它不能容忍错规则。这是最危险的一种:一条写错的命令、一条过期的禁令,会被严格且一致地执行。没有 AGENTS.md 的时候,AI 犯的是随机的错;有了一份写错的文件,它犯的是稳定的错。所以「删掉过期的」比「补上新的」更重要。

一句话概括:它降低方差,不提高上限。它让平庸的那几次变得可靠,但不会让最好的一次变得更好。

八、怎么开始:先写两节,二十行

不用一次写全。第一版只写两节:常用命令和禁止事项。

# AGENTS.md ## 常用命令 包管理器是 pnpm,不要用 npm / yarn 装依赖。 `pnpm install` 装依赖 `pnpm dev` 起本地全栈 `pnpm test` 跑全量单测 `pnpm lint:fix` 格式化 `pnpm typecheck` 类型检查 提交前必跑:`pnpm lint:fix && pnpm typecheck && pnpm test` ## 禁止事项 - 不要编辑 `dist/`、`src/generated/`,它们是构建产物,改动会被覆盖 - 不要提交 `.env`,本地配置写 `.env.local` - 不要升级依赖大版本,需要升就单独开 PR

十三行。写完你会发现,下一次 AI 干活的时候,它不再问你「用什么装依赖」,也不再改dist里的文件。

然后让它自己长。每犯一次「约定类」错误,就补一行。这里有个判断要先做:

这是能力问题,还是约定问题?

能力问题(不会写某类算法、读不懂某个协议)换模型、换工具、拆任务。约定问题才写进 AGENTS.md。搞混了会得到一个越来越长、却越来越没用的文件——那本质上是把「模型不够强」写成了「规则不够多」。

最后是维护。一个月回头看一次,问三个问题:哪条已经过时了?哪条从来没被违反过(说明它没用)?哪条被违反了好几次(说明写得不清楚)?它和代码一样,是有维护成本的资产,不是一次性文档。

九、写在最后

把这条演进线拉直,会看到一件挺有意思的事:

  • Tool / Function Calling(2023)解决了「AI 能不能动手」;
  • MCP(2024)解决了「工具怎么标准化接进来」;
  • A2A(2025)解决了「Agent 之间怎么协作」;
  • Skill(2025)解决了「这一类活按什么方法做」;
  • AGENTS.md(2025)解决了最后一件、也最琐碎的一件事:「在我们这个仓库里,具体该守什么规矩」。

前四层都在解决「AI 会不会干活」,第五层解决的是「它在你这儿该怎么干活」。

而它有个特殊之处:这是整条线上唯一一个不需要写代码的环节。不用 SDK,不用协议,不用起服务。门槛低到只需要一个 Markdown 文件、二十分钟,回报却直接体现在「它今天少问了我两个问题」上。

所以我的建议不是「去研究 AGENTS.md 的规范」。规范只有一页,五分钟就能读完。

建议是:今晚花二十分钟,打开你最常让 AI 改的那个仓库,写两节——命令,和禁区。

写完别急着补全。等它下一次犯错,你再补那第三行。它会长成你们团队自己的样子,而不是任何模板的样子。

参考资料:OpenAI Codex 文档(AGENTS.md 约定,2025-08)、Anthropic Claude Code 文档(内存与 CLAUDE.md)、AGENTS.md 开源规范仓库(agents.md)、Linux 基金会 AAIF 公告(2025-12)。文中仓库数量为 2026 年 3 月的公开统计口径,会随时间变化。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/21 2:30:44

AI落地的替代悖论:裁员预期如何摧毁AI最需要的经验供给

【摘要】埃森哲《2026中国企业数字化转型指数》覆盖七个行业160余家中国企业&#xff0c;数据显示生成式AI规模化应用占比从2025年的46%升至2026年的88%&#xff0c;但实现显著业务成果的企业仅从9%升至14%&#xff0c;仅34%完成配套组织架构重构。围绕AI落地的核心替代悖论&am…

作者头像 李华
网站建设 2026/10/21 2:30:33

正气为本:防性病复发的根本之道

摘要 摘要&#xff1a;外邪能否致病&#xff0c;关键不在是否接触病原&#xff0c;而在正气是否充盈、卫气是否固密。本文以《黄帝内经》“正气存内&#xff0c;邪不可干”为纲&#xff0c;论证阴毒类疾患的本质是邪乘虚入&#xff0c;西药虽能祛邪却难固本&#xff0c;防病防…

作者头像 李华
网站建设 2026/10/21 2:30:25

【Linux】文件系统(一)

目录 磁盘的理解 存储结构 相关概念 CHS和LAB CHS LAB 公式转换 文件系统 初步 ”块“的概念 “分区” iNode 块组内部 Super Block&#xff08;超级块&#xff09; GDT&#xff08;Group Descriptor Table&#xff09; Block Bitmap&#xff08;块位图&#x…

作者头像 李华
网站建设 2026/10/21 2:30:10

冒泡排序从入门到精通:优化、递归与实战避坑指南

排序算法是每个学编程的人绕不开的第一道坎&#xff0c;而冒泡排序几乎毫无例外地成为这门课的起点。很多人对它的印象停留在"两个for循环、交换相邻元素、考试要背"这个层面&#xff0c;写完交作业就再也没碰过。但真正把冒泡排序吃透的人会发现&#xff0c;它其实是…

作者头像 李华