资讯动态

AI编程记忆缺失怎么办?从无状态模型到AGENTS.md的Memory工程实践

发布时间:2026/10/13 19:20:20 来源:尧图企业网站定制
你有没有遇到过这种情况昨天跟 AI 编程助手聊得好好的今天开一个新会话它连最基本的项目约定都忘得一干二净。更离谱的是它可能还会一本正经地提出一个和你现有架构完全冲突的方案。这不是模型变笨了而是它天生“无状态”——不是该记的事情不记而是你根本没地方让它记。于是我们开始把项目里那些只存在于老员工脑子里的经验写进仓库里的 AGENTS.md 文件用声明式配置把项目的长期记忆固化下来。这个转变我把它叫作“AI 编程范式转换”也是解决 AI 协作失忆最务实的路径。这个内容适合谁如果你正在用主流 AI 编程工具开发实际项目被“上下文丢失”“规则漂移”“重复解释”折磨过那么这篇文章会告诉你无状态模型的问题到底出在哪Memory 工程怎么落地以及 AGENTS.md 到底该怎么写才能真有效。1. 从“无状态”到“Memory 工程”范式转换的本质1.1 模型无状态是因为它本来就不应该替你记东西先想一个问题大语言模型在生成代码时靠的是什么它靠的是模型参数里固化的“通用知识”加上当前对话里你喂给它的那点上下文。换句话说每一次请求都是一次全新推理模型不会在一个会话结束后自动把“我认为这个项目的代码风格是 X”写回某个持久化磁盘。这种架构设计在很多场景下是优点因为它让模型保持轻量、无偏见、不依赖运行状态但在 AI 编程场景里就变成了痛点。你把项目目录结构、命名规范、技术栈局限一条条说给它听它懂了可当你第二天新建会话它又回到了那个“什么都不知道”的初始状态。有人把这个问题归结为“上下文窗口太小”实际上不只是窗口大小的问题而是缺少一层稳定的“记忆层”。上下文窗口更像是一块临时白板白板再大擦掉之后仍然一无所有。早期我们怎么解决靠 Prompt。把几十条规范拼进一个超长系统提示词把 README 全文复制进去把配置文件贴给模型看。这种做法本质上是用 Prompt 充当临时记忆但代价越来越明显Prompt 越长模型越容易在中间位置丢失注意力每次会话都要重新传输一遍token 成本高而且同一个项目在不同人手里Prompt 内容可能完全不同没法统一审查。1.2 无状态模型的三笔账一致性、可维护性、成本我见过很多团队在引入 AI 编程工具后前两周效率很高一个月后开始抱怨“AI 越来越蠢”。真实原因不是模型变蠢了而是项目的信息增量超过了 Prompt 的承载能力。仓库越来越复杂AI 每次能看到的上下文却有限于是它只能靠“猜”来理解你的项目猜出来的代码自然五花八门。算一笔细账假设一个项目有 20 个关键约定平均每条 50 字写进 Prompt 就是 1000 字。如果每天开 30 次会话一个月下来光重复传输这些约定就要烧掉几十万 token。可如果把这 1000 字放进仓库根目录的 AGENTS.md工具启动时自动加载你只需要支付一次读取成本还能通过 Git 代码审查追踪每次修改从源头保证一致性。这笔账怎么算都划算。更重要的是无状态模型带来的问题并不仅仅是效率损失而是“不可预测性”。今天 AI 给出的代码符合你口头强调的规则明天它可能因为上下文里没有那段强调就自行发挥。对于一个需要多人协作、长期迭代的代码库来说这种随机性是最危险的。我们需要一种机制把隐性规则变成显式契约把“每次碰运气”变成“每次按约定执行”这就是 Memory 工程登场的背景。1.3 Memory 工程不是玄学是把记忆当成基础设施我理解的 Memory 工程不是给模型外挂一个“记忆数据库”那么简单它是一套方法论把项目中的事实信息、规则信息、行为偏好分层组织用稳定、可读、可审查的方式存储起来并在合适的时机注入到模型的上下文中。这套方法论和检索增强生成RAG有交集但更强调“规则级记忆”而非“片段级记忆”。RAG 通常是用户提问后去文档库里搜索相似片段返回的是碎片化内容而 Memory 工程里的 AGENTS.md 是一份结构化、带优先级、面向决策的配置文件它回答的不是“这个函数怎么实现”而是“这个项目里什么该做、什么不该做、用什么风格做、做完怎么验证”。简单说RAG 偏“查资料”Memory 工程偏“定规矩”。编程工具真正需要的恰恰是后者因为代码生成过程里最影响质量的往往不是某一段历史代码而是项目层面的偏好和约束。把这些偏好和约束写成声明式配置就相当于给 AI 配了一份“工作手册”。这也是我为什么认为AGENTS.md 会是未来每个仓库的标配文件。2. AGENTS.md一种声明式的项目记忆2.1 它是什么不是魔法文件很多人听到 AGENTS.md第一反应是“是不是又有什么厂商发明了新的特殊文件”。它确实是一个文件名约定放在仓库根目录或者模块根目录用 Markdown 编写用来给 AI 编程工具、自动化代理、甚至新加入的开发者读取。但我想先泼一盆冷水它不是一个魔法文件不是写上几句咒语模型就会乖乖听话。它的本质是一份“上下文契约”一份把人类团队默认知道、但模型无法自己推断的信息显式写出来的文档。为什么默认放在根目录因为 AI 工具通常会有一个“探索仓库”的动作根目录是它读取优先级最高的位置。放在根目录意味着工具的自动加载逻辑可以低成本发现它。更深一层根目录代表“整个项目的公共记忆”而子目录里的配置文件则更多表达某个模块的局部记忆。我见过有人把 AGENTS.md 写得像一本 100 页的使用指南里面堆满了公司介绍、产品发展史、架构演进路线图。这些内容对人有价值但对 AI 生成代码没什么直接帮助。真正有效的 AGENTS.md 应该像一份“新员工入职当天会收到的操作手册”简短、具体、能直接指导行为。比如“这个仓库用 pnpm不要提交 lock 文件之外的包管理器产物”“新业务代码必须放在 modules 目录不许放业务代码在 common 目录”“测试文件命名统一用 .test.ts”。这些都是模型在没有明确告知时无法可靠推测的信息。2.2 与 README、规范文档、配置文件的差异在哪不少团队会问我不是已经有 README 了吗把内容复制过去不就行了我的看法是README 和 AGENTS.md 关注点不同甚至服务对象也不同。README 首先服务的是“人”尤其是不了解这个项目的访客和后续维护者它讲的是“这是什么、怎么跑起来、有哪些功能”。AGENTS.md 服务的主要是“会自动做出代码变更的代理”它讲的是“你在这个项目里做变更时必须遵守什么”。两者有重叠但不该互相替代。一张简单的对比表能说清楚项目READMEAGENTS.md主要读者人类开发者、访客AI 工具、自动化代理、新加入的开发者核心问题项目是干什么的在这里做变更要遵守什么内容倾向介绍性、概述性指令性、约束性变更频率低中高随项目约定变化载体类型文档声明式配置至于规范文档、ADR架构决策记录、CONTRIBUTING它们当然也有价值但问题是太分散。一个项目可能有 docs/adr/001-xxx.md、docs/architecture.md、CONTRIBUTING.mdAI 工具在拿到任务时不一定知道该去读哪一份。AGENTS.md 可以承担“索引摘要”的双重职责把最重要的约束摘出来放在前面把详细文档的链接放在后面。这样模型能快速获得决策所需信息需要深入细节时也知道去哪里找。2.3 声明式配置赢在确定性也输在静态性“声明式”这个词听起来有点高大上实际上很简单配置里写“最终应该是什么样的状态”而不是写“第一步怎么做、第二步怎么做”。比如声明式写法是“所有对外接口必须使用领域对象作为入参禁止直接暴露数据库实体”命令式写法则是“你改一下 Controller把 Entity 换成 DTO”。前者描述规则后者描述操作。AI 工具需要的是前者因为同样的操作在不同场景下可能都不一样但规则是稳定的。声明式配置最大的优点是确定性它是文本文件能被 Git 追踪能被 code review能被自动化检查没人能在部署过程中不知不觉改它。这一点特别重要AI 生成的代码质量波动大如果连约束本身都是加密在某个黑盒配置里那出了问题根本无从排查。把规则写进仓库文件意味着每一次规则变化都有记录模型的行为至少能对着规则解释。但声明式配置也有天生的短板它是静态的无法总是反映代码库的实时变化。你写下“所有工具函数必须放在 src/utils”的规则后来因为架构调整团队决定把工具函数分散到各个 domain 目录如果忘了更新 AGENTS.md模型就会按照过时规则继续行事。所以后面我会专门讲维护策略别让 AGENTS.md 变成一个“祖传古董文档”。3. 实操从零写一份不踩坑的 AGENTS.md3.1 先做一次“入职口述”整理写 AGENTS.md 之前别急着打开编辑器。我建议你先做个练习假设明天有一个新人入职他的工作是在你的仓库里做功能开发你会口头告诉他哪些事把它们列出来。通常会被口头告知的内容包括这个项目实际用的技术栈版本哪些地方和网上教程不一样业务代码放哪个目录、公共代码放哪个目录、谁不能依赖谁分支命名规范、提交信息风格、MR 前要跑什么命令一些“历史遗留原因”导致的特殊处理比如某个模块只能走异步、某个服务必须用特定配置前缀完成一个任务的标准是什么测试覆盖率要不要强约束文档要不要同步更新。你会发现这些信息很少全部写在 README 里更多是存在老员工的脑子里。AGENTS.md 要做的就是把“老员工口头常识”转成“所有代理都能读取的显式规则”。我实际操作时会把列表分成三类事实记忆项目结构、技术栈、命令、规则记忆命名、架构边界、禁止事项、行为记忆开发流程、完成定义、验证方式。分类清清爽爽后面写配置不会乱。3.2 最小骨架示例抄走就能用一个可运行、不啰嗦的 AGENTS.md 骨架大概是这样的# AGENTS.md ## 项目概览 - 这是一个处理费用报销的领域服务不包含前端页面。 - 整体采用领域驱动设计分层接口层、应用层、领域层、基础设施层。 ## 技术栈与命令 - 包管理器使用 pnpm禁止提交 package-lock.json。 - 启动开发环境pnpm dev。 - 运行全部测试pnpm test。 - 提交前必须通过pnpm lint 和 pnpm typecheck。 ## 编码约定 - 目录命名使用 kebab-case文件命名使用 PascalCase组件和 camelCase工具函数。 - 所有对外服务入口必须写在 interfaces 目录内部逻辑禁止直接暴露。 - 接口返回一律使用统一响应结构错误码从 constants/error-codes.ts 引用禁止硬编码。 - 新增依赖需要先评估是否需要依赖安装必须用 pnpm add不手动改 package.json。 ## 架构边界 - 领域层不允许引入任何 HTTP、ORM、消息队列相关依赖。 - 应用层只编排业务用例不写具体数据库 SQL。 - 跨聚合的数据查询必须走领域服务接口禁止直接跨表 join。 ## 任务执行规范 - 修改公共模块时必须先找到所有调用方并逐一评估影响。 - 新增配置文件时必须同步更新 AGENTS.md 的“技术栈与命令”小节。 - 完成标准lint、typecheck、测试全部通过并且有对应的测试用例覆盖新逻辑。这个骨架没有高大上的词但每一条都能被模型直接执行。你可能会发现有些内容会和你现有的 ESLint 规则重复没关系AGENTS.md 的价值不是替代 linter而是把 linter 背后的“为什么”和“不可见的约束”讲清楚。比如 ESLint 可以禁止某个函数使用但解释不了为什么某条业务规则必须走某个接口。3.3 每一条规则都要能回答四个问题我写规则多了总结出一个自检清单每一条规则如果回答不了下面四个问题要么删掉要么重写。第一个问题这条规则是“可验证”的吗好的规则带有明确的判断标准。比如“代码风格保持整洁”不可验证“使用 biome 并开启默认规则CI 中执行 lint 检查”可验证。第二个问题这条规则是“必要”的吗如果模型不知道也不会产生错误行为那就别写。AGENTS.md 不是收藏夹写满规则会让每一条的权重都下降。第三个问题这条规则有“明确主体”吗约束的是谁、什么类型文件、什么场景都应当写清楚。第四个问题这条规则和现有代码事实一致吗你可以随手抽查几个文件是否真的遵守了规则如果代码库本身违反了规则模型反而会困惑到底该听谁的。还要注意“表达方式”。我发现用否定句太多时模型容易矫枉过正。比较下面两句错误示范不要使用 any 类型不要在业务代码里写复杂语句。正确示范业务代码中的函数类型必须显式定义若推断出 any需要重写类型或使用明确断言。前者只说了“不要”模型需要自己判断边界后者给了替代路径模型照着执行就行。尽量多写“应该怎么做”少写“不能怎么做”。3.4 用版本控制维护这份记忆把 AGENTS.md 看成普通代码一样维护。我建议把它加入 PR 的变更要求如果这次改动引入了新的目录结构、替换了默认命令、调整了模块边界PR 描述里必须勾选“已同步更新 AGENTS.md”。这个动作不复杂但能防止规则文档慢慢变成“僵尸文档”。另一个经验是别让 AGENTS.md 陷入“无人所有权”。如果团队里每个人都觉得自己能改最后多半没人改。更好的做法是指定某个资深开发者担任“记忆维护者”或者至少在 code review 时明确要求修改 AGENTS.md 的 PR 必须由熟悉架构细节的人审核。你要知道这份文件的正确性直接影响后面所有 AI 生成代码的质量它值得享有和核心业务代码同等程度的审查待遇。4. Memory 工程落地从 IDE 到工作流4.1 三层记忆项目级、模块级、会话级一份 AGENTS.md 并不能覆盖所有场景尤其当仓库变得庞大。我的经验是采用三层记忆结构。第一层是项目级记忆也就是根目录 AGENTS.md它描述“整个仓库不可违背的公共约定”。第二层是模块级记忆在每个相对独立的模块目录里放一份局部 AGENTS.md覆盖该模块的特殊逻辑。比如你的项目里有一个专门做数据导入的模块它可能有完全不同的命令、不同的测试方式、不同的目录组织这些细节不应该污染根目录配置。第三层是会话级记忆包括当前任务相关的变更上下文这部分可以由 IDE 工具动态添加或者由你在对话里临时补充。有人会担心多个 AGENTS.md 会不会冲突会所以要定一个规则子目录里的配置必须和根目录配置保持兼容子目录只允许追加更具体的约束不允许推翻根目录的公共约定。如果真想推翻公共约定那就说明根目录的约定已经过时应该先改根目录再同步所有子目录。这种“从根到叶逐层细化”的思路和大型前端项目的样式层级管理很像全局设计规范是底线局部组件可以在底线之上有自己更细的规范。4.2 用上下文窗口的思路来约束配置长度模型读取 AGENTS.md 是会占用上下文窗口的。窗口一旦被又长又臭的规则塞满模型反而没有余力读取你真正的任务代码。这就像你给新员工发了 80 页制度手册他翻完手册就忘了今天具体要改哪个文件。怎么控制配置长度我给自己的约束是根目录 AGENTS.md 的核心规则尽量控制在 40 到 60 行以内大约 1 到 2k token。超出这个量就把细节拆到 modules 或 docs 下的分文件里在根配置里只留一个“索引 最核心约束”。另外重要程度排序很重要把最容易影响代码正确性的规则放在文件上半部分把流程类、偏好类的内容放在后半部分。上下文注意力在前后两端更强所以主要规则放头部最有效。还有一个节省上下文的技巧别把一整个接口列表、数据库表结构、超长命令输出写进规则文档。这些东西动态变化快而且可以通过让工具去读代码仓库自行获取。AGENTS.md 只需要给出“路径提示”和“使用规则”比如“数据库迁移文件统一放 migrations/执行入口是 pnpm db:migrate”而不需要列出每一个迁移文件的名字。4.3 把 AGENTS.md 接进常规工程流程最理想的状态是AGENTS.md 不只被 AI 工具被动读取还能融入真实工程流程。有几个低成本做法可以立刻启用。一是提交模板里增加“是否更新 AGENTS.md”的勾选二是 CI 里加一个轻量检查专门比较 AGENTS.md 里提到的目录是否真实存在、提到的命令是否能在项目里的 package 脚本里找到跑一遍就能发现某些规则已经和代码脱节三是把 AGENTS.md 作为“代码生成器”的输入之一如果你团队里已经有一些代码生成脚本可以在生成代码前把根目录配置作为约束传给生成链路减少生成结果的随机性。更有价值的是在 MR 描述、AI 生成的 commit 消息、自动化 changelog 里统一引用 AGENTS.md。这相当于给项目的所有“自动参与者”立了同一个标准不管是人写的代码还是 AI 写的代码都必须运行同一套命令、遵守同一套边界。真正落地的 Memory 工程不是一个文件放在那里当摆设而是让这个文件深度参与项目日常流转的每个环节。5. 常见问题与避坑实录5.1 规则写了模型还是“假装没看见”这是我收到最多的吐槽。遇到这种情况先别急着骂模型对照下面几个原因排查。第一个原因是规则藏在长篇背景介绍里。很多人的 AGENTS.md 开头写了一大段项目意义、产品愿景核心约束放到文件后半段模型很容易对中间内容产生注意力衰减。把最重要的规则提到文件最前面哪怕只是一个“必须遵守清单”也比藏在后面强。第二个原因是规则太抽象。如果模型不知道“领域服务”在代码库里具体指谁那“必须在领域服务里做校验”就是一句废话。规则里应该带上真实路径、类名后缀、文件示例。第三个原因是规则之间互相矛盾。比如一条说“所有工具函数必须放 utils”另一条说“各模块自包含禁止公共工具层”模型无法同时满足自然会随机挑一条执行。规则写完之后至少通读一遍找出冲突并消解。5.2 AGENTS.md 膨胀成 20KB 大文档怎么办一旦 AGENTS.md 开始变长效率就会急剧下降。我的处理方式很直接把 AGENTS.md 当成“总纲索引”把详细规则拆出去。比如新建 docs/agents/commands.md、docs/agents/architecture.md、docs/agents/commit-guidelines.md根文件里只需要写“常用命令见 docs/agents/commands.md核心约定如下……”这样模型读取时仍然能快速抓住全局需要细节时再按链接寻址。若你的 AI 工具不支持自动读取链接文件那就手动把链接放在对话首条消息里让模型主动读取一般也能达到效果。膨胀还有另一个原因什么都想写进去。我见过有人把内部会议纪要、某位老员工的个人偏好、某个历史事故的完整复盘都塞进 AGENTS.md这其实是把“项目记忆”和“项目知识库”搞混了。记忆工程要解决的是“做变更时应该遵守什么”不是“事情是怎么发生的”。历史背景可以存到知识库但别放在每时每刻都会加载的配置里。5.3 monorepo 和多模块项目怎么拆分记忆在 monorepo 环境下根目录一份 AGENTS.md 肯定不够用但每个包各写一份又会造成大量重复。我的建议是根文件保留“基础设施、全仓命令、公共编码约束、质量门槛”子包文件只写“该包的特有命令、特有架构约束、业务领域规则”。父级和子级合并时采用“子级覆盖同名冲突项新项追加”的策略前提是前面说过的兼容性原则。实操中还有一个监督技巧CI 里可以检查子包的 AGENTS.md 是否引用了根文件未声明的新命令。如果子包里的命令路径和根文件里的包管理器不一致立刻报错。这种方法能防止各个子包各自为政最后整个 monorepo 的 AI 协作变成一盘散沙。5.4 代码和 AGENTS.md 不一致怎么办代码仓库在演进规则文档却常常停在原地。解决这个问题最有效的手段是“让 AGENTS.md 靠近代码事实”而不是“让代码反过来迁就文档”。我每过一段时间会抽查两个模块看看规则里描述的目录结构是否还存在、禁止的依赖是否已经被移除、命令是否还能跑通。发现偏差后优先修改 AGENTS.md 而不是代码因为代码是已经运行的现实文档才是时间的阴影。如果你团队里有自动生成配置文件的习惯也可以考虑把 AGENTS.md 的部分内容变成生成产物比如目录结构、命令列表通过脚本扫描 package 文件自动生成人工只维护真正需要判断的规则部分。这样一个仓库的生命力会强很多AI 工具拿到的记忆也更容易保持新鲜。再分享一个我坚持很久的小习惯每次在对话里教了 AI 一个新约定我会顺手打开仓库里的 AGENTS.md把这条约定补进去。一次只补一行不追求完美但保证下一次再也不会重复解释。积累一个月你回头看会觉得这个不到 5 分钟的动作价值比调无数遍 Prompt 都大。毕竟 Prompt 是一次性的火焰AGENTS.md 才是能持续燃烧的薪柴。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑