AGENTS.md:为AI编码助手构建项目级记忆的声明式配置
1. 无状态模型的失效AI 协作中最容易被忽视的上下文断层1.1 一次典型的「AI 失忆」现场先说个我最近的真实经历。某天上午我对着一个后端项目连续调了三个小时的接口逻辑AI 编码助手全程在线从路由设计、鉴权中间件到数据库表结构聊得清清楚楚。中途我重构了一个核心模块的目录结构把services/order.go挪到了billing/order/service.go顺带改了包名。下午我重新打开一个新的对话窗口想让它帮我在订单模块里补一个批量导出接口。结果它张口就问「请提供订单模块的相关代码」还建议我在services/下新建文件。那一刻我就知道上午那几个小时的上下文在它重新启动的那一刻就已经归零了。这个场景几乎所有深度用过 AI 编码工具的人都不陌生。你给它分析了半天项目它似乎心领神会但只要换一个会话、换一台机器或者隔了一晚上它就像失忆了一样把你所有口头的约定、架构决策、编码习惯全忘得干干净净。很多人把这个归咎于「AI 还不够聪明」但我更倾向于换一个角度来看这是我们自己还没有建立一套「记忆工程」体系导致的。无状态模型本身不是缺陷它就是大语言模型的工作方式——每次调用都是一次独立的推理过去的信息只存在于对话上下文里。可问题是软件开发恰恰是一个强状态、强长期上下文的领域项目有历史包袱有架构决策记录有团队约定的代码风格这些都不是靠一轮对话能完整传递的。1.2 Token 窗口很大但「记忆感」依然很浅有人可能会反驳现在的 AI 编码助手动辄支持几十万、甚至上百万 token 的上下文窗口你把整个项目塞进去不就行了我试过效果差强人意。首先把整个代码库塞进上下文是不现实的大部分商业工具也有配额和性能限制检索和分析的延迟会明显上升。其次也是更本质的问题token 窗口再大也只是一个短期缓冲区而不是长期记忆。它像一块白板每次会话开始时都是干净的你可以往上写很多内容但下次会话开始时它又是空白的。哪怕窗口足够大AI 在窗口里「看到」的东西也未必是它该优先关注的——项目里最有价值的架构约束、踩坑记录、命名惯例往往淹没在大量无关的样板代码里。打个生活化的比方你请了一位临时助理来帮你处理一天的工作他记性极好当天交代的事一件不忘。但第二天换一位新助理来他连你公司的组织架构都不知道也不清楚你讨厌什么样的汇报格式。每次都要重新交代一遍哪怕你的旧助理昨天已经整理好了员工手册——但新助理没有读过它。所以真正的问题不是「窗口不够大」而是我们没有把项目的关键记忆沉淀成一个可被 AI 主动读取的载体。如果有一份文件每次 AI 启动新的工作上下文时都会自动加载里面清晰地写着这个项目的架构约定、命令规范、代码风格、需要规避的坑那「失忆」问题就能从根上缓解大半。1.3 范式转换从「每次口述」到「声明式配置」早期大家是怎么应对 AI 失忆的主流做法是攒一个超长私有提示词每次开新会话时手动粘贴进去甚至用各种方式把提示词做成系统级模板。我见过有的开发者把提示词写到几千字里面涵盖了项目概况、角色设定、输出要求、禁止事项写得比项目文档还复杂。这种做法在单机小项目上勉强能跑问题在于它完全依赖「人肉传输」。提示词存在个人笔记里、存聊天记录里团队成员之间各存一份版本稍微一变化几条上的约定就开始分裂。更麻烦的是这些提示词描述的东西往往已经从项目实际中漂移了——项目重构了三次提示词还停在最初的架构描述上。而从无状态模型到声明式配置解决的是两个层面的问题让记忆成为项目的一部分而不是对话的一部分。第一记忆文件放在仓库里进入项目的任何人都能读取和维护它跟代码一起走不依赖某个人的个人提示词第二AI 编码工具在启动时会主动加载这些文件不需要开发者每次手动拼接上下文。这就是标题里说的「范式转换」——把零散的对话约定转变成结构化的、可版本化的、随仓库分发的声明式配置。市面上已经开始出现类似的记忆文件约定比如有的工具约定某个命名规则的 Markdown 文件AGENTS.md、项目目录下的规则文件等等大家的目的都一样给 AI 一个有据可循的稳定记忆源。2. Memory 工程的核心逻辑记忆不能只靠对话2.1 记忆的分层逻辑在深入 AGENTS.md 之前我觉得有必要先把「记忆」这件事拆开看。工程里的记忆至少可以分三层记忆层级生命周期载体例子对话内记忆单次会话上下文窗口你刚才让它改了什么函数项目记忆项目生命周期仓库内文件构建命令、架构约束、代码规范团队记忆团队长期积累共享文档/模板团队对错误处理方式的共识无状态模型天然只支持第一层。我们做 Memory 工程要解决的就是把第二层、第三层的内容稳定地搬进 AI 的上下文窗口中。注意这里有个关键点不是把整个项目历史都喂给 AI那太离谱了。我们要做的是把项目的「关键约束」提炼成契约式的文本让 AI 每次开始工作时能通过一个低成本的方式读到这份契约而不是靠你重复复述。2.2 从「大提示词」到「项目记忆文件」的路径我最早维护的那套私有提示词后来经历了三个阶段的演变。第一阶段是纯口头约定。AI 用久了我发现它总是把错误处理写成fmt.Println加return而项目里要求的是统一错误包装。我每次都要在新会话里提醒一次烦不胜烦。第二阶段是笨拙的大提示词。我把所有约定集中到一份巨大的个人提示词里每次开新会话都粘贴效果确实有但问题也随之而来提示词里提到的目录已经不存在了、链接的规范文档已经超时了AI 照着过期的约定干活反而添乱。第三阶段才是真正的转折点我学着把记忆文件放进了项目仓库。仓库根目录多了一个大家都默认会读取的说明文件里面只写了三部分内容——项目怎么跑、代码规范是什么、有什么绝对不要做。AI 工具在项目目录下启动时绝大多数都会自动读取这份文件作为初始上下文。从那一刻起我对 AI 的「概率性失忆」基本告别了。这个路径本身很有代表性记忆必须实体化必须从大脑中搬到文件系统中才能被 AI 稳定访问。2.3 声明式配置为什么优于程序化指令这里再说一个容易被忽视的理念问题我们到底应该怎么给 AI 写规则在初期很多人习惯用命令式语气写约束比如「你必须先执行测试再执行构建」「遇到 X 问题时你必须先执行 A然后执行 B」。这种写法不是不行但维护成本非常高——一旦流程变化整段重写指令之间还容易互相冲突。声明式配置的思路不同你不告诉 AI 具体怎么一步步做你告诉它这个项目的状态和约束是什么。比如「测试命令为make test」「所有公共方法必须有注释」「禁止在服务层直接操作数据库」。剩下的是「怎么做、什么顺序做」AI 自然会在符合约束的前提下自己规划。用人话讲命令式是请了个只会照章办事的员工你离开就开始出问题声明式是请了个靠谱的工程师你告诉它边界和标准剩下的它自己发挥。前者遇到稍微复杂的场景就会卡壳后者在约束清晰的前提下能灵活处理大量的意外情况。AGENTS.md 这种声明式配置之所以能成为趋势核心就是因为它抓住了「约束比流程稳定」这个本质。3. AGENTS.md 的设计与结构一份能用的配置文件长什么样3.1 先看一个最简可用版本AGENTS.md 这个概念本质上就是给 AI 代理阅读的项目说明书。它在仓库里的形态是一个 Markdown 文件通常放在根目录也可以按子目录拆分。我拿一个真实的轻量项目举例这份文件是精简过的# AGENTS.md ## 项目概述 这是一个内部工单管理系统前端使用 React后端使用 Go。 代码仓库采用 monorepo 结构web/ 和 api/ 两个子目录分别管理前端与后端。 ## 技术栈与命令 - 后端服务cd api make run - 前端开发cd web npm run dev - 单元测试cd api make test - 接口文档api/docs/ 目录下修改接口后必须同步更新 ## 编码规范 - Go 代码遵循官方标准错误处理使用 errors.Wrap 包装并附加上下文。 - React 组件使用 TypeScript Hooks禁止使用类组件。 - 公共函数和导出组件必须写 JSDoc 注释。 - 数据库迁移脚本放在 api/migrations/新脚本命名格式日期_描述.sql。 ## 约束 - 不要在业务代码中直接使用 log.Printf 输出统一使用 pkg/logger。 - 不要修改 web/src/api 下的自动生成文件如有需要请先运行代码生成脚本再提交。 - 涉及环境变量时一律通过配置文件读取禁止硬编码。你没看错就是这么朴素。这份文件没有角色扮演没有夸张的设定更像是一份高度浓缩的「新成员入职手册」只不过读者不是人类而是 AI。它涵盖了项目概况、技术栈、命令、代码风格、约束五个维度约 20 多行。关键在于一旦把这个文件放到仓库根目录AI 工具在项目里启动新会话时就会自动把它作为初始上下文的一部分读取。你不需要在新会话里重复交代任何内容它自己就知道这个项目用什么语言、跑什么命令、遵守什么规范。3.2 每个核心字段的设计意图项目概述给 AI 一个全局视角。它不知道你在做电商还是做支付网关一份两句话的概述能让后续所有决策都建立在正确的前提下。这里要注意项目的业务定位一定要写清楚否则 AI 容易在不同模块之间瞎猜。技术栈与命令这是 AGENTS.md 里性价比最高的一部分。因为 AI 最大的不确定性之一就是「这个项目怎么运行」。你直接告诉它命令它就不用靠猜了。特别是测试命令务必写上AI 写完代码之后能自己验证对不对这是质量下限的保证。编码规范不需要罗列一堆教科书级的规范只写这个项目特有的、和通用做法不一样的地方。比如团队规定错误必须包装、某些目录不可动、格式工具用哪个这些才是真正能减少返工的信息。约束我认为这是 AGENTS.md 的核心价值所在。把项目里最容易出问题的几个「红线」明确写出来AI 在思考过程中会自动绕开这些坑。比如「自动生成文件不要手改」「环境变量不要硬编码」这些一旦出事就是大返工值得明确写进文件。还有两类内容我建议不要写进去一类是过于抽象的口号比如「代码要优雅」「保证高质量」AI 无法把这类话映射成具体行动另一类是过于漫长的背景故事比如项目的五年规划这些信息对 AI 做一次代码修改毫无帮助反而稀释了有效信号的密度。3.3 多文件组织从单文件到 AGENTS 目录单文件适合中小项目项目一旦复杂起来把所有内容塞进一个 README 式的 AGENTS.md 就会变得臃肿。现在主流的做法是分成一个入口文件加若干子文件入口 AGENTS.md 只保留最重要的三条约束和目录指引细节放到对应的子文件里。比如这样AGENTS.md # 主入口只写核心约束 AGENTS/ api-usage.md # 接口调用与错误处理约定 coding-style.md # 语言级风格规范 workflows.md # 测试、构建、发布流程 architecture.md # 模块关系与依赖方向入口文件的最后加一段指向子文件的说明比如「关于接口错误处理的详细约定见AGENTS/api-usage.md」。当 AI 在推理过程中遇到相关问题时可以自己判断是否需要去读那个子文件。这种多文件组织方式本质上是在给 AI 做一个分级加载的内存系统核心信息永远保持轻量细节按需加载跟操作系统的两级缓存有点像。对于代码量很大的老项目这个设计几乎是必需的否则 AGENTS.md 本身就会变成一个 AI 读不完的巨大文本。4. 实战落地从零为真实项目编写 AGENTS.md4.1 动笔之前先做「项目体检」很多人第一次写 AGENTS.md 时容易犯的毛病就是凭空对着一个空白文档憋内容。这完全没有必要因为你项目里已经有大量的信息源等着你去提取只是它们现在是散落在人脑里的。我的建议是打开项目之前先回答下面这些实际问题从克隆仓库到本地跑起来需要哪几条命令有没有需要手动配置的环境变量或服务项目的测试体系是什么单元测试、集成测试分别用什么命令跑代码风格上有哪些和主流规范不一致的约定比如团队坚持用snake_case还是camelCase缩进用制表符还是空格哪些目录是不能手动修改的哪些文件是自动生成的新增一个功能模块时需要同步更新哪些文件比如路由注册、数据库迁移、接口文档。之前的开发中有没有反复踩过的坑比如某个库的已知限制、某个部署环境的特殊要求。拿这些问题的答案去写AGENTS.md 才会真正有信息量而不是一堆废话。我特别推荐把「跑起来需要哪些命令」和「测试怎么跑」这两个问题放在最前面因为这两条是 AI 保证输出质量的基础设施。4.2 第一版写完之后怎么验证它真的有用写完 AGENTS.md 并不算结束关键要验证它真的被 AI 读进去了。我一般用三步验证法第一步在项目根目录开一个全新的 AI 会话故意不粘贴任何额外背景直接问它「这个项目的技术栈和启动命令是什么」如果它能准确回答说明 AGENTS.md 被加载了。如果答非所问你先检查文件位置对不对是不是放在了根目录、文件名是否准确。第二步让它执行一个带约束的任务比如「在services层新增一个方法处理超时订单的状态更新」。然后看它输出的代码是否符合 AGENTS.md 里的约定错误是用自定义的包装器处理的吗测试文件有没有同步生成有没有在业务层碰数据库第三步也是最有意思的一步故意提出一个违反约束的请求比如「帮我在服务层直接写一个查询数据库的函数」。观察 AI 的反应。合格的 AGENTS.md 应该让 AI 在这种时候主动提醒你「这个操作不符合项目约束建议放到数据访问层」并给出替代方案。如果没有这个反应说明约束写得还是太弱语义不够清晰需要加强措辞。4.3 把 AGENTS.md 和 CI 流程绑在一起文件写在仓库里如果不加任何保障慢慢就会过期。我自己的做法是把它纳入代码评审流程任何涉及项目结构、构建命令、代码规范变动的 PR都要同步检查 AGENTS.md 是否需要更新。更进一步的话可以在 CI 里加一个小脚本对 AGENTS.md 做格式校验比如检查是否包含必填的标题项目概述、命令、约束检查目录引用的链接是否有效。不是每个团队都有余力做这一步但只要加上了就能最大程度避免「文档和代码分家」的老毛病。我当时给团队加了一个很简单的检查只有 30 行 Python把 AGENTS.md 中引用的本地文件路径都提取出来逐个检查是否存在。效果立竿见影从那以后AGENTS.md 里指向子文件的链接再也没断过。5. 我踩过的那些坑AGENTS.md 的反模式清单5.1 把 AGENTS.md 写成了 README 的复制品这是最常见的坑。我见过不少人把 AGENTS.md 写得像项目简介一上来就是「本系统旨在为用户提供高效便捷的……」然后真正做到项目运行说明、编码规范的部分反而一笔带过。AI 每次启动时都要先读一大段没有操作价值的信息真正重要的约束沉在最下面甚至根本没写到。我后来给自己定了一个规矩AGENTS.md 里的每一句话都必须能直接映射成 AI 的一个行为约束或决策依据。凡是「我们很重视」「系统很强大」这类描述性内容一律删掉。写完后我会通读一遍如果某段话 AI 读完之后没有任何可操作的行为变化就说明它在浪费 token。5.2 禁止事项写得太多、太零散有些团队喜欢在 AGENTS.md 里列一大堆「不要做 X」「不要做 Y」结果 AI 反而不知道哪些是真正重要的。这里需要一个优先级意识约束写十条AI 每条都会读但它不会每条都同等重视。我的经验是禁止事项超过五条就会开始失效。你应该把前三条留给真正会导致严重返工的红线——比如「不要手改迁移脚本」「不要在业务层写裸 SQL」「不要滥用全局变量」——后面的内容要么合并要么降级到子文件里。约束要有层次主文件管红线子文件管细节。5.3 规则太死把 AI 的能力锁死了还有一类反模式是把 AGENTS.md 写成了严格的流程手册第一步必须这样第二步必须那样输出必须用什么格式。这种写法短期看似乎约束住了 AI但长期看会让它的表现变得极其僵硬遇到流程没有覆盖到的情况时反而不知道怎么办。声明式配置的精神是「守住边界放开过程」。你要描述的是「满足什么条件」「遵守什么约束」而不是「每一步的精确顺序」。比如「提交信息必须包含对应的 issue 编号」是约束而「提交之前必须先 git pull 再 commit」就太死板了遇到冲突时 AI 反而会卡住。5.4 忘了 AGENTS.md 需要持续维护这个问题最隐蔽也最致命。项目重构了、目录改了、包名换了AGENTS.md 还停在三个月前。AI 每次加载它读到的是过期的项目结构然后按照错误的信息做出更错误的决策。这时候 AGENTS.md 不但没有帮上忙反而成了给 AI 喂错误信息的来源。解决方案其实也简单把它当成一个活文档每次大重构之后强制自己更新。把「更新 AGENTS.md」写进团队的 PR 模板里或者像我前面说的在 CI 里做基本的完整性检查。宁可让它短小、准确也不要让它冗长、过期。6. 从个人技巧到团队基建Memory 工程的下一步6.1 让「记忆」成为团队共识的载体AGENTS.md 最大的价值不只在于帮个人应对 AI 失忆更在于它天然是一个团队级别的协作契约。因为文件跟着仓库走团队里的任何一个人对 AI 的行为约定作出修改全组都会同步生效。这比每个人维护一份私有提示词要健康得多——规则不再散落在个人笔记里而是沉淀在公共代码库中。我现在的习惯是在项目设计评审时就把 AGENTS.md 的更新作为一项常规交付物。架构评审通过后顺手把新的架构决策写成两句话加进 AGENTS.md这样后续所有人在这个仓库里调 AI 时都能站在同一个认知水平线上。它其实就是团队知识库的一个轻量级、机器可读的入口。6.2 静态配置之后动态上下文是更大的机会AGENTS.md 的文件形式大概率还会继续演进但更值得关注的是它背后的设计理念——按需加载、分级记忆、动态组装。现在已经有一些工具在做智能上下文管理根据当前正在编辑的文件自动把项目里相关的架构说明、依赖关系、相似代码片段注入上下文。这种能力如果再往上走AGENTS.md 这种静态配置文件就会升级成一个「索引」AI 根据当前任务动态决定去加载哪部分记忆。我有预感未来两年会看到越来越多的项目在代码库里沉淀这种结构化的 AI 记忆来源AI 编码协作的质量将从「模型能力竞争」逐步转向「上下文工程质量竞争」。哪个项目能把记忆组织得又准又轻哪个项目的 AI 产出质量就会明显高一大截。6.3 对开发者来说这意味着什么说得直白一点进化了以前写代码是跟编译器打交道未来的写代码工作会越来越多地变成跟 AI 描述清楚你要什么而描述清楚的前提是你先把项目本身的记忆体系搭建好。这不是一门可以投机取巧的技能它需要你在实际项目里不断打磨什么样的约束写得有效什么样的内容写进去是噪音每个项目都有不同的答案。就我个人而言自从把 AGENTS.md 这类记忆文件作为项目标配之后AI 编码的体验发生了实质性的变化。最明显的一点是我不再需要反复向它解释项目背景了它自己对项目的理解稳定地保持在一个较高水位上。过去那种「上午聊得好好的下午全忘了」的挫败感已经很久没有出现过了。如果你还在被 AI 编码助手的「失忆」问题困扰我的建议很简单别想着继续堆更长的提示词试着打开项目根目录写一份干净的 AGENTS.md把项目怎么跑、约束是什么、红线在哪里写清楚。从明天的新会话开始你会明显感受到不同的。