ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

无状态AI编程的Memory工程:AGENTS.md声明式配置实战指南

无状态AI编程的Memory工程:AGENTS.md声明式配置实战指南

1. 从"每次重新解释"到"一次声明":AI编程范式的真实转折点

如果你最近半年深度用过任何一款AI编程助手,大概率经历过这种循环:新开一个会话窗口,把项目结构、技术栈、代码规范、命名习惯、测试框架、甚至"不要用var要用const"这种细节重新交代一遍。运气好的话,AI能记住前几轮对话的上下文;运气不好,聊到第十轮它就开始"失忆",把你三小时前强调过的架构约束忘得一干二净。

这不是模型不够聪明,而是**无状态(stateless)**这个底层特性决定的。绝大多数AI编程工具的本质是:你给它一段上下文,它给你一段补全。会话结束,一切归零。下次再来,它对你一无所知。

我最初也以为这只是"上下文窗口不够大"的问题,后来发现完全不是。就算把窗口扩到几十万token,你依然要面对一个更根本的矛盾:项目的长期知识是稳定的,而每次对话的上下文是易失的。把稳定知识塞进易失容器里,本身就是设计错配。

于是就有了AGENTS.md这类声明式配置文件的出现。它的思路很朴素:既然AI每次都是"失忆"的,那就把项目里那些不该被遗忘的东西——架构约定、目录职责、编码规范、常用命令、禁区清单——写成一个AI每次都会读取的声明文件。模型依然无状态,但它的"工作环境"变成了有状态的。

这个转变的意义,比表面看起来大得多。它标志着AI编程从"对话式提示"走向"工程化配置",从"我教AI做事"走向"我定义AI的工作环境"。前者依赖人的记忆和耐心,后者依赖一份可版本控制、可团队共享、可迭代演进的配置文件。

这篇文章想聊的就是这件事:为什么无状态模型需要Memory工程,AGENTS.md这类声明式配置到底解决了什么问题,以及怎么从零搭出一套真正好用的配置体系。不管你是刚接触AI编程的新手,还是已经踩过一堆坑的老手,下面这些内容应该都能帮你少走点弯路。

2. 无状态模型的三个硬伤,以及为什么"多聊几句"救不了

2.1 硬伤一:上下文是消耗品,不是资产

很多人对AI编程有个误解,觉得"只要我提示词写得够详细,AI就能一直靠谱"。实测下来,这个假设在单次任务里勉强成立,一旦跨任务就崩。

原因在于,上下文窗口里的内容是有"优先级衰减"的。你开头写的架构说明,随着对话推进会被后续的代码片段、报错信息、调试记录不断挤压。模型对早期内容的注意力会下降,这不是bug,是注意力机制的固有特性。

我做过一个粗糙的测试:让AI在一个会话里连续完成五个小功能,每个功能都涉及"所有API调用必须走统一的request封装"这条约束。第一个功能它老老实实遵守,第三个功能开始偶尔绕过封装直接fetch,第五个功能基本忘光了。全程我一个字都没改过约束,它自己"忘"的。

这说明什么?上下文里的信息不等于模型的行为约束。你写进去了,不代表它会一直执行。而无状态模型每次重启,连这点"临时记忆"都没了。

2.2 硬伤二:知识无法沉淀,团队无法共享

第二个问题更隐蔽,但对团队协作的伤害更大。

假设你花了两小时,终于把AI调教得能按你们团队的规范写代码了。这套"调教成果"存在哪?存在你那个会话窗口里。关掉就没了。同事想用?对不起,他得自己再调教一遍。新人入职?他连从哪开始都不知道。

这就是无状态模型的第二个硬伤:它让"如何与AI协作"这件事变成了个人经验,而不是团队资产。每个人都在重复造轮子,每个人踩的坑都不一样,但没人把这些坑固化下来。

对比一下传统工程实践:代码规范写成ESLint配置,构建流程写成CI脚本,部署步骤写成Dockerfile。这些都是"声明式"的,写一次,所有人受益,还能进版本控制。而AI协作呢?大部分团队还停留在"口口相传"的阶段。

2.3 硬伤三:提示词越写越长,维护成本指数上升

第三个硬伤是前两个的必然结果。既然上下文会衰减、知识无法沉淀,那人的本能反应就是"那我写长一点、写全一点"。

于是你看到很多人的提示词模板越来越夸张:开头五百字项目背景,中间八百字编码规范,结尾三百字禁区清单。每次新会话都要粘贴一遍,改一个细节要同步改五个地方,不同人手里的版本还各不相同。

这套东西维护起来有多痛苦,用过的人都懂。更讽刺的是,你写得越长,模型对每一段的注意力反而越分散,效果未必更好。用堆砌对抗遗忘,是典型的用战术勤奋掩盖战略懒惰。

三个硬伤指向同一个结论:无状态模型缺的不是"更多上下文",而是一个独立于会话、可持久化、可声明、可共享的配置层。这就是Memory工程要解决的问题,也是AGENTS.md这类文件存在的理由。

3. AGENTS.md到底声明了什么:一份配置文件的解剖

3.1 它不是提示词,是"工作环境说明书"

先纠正一个常见误解:很多人把AGENTS.md当成"更长的系统提示词"。这个理解偏了。

提示词是任务级的,针对某一次具体请求;AGENTS.md是项目级的,描述的是这个项目长期不变的约定。打个比方,提示词像是你给外包同事发的"这次帮我改个登录页"的需求,AGENTS.md像是你给他的"我们公司代码库的入职手册"。前者每次不同,后者基本稳定。

这个定位差异决定了写法差异。提示词可以很口语、很具体、很临时;AGENTS.md必须结构化、稳定、可长期维护。它回答的不是"这次做什么",而是"在这个项目里,事情一般怎么做"。

3.2 一份合格的AGENTS.md通常包含哪几块

我翻过不少团队的实际配置,也自己迭代过好几版,总结下来,一份好用的AGENTS.md基本逃不出这几块内容:

模块作用典型内容
项目概览让AI快速建立全局认知技术栈、目录结构、核心模块职责
编码规范约束代码风格与写法命名约定、导入顺序、错误处理模式
命令清单告诉AI怎么跑项目安装、启动、测试、构建、lint命令
禁区清单明确不能碰的地方禁止修改的文件、禁止引入的依赖
协作约定定义AI的工作方式改动前先说明、大改先给方案、提交信息格式

注意最后一块"协作约定",这是很多人会忽略但极其重要的一环。它约束的不是代码,而是AI的行为模式。比如"任何涉及三个以上文件的改动,先输出方案再动手",这一条能帮你省下大量返工时间。

3.3 为什么是Markdown,为什么是"声明式"

有人会问,为什么不用JSON、YAML这种更"结构化"的格式?

因为AGENTS.md的读者是语言模型,不是程序。Markdown的层级、列表、加粗这些视觉信号,恰好是模型理解"哪些是重点、哪些是分类"的天然线索。用YAML写规范,模型也能读,但可读性和可维护性对人都差很多。

至于"声明式",核心在于描述状态而非过程。你不要写"第一步打开文件,第二步找到函数,第三步修改",而要写"所有网络请求必须经过request模块"。前者是命令式,后者是声明式。声明式的好处是:不管AI用什么方式实现,只要结果符合声明就行,给了模型更大的发挥空间,也减少了你的维护负担。

4. 从零搭一套Memory体系:我的分层配置实践

4.1 分层思路:全局、项目、任务三层各管各的

一上来就把所有东西塞进一个AGENTS.md,很快就会变成一锅粥。我踩过这个坑,后来改成三层结构,清爽很多。

全局层放那些跨项目通用的约定,比如"回答用中文""代码注释用英文""不确定时先问不要猜"。这层内容基本不变,可以放在用户级配置里。

项目层就是AGENTS.md的主战场,放这个项目特有的技术栈、目录结构、命令、规范。这层随项目走,进版本控制。

任务层是临时的,针对当前这次具体工作,比如"这次只改登录模块,别动其他文件"。这层可以放在会话开头的提示里,用完即弃。

三层各司其职,改哪层改哪层,不会互相污染。关键是不要把任务级的东西写进项目级,否则AGENTS.md会越来越臃肿,最后没人愿意维护。

4.2 项目层AGENTS.md的实操模板

下面这份是我目前用得比较顺的模板,你可以直接抄去改:

# 项目协作说明 ## 技术栈 - 语言:TypeScript 5.x - 框架:React 18 + Vite - 状态管理:Zustand - 测试:Vitest + Testing Library ## 目录职责 - src/components:纯展示组件,不含业务逻辑 - src/features:按功能域组织的业务模块 - src/lib:与框架无关的工具函数 - src/api:所有网络请求封装,禁止在组件里直接fetch ## 编码规范 - 组件用函数式,禁止class组件 - 变量命名用camelCase,常量用UPPER_SNAKE_CASE - 所有异步操作必须处理错误分支 - 导入顺序:外部依赖 → 内部模块 → 类型 ## 常用命令 - 安装:pnpm install - 开发:pnpm dev - 测试:pnpm test - 构建:pnpm build ## 禁区 - 不要修改 src/lib/legacy 下的任何文件 - 不要引入新的状态管理库 - 不要改动 vite.config.ts 的别名配置 ## 协作约定 - 涉及三个以上文件的改动,先给方案再动手 - 每次改动后说明改了哪些文件、为什么 - 不确定的地方先问,不要自行假设

这份模板大概一百多行,覆盖了日常八成场景。注意"禁区"和"协作约定"这两块,是真正能帮你省时间的地方。

4.3 一个容易被忽略的细节:命令要写"可复制"的

我见过不少AGENTS.md把命令写成"运行测试套件"这种描述性文字。这其实浪费了声明式配置的价值。

正确做法是把命令写成可以直接复制执行的形式,比如pnpm test --watch。这样AI在需要验证改动时,能直接调用,不用猜你们项目到底用npm还是pnpm、用test还是vitest。命令写得越具体,AI的自主性越强,你被打断的次数越少。

同理,路径也要写全。别写"配置文件",写src/config/app.config.ts。模型不需要你省字,它需要的是精确。

5. 声明式配置踩过的坑:五个真实教训

5.1 坑一:写得太满,反而没人看

我第一版AGENTS.md写了四百多行,恨不得把团队三年的规范全塞进去。结果呢?模型开始"选择性忽略",我自己也懒得维护,改一处忘一处。

后来我做了个减法:只保留那些"不写就会出错"的条目。比如"不要用var"这种,其实ESLint已经管了,没必要写。真正要写的是那些工具管不了、只有人知道的约定,比如"这个模块的历史包袱很重,改动要格外小心"。

判断标准很简单:如果这条约定违反了,会不会导致返工或线上问题?会,就写;不会,就删。

5.2 坑二:把"建议"和"强制"混在一起

早期我写规范时不分轻重,结果模型分不清哪些是硬约束、哪些是软偏好。比如我写了"尽量用函数式组件",它有时候用有时候不用,我还怪它不听话。

后来我学乖了,用词上做区分:强制项用"必须""禁止",建议项用"优先""尽量"。模型对这类程度词的敏感度比想象中高。更狠一点的做法是,把强制项单独列一个"硬约束"小节,视觉上就区分开。

5.3 坑三:忘了写"怎么验证"

这是最容易被忽略的一条。你告诉AI"改完要测试",但没告诉它"怎么测试算通过"。结果它跑了个测试命令,看到没报错就以为完事了,其实测试根本没覆盖到改动的地方。

解决办法是在AGENTS.md里明确验证标准。比如"改动API层后,必须运行pnpm test:api,且所有用例通过"。把验证动作和验证标准都写清楚,AI才知道什么叫"做完了"。

5.4 坑四:配置和代码不同步

AGENTS.md最大的敌人是"过期"。项目重构了,目录结构变了,配置还写着老路径;依赖升级了,命令变了,配置还是旧的。模型照着过期配置干活,出的错比没有配置还离谱。

我的做法是把AGENTS.md纳入代码评审。任何涉及目录结构、命令、依赖的改动,PR里必须同步更新AGENTS.md。这听起来麻烦,但比事后排查"为什么AI老是找错文件"要省事得多。

5.5 坑五:以为写了就万事大吉

最后一个坑最隐蔽:把AGENTS.md当成"一劳永逸"的银弹。

它不是。模型依然会犯错,依然会偶尔忽略配置。声明式配置的作用是大幅降低出错概率,不是消除出错。你还是要在关键节点做检查,尤其是涉及数据、权限、线上配置的改动。

我的经验是:配置负责让AI"大概率做对",人负责在"关键处兜底"。两者不是替代关系,是配合关系。

6. 范式转换的深层逻辑:从"教AI"到"定义环境"

6.1 为什么说这是范式转换,不是工具升级

表面看,AGENTS.md只是多了个配置文件。但往深了想,它改变的是人和AI的协作关系。

在"对话式提示"范式里,人是老师,AI是学生。每次协作都是一次教学,教完就忘,下次重来。人的精力大量消耗在"重复解释"上。

在"声明式配置"范式里,人是环境设计者,AI是环境里的执行者。你不再教它每一步怎么做,而是定义好它工作的边界、资源和规则,让它自己在里面跑。人的精力从"重复解释"转移到"设计环境"和"关键决策"上。

这个转变,和软件工程从"手写汇编"到"高级语言+编译器"的演进,本质上是同一类事情:把重复的、易错的、可固化的部分抽象出来,让人专注于真正需要判断力的部分。

6.2 Memory工程的边界:什么该记,什么不该记

既然是Memory工程,就得回答"记什么"。我的判断标准是三条:

第一,记"稳定"不记"易变"。技术栈、目录结构、编码规范这些半年不变的东西,值得记。今天要改哪个bug、明天要加哪个功能,不值得记。

第二,记"隐性"不记"显性"。ESLint能管的,不用记;只有老员工才知道的"这个模块别乱动",必须记。Memory的价值在于承载那些工具无法表达的团队知识。

第三,记"高频"不记"低频"。天天用到的约定优先记,一年用一次的边缘情况可以放放。配置的维护成本是有限的,要用在刀刃上。

6.3 一个反直觉的结论:配置越少,效果越好

最后分享一个我踩了很多坑才悟出来的结论:AGENTS.md不是越全越好,而是越精越好。

我见过效果最好的配置,往往只有五六十行,但每一条都是"血泪教训"换来的。相反,那些动辄几百行的"大而全"配置,模型读起来费劲,人维护起来更费劲,最后沦为摆设。

这背后的逻辑是:声明式配置的价值不在于"覆盖多少",而在于"命中多少"。十条精准的约束,比一百条泛泛的规范有用得多。与其追求全面,不如追求精准——每写一条,都问自己"这条真的会改变AI的行为吗",答不上来就删掉。

7. 落地建议:从今天开始能做的三件事

如果你读到这里,想动手试试,我给三个从易到难的建议。

第一件,先写一份最小可用的AGENTS.md。不用追求完美,把技术栈、目录结构、常用命令这三块写清楚就行。这三块是AI最常需要、也最容易搞错的信息。写完放进项目根目录,下次开新会话时让它先读一遍,你会立刻感受到差别。

第二件,把"禁区清单"单独拎出来。这是投入产出比最高的一块。列出那些"改了会出事"的文件和目录,明确告诉AI别碰。这一条能帮你避免大部分低级事故。

第三件,建立配置的更新机制。把AGENTS.md纳入代码评审,任何结构性改动同步更新。这一步不做,前面两步的收益会随时间快速衰减。

至于更进阶的分层配置、多环境配置、配置的自动化校验,可以等基础跑顺了再逐步加。Memory工程是个长期活,别指望一次到位。

我在实际使用中最大的体会是:AI编程的上限,不取决于模型多强,而取决于你给它搭的环境多好。同样一个模型,在裸奔状态下和在有良好配置的环境里,表现差距可能是数量级的。与其抱怨AI"不够聪明",不如先检查一下,你有没有给它一个值得聪明的环境。

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进