
1. 为什么我决定告别“无状态”的AI编程方式1.1 一个让人抓狂的失忆现场半年前我对AI编程助手的态度是又爱又恨。爱是因为它的代码生成能力确实强恨是因为它太容易“失忆”了。同一个项目我连续写了三个月但每次新开一个对话窗口它都要重新认识这个项目一遍——“项目用的什么框架”“依赖怎么装”“测试命令是什么”——这些问题我反复回答了不下二十遍。最崩溃的一次是让它重构一个工具函数。它按照自己的想象把所有内部模块重写了一遍命名风格不对、目录结构不对、错误处理方式也不对。我盯着屏幕愣了很久它昨天刚帮我写过相邻的代码怎么今天就什么都不记得了这让我意识到一个更深层的问题我一直在用一种“无状态”的方式和AI协作。每次对话都是全新开始每次都要重新交代背景每次它给出的建议都可能和上个月的决定冲突。问题不在模型的智力而在“记忆”。我把这个阶段称为“无状态AI编程”它最大的特征就是上下文是一次性的、临时的、不结构化的。1.2 无状态的底层逻辑模型本来就没有“硬盘”想解决问题得先弄明白为什么AI会失忆。大模型的本质是一个纯函数输入一批token序列输出下一段token序列。它内部没有像人一样的长期记忆存储不存在“我记得你上次说过”这种机制。所谓的“记忆”完全依赖每次请求时输入上下文里塞进去的信息。这就好比一个只有工作台、没有书架的助手。你每次让它干活都得把参考书重新堆到它桌上。它的工作台上下文窗口虽然不小但毕竟是有限的塞太多东西它就会注意力涣散甚至出现“lost in the middle”——对上下文中间部分的信息越来越不敏感。明白了这个原理就知道“记忆”不是一个模型能力问题而是一个工程问题我们得想办法把项目相关的关键信息稳定地装进它每次读取的上下文里而且要以它最容易消化的格式组织。如果这些信息能跟着项目走、能进版本库、能被统一维护那AI的“失忆”问题就从根上缓解了。1.3 我试过的几种“伪记忆”方案为什么都治标不治本在彻底转向AGENTS.md之前我试过好几种看起来可行的方案各有各的死角。第一种是临时长prompt。开工前先给它贴一大段项目背景、技术栈、约定让它“记住”。问题是这段文本每次都要重写不同成员写的质量参差不齐而且一旦对话长了前面的内容照样会漂移、被遗忘。这种方案的可持续性基本为零。第二种是死磕单次长对话。要求AI在一个上下文里完成所有任务不换窗口。但上下文窗口总有上限项目稍微复杂一点就顶不住了。而且对话拖长了之后AI对早期指令的遵循度会肉眼可见地下降。第三种是把设计文档、技术方案全塞给它。听起来靠谱实际上塞进去的信息大部分是噪音。它不得不在一堆文档里找关键命令和约定准确率并不高。更麻烦的是文档一旦和代码脱节AI会自信地按照旧约定给你建议反而帮倒忙。这三条路走完我基本确认了一件事我们需要一种结构化的、跟项目走的、可维护的记忆载体。这个载体不能是临时口头叮嘱也不该是冗长的文档而应该是一个精炼的、声明式的配置文件。这就是AGENTS.md出现的意义。2. Memory 工程的核心命题AI到底该记住什么、忘掉什么2.1 先把记忆分层别把所有信息都叫“记忆”研究Memory工程时我做的第一件事是给“记忆”分层。因为不同信息的性质完全不同维护方式、失效机制也完全不同混在一起管理必出问题。我自己习惯用四层模型记忆层级存储位置什么时候失效谁来维护L0 模型知识模型参数内部几乎不失效模型厂商L1 会话上下文当前对话窗口对话结束即失效使用者临时提供L2 项目记忆AGENTS.md、代码库、配置文件代码变更时需同步更新项目成员共同维护L3 个人与团队约定个人规则文件、团队规范文档约定更新时失效个人/团队负责人过去我们花大量精力在L1上——每次对话前辛苦地铺陈背景。但L1是最脆弱的随时会丢。真正值得投入的是把那些反复使用的信息从L1“迁移”到L2沉淀成项目自带的记忆资产。AGENTS.md正是L2的承载者。分完层之后我对“记忆工程”有了一个清晰的定义把项目里稳定、高频、影响正确性的信息以声明式的格式固化到代码库中让AI代理在每次工作前自动加载。2.2 什么值得写进项目记忆什么不值得写这是我在实践中踩过最多坑的地方。一开始我恨不得把项目的所有细节都写进AGENTS.md后来发现这完全是灾难。你需要一条判断准则来判断哪些信息值得写。我的准则是如果删掉这条信息AI在大多数情况下还能不能干好活如果它靠常识、靠代码本身就能推断出来那就不写。如果它推断不出来或者推断会出错那就写进去。按这个准则值得写的是这三类直接影响正确性的技术栈与版本、核心架构约束、模块边界、数据流向频繁使用的构建命令、测试命令、lint规则、代码规范容易出错的项目的领域术语、历史决策、代码生成时要避开的坑不值得写的是另外三类代码里一眼能看到的这个函数在哪、那个类叫什么AI自己会读一次性任务信息本次功能的需求描述、临时任务指令会频繁变化的信息今天改明天变的细节比如临时环境变量、某次调试方案2.3 记忆不是越多越好“提权”与“降噪”同样重要很多人误以为给AI的信息越多它就越懂项目。实际上上下文窗口里的信息就像桌面上的文件每张纸都在争夺它的注意力。信息过载后AI会出现两种典型问题一是抓不住重点二是把次要信息当成主要约束。所以Memory工程里除了“写什么”还得管“怎么读”——我习惯用“提权”和“降噪”两个动作来优化。“提权”是把关键约束放到配置文件的显眼位置、用固定格式输出、用明确的祈使句。比如“测试命令必须用pytest不要用unittest”比“项目测试用的是pytest比较多”有效得多。高优先级规则我还会在AGENTS.md顶部专门设一个“Hard Rules”区块。“降噪”是把那些可有可无的说明、模棱两可的描述、和代码库里已有内容重复的段落统统删掉。一份好的AGENTS.md读起来应该像给新同事的交接手册只有“必须知道”的事而不是项目流水账。记住AI对这个配置文件的注意力和它对prompt的注意力一样有价值。精简就是给记忆提权。3. AGENTS.md 落地实操目录、模块与一份可用模板3.1 从“每次叮嘱”到“项目自带说明书”理解记忆分层之后我真正落地的方式是用AGENTS.md。它本质上是一个声明式配置文件放在项目根目录AI代理启动时会自动读取它把它作为理解项目、执行任务的指导上下文。它和传统prompt有个本质区别。传统prompt是“命令式”的每次对话都要临时给AI下达指令——“请记住项目背景”“请按照这个规范来”。而AGENTS.md是“声明式”的项目里自带一份说明书AI来了自己读不依赖每次有人想起来叮嘱一遍。维度命令式临时prompt声明式AGENTS.md触发方式每次手工粘贴/输入AI代理启动时自动加载持久性对话结束即失效随项目代码库长期存在维护责任使用者临时编写项目成员共同维护、随代码演进一致性不同人写的质量参差统一格式稳定可审查版本管理无进入git随PR一起变更用生活中的类比来说命令式就像每次让新同事干活前口头交代一遍规矩说多了难免漏声明式则是入职时递上一本手册把公司规章制度、工作流程写得一清二楚它会自己翻还会一直带着。3.2 AGENTS.md 放哪、写什么目录结构与内容模块AGENTS.md 最基础的位置是项目根目录。项目大了之后还可以在子目录放局部的AGENTS.md比如前端目录、后端目录、测试目录等。AI代理读取时会按层级合并根目录定义全局规则子目录定义局部规则子目录优先级更高。我在根目录的AGENTS.md里主要放六个模块Project Overview项目概览一句话说明项目是干什么的技术栈是什么核心目录结构长什么样。这段让AI在几秒内建立对项目的基本认知。Commands命令清单构建、测试、运行、代码检查、部署等命令每条都要准确。AI最常犯的错就是用错命令这一块能直接减少错误。Code Style代码规范命名习惯、注释风格、错误处理方式、格式化约定。特别注意项目内已有的惯例比如用snake_case还是camelCase返回值是Result类型还是直接抛异常。Architecture Rules架构约束模块边界、依赖方向、禁止事项。比如“领域层不允许依赖基础设施层”“所有外部请求必须先经过网关层”。这些约束AI不会从代码里自学到必须显式告诉它。Workflow工作流约定开始一个任务前要做什么、改完代码后要做什么、提交前要跑哪些检查。让AI按照团队统一的工作流干活。Domain Terms领域术语表项目里特有的业务名词、缩写、概念解释。AI不了解业务语境时会乱猜有了术语表就稳了。3.3 一份可以直接套用的最小可用模板以下是我目前自己在新项目里使用的模板精简到能直接复制改用的程度# AGENTS.md ## Project Overview 一句话描述项目目标。技术栈主要语言、框架、包管理器。 核心目录 - src/ 业务源码 - tests/ 测试代码 - scripts/ 工具脚本 ## Hard Rules - 禁止使用全局可变状态除非有显式的生命周期管理 - 所有新增业务代码必须带对应测试 ## Commands - 安装依赖: npm install - 本地开发: npm run dev - 运行测试: npm test - 代码检查: npm run lint - 生产构建: npm run build ## Code Style - 命名变量/函数用 camelCase组件/类用 PascalCase常量用 UPPER_SNAKE_CASE - 注释公共API写JSDoc内部实现写简短行注释即可 - 错误处理优先返回失败结果类型不在业务代码里抛出裸异常 - 格式化使用项目自带 prettier 配置不要手工调整 ## Architecture Rules - UI层 → 应用层 → 领域层 → 基础设施层禁止反向依赖 - 外部API调用必须封装在基础设施层业务层不得直接接触HTTP客户端 - 数据库操作只允许出现在仓储实现中 ## Workflow - 开始任务前先读相关模块已有代码确认现有风格再动手 - 修改完成后运行 npm test 和 npm run lint确保全部通过 - 提交代码前检查diff确认无调试残留、无临时注释 ## Domain Terms - SKU商品最小库存单位 - 渠道包按分发渠道区分的构建产物不同渠道含不同配置 - 回放流用户在直播结束后查看的录播数据流这个模板大概80多行对多数中大型项目已经够用。关键是每个区块都保持“具体、可执行、可验证”不要让AI猜。3.4 AI代理是怎样“读取”这份配置的这里稍微解释一下执行机制不然很多人会误以为AGENTS.md有什么魔法。它本质上不是模型原生的能力而是当前主流AI编程工具和代理框架普遍支持的一种约定工作开始时工具会自动读取项目根目录下的AGENTS.md以及子目录的局部版本把内容拼进系统提示词或上下文开头然后随每个请求一起发送给模型。因为这份配置始终出现在上下文的前部位置它对后续输出的影响力很大。你可以把它理解为“给模型的起手式”——模型还没看你的代码先看到了你给它定下的规矩。这种位置优势比在对话中间临时插入一段说明有效得多。需要注意的是AGENTS.md提供的约束并不是“强制执行”的。模型没有编译期检查它只是在下一次生成时大概率遵守这个上下文。所以配置内容必须足够清晰、没有歧义、没有内部冲突否则AI依然会“选择困难”。这也解释了为什么后面我要专门讲踩坑记录——声明式配置写不好比不写还糟糕。4. 实测收益与踩坑记录配置不是写得越多越好4.1 我实测到的三个明显变化给项目接上AGENTS.md之后我观察了两周有三个变化特别明显。第一个是新对话进入状态的速度。以前新开窗口要先寒暄、铺垫、贴背景起码花三五分钟。现在不用了——打开项目就能直接聊需求AI对这个项目已经有基本认知第一版答案的质量直接高了一个档次。第二个是输出风格和项目约定的一致性。过去AI生成的代码一眼就能看出来是“模型生成的”——命名随意、结构扁平、错误处理敷衍。现在它严格遵守项目规范命名风格、模块划分、错误处理方式都和已有代码融为一体review的时候少改很多东西。第三个是建议的可靠性提升。因为配置里写了架构约束和领域术语AI给出的方案会更贴合项目实际情况。以前它会为了看起来“聪明”而过度设计现在它知道这个项目的边界在哪哪些方案在这个项目里根本不适用。4.2 踩过的坑长篇小说式写法、规则冲突、过时配置收益很香但坑也不少。我把踩过的坑分成四类每一类都是真实经历。坑一写得像长篇小说token占太多反而失效。我最早把AGENTS.md当成设计文档来写动辄四五百行结果AI确实“读”了但注意力被稀释得很厉害——它记住了开头一两段后面全被忽略了。后来我把配置压到100行以内只保留不可推断的信息和硬约束反而效果好得多。验证方法很简单看AI的输出是否稳定遵守中后段的规则如果不遵守说明你的配置太长了。坑二规则和代码重复导致维护双倍成本。我在配置里写了一大段“controllers层包含哪些文件、services层包含哪些文件”结果代码一重构配置文件就过期了。AI照着旧规则给建议越帮越忙。后来我把所有能从代码本身读出来的内容全部移出配置AGENTS.md只保留“代码里看不出来的约定”。坑三规则内部冲突且没有声明优先级。有一次根目录写了“所有模块禁止直接访问数据库”但子目录的AGENTS.md又写了“报表模块可以直接写SQL”。AI遇到这种冲突会随机选择一条遵守行为不可预测。解决方法是在文件里显式声明“子目录规则优先于根目录规则”并且全局规则里对冲突情况给出明确的裁决策略。坑四过时配置没清理AI守着旧约定。项目某个模块换了技术方案但AGENTS.md里的旧约束没删。AI每次改这个模块都严格遵守旧约定代码风格新旧割裂。这个坑最隐蔽因为AI不会主动指出你的配置过时了。我后来的做法是每次技术方案变更时把“更新AGENTS.md”也列进任务清单当成一等公民来对待。4.3 一套经过验证的维护节奏基于这些坑我逐渐形成了一套维护节奏现在分享出来供参考。首先是更新时间点。技术栈变更、架构调整、命令改变、代码规范调整——这四个时刻必须同步更新AGENTS.md。我把这条要求写进了团队的工作流约定谁改动这些内容谁就负责更新配置。其次是纳入code review。AGENTS.md对我来说是代码资产不是文档附属品。每次PR我都要看一下“本次改动是否需要同步AGENTS.md”如果需要但没改直接打回。我甚至会让AI自己在PR描述里检查“改动是否违反现有AGENTS.md规则”相当于用AI来监督AI。最后是定期清理。我习惯按项目节奏每完成一个里程碑就过一遍AGENTS.md删掉不再适用的规则、合并重复表述、更新术语表。这个习惯的价值在于配置文件的体积会自然膨胀定期削峰才能让它保持“精炼可读”的状态。5. 从个人项目到团队协作共享记忆的维护与演进5.1 团队场景AGENTS.md 变成团队的“公共记忆”AGENTS.md最初是我个人项目里的实验后来我把它带进了团队项目效果比预想的更好。原因是它天然适合多人协作者维护的“公共记忆”——团队里每个人都可能有自己的一套和AI协作的口头习惯但把这些习惯沉淀到一份共享配置文件之后AI无论和谁协作行为都保持一致。这里有个很好用的分工README是给人看的AGENTS.md是给AI代理看的。README负责介绍项目、快速上手、架构选型它面向的是人类读者需要故事性和引导性。AGENTS.md面向的是AI代理它需要的是精确、命令式、无歧义的规则。两份文件可以互相引用但不要互相替代。把内容混在一起AI会分不清哪些是需要执行的规则哪些只是背景说明。团队场景下还有一个额外的好处code review中反复强调的约定可以同步沉淀进AGENTS.md。比如“这个模块的接口设计要注意什么”“这种异常场景我们统一怎么处理”写进去之后AI会在后续生成时自动遵守减少人工review反复唠叨的成本。5.2 记忆的版本化与自动化AGENTS.md 的演进方向我现在看到的一个趋势是AGENTS.md这类配置文件正在从“手工维护的文档”变成“和代码同步演进的工程资产”。让配置文件随代码一起进git只是第一步更新的方向有三个。第一个是记忆的自动提取。目前AGENTS.md的内容基本靠人来写但理论上可以从git历史、commit消息、issue记录里自动提炼项目事实生成初稿再由人来review。已经有团队在实验这种模式让AI自己总结“项目这周的约定变化”然后人工确认合并进AGENTS.md。第二个是配置的运行时校验。既然配置里写了“禁反向依赖”能不能做成一个hook在CI阶段跑一遍静态分析违反配置规则就直接报错这种把“声明式约定”变成“可执行检查”的思路我认为是声明式记忆的最终形态——AI不仅能读规则代码库本身也有机制来执行规则。第三个是跨项目的个人记忆库。除了项目级的AGENTS.md还可以维护一份个人级的规则文件比如“我偏向函数式风格”“注释不写版权头”“错误处理必须显式”。AI代理会先读个人规则再读项目规则两层结合。这对自由职业者或经常切换项目的开发者尤其有价值。5.3 最后分享一点个人体会研究Memory工程这段时间最让我醒忹的一点是AI编程的瓶颈已经不完全在模型能力而在于我们对“上下文”的管理方式。AGENTS.md不是什么神奇魔法它只是把“如何和AI协作”这件事从临时的口头叮嘱变成了项目里一等的代码资产。我现在每开一个新项目第一件事不是写README而是先写AGENTS.md——先把AI需要知道的东西定下来再让AI帮我把其他东西写出来。刚开始维护它的时候会觉得麻烦但运行一两个星期之后你会明显感觉到和AI协作的体验完全不同它不再是那个每次见面都要重新认识项目的陌生人而是一个读过项目手册、懂得行规的老搭档。如果你也在和AI协作开发的过程中被“失忆”困扰我真心建议你从一份一百行左右的AGENTS.md开始。不用追求完美先写最常被问到的那些问题和最常被违反的那些规则然后跟着项目一起演进。你会回来感谢自己的。