
1. 为什么“聊完就忘”的AI助手需要一份AGENTS.md用AI编程助手写代码这件事很多人已经跑通了单点提效让它补个函数、写个单测、解释一段遗留代码效果都不错。但真正把AI助手放进一个持续迭代的项目里问题就暴露了——它没有记忆也没有规矩。今天你告诉它“这个项目用四空格缩进、错误码统一走Result封装、数据库迁移必须走migration脚本”明天新开一个会话它照样按自己的默认习惯给你生成一堆风格不一致的代码。你反复纠正它反复遗忘最后你发现与其说是在用AI提效不如说是在给AI当保姆。这个问题的本质不是模型能力不够而是项目治理信息没有持久化。人类新成员入职靠的是README、编码规范文档、架构决策记录ADR、CI配置这些东西来对齐上下文。AI助手同样需要一份它能稳定读取、且每次会话都会自动加载的“项目宪法”。AGENTS.md就是干这个的——它放在项目根目录用自然语言描述这个项目的技术栈、目录约定、编码规范、禁止事项、常用命令AI助手在每次会话开始时读取它从而获得跨会话的持久记忆。但光有一份静态的AGENTS.md还不够。项目是活的规范会变模块会增删依赖会升级。如果AGENTS.md本身没人维护它很快就会变成一份过时的、误导AI的文档。所以真正要解决的问题是如何为AI编程助手构建一套持久化的项目治理框架让治理信息既能被AI稳定消费又能在项目演进中保持同步和一致。这套框架的核心是把“项目状态”和“状态迁移规则”显式建模出来——也就是引入状态机的思路。状态机在这里不是Java里那种State模式的具体实现而是一种思维方式项目当前处于什么阶段、允许哪些操作、操作后迁移到什么状态全部写清楚AI才能在这个约束空间里安全地干活。这篇文章适合三类人看一是已经在项目里用AI助手、但被“上下文丢失”折磨过的开发者二是团队里负责工程规范、想让AI产出更可控的技术负责人三是对AI Native研发范式感兴趣、想搞清楚“治理”这件事在AI时代怎么落地的人。我会从AGENTS.md的实际写法讲起拆解状态机如何嵌入治理框架再给出可复现的落地步骤和踩坑经验。全程不聊虚的都是能直接抄的配置和思路。2. AGENTS.md到底该写什么从“给AI看的README”到可执行约束2.1 AGENTS.md和README的本质区别很多人第一反应是我项目已经有README了AI读README不就行了实测下来不行原因有两个。第一README是写给人类看的它默认读者有常识、能脑补、会自己查文档AI助手没有这些默认能力它需要的是显式、无歧义、可执行的指令。第二README讲的是“这个项目是什么”而AGENTS.md要讲的是“你在这个项目里应该怎么干活”——前者是描述性的后者是规范性的。举个具体例子。README里可能写“本项目使用PostgreSQL作为主数据库”。这句话对人类够了但对AI不够。AI需要知道的是连接配置放在哪个文件、迁移脚本用什么工具生成、查询层是否允许直接写原生SQL、测试环境用不用真实数据库。这些信息不写清楚AI就会按它训练数据里最常见的做法来结果和你项目的实际约定冲突。所以AGENTS.md的定位是一份面向AI助手的、可执行的工程约束清单。它不追求文采追求的是“AI读完就知道边界在哪”。2.2 一份可落地的AGENTS.md结构模板下面这份结构是我在多个项目里迭代出来的直接给模板你可以按自己项目裁剪# AGENTS.md ## 项目概览 - 技术栈TypeScript 5.x Node 20 Fastify PostgreSQL 15 - 包管理器pnpm禁止使用npm/yarn - 代码风格ESLint Prettier提交前必须通过lint ## 目录约定 - src/domain领域模型禁止引入任何框架依赖 - src/infra基础设施数据库、外部服务适配器 - src/apiHTTP层只做参数校验和编排 - tests/测试文件与被测文件同目录命名 *.test.ts ## 编码规范 - 所有导出函数必须有显式返回类型 - 错误处理统一使用 ResultT, E 类型禁止抛裸异常 - 禁止使用 any必要时用 unknown 类型守卫 - 异步操作必须处理 rejection禁止 floating promise ## 常用命令 - 安装依赖pnpm install - 跑测试pnpm test - 类型检查pnpm typecheck - 生成迁移pnpm migrate:generate --name name ## 禁止事项 - 禁止修改 package.json 的 dependencies 而不更新 lockfile - 禁止在 domain 层引入 infra 层代码 - 禁止提交 console.log用 logger 替代 - 禁止绕过 CI 直接 push 到 main ## 当前项目状态 - 阶段v1.2 开发中 - 冻结模块auth重构中暂不接受新功能 - 活跃模块billing、notification这份模板的关键在于最后两节——“禁止事项”和“当前项目状态”。前者是硬约束后者是动态上下文。很多AGENTS.md只写了前面那些静态规范结果AI在重构期间还往冻结模块里加功能这就是缺少状态信息导致的。2.3 让AI真正“读到”AGENTS.md的几种接入方式写完文件只是第一步关键是让AI助手在每次会话里都能加载它。不同工具的接入方式不一样我按常见几类说支持项目级配置的助手直接在项目根目录放AGENTS.md工具启动时自动读取。这是最省事的前提是你用的工具认这个约定。需要显式引用的助手在会话开头用一条固定提示词把文件内容喂进去比如“请先阅读项目根目录的AGENTS.md后续所有操作都遵守其中约定”。可以把这个提示词存成片段每次粘贴。本地部署的编程助手如果你用的是本地跑的模型比如通过llama.cpp这类方案可以把AGENTS.md的内容拼进系统提示词里做成一个固定的system prompt模板这样每次会话自动带上。注意不管用哪种方式都要验证AI是否真的读进去了。最简单的验证方法是故意在AGENTS.md里写一条反直觉的约定比如“本项目所有变量命名用下划线风格”然后让AI写个函数看它是否遵守。不遵守就说明加载链路有问题。2.4 静态文档的天花板在哪里AGENTS.md解决了“规范持久化”但它解决不了“状态一致性”。举个例子项目从v1.1升到v1.2某个模块从活跃变成冻结某个依赖从允许变成禁止。这些变化如果只靠人手动改AGENTS.md迟早会漏。更麻烦的是AI助手可能同时面对多个信息源——AGENTS.md说一套CI配置说一套实际代码又是另一套它该信谁这就是为什么光有AGENTS.md不够还需要一套机制来管理“项目当前处于什么状态、状态之间怎么迁移”。换句话说我们需要把状态机引入治理框架。3. 把状态机思维嵌进治理框架让AI知道“现在能做什么”3.1 状态机在这里不是代码模式是治理模型先澄清一个容易混淆的点。提到状态机很多人想到的是Java里的State模式、C#的stateless库、或者画一张状态机图。这些是实现层面的东西。而我在治理框架里说的状态机是建模层面的把项目或模块的生命周期抽象成有限个状态把允许的操作抽象成迁移边把迁移条件写清楚。它不需要你写一行状态机代码但它需要你把状态和迁移规则显式地写进治理文档里。为什么这个建模对AI助手特别重要因为AI的默认行为是“你让它干啥它就干啥”它不会主动判断“这个操作在当前阶段是否合适”。你让它给auth模块加个功能它就加了哪怕auth正在重构、处于冻结状态。状态机模型的作用就是给AI一个判断依据当前状态是frozen允许的操作只有read和bugfixfeature请求应该被拒绝并提示原因。3.2 用状态迁移表描述模块生命周期把状态机落到文档里最实用的形式是一张状态迁移表。以模块生命周期为例当前状态允许操作迁移到触发条件draft设计、评审review设计文档完成review评审、修改approved / draft评审通过 / 打回approved开发、测试active首个PR合并active开发、重构、修bugfrozen / deprecated进入重构 / 计划下线frozen只读、修bugactive / deprecated重构完成 / 决定下线deprecated只读-终态这张表放进AGENTS.md或者单独的GOVERNANCE.md里AI助手读到后就能在收到操作请求时先查表当前模块是什么状态这个操作在允许列表里吗不在就拒绝并说明。这比单纯写“auth模块重构中”要精确得多因为“重构中”是模糊的而“frozen状态只允许read和bugfix”是可判定的。3.3 状态信息从哪来手工维护还是自动同步状态迁移表最怕的是和实际不同步。我的经验是分两层状态定义手工维护状态值尽量自动同步。状态定义有哪些状态、允许哪些迁移变化频率低手工维护没问题。状态值某个模块当前处于哪个状态变化频率高最好从代码仓库的客观事实里推导。比如模块目录下有没有FROZEN标记文件模块的CODEOWNERS是否被清空最近N天该模块的提交是否只包含bugfix类型CI里该模块的测试是否被标记为skip这些信号可以用一个简单的脚本定期扫描生成一份STATE.mdAI助手读这个文件就知道当前状态。这样人只需要维护规则机器负责填值一致性有保障。3.4 状态机如何约束AI的“越界”行为有了状态模型接下来要在提示词层面把它变成AI的行为约束。核心思路是在AGENTS.md里明确写出“操作前先查状态”的流程。比如可以这样写## 操作前置检查 在执行任何代码修改前你必须 1. 确定目标模块 2. 查阅 STATE.md 中该模块的当前状态 3. 对照状态迁移表确认你的操作在当前状态下被允许 4. 如果不被允许停止操作并说明原因不要自行判断“应该没关系”这条规则看起来简单但它把AI从“执行者”变成了“先判断再执行”的agent。实测下来加了这条之后AI往冻结模块里乱加功能的概率大幅下降。当然它偶尔还是会漏所以还需要下一层的校验机制。4. 从文档到执行让治理框架真正跑起来的落地步骤4.1 第一步盘点项目里需要治理的维度不要一上来就写文档先盘点。一个项目需要治理的维度通常包括代码风格、目录结构、依赖管理、错误处理、测试策略、提交规范、分支策略、发布流程、模块生命周期。把这些列出来标注哪些是AI助手会直接影响的比如代码风格、错误处理哪些是间接影响的比如发布流程。优先治理直接影响的那几个因为AI最容易在这些地方越界。盘点的时候建议拉一个表格每个维度写清楚当前有没有明确约定约定写在哪AI是否知道我见过太多项目约定只存在于某个老员工的脑子里文档里没有AI更不可能知道。这种就是治理缺口。4.2 第二步写AGENTS.md并接入AI助手按第2节的模板写第一版AGENTS.md。写的时候有个原则宁可具体不要抽象。“代码要整洁”是废话“导出函数必须有显式返回类型”才是可执行的。写完接入AI助手用第2.3节的验证方法确认它真的读到了。这一步有个常见坑AGENTS.md写太长AI的上下文窗口被占满反而影响它处理实际任务。我的经验是控制在500到1500字之间把最关键的约束放前面。如果内容确实多拆成AGENTS.md核心约束 GOVERNANCE.md详细规范AGENTS.md里用一行指向后者让AI按需读取。4.3 第三步定义状态模型并生成STATE.md按第3节的思路定义状态和迁移规则写进GOVERNANCE.md。然后写一个扫描脚本从仓库客观事实推导各模块当前状态输出STATE.md。脚本可以用任何你顺手的语言写核心逻辑就是读文件标记、读git log、读CI配置然后按规则映射到状态。这个脚本建议挂到CI里每次合并到main就重新生成STATE.md并提交。这样状态值永远是新鲜的AI读到的就是当前真实状态。4.4 第四步在提示词里加入操作前置检查把第3.4节那段“操作前置检查”写进AGENTS.md。同时如果你用的AI助手支持自定义系统提示词把这段也放进去双保险。实测下来文档里写一遍、系统提示词里写一遍遵守率明显高于只写一遍。4.5 第五步建立反馈回路持续修正治理框架不是写完就完事。每次AI助手违反约定都要问是AGENTS.md没写清楚还是状态信息过时了还是提示词没生效把每次违规当成一次框架的bug来修。我一般会在项目里开一个governance-issues的标签专门记录这类问题每周过一遍。这个反馈回路是整套框架能持续运转的关键。没有它AGENTS.md三个月后就变成摆设。5. 实测中踩过的坑和几条硬核经验5.1 坑一AGENTS.md写成“愿望清单”AI无法执行最常见的错误是把AGENTS.md写成价值观宣言“代码要可维护”“架构要清晰”“测试要充分”。这些话对人类是激励对AI是噪音因为它不知道具体怎么做。修正方法很简单每写一条问自己“这条能不能转成一个可判定的检查”不能就删掉或改写。比如“测试要充分”改成“新增函数必须附带至少一个正常路径和一个异常路径的测试用例”。5.2 坑二状态信息手工维护一周后就失真我早期版本的状态信息是手工写在AGENTS.md里的结果项目一忙就忘了更新AI读到的还是两周前的状态。后来改成脚本自动生成STATE.md失真问题基本解决。这里的关键认知是凡是变化频率高的信息都不要指望人手工维护。让机器从客观事实推导人只维护推导规则。5.3 坑三多个信息源冲突AI无所适从项目里同时存在AGENTS.md、CI配置、ESLint配置、CODEOWNERS这些信息源如果互相矛盾AI会随机选一个信。比如AGENTS.md说用四空格缩进ESLint配置却是两空格AI就懵了。解决办法是指定单一事实来源在AGENTS.md里明确写“代码风格以.eslintrc为准本文档不重复定义”。让AI知道冲突时信谁。5.4 坑四把状态机写得太复杂AI理解不了状态机建模有个度。我见过有人把模块状态细分成十几个迁移条件写了几十条结果AI读完之后反而不知道怎么干活了。经验是状态数量控制在5到7个迁移条件用自然语言一句话说清。状态机的价值在于约束不在于完备。够用就行。5.5 一条被低估的经验让AI自己维护治理文档最后一个经验可能有点反直觉治理文档本身也可以让AI来维护。具体做法是在AGENTS.md里加一条规则“当你发现实际代码约定与本文档不一致时不要自行判断哪个对而是提出一个文档更新建议”。这样AI在干活过程中会顺手帮你发现文档和现实的偏差相当于一个免费的治理审计员。我用了这个做法之后AGENTS.md的过时问题明显减少。6. 框架的边界哪些事它管不了以及后续怎么扩展这套框架能解决的是“AI助手在项目里的行为一致性和状态感知”问题。但它管不了几件事得说清楚免得期望过高。第一它管不了AI的判断质量。框架能告诉AI“当前模块是frozen只能修bug”但修bug修得对不对还是取决于模型能力和你的review。框架降低的是低级错误和越界行为不是替代代码审查。第二它管不了跨项目的治理。如果你的组织有多个项目每个项目一份AGENTS.md维护成本会上升。这时候可以考虑抽一层组织级的治理模板各项目继承后再覆盖。但这属于进阶话题单项目跑顺了再考虑。第三它依赖AI助手愿意读文档。有些工具对项目级配置的支持不好或者模型本身对长上下文里的约束遵守率低。这种情况下框架的效果会打折扣。选工具的时候要把这一点纳入考量。后续扩展方向我个人比较看好两个。一是把状态迁移和CI门禁打通AI提交的PR如果违反了状态约束比如往frozen模块加了featureCI直接拒绝形成硬约束而不只是提示词约束。二是把治理框架和测试开发结合让AI在写测试时也遵守状态模型比如frozen模块的测试只允许增加回归用例不允许增加新功能用例。这两个方向都能让治理从“软约束”走向“硬约束”是这套框架真正成熟的标志。我在实际项目里跑这套框架大概半年最直观的感受是AI助手从“需要反复纠正的新人”变成了“知道规矩的熟手”。它还是会犯错但犯的是能力范围内的错而不是“明明告诉过它”的错。这个区别用过的人都懂。