AI 编程工具容易重复犯错,核心是记忆问题而非提示词问题;AGENTS.md 应作为项目级上下文文件编程,而非人类文档。
如果你使用编程 AI 智能体超过一定时间,就会撞上同一堵墙:它不断犯你已经纠正过的错误。错误的包管理器、禁用的模式、修改了不该碰的文件。你修了,它又犯,你再修,最后你花在监督工具上的时间比它帮你省下的还多。
标准建议是"写更好的提示词"——这就把一个记忆问题当成了措辞问题。真正的解决方案是架构层面的:给 AI 智能体一个永久的、项目级的上下文文件,它在每次会话开始时都会读取。这个文件叫 AGENTS.md,它是你能给 AI 智能体的最接近记忆的东西。
但这里有个陷阱:大多数人创建了一个却发现没有任何改变,因为他们用散文填满了它。他们写了一篇文档,AI 智能体忽略了它——因为文档本来就不应该是这样的。散文是模糊的,它给 AI 智能体提供的信息无非是它已经默认知道的那些通用项目信息。AGENTS.md 是给 AI 智能体的编程,而不是给人类看的文档。本文解释为什么这个区别至关重要——以及当你把它当作代码来写时,这个文件看起来是什么样的。
编程 AI 智能体是无状态的。会话之间,它们什么都不保留。每次对话都从零开始:一个空白的上下文,加上一套从 AI 智能体在训练中看过的代码推导出的猜测——那是别人的代码,不是你的。
这就是你反复重复自己的全部原因。不是模型不行,也不是你提示词写得不好。AI 智能体真的不知道你的项目用的是 pnpm,不知道你的测试需要运行中的数据库,也不知道 dist/ 是生成的、绝对不能编辑。它得猜,猜错了,你纠正,然后纠正的内容在会话结束的瞬间就蒸发了。
Anthropic 的数据证实了这个差距有多大:工程师在大约 60% 的工作中使用 AI,但完全委托的任务只有 0–20%。缺失的那块不是模型能力——是配置。一个配置良好的 AI 智能体可以自主运行;一个无状态的 AI 智能体则需要不断盯着。
这个文件之所以能解决这个问题,源于一个几乎没有任何指南解释的机制:AI 智能体在每次会话开始时会重新读取它。你在聊天中输入的指令会被更新的 token 掩埋,注意力会漂移——这就是上下文漂移,在每个长对话中都会发生。文件中的指令不会衰减,因为它们是被重新读取的,而不是被记住的。AI 智能体不是从上一个会话中回忆你的规则;它是每次都重新加载它们,新鲜的。
可以把它想象成给 AI 员工的入职文档。README 告诉人类项目是什么。AGENTS.md 告诉 AI 智能体如何在这里工作:确切的命令、约定、"不要碰"的区域,以及已经坑过人的陷阱。
这是一个改变一切的思维转换。文档描述一个系统。代码导致行为。当你像写 README 一样写 AGENTS.md——描述性的、友好的、全面的——你写的就是 AI 智能体读了但大部分会忽略的散文,因为散文是模糊的,而 AI 智能体已经有了内置的默认行为。
当你像写代码一样写它,每一行都有它的作用。一行如果不改变编辑行为,就不配待在文件里。写好它的规则和你写好代码的规则是一样的:
Token 成本是真实存在的。这个文件里的每个词都会在每次会话开始时加载到上下文中,加载到每个任务里。一段 500 词的团队工程哲学背景故事,会挤掉 500 词的实际任务上下文。而上下文膨胀不是免费的——Chroma 2025 年的研究发现,所有 18 个前沿模型在输入增长时准确性都会下降,有些从 95% 跌到 60% 以下。一个臃肿的文件不是中性的;它在主动让 AI 智能体变差。保持在约 200 行以下。如果删除一行不会改变 AI 智能体的输出,就删掉它。
具体性胜过愿景。"写干净、可维护的代码"不起任何作用——AI 智能体本来就在努力这么做。只包含对你的项目特定的、AI 智能体无法从阅读代码中推断出来的规则。"使用 pnpm,不用 npm"会改变行为。"遵循最佳实践"不会。
每个"永远不要"都需要一个"应该用"。纯粹的禁令会造成死胡同。"永远不要用 any"让 AI 智能体不知道该怎么做。"永远不要用 any——用 unknown,然后用类型守卫收窄它"给了它一条退路。同样的规则精简版:"使用 pnpm"是一个 AI 智能体会忘记的事实;"永远不要用 npm——用 pnpm 安装和运行一切"改变了一个行为,并在一行里指出了替代方案。
结构有助于解析。标题、项目符号和精确的命令比段落更容易优先处理。同样内容,组织好了有用十倍。
还有一件事值得坦诚:这是杠杆,不是魔法。正如 Martin Fowler 所说,上下文工程提高了有用结果的概率——它永远无法保证。不管你的文件多好,LLM 还是 LLM。当一条规则必须绝对成立时,不要写在 Markdown 里;用 hook 确定性强制执行。把文件当作 AI 智能体的指导,把 hook 当作它的护栏。
这是骨架。它故意混合了两类内容。精简核心——第 1、5、6、7、9 节——是改变编辑行为的部分:精确的命令、约定、护栏。工作流契约——第 2、3、4 节和第 8 节的"有疑问时"检查清单——告诉 AI 智能体如何运作:先计划再编码、一个审批门、一个技能白名单。那不是填充物;它是对 AI 智能体如何与你协作进行编程。它反映了一种流行的工作流——监督式"凭感觉工程",AI 智能体写自己的实现提示词,然后你审批。运行那个工作流它就有回报;更自主地工作或手动工作就删掉它——精简核心在哪儿都适用。无论如何,这是一个模板,不是最终文件:任何对你的项目不成立的内容都要删除,而不是保留。
# AGENTS.md
你是一个 principal 级别的 <role> 工程师和 AI 实现智能体,工作在 <PROJECT>,<一句话描述>。
你的工作是理解需求,使用正确的项目技能,创建一个清晰的实现提示词,请求审批,然后实现。
---
# 1. 产品
<PROJECT> <它做什么>。
只构建:
- <功能>
- <功能>
不要过度构建。
---
<!-- 可选:工作流契约。第 2–4 节(以及第 8 节中的"有疑问时"检查清单)只有在运行监督式、AI 驱动的工作流(计划、审批、实现)时才值得付出。精简核心用户可以删除它们。-->
# 2. 工作流
对于每个实现请求:
1. 阅读 `AGENTS.md`。
2. 阅读用户明确提到的技能。
3. 阅读批准技能列表中明显需要支持的相关技能。
4. 检查相关代码。
5. 只有当任务有意义的模糊性时,才提出一个聚焦的问题。
6. 在 `prompts/` 中创建一个详细的提示词文件。
7. 问:"我在 `prompts/<文件名>.md` 准备好了实现提示词。可以执行吗?"
8. 只有在用户审批后才实现。
9. 运行可用的检查。
10. 分享确切的步骤来测试或运行完成的功能。
除非用户明确说要跳过提示词创建,否则不要在创建提示词之前写代码。
---
# 3. 技能
只使用这些技能:
- `.agents/skills/<skill>`
不要发明新技能。
---
# 4. 提示词文件
提示词文件放在 `prompts/` 目录中。
每个提示词必须包括:
- 目标
- 已读的技能
- 已检查的现有代码
- 决策或假设
- 可能改变的文件
- 实现需求
- 安全需求
- 验收标准
- 要运行的检查
- 实现后预期的精确手动测试步骤
<!-- 工作流契约可选部分结束。从这里开始都是精简核心——即使没有工作流部分也要保留。 -->
---
# 5. 架构
保持这些层分离:
- <层>:<职责>
- <层>:<职责>
<边界规则,例如"UI 只显示存储的数据。">
---
# 6. 技术栈
使用:
- <栈>
不要使用:
- <栈>
---
# 7. 事实来源
<命名 AI 智能体应该依赖的权威来源——数据库、规范文档、配置文件、API。这是你项目视为 ground truth 的任何东西。>
<每条记录或实体存储什么、必填字段、什么永远不能硬编码或假设。>
---
# 8. 安全、代码标准和最终规则
永远不要暴露给浏览器代码:<密钥>。
永远不要从浏览器代码运行:<有副作用的工作>。
<语言/风格规则:显式类型、不用 `any`、小函数。>
有疑问时:
1. 保持小。
2. 使用相关技能。
3. 保留 server/client 边界。
4. 需要时提出聚焦的问题。
5. 编码前先保存提示词。
6. 问是否可以执行。
7. 确认后实现。
8. 运行可用的检查。
9. 分享确切的测试步骤。
---
# 9. 命令和检查
"运行可用的检查"(第 2 和第 8 节)意味着从项目根目录运行这些并报告结果:
- `<command>` — <它做什么>
- `<command>` — <它做什么>
开发和运行时:
- `<command>` — 启动开发服务器
- `<command>` — 运行测试
实现完成后,运行检查并报告确切输出。未经运行,不得声称检查通过。
现在讲讲人们容易忽略的部分:每个章节为什么存在。先从精简核心开始——四个会随修改而变化的章节:
**Product / "Build only"** — 智能体最清楚自己应该服务于谁、允许构建什么时,表现最好。"不要过度构建"是防止幻觉的护栏:它阻止智能体将一个小请求扩展为对代码库的全面重写。
**Architecture + tech stack** — "不要使用"清单和"使用"清单同样重要。它阻止智能体引入你刻意规避的依赖。
**Source of truth** — 智能体所依赖的事实来源的唯一权威位置,可以是数据库、规范或配置文件。它将模糊的功能需求转化为具体决策,而非靠猜。
**Commands and checks** — 投入产出比最高的章节。精确的调用方式,包括智能体往往会猜错的标志位。"未经运行不得声称检查通过"是证据规则:智能体必须报告真实输出,而非假设成功。
然后是工作流契约——仅在你运行有人监督的智能体驱动工作流时使用:
**Workflow** —— 这才是让文件从文档变成编程的关键。编号步骤和审批门是最重要的部分:智能体做计划,你审批,它执行。这不是文档;这是一个控制循环。
**Skills + prompt files** —— 白名单("不要发明新技能")加上强制性的"计划先于代码"步骤,并定义了必需的章节清单。这就是让审批门真实有效的机制:智能体不可能只展示一行计划就了事。
**Security + final rule** —— 当规则没有覆盖到的情况时的后备检查清单。它告诉智能体在不知道该怎么做时如何表现——而这恰恰是即兴发挥容易出问题的时刻。
Airflow 项目展示了这种做法在现实世界中能做到什么程度。它的 AGENTS.md 指示:"永远不要直接在宿主机上运行 pytest、python 或 airflow 命令——始终使用 breeze。"就这一行,智能体就不会再用错误版本的 Python 环境污染开发者的机器。这是一个能真正避免痛苦的护栏,它之所以有效,是因为它指明了替代方案,而不仅仅是禁止。
如果你使用 Claude Code,有一个实用提示:Claude Code 原生读取 CLAUDE.md,而不是 AGENTS.md。用一行导入桥接它们:
@AGENTS.md
`@AGENTS.md` 导入在会话开始时展开,所以你可以保持单一事实来源,并在其下方添加 Claude 特定的规则。
在我开始使用 AGENTS.md 之前,每个项目的开始都是一样的:初始化仓库,然后打出一长段提示,覆盖我想构建的所有内容、约定和不要触碰的东西。那一次会话是有效的。第二天我打开新会话,所有内容都消失了。我会重复自己,重新纠正一个它之前已经犯过的错误,然后看着它用另一种方式做出类似的错误。很快我就感到沮丧了。
转折点是在做其他事情之前先写一个结构良好的 AGENTS.md。智能体不再重复那些错误——不是因为我提示得更好,而是因为它可以在每次会话时重新读取我的指令,而不是试图记住它们。工作变得更容易了,而且有一个我意想不到的副作用:我消耗的 token 更少了。每个会话反复重新解释一切是最大的 token 浪费,当你为计划付费时,这种浪费就是真金白银。一份好的 AGENTS.md 是廉价的保险,可以防止这种浪费。
真实世界的证明表明这可以规模化
一个文件可能感觉很小。但采用数据说的却是另一回事。
AGENTS.md 现在是一个开放标准,由 OpenAI 于 2025 年 8 月发布,并于 2025 年 12 月与 Anthropic 联合捐赠给 Linux 基金会的 Agentic AI Foundation。它被用于超过 60,000 个开源仓库,并被每个主要智能体原生读取:Codex、Cursor、Copilot、Claude Code(通过导入)、Google 的 Jules、Gemini CLI、Windsurf 等。一个文件,兼容所有工具。这就是标准的意义。
其中最极端的使用案例是 OpenAI 自己的仓库,它内置了 88 个嵌套的 AGENTS.md 文件——一个根文件用于全局约定,每个子项目有子目录文件。智能体会自动读取目录树中最近的文件,所以最近的那个优先。这就是如何从"我的小项目用一个文件"扩展到"monorepo 用一套层级体系"。
在企业端,Context Engineering 配置是使头条智能体故事成为可能的那一层。Rakuten 在 1.25 亿行代码上运行自主代码修复系统;TELUS 将全管道 AI 集成归功于节省了 50 万工程小时。这样的系统必须可靠——而可靠的智能体需要理解它们操作的代码库,这正是编写良好的上下文文件的作用。
对于个人开发者的信息更简单:如果一个拥有 6 万个仓库的开放标准和财富 500 强工程组织都把这个文件当作基础设施,那值得你花三十分钟好好写一份。
让你的文件变得无用的错误
大多数 AGENTS.md 文件失败的原因只有五个。来看看它们长什么样以及如何修复。
1. **写小说**。一篇 500 字的关于代码库历史的论文。它在每个会话中都消耗上下文,却把重要的规则埋没了。修复:无情地删减。如果一句话不会改变智能体的输出,它就是冗余的。
2. **愿望清单**。"写干净、有文档的代码。遵循最佳实践。"智能体默认就会这样做,所以这个文件纯粹是噪音。修复:删除智能体不用告诉就会做对的所有内容。
3. **只有负面规则**。"永远不要使用任何。""不要提交到 main。"没有替代方案,智能体就会即兴发挥——通常表现很差。修复:每个禁止都要有"改为"的说明。
4. **自相矛盾**。"始终编写全面的测试"和"保持会话快速,最小化 token 使用"是相互冲突的。智能体在两者之间摇摆。修复:设定明确的优先级并记录权衡。
5. **设置后遗忘**。这是无声的杀手。最近一项针对 356 个仓库的研究发现,23% 的 AI 配置文件中有过时的代码引用——文件指向重命名的路径、已删除的模块和过时的命令。过时的指令不仅仅是浪费 token;它们会主动误导。修复:像对待代码一样对待这个文件。每月审查一次,在顶部加上 `# last reviewed: YYYY-MM-DD` 注释,删除任何不再反映现实的内容。
你可以在大约半小时内获得全部收益:
**写这个文件**。从上面的模板开始,适配到你的项目:命令、约定、护栏。删除任何不会改变智能体输出的内容。
**验证你的命令**。自己运行每个命令。一个充满无效命令的 AGENTS.md 比没有文件更糟糕。
**运行一个真实的会话**。给智能体一个涉及你约定的任务——一次重构、一个新端点——然后观察它是否遵循文件。
**故意测试一个护栏**。让智能体做你的文件禁止的事情(例如"在这里添加 console.log")。如果它照做了,规则太模糊了——重写为硬约束或移到钩子里。
然后保持新鲜循环:将文件提交到 git,每月审查,并在智能体重复犯错时添加规则。一次变成规则的纠正是一次你再也不需要做的纠正。
**一行要点**
你的编码智能体不受模型限制——而受限于它对你的项目的了解程度。一个简短、具体且维护良好的 AGENTS.md 是你对 AI 工作流所能做的最高杠杆改变。不是因为这个文件有魔力,而是因为它是智能体唯一的永久记忆。
把它当作文档来写,你只是给一本手册加了一段话。把它当作代码来写,你给了一个队友一个大脑。
---
**AGENTS.md 是否取代 CLAUDE.md?**
不。AGENTS.md 是大多数智能体读取的工具无关标准。Claude Code 原生读取 CLAUDE.md——用一行 `@AGENTS.md` 导入桥接两者,这样你就可以保持单一事实来源。
**AGENTS.md 应该多长?**
200 行以内。每个词在每个会话中都会加载到上下文里,上下文膨胀会降低模型准确性。如果删除一行不会改变智能体的输出,就删除它。
**为什么我的编码智能体不断重复犯错?**
因为它是无状态的——它在会话之间忘记一切,从关于你项目的训练数据猜测重新开始。AGENTS.md 在每个会话开始时重新读取,所以它充当智能体的永久记忆。
**AGENTS.md 应该放在哪里?**
仓库根目录。对于 monorepo,在每个子目录添加一个——智能体读取最近的文件,所以最近的那个优先(OpenAI 的仓库内置了 88 个)。
行动号召:将模板复制到你的仓库中,然后运行一个会话。但在这样做之前,先思考一下这个问题的答案:你的编程智能体在每个会话中重复犯什么错误?这就是你文件的第一行。先从那一条规则开始——包括"而不是"那部分——然后测试它。一次修正变成一条规则,就意味着这个错误你再也不会犯第二次。
如需进一步行动,你可以考虑屏蔽此人或举报滥用行为。