145 行 AGENTS.md,怎么管住 AI 不写垃圾代码

让 Claude / Cursor / Copilot 帮你写代码这事儿,听起来很美。真用起来你就知道——AI 写代码,跟刚毕业又心高气傲的新人差不多:能写、能跑、看着挺像模像样,但你不盯紧了,第二天你就在屎山里游泳。

不是说 AI 不行——是它不知道这个项目的规矩。它没经历过你踩过的坑,没看过那个失败现场,不知道为什么”全屏 OCR”在这个项目里是禁忌。

所以我们项目里有一份 AGENTS.md,145 行,专门写给 AI 看的。这篇说说每一条背后的真实账。

为什么要写这种文件

最早不写。让 Cursor 在项目里自由发挥,结果:

  • 同样的工具方法,AI 重复造了三份,分散在三个文件
  • AI 喜欢用 getattr(obj, 'xxx', None)——可读性灾难
  • AI 写新功能时完全无视项目已有的命名规范、目录结构
  • 测试里硬编码本机绝对路径
  • 写到一半把已有的功能误删,理由是”看起来没用到”

每一条都得人肉去 review、回滚、改正。比自己写还累。

后来想通了——AI 不是不能写,是不知道边界。把边界写出来,明确告诉它”这种事不能做”“那种事必须做”,效果立马不一样。

AGENTS.md 就这么诞生了。

文件长什么样

挑几段贴出来。完整文件 145 行,分几个大块:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
## 基本要求
* 所有回复必须使用简体中文。
* 代码注释必须使用中文。
* 所有方法必须带有文档注释和类型标注,按 Python 官方风格编写。
* 不理解需求、资料不足、样本不足、规则冲突时,必须停止并询问用户,禁止盲做。
* 不得伪造测试通过、删除失败样本、跳过失败用例或隐藏失败原因。

## 图像识别要求
* 禁止使用强模板匹配作为核心方案。
* 禁止写死绝对坐标。
* 禁止假定固定分辨率、固定截图尺寸或固定 UI 缩放。
* 识别逻辑应使用相对位置、检测框、轮廓、颜色、OCR、目标检测、多信号融合等方式。

## 代码风格
* 字符串匹配必须使用 src/utils/string_tools.py
* OpenCV 可复用方法在 src/utils/opencv_tools.py
* 容易造成性能问题的方法需使用 src/utils/performance_tools.py 装饰
* 游戏主数据库读取需使用 src/utils/game_database_tools.py
* 点击 Yolo_Box/元素尽量使用 device.click_element() 非自行判断的坐标不允许使用 device.click()
* 尽可能不使用全屏 OCR,效率过低,可以使用 HSV+蒙版提取参考点后再 OCR

看着像古板老板娘列的车间规矩——其实每一条背后都有一次具体的”事故”。

几条规则的真实账

挑几条最有代表性的展开说说。

“禁止使用强模板匹配作为核心方案”

模板匹配是新手最容易上手的方案——截一张按钮的图,cv2.matchTemplate 一调,搞定。

我们早期就这么干的。然后游戏更新了一次,按钮换了配色——所有模板全废。再然后用户用 1920×1080 之外的分辨率——所有模板全废。再再然后某个皮肤更换——所有模板部分失效。

短短两个月模板库重做了三轮。最后下狠心全部迁到 YOLO + OCR + CLIP 的多信号融合。这条规则就是那段血泪的产物

不写在 AGENTS.md 里?AI 看你代码里有 cv2.matchTemplate 的痕迹,下次写新功能保准给你来一段——它觉得”这个项目已经在这么做了”。

“尽可能不使用全屏 OCR,效率过低”

OCR 跑全屏是个昂贵操作。一张 1920×1080 截图丢给 OCR,CPU 单线程上要花 200~500ms。每次决策都这么搞,UI 直接卡死。

正确做法是先用便宜的方式(HSV 蒙版、YOLO 框)定位到目标区域,再对小区域做 OCR。30×100 像素的 OCR 大概 10~20ms,差一个数量级。

AI 不知道这个性能差距。它写代码图省事,“管它呢,OCR 跑一遍最直接”。写在规则里,每次它要做识别都得想一下”是不是该先收窄区域”。

“点击 Yolo_Box/元素尽量使用 device.click_element(),非自行判断的坐标不允许使用 device.click()”

click_element 接受一个 YOLO 检测框,内部会算出框中心点再点击。click(x, y) 接受坐标。

为啥要分?因为坐标是相对于截图分辨率的。同一个像素坐标在不同分辨率下指向完全不同的 UI 元素。click_element 内部会做坐标系转换,click 不会。

AI 第一反应永远是 click(x, y)——它觉得直接。然后用户分辨率一换,所有点击全偏。

规则写明白,AI 至少会先尝试 click_element,找不到合适的 element 再考虑 click

“能复用的工具方法尽量写到 src/utils 中”

这条针对的是 AI 最喜欢的毛病——重复造轮子

让 AI 加个新功能,它需要个”模糊字符串匹配”。它不会去翻你 string_tools.py 看有没有,直接在新文件里写一个 def fuzzy_match(...)。下个月需要类似功能时,又写一个略有不同的 def similar_match(...)。半年后你的项目里散落着八个”模糊匹配”实现,谁都不知道该用哪个。

规则写明白,AI 会先去 src/utils 翻翻。即使它还是想新写一个,至少会留个”我没找到合适的现有方法”的说明,方便你 review 时纠正。

“不理解需求、资料不足、规则冲突时,必须停止并询问用户”

这条是反 AI 本能的——AI 天生爱”自圆其说”。你给它一个模糊需求,它会自己脑补一个合理的解释然后开始动手。代码写得很顺,但走的不是你要的方向。

写明白”不懂就问”,AI 至少在执行前会先确认。哪怕只是确认 30% 的细节,也比闷头干完后推倒重来强。

“不得伪造测试通过、删除失败样本、跳过失败用例或隐藏失败原因”

这条够直白,听起来还有点搞笑——但真的发生过。

AI 跑测试发现某个用例失败,第一反应是”分析失败原因然后修”。当它修不动的时候,它会非常自然地”修改测试本身让它通过”——把 assert 改宽松、把测试 skip 掉、甚至直接 mock 掉被测函数。

第一次发现这事儿的时候我盯着 diff 看了好几分钟才反应过来。AI 没”恶意”——它只是把”测试通过”当成 KPI 了,达成 KPI 的最短路径就是改测试。

写规则不能让你完全杜绝,但能极大降低发生率。每次 review 也得专门盯一下”测试本身有没有被改”。

反 AI 味的几条

除了”禁止做什么”,还有”必须怎么写”的约束。这部分针对的是 AI 特有的写作病。

1
2
3
4
5
## README 与文案约束
* README 应像真实项目维护者写的文档,禁止写成营销页、宣传稿或 AI 生成味很重的长文。
* README 只写用户真正需要的信息:项目用途、安装方式、基本用法、配置说明、常见问题、开发说明。
* 禁止把实现细节、内部调试过程、无关背景、过度优势描述、空泛愿景塞进 README。
* README 中的功能描述必须与当前代码真实能力一致,未完成能力必须明确标注状态,禁止夸大。

AI 写 README 的味儿很冲——

🌟 这是一个革命性的工具,重新定义了 XXX 的体验。本项目采用先进的 AI 技术……

谁看了不抠脚?写规则强制把这种 hype 内容删掉。

1
2
3
## UI 文案
* UI 文案、设置项说明、提示文本必须简短、明确、可操作。
* 错误提示应说明发生了什么、用户能做什么;不要输出堆栈、内部变量名或调试废话。

AI 写错误提示也是一绝——

在执行 task_runner.execute_step() 方法时遇到 ConnectionResetError, 详情:Connection reset by peer (errno 54)。请检查 src/core/device/Android/adb_client.py 第 234 行。

这种提示甩给普通用户,等于让他自己看堆栈。规则强制 AI 把堆栈隐藏到日志里,UI 上只显示”连不上设备,请检查 USB 线”。

写 AGENTS.md 的几条心得

写了几版之后总结的:

1. 规则要带”为什么”,至少在团队内部知识里要有。

AGENTS.md 本身要简洁,但每条规则背后的原因得有记录——可以是 commit message、可以是单独的 ADR、可以是内部文档。AI 偶尔会”挑战”规则(“我觉得这条不适用于当前场景”),有原因记录在你能直接反驳。

2. 规则越具体越好,避免空话。

“代码要清晰”是废话。“字符串匹配必须使用 src/utils/string_tools.py”是规则。前者 AI 当耳边风,后者它真的会查。

3. 规则数量要克制。

145 行已经接近上限——再长 AI 自己都注意力涣散。每加一条规则都要问:这条值不值得占 AI 的注意力预算?

4. 规则要定期 review。

项目演进过程中,有些规则会过时(比如某个工具方法被废弃),有些新坑要补上规则。每个季度过一遍 AGENTS.md,删过时的、加新的。

5. 把规则和实际审查结合。

写规则不等于强制执行。AI 还是会偶尔越界,PR review 时人要盯一下。我们的做法是 review checklist 直接对照 AGENTS.md 的几个关键条款——“有没有写死坐标”“测试有没有被改弱”。

一个意外收获

AGENTS.md 写完之后,我们发现一件有意思的事——这份文件不仅对 AI 有用,对新加入的人类同事也很有用

新人来了,让他先读一遍 AGENTS.md,半小时就能把项目的”边界规矩”理清楚。比口口相传”哦对了我们不许用模板匹配”靠谱得多。

某种意义上,写给 AI 的规范,最后变成了这个项目最浓缩的工程文化沉淀

收个尾

让 AI 写代码这事儿,未来肯定越来越普遍。但 AI 永远不会自己知道”这个项目的规矩”——这些规矩是你踩坑踩出来的,是你的工程文化,是你团队的共识。

把这些规矩显式写出来,是给 AI 一份”入职手册”。它不会替你做决策,但至少能在你的边界内做事。

不写 AGENTS.md 让 AI 写代码?就跟新人入职第一天没人带、没文档、没规矩,让他自由发挥一样——能用的产出占比,懂的都懂。

欢迎关注我的其它发布渠道