开发教程

给已有项目补一份 AI 预读取文档:AGENTS.md 与上下文治理实践

编辑部阅读约 6 分钟

已有项目接入 AI 编程工具后,光给 PRD 和截图往往对不准代码。问题通常不在模型,而在项目缺少一份常驻的约定文档。本文说明该补什么样的文件、写哪些内容、如何用渐进式披露拆分大文档,以及规则维护和提需求方式的改进清单。

问题:为什么把 PRD 和截图喂给 AI,代码还是写偏

一个典型的场景是:后端出身的人接手前端项目,把需求文档、原型图、截图一起丢给 AI 编程工具,让它生成或修改页面。结果经常是——接口字段名对不上、组件参数用错、样式引入了项目里根本没有的库、明明有现成的公共组件却重新手写了一遍。反复纠正几次,效率反而不如自己写。

PRD 只回答「要做什么」,不回答「这个项目里该怎么做」。技术栈、组件库版本、目录约定、字段命名、金额与时间的存储方式、哪些文件不许碰,这些信息在需求文档里从来不会出现,但它们恰恰决定了生成结果能不能直接落到代码里。所以需要补的不是更详细的需求,而是一份每次对话都会被读取的项目约定文档。

先分清两种上下文:任务上下文与常驻上下文

  • 任务上下文:本次要改什么、涉及哪个页面、验收标准。它是临时的,一次任务结束就没用了。
  • 常驻上下文:项目是什么、用了什么技术栈、遵循哪些约定、有哪些历史坑。它需要长期存在、反复被读、持续演进。

绝大多数准确率问题,是常驻上下文缺失造成的。补的方式不是写一份巨长的说明丢给 AI,而是建立一个分层的、可维护的规则体系。

载体选择:不同工具读不同的文件

载体 典型使用者 适用场景
AGENTS.md 支持该约定的多种工具 跨工具共用的项目说明,放在仓库根目录
CLAUDE.md Claude Code 一类工具 项目规则与 Agent 行为约束
.cursorrules 或项目规则目录 Cursor 一类编辑器 编辑器内的补全与对话
子目录规则文件 支持目录级规则的工具有 大型仓库按模块隔离约定

具体文件名和加载优先级各工具并不相同,且仍在变化,配置前请以对应工具的官方文档最新说明为准。稳妥做法是:先写一份内容中立的 AGENTS.md 作为唯一事实来源,再用各工具的入口文件引用或复制关键条目,避免同一份规则维护两套。

初版该写什么:五段结构

不要一上来就写几十页。第一版控制在能覆盖 80% 常见错误的长度,重点写「不写就会错」的东西:

# 项目概览
B 端后台,前端 Vue 3 + Vite + TypeScript,后端 FastAPI,数据库 PostgreSQL。

# 技术栈与版本
- 组件库:使用仓库内已有的 UI 库,禁止自行升级大版本或引入同类新库
- 状态管理:Pinia,禁止引入 Vuex
- 请求层:统一走 src/api/request.ts,禁止在组件内直接 fetch

# 目录与命名约定
- 页面:src/views/<模块>/ ;复用组件:src/components/
- 接口类型统一放 src/types/,返回值必须有类型

# 边界与特殊逻辑
- 金额以整数分存储,仅展示层除以 100
- 时间统一按 UTC 存储,仅展示层做时区转换
- 分页参数以 1 为起始页,与后端保持一致

# 禁止事项(踩过的坑逐条追加)
- 禁止用 any 绕过类型检查
- 禁止修改 .env、部署脚本、依赖锁文件
- 禁止在 components 下发起业务请求

其中「禁止事项」是最有价值的一段。它不需要一开始就完整,而是随着每次 AI 犯错不断追加——相当于把踩过的坑沉淀成约束,写得越久越值钱。

大项目别塞进一个文件:渐进式披露

仓库一大,把所有文档都堆进根目录文件,会带来两个后果:每次都消耗大量上下文,真正关键的几条反而被淹没。更合理的做法是分层披露,让 AI 先读精简的入口,需要时再去读细节:

repo/
├── AGENTS.md              # 常驻:项目是什么、技术栈、硬性禁止项
├── docs/
│   ├── architecture.md    # 按需:模块划分、调用链
│   ├── components.md      # 按需:组件用法、常见参数与版本差异
│   └── pitfalls.md        # 按需:历史边界问题与踩坑记录
└── .agents/
    └── skills/
        └── new-endpoint/
            └── SKILL.md   # 可复用流程:新增接口的标准步骤

入口文件里写清「什么情况下该去读哪个文件」,比把内容全部前置更有效。进一步可以按用途再分三层:项目规则(人工维护、变更需评审)、长期偏好与经验(半自动积累)、临时工作笔记(任务结束即清理)。很多团队做的所谓「记忆文件演化」,本质就是让这三层各自有生命周期,别混在一起。

提需求的方式同样影响准确率

有了规则文件之后,任务描述也要配合。把需求定位到具体模块和接口,比写一大段自然语言描述有效得多:

根据 AGENTS.md 与 docs/components.md,在 src/views/order/ 下新增订单导出按钮。
约束:只改该目录;复用 ExportButton 组件;不要改动 api 层以外的文件。
先列出将要修改的文件清单,确认后再动手。

三个要点:指明参照哪份文档、圈定可改范围、要求先给计划再改代码。这样即使 AI 理解有偏差,也能在改代码之前被发现。

常见误区与注意事项

  • 规则膨胀:文件越长,模型越容易顾此失彼。定期删掉已经内化或过期的条目,保留仍然会出错的那些。
  • 规则冲突:两条互相矛盾的约定会让输出摇摆不定。合并同类项,同一件事只留一条。
  • 写进敏感信息:令牌、内网地址、数据库连接串不要写进规则文件,它会随仓库一起被提交和读取。
  • 过度依赖记忆工具:动态记忆类方案适合长期对话场景,但对「让代码写得对」这件事,一份准确的项目约定往往比一套记忆框架更直接。先把手写规则跑顺,再考虑引入工具。
  • 以为写完就一劳永逸:技术栈升级、组件库换版本后,文档必须同步更新,否则它比没有更糟。

另外,如果团队需要让 Agent 长时间在线跑批量重构或定时巡检,本地机器休眠断连会打断任务,可以考虑把运行环境放到一台常驻的机器上(例如按月租用的远程 Mac)。但这只解决运行连续性问题,不能替代上下文治理——文档写不好,跑多久都还是偏。

小结:一份可执行的检查清单

  1. 在仓库根目录建立 AGENTS.md,按「概览 / 技术栈 / 目录约定 / 边界 / 禁止事项」五段起草,控制长度。
  2. 把组件库版本差异、金额与时间处理、分页与字段命名这类最容易出错的约定单列出来。
  3. 文档超过一屏时,拆成 docs/ 下的专题文件,入口只留导航和硬性规则。
  4. 每次 AI 犯错,追加一条禁令,并注明原因,避免后人误删。
  5. 提需求时指明参照文档、限定改动范围、要求先出文件清单。
  6. 每隔一段时间清理过期规则,检查是否存在互相矛盾的条目。
  7. 规则文件纳入代码评审,和代码一起演进。

补文档这件事的投入产出比通常很高:前期花一两个小时梳理,后续每次对话都能省下反复纠正的时间。先从最容易错的三五条写起,比追求一份完美的大而全文档要现实得多。

CLAUDE.mdAI编程AGENTS.md上下文治理项目文档