最近一段时间,我越来越频繁地听到一句话:“AI 编码助手越用越笨。”明明昨天还讨论好的模块划分,今天换个会话就全忘了;上个月定下的命名规范,它总是按照自己的习惯来。如果你也有同感,那大概率不是模型能力不够,而是我们还在用“无状态模型”的工作方式使用它。任何一次对话之间都没有记忆通道,上一轮的结论、约定、架构取舍,都会被当成临时数据丢在身后。这也是“AI 编程范式转换”这个说法最近被反复提起的原因:我们正在从“每次提问都从零开始”的模式,转向有记忆、有配置、可维护的协作方式。而这个转向过程中,Memory 工程和 AGENTS.md 声明式配置,是我认为最值得先落地的两个抓手。下面我会把无状态模型的问题拆开,讲清楚 Memory 工程到底要建什么,然后给出一套可以直接抄走的 AGENTS.md 配置思路。
1. AI 编程的范式转换:无状态请求为何正在成为瓶颈
1.1 无状态模型的“短命记忆”
无状态,听起来是个很中性的技术词,但如果放到 AI 编程协作里,它带来的体验就是“每次对话都是一场新面试”。你把项目背景说了一遍,它记住了;你说“按之前的方案来”,它一脸空白;你重新解释三遍之后,它提供了一个和昨天完全相反的架构建议。这就是无状态模型的典型表现:每一次请求都独立推理,模型不保存上一次对话的结论,所有信息要么在当前上下文窗口里,要么就彻底消失。
这种设计在早期的 API 调用场景里很合理,部署简单、并发可控、请求之间互不影响。但当 AI 变成日常结对搭档之后,“短命记忆”就成了致命伤。因为软件开发本身是一个强状态过程:代码库里沉淀了过去的决策,README 里记录了使用方式,Issue 里挂着未解决的问题。你把一个活生生的项目硬塞给一个“失忆”的模型,它当然会表现得像刚入职第一天的新人,客气、肯干,但总在等你重复最基本的信息。
最让我受不了的不是翻译错误或者代码格式问题,而是它真的会“漂移”。上一轮它还在按照你定义的接口风格写服务层,新一轮它就自己发明了一套新的抽象。你反复纠正,但它永远只是“临时记住”,换个会话又回到默认习惯。模型没变,变的是记忆。无状态模型并没有给这些长期约定留出位置。
1.2 记忆缺失的连锁成本
如果只是重复解释,那最多是浪费几分钟话费。但真实项目里,记忆缺失会形成连锁成本。
第一层是 token 成本。你把上下文、目录结构、技术选型、失败过的方案重新描述一遍,这些内容全都占用上下文空间。上下文窗口是固定的,被背景信息挤占之后,留给真正需要推理的代码的空间就会变少。一旦代码长一点,模型就开始“抓瞎”,你会误以为它能力不行。
第二层是纠错成本。模型不记得“这个模块之前已经确认不要了”,于是又把废弃方案捡了回来;它不记得“数据库连接串不提交到仓库”,于是测试代码里直接硬编码。你发现问题之后,往往不是改一行,而是要推倒一小部分设计重来。我见过一个刚起步的功能,明明前一次会话已经确定了目录结构,下次重开却完全按默认结构生成,结果三个模块互相冲突,光调整依赖关系就花了一个小时。问题根本不是模型笨,而是缺少一个把结论带回下一个会话的机制。
第三层是团队协作成本。无状态对话的记忆只存在于某一个人的某个聊天窗口里,其他协作者完全不知道 AI 被灌输了什么约定。你这边让它“统一使用异常而非返回错误码”,同事那边没同步,AI 又按另一种风格生成了代码。这种不一致比不用 AI 还麻烦。所以范式转换不是锦上添花,而是规模化使用 AI 编程助手的必经之路。
1.3 范式转换的三个现实方向
目前大家探索的方向大概能分成三条线。
第一条是“会话状态外置”,把聊天过程中沉淀下来的结论主动保存成文件,下一次会话开始时重新加载。这是成本最低、见效最快的方式,也是后面 AGENTS.md 的基础。
第二条是“信息检索增强”,给项目建索引,在需要的时候只把相关文件片段喂给模型,而不是把所有内容都塞进上下文。这个方向解决的是“大海捞针”的问题,适合代码量很大的仓库。
第三条就是“声明式行为约束”。通过一份放在项目根目录的说明文件,把项目的定位、规则、禁止事项、架构决策都写清楚,让 AI 在开工前先读这份“项目宪法”。这种做法把记忆从聊天记录里抽出来,变成可以版本管理、可以评审、可以复用的项目资产。
这三条线并不互斥。我的建议是:先做第三条,再补第一条和第二条。因为不管检索技术多强,如果项目层面缺少稳定的价值判断和行为约束,AI 仍然会给你一堆“看起来对但不符合项目气质”的代码。AGENTS.md 就是那个把项目和 AI 对齐频率的校准器。
2. Memory 工程:给编程助手建立一套“持久记忆”
2.1 Memory 工程到底在解决什么问题
Memory 工程不是一个产品功能,更不是某家厂商的私有概念。它关注的是一组更本质的问题:记忆数据怎么产生、怎么保存、怎么按需加载、怎么更新和失效?换句话说,如果你打算让 AI 拥有 1.5 个小时以上的记忆力,你就得考虑把它需要知道的东西放到哪里、以什么格式存放、谁会负责维护。
有人会把 Memory 工程简单理解成“搞个向量数据库,把文档全部灌进去”。这个理解太偏了。向量数据库解决的是相似度检索问题,但记忆不只是“找得到”而已,它还包括优先级、新鲜度、冲突处理。比如年初定下的“所有服务必须通过网关鉴权”这条规则,可能到现在依然有效,但一个充满了临时调试接口的代码片段,就不该长期躺在记忆里。
Memory 工程真正要解决的是三件事。一是跨会话延续性:上午和 AI 讨论出的结论,下午还能被它的行为体现出来。二是多路径一致性:不管你是自己手动写代码,还是让 AI 生成,最终脑子里对项目的理解应该是一致的,不会出现“AI 觉得 A 方案对,你觉得 B 方案对”的情况。三是成本可控:记忆不是越多越好,每条记忆的保存和读取都有代价,得知道什么时候该记住、什么时候该忘。
2.2 该记住什么:记忆类型与性价比
项目里的信息种类很多,但不是所有信息都值得写进记忆系统。我习惯把记忆分成四类。
| 记忆类型 | 典型内容 | 读取频率 | 推荐存放方式 |
|---|---|---|---|
| 项目事实 | 目录结构、技术栈、启动命令、端口号 | 高 | AGENTS.md 或仓库根目录说明 |
| 架构决策 | 为什么选这个方案、放弃过什么 | 中 | 独立决策记录文件 |
| 行为偏好 | 命名风格、错误处理、测试范围 | 高 | AGENTS.md 中的“工程约定” |
| 进行中任务 | 当前改到哪、下个步骤是什么 | 低 | 临时会话摘要,不写进长期记忆 |
为什么要这样划分?因为“项目事实”和“行为偏好”是 AI 每次干活都要依赖的,它们必须放在明显的、固定路径的位置;而“架构决策”通常不会在每行代码里体现,但真遇到关键岔路口时又非常重要;“进行中任务”则高速变化,如果写进长期记忆,很容易造成污染。让 AI 背着一堆昨天的待办清单去写今天的代码,纯属自找麻烦。
另外,记忆的格式要足够轻。不要试图把整个 README 塞进 AGENTS.md,也不要让 AI 去读一份几千行的设计文档。它需要的是“指针”和“摘要”:具体细节放在文件里,在配置文件里写清楚路径和检索条件。这样既保留可追溯性,又不会把上下文窗口撑爆。
2.3 落地 Memory 的最小闭环
我不建议一上来就搭一套复杂的记忆服务。对大多数项目来说,最小闭环只需要三步。
第一步,建立“记忆容器”。在仓库根目录放一个 AGENTS.md,再新建一个 docs/decisions 目录,用来存放结构化的决策记录。如果项目里已经有很多文档,那就在 AGENTS.md 里写明哪些文档是权威版本,避免 AI 乱找。
第二步,定义“写入规则”。你要决定什么情况下记忆会被更新。比如“每次确定一个新的架构取舍,就写一条简短的决策记录”“每次会话结束时,把当前进度写到 docs/notes/current-task.md”。关键是写入规则要具体,否则 AI 不知道该更新哪份文件。
第三步,约定“读取触发点”。每次会话开始时,先让 AI 阅读 AGENTS.md,并明确告诉它“这是项目级上下文,后续所有操作都要遵循”。当需要细节时,再根据 AGENTS.md 里的路径索引去读具体文件。这样形成的闭环就是把记忆从“大脑里的临时缓存”搬到“代码仓库里的持久文件”,然后通过固定的读写流程保证它不腐坏。
我见过不少团队用这个最小闭环跑了几周之后,最大的变化不是代码质量突飞猛进,而是“重复解释的次数明显变少”。你不需要一遍遍教 AI 你的项目怎么组织,它自己会去读那份声明。这就是 Memory 工程最简单的价值。
3. AGENTS.md 声明式配置:把记忆变成项目资产
3.1 为什么声明式配置优于聊天记忆
聊天记忆的问题在于它太“贴身”了,跟某一次对话绑定,跟某一个聊天窗口绑定,跟某一个人的输入习惯绑定。一旦换窗口、换设备、换同事,记忆全部归零。而 AGENTS.md 走的是另一条路:它把记忆写成一份文件,放进代码仓库里,跟着分支走、跟着版本走、跟着人走。
声明式配置的核心,是“描述目标状态,而不是描述操作步骤”。你在 AGENTS.md 里写的不是“当你看到 utils 目录,请先打开 config.py 再回答”,而是“本项目所有外部配置必须集中在 config 目录下,不允许散落”。前者是命令,后者是规则。命令容易被情境击穿,规则却能稳定约束 AI 在不同任务里的行为。
这种文件还有一个隐性价值:人类可读、可评审、可 diff。你给 AGENTS.md 加了一条新约定,不是模型悄悄记在心里,而是会在代码评审里被看到,同事可以在合并请求里提出异议。记忆从个人私货变成了团队共识,这个转变对协作的改善是决定性的。
当然,很多工具链可能还没有原生支持 AGENTS.md。遇到这种情况,我会用一个很轻的补偿手段:在每个新会话的第一句话里固定引用它,比如“开始工作前,请先阅读仓库根目录的 AGENTS.md,并严格遵循里面的工程约定”。当你把这件事养成习惯之后,即使工具不支持自动发现,记忆通道也一样能打通。
3.2 一个可直接套用的 AGENTS.md 骨架
下面这份骨架,是我自己项目中演化出来的版本。它不长,但覆盖了 AI 编程协作里最容易出问题的几个环节。
# AGENTS.md — 项目上下文声明 > 用途:AI 编程助手每次会话开始时应首先阅读本文件。 > 如果你发现下文与用户口头指令冲突,以用户在本会话中的明确指令为准。 ## 1. 项目简介 一句话说明:这个仓库做什么、服务对象是谁、当前处于什么阶段。 ## 2. 技术栈与目录约定 - 语言与框架:... - 关键目录:src/ 是业务代码,tests/ 是测试代码 - 构建与验证命令:... - 配置文件统一放在 config/ 下 ## 3. 工程约定 - 命名规范:... - 错误处理:优先使用异常,不在业务代码里吞掉异常 - 测试要求:新增公共方法必须补单元测试 - 代码风格:不主动格式化超出修改范围的文件 ## 4. 架构决策 - 2025-01-10:选择基于消息队列的解耦方案,拒绝在服务层直接调用三方 SDK - 2025-02-03:数据库访问统一走数据访问层,业务代码不允许直接拼接 SQL ## 5. 当前焦点 - 正在开发支付回调链路 - 下一步:补齐幂等校验与失败重试 ## 6. 禁止事项 - 不要生成 mock 数据到生产路径 - 不要修改未在任务范围中的迁移文件 - 不要在代码中存储明文密钥每个段落都有存在的理由。“项目简介”让 AI 判断问题时有一个基本立场;“技术栈与目录约定”减少它猜测的成本;“工程约定”是出现频率最高、也最容易被 AI 违反的部分;“架构决策”是给关键岔路口用的;“当前焦点”是会频繁漂移的部分,更新频率很高;“禁止事项”则是给 AI 的护栏,减少破坏性操作。
3.3 配置项背后的运行逻辑
你可能会问:AI 真的会老老实实看这份文件吗?我的看法是,别指望它自动变得自觉,而是要把“阅读它”设计成会话流程的一部分。就像一个新成员入职,你先让他读项目文档再碰代码,这个动作本身就是在建立上下文。
从技术上看,AGENTS.md 承担的是“系统提示词”的一部分,它规定的不只是内容,还有决策优先级。比如文件开头的引用块里写了一句话:如果文件内容与用户口头指令冲突,以用户本会话的明确指令为准。这是为了防止配置被当成“不可违背的神谕”,导致用户明明在临时改方案,AI 却死守旧规则。
另一个容易被忽略的地方是“写法”。写 AGENTS.md 要尽量使用祈使句,比如“优先使用异常”“不要修改超出范围的文件”,比“开发中请注意异常处理”这种模糊表达有效得多。AI 程序对这种命令式语义的把握更准。你还可以在每条规则后面补一句简短的“为什么”,但不要写太长,五十个字以内就够。原因是 AGENTS.md 的主要使用者是模型,不是人,太啰嗦会稀释规则密度。
这份文件最好不要超过两百行。如果项目确实复杂,那就把细节拆到子目录里的文档,在 AGENTS.md 里只留索引。配置是给记忆指路的,不是把记忆全文背下来。
4. 从无状态对话到 AGENTS.md:一条可照抄的迁移路径
4.1 存量项目:从高频问题开始切片
老项目往往已经有大量历史包袱,不要想着一次性把整个项目规则都写清楚。我会从一个最实用的动作开始:翻出过去两周的对话记录,找出那些你重复讲过至少三次的内容。可能是“我们不用 XX 框架的默认模板”,可能是“数据库迁移文件必须单独审查”,也可能是“接口返回格式统一为 {code, message, data}”。这些内容就是最值得固化成 AGENTS.md 的第一批规则。
另一个来源是“人肉纠正记录”。你回想一下,AI 生成代码后你手动改得最多的都是哪里。如果你每次都要把命名从下划线改成驼峰,那就在 AGENTS.md 里写明命名规范;如果你每次都要补充错误处理逻辑,那就写一条“所有外部依赖调用必须包异常边界”。先解决最高频的摩擦,不要试图覆盖所有边界。等运行一两周之后,再根据实际翻车记录迭代新的版本。
这里有一个度要把握好:AGENTS.md 写的是“当前必须遵守的”和“经常反的错”,不是项目百科全书。如果某条规则已经深入人心,就算 AI 偶尔犯错,手动改的成本也很低,那就没必要写进去。配置越多,AI 的上下文负担越重,反而会变得保守而迟钝。
4.2 新项目:先写骨架再写代码
新项目反而是最容易落地 AGENTS.md 的场景。我现在的习惯是,项目初始化之后第一件事不是急着写核心逻辑,而是花二十分钟把 AGENTS.md 的第一版写出来。不需要很全面,但至少要有项目简介、技术栈、目录约定、禁止事项这四个部分。
为什么要写禁止事项?因为项目刚起步时最怕 AI 越界。它会自作主张生成额外的抽象层,或者往公共配置里塞一堆用不到的依赖。你在文件里清楚写“不要生成未要求的抽象层”“不要修改依赖清单”,就能明显减少这类问题。
写完第一版后,我会先做一个小实验:把同一份任务分别给“读了 AGENTS.md 的会话”和“没读 AGENTS.md 的会话”跑一遍。对比输出,你很快就能感受到声明式配置带来的差异。前者会更贴近项目的骨架,后者则更像一个泛泛而谈的代码模板生成器。这个实验成本很低,但说服力极强。
4.3 AGENTS.md 与记忆的联动策略
单独一份 AGENTS.md 还不够,它需要和“文件索引”以及“会话摘要”协同工作。
我在实际项目里会把记忆体系分成三层。第一层是常驻配置,就是 AGENTS.md,每次会话开始都要读。第二层是局部上下文,当任务涉及某个模块时,AI 需要去读该模块下的 README 或代码说明,这一层按需加载。第三层是短期进度,专门找一个 docs/notes/ 目录记录当前进行中的任务,每次会话结束时更新。
三层结构的好处是:AGENTS.md 保持精简,不需要承载所有细节;局部上下文只针对当前任务,性价比最高;短期进度针对即将开始的工作,让下一次会话可以接着上回继续说。
联动的时候要注意一个原则:AGENTS.md 里的规则是“慢变量”,不该频繁变动;决策记录是“中变量”,得有人工确认;当前焦点是“快变量”,可以由 AI 在会话结束时总结并更新。把不同生命周期的信息放进不同文件里,才不会出现“改一条规则连带着改坏十条配置”的情况。
5. 踩坑记录与排查技巧实录
5.1 配置不生效:最常见的三个原因
我踩过最大的坑,就是写完 AGENTS.md 之后,AI 压根不读。排查了一圈,发现无非是这么几个原因。
第一个是文件名大小写不匹配。标准文件名是 AGENTS.md,全大写。有人会顺手写成 agents.md 或者 Agents.md,在一些大小写敏感的环境里,AI 的自动发现逻辑就识别不到。如果工具链自己不带自动发现,那就要靠会话开场白来触发。
第二个是文件放错了位置。AGENTS.md 通常放在仓库根目录,而不是某个子目录里。放在子目录的作用范围会收缩,不是不能用,但如果你希望它成为项目级记忆,根目录才是正确位置。第三个是工具缓存。有些场景会把项目索引缓存起来,文件改了但认识没跟上。做法很简单:换个新会话,或者在能清除项目索引的地方重新加载一次。
最简单也最有效的解题思路,是不要依赖“自动发现”。在会话启动模板里直接加上这句话:“请先阅读仓库根目录的 AGENTS.md,理解项目上下文后再开始。”把主动触发写进自己的操作流程,比寄希望于任何自动机制都可靠。
5.2 记忆膨胀与规则冲突
AGENTS.md 的另一个常见问题是越写越长。一开始觉得每条规则都有用,舍不得删,最后整个文件堆到几百行,AI 反而不知道重点在哪,每条规则都只得到了一点点注意力。我会给自己定一个死线:超过 200 行就要拆。把详细解释挪到 docs/conventions/*.md,在 AGENTS.md 里只留“规则一句话 + 文档链接”。
规则冲突也一定会出现。比如 AGENTS.md 里写了“所有接口都要走统一网关”,但某个决策记录里又写了“本地开发环境可以绕过网关以提升联调效率”。如果两条规则同时存在,AI 就会陷入两难。解决办法是给规则添加“适用范围”字段。统一网关那条写明“生产环境必须”,绕过网关那条写明“仅限本地开发配置文件”。我还会定期用文本搜索把含“不要”“禁止”“必须”的句子列出来,人工扫一眼有没有互相矛盾的地方。
还有一类问题更难察觉,叫做“即时偏好污染”。某次对话里你随口说了一句“这次先用字典存配置”,AI 下一轮就把这条写进了长期配置。当事人看到之后一脸懵,这只是一次临时妥协。要避免这个问题,最直接的办法是给 AI 写入权限之前加一个确认机制:当它准备修改 AGENTS.md 或决策记录时,先输出 diff,由人来决定合不合并。这一步很笨,但对配置质量有决定性保护。
5.3 常见问题速查表
| 症状 | 可能原因 | 处理方式 |
|---|---|---|
| 模型完全没按约定来 | 会话未主动引用 AGENTS.md | 在会话启动模板里强制加入阅读步骤 |
| 部分规则失效 | 文件路径、大小写不对,或索引缓存未更新 | 检查根目录文件名;新开会话重试 |
| AGENTS.md 太长导致上下文被占 | 所有细节都堆在同一份文件 | 拆分子文档,只在主文件留索引 |
| 新旧规则冲突 | 决策记录与工程约定没有优先级定义 | 给规则加适用范围,并补充“本规则优先”说明 |
| AI 把临时偏好写进长期配置 | 没有写入审核机制 | 约谈 AI 修改配置前先输出 diff 供人工确认 |
这张表看起来都是小问题,但真正跑起来的时候,几乎每一项都会反复出现。特别是没有核审机制的项目,通常过一两周之后 AGENTS.md 就会变得又长又矛盾,最后丧失约束力。所以我不太推荐“让 AI 全自动维护配置文件”的做法。声明式配置的价值在于稳定和透明,一旦失去人工把关,它就变成了另一堆需要清理的技术债。
6. 写在后面:一些个人体会
6.1 我现在的默认工作流
现在不管是新项目还是老项目,我都会在开工时先确认 AGENTS.md 存在,不存在就立刻补一份最简版本。然后我会在项目里约定一个固定动作:每次会话结束时,让 AI 根据当前进度更新“当前焦点”小节,或者把结论追加到 docs/notes/。这听起来很简单,但它彻底改变了 AI 编程的连续感。我再也不用反复介绍自己是谁、项目在干嘛、代码在哪。AI 自己会在第一步读文件。
有一件让我印象很深的事:某次我在一个几十个文件的项目里,让 AI 只改某个模块的异常处理逻辑,它居然没有去动其他文件,还主动提醒我有一条工程约定和当时的改动目标冲突。当时我意识到,AGENTS.md 不是一份可选的文档,而是让 AI 真正理解项目秩序的最小必要单元。
6.2 一个值得长期坚持的习惯
最后再分享一个我自己坚持了很久的习惯:把 AGENTS.md 的变更当成重要代码变更来对待,每次改动都要能说清楚“为什么”。不轻易加规则,也不轻易删规则。加了规则,说明我们反复在同一个地方摔倒,需要一条护栏;删了规则,说明这条约束已经成了团队本能,或者已经被更新的决策取代。
所有记忆系统都需要维护,AGENTS.md 也一样。无状态模型是起点,Memory 工程是路线,AGENTS.md 则是我用来把路线钉在地上的界碑。你也可以先从一个很小的会话开始,写完第一版 AGENTS.md 之后,你就会发现“越用越笨”的那只 AI 编程助手,开始有了点项目老人的样子。