文章

给 AI 协作配置做减法

上周我把 platform 项目里的 AI 协作配置推倒重来了一遍。git 统计删了 3513 行,加了 412 行。

四个月前我写过一篇《如何在老项目里用 AI 写代码的一些感悟:从搭系统到落地的一整套方法》,介绍当时搭的那套东西:根目录一个 AGENTS.md 负责规则和路由,ai-doc 目录放知识库,再加四个 skill 分别管开发、调试、测试和知识回写。写那篇的时候我对这套结构挺满意,它在当时也确实管用。但这几个月 GPT-6.1 和 Opus 5.5 相继出来,我日常换着用,越来越觉得它在碍事。这篇记录一下拆的原因和拆完的样子。


直接的导火索是 Todone 里的一个新功能:例行清单。就是每周大扫除、出门前检查这类周期性的事项,到点自动清空,重新勾一遍。

需求我自认为说得很清楚:父级刷新了,继承它的子项就全部重新开始,子项本身没有周期的概念。结果 Agent 自己发明了"本轮"、"提前 N 天进入"、"未到期折叠"一整套概念,把 UI 整个做完才拿给我看。我盯着看了半天,没看懂它在干什么。

一开始我以为是规则不够细。旧的 AGENTS.md 里明明有一条"大改动先对齐架构",我想是不是触发条件没写全。翻回去一看才发现,这条规则的触发条件是跨模块、改 schema 、改接口这些技术特征,而这次的问题根本不在技术上。它把语义理解错了,又用很高的完成度把这个误解实现了出来。之后还有两次,我们还在讨论细节,它已经开始写代码了。

这件事让我意识到,旧体系防的东西和现在实际会出的问题已经错位了。那套配置的前提是模型不太会找东西、不太会安排工作,所以我替它规划先读什么后读什么、改动分大小、修 bug 先复现、测试按风险分级。现在的模型这些都会,做得还比我写的规则细。真正的风险变成了它太能干:一个误解,它能给你实现得完完整整、漂漂亮亮,这时候返工最贵。

所以新规则改成按"谁说了算"划线:产品、交互、数据结构的决定,先和我对齐再动手;技术实现它自己决定,不用问。我要什么只有我知道,怎么做它通常比我清楚。改完这一条,后面几轮顺了很多。它会把拿不准的点逐个列出来,各附一个默认答案,我只改不同意的那几条。

(这种一次抛一个决策、带默认答案的做法,旧文里其实写过。现在回头看,旧文里经得起时间的,也就是这类讲人和模型怎么分工的东西。)


拆开以后,其他问题也看得更清楚了。

流程类的规则大多变成了念经。最典型的是"相邻回归":当时模型改完 A 经常把旁边的 B 弄坏,我就要求每次改完顺手测一个相邻功能。可改动碰不到旁边,这一步就是白干;真需要大范围回归,测一个相邻功能又远远不够。合适的测试量取决于改了什么,写死成一条规则只会更糙。现在 AGENTS.md 里关于测试只有一句话:"测多少、怎么验证,自己判断。"

知识库的问题更隐蔽。ai-doc 有三千四百行,我后来逐条翻过,真正写着"代码里看不出来的事"的大概不到一成,其余都在用自然语言复述代码:哪个接口在哪个文件,某个组件怎么用,状态怎么流转。复述的东西迟早和代码对不上。这次 Agent 一开始死活不肯用真后端测,原因是配置文件里留着一个早就作废的占位项,它据此判断测试库没配。实际上测试库一直都在,地址早就挪进了 sqlite 。人看到这种东西会觉得奇怪,去问一句;模型往往直接就信了。过期文档比没有文档更坏。

还有一些是随工具进步自然作废的。我以前写过 UI 定位文档,记录某个按钮的 role 和 name ,方便模型在浏览器里找元素,现在的 Agent 直接读无障碍树。文档末尾的 Last verified 日期、TODO-verify 标记、覆盖率表,都是为了让知识库显得可信而加的维护负担。现在我对这类东西已经很反感了。

最让我自嘲的是那份生产操作手册。之前 D1 出过两次数据事故,我一怒之下写了两百多行,有操作台账、状态门禁、多层验证。结果 Agent 对任何沾"生产"二字的事都紧张兮兮,推完代码要盯着 CI 跑完,还要做线上冒烟。可这是个人项目,用户就我一个,部署挂了重推一次就是。真正不能出错的只有几份长期积累的数据,把所有外部操作都按高危处理,反倒把这条线淹没了。


新配置只有一个原则:只写模型从代码里读不出来的东西。

根目录的 AGENTS.md 现在 44 行。第一句是项目定位:

个人项目:作者就是唯一用户,自己写、自己用。没有线上值班,发布可以很随意;但有几份长期积累的数据很重要,要认真对待。

这一句顶掉了那两百行手册。Agent 的风险判断基本就对了,该放开的放开,该小心的小心。后面依次是数据这条硬线(只新增可以直接做,改写删除先备份再问我)、发布方式(push 到 master 自动部署,带 #ignoreDeploy 跳过)、常用命令和协作偏好。常用命令里特意加了一句"tsc 目前本来就有约 29 个旧错误,只看新增的"。这种环境事实很小,可不写的话,它每次都得先花时间搞清楚这些错误是不是自己弄出来的。

ai-doc 整个删了。模块相关的东西放进模块目录下各自的 AGENTS.md ,backend/ 、frontend/ 、frontend/src/todone/ 等各一份。Claude Code 读到某个目录的文件时会自动加载那里的 AGENTS.md ,知识跟着代码走,改代码时顺手就能看到、顺手就能改。

这些模块笔记只记两类东西。一类是拍过板的产品决定,比如例行清单只有设了规则的那一层才有周期,子项随上级一起刷新,没有提前量,临时补充的事项不会被自动删掉。日期具体怎么算,看代码就行。另一类是坑,比如 D1 适配器的字段不能带数据库默认值,否则下次自动迁移会被误判成破坏性变更;又比如某个取任务的函数会顺手改排序,不能拿来做 ID 校验。这些读代码读不出来,模型踩一次要折腾很久,写下来最划算。

四个流程 skill 全删,换成两个操作型的。platform-local 讲本地怎么跑、连的是哪个测试库、账号从哪读、造数据避开哪些坑,附一个自动登录后调接口的 api.py ,和一段在浏览器里模拟拖拽的 js 。platform-data 讲生产数据在哪、三份 Worker 配置各对应哪个库、怎么备份、数据迁移照哪个现成命令写。我挑 skill 的标准是低频、步骤多、带项目特有的事实,最好能附脚本。skill 平时只占一行描述,用到才展开;脚本直接执行,源码不进上下文。这次 Agent 在本地环境上浪费的时间最多,又是翻配置又是重写登录逻辑,所以第一个就做它。至于怎么开发、怎么调试,模型比我会,用不着教。

"动生产数据前先问我"这条,没有只写在文字里。我在 Claude Code 的 settings.json 里把 wrangler d1 execute 、deploy 、secret 这类命令设成了必须确认。文字只是建议,权限才是强制。Codex 那边没有这层拦截,就在 skill 里写明,让它自己守住。

btw ,两个工具我都用,所以配置要两边通用。只留 AGENTS.md ,删掉了 CLAUDE.md ,因为 Claude Code 现在能直接读 AGENTS.md ,可仓库里只要有 CLAUDE.md ,它就不读 AGENTS.md 了。skill 放在 .agents/skills/ ,Codex 原生读取,Claude Code 通过本地软链 .claude/skills 读取。还有个容易忽略的差别:Codex 只加载从仓库根到当前工作目录这条路径上的 AGENTS.md ,模块目录下的读不到,所以根文件里列出了各模块笔记的位置,让它改模块前自己去看。


维护方式也跟着变了。以前有一个专门的 skill 负责把新知识写回 ai-doc ,现在没有了。同一个错误第二次出现,才往对应的 AGENTS.md 里补一条。第一次犯错多半是偶然,第二次才说明那里确实有个代码表达不出来的东西。

回头看四个月前那篇文章,大半篇幅在讲怎么让模型找到该读的东西。这个问题工具已经替我解决了。剩下要告诉它的,只有我要什么、哪条线不能碰,这两件事写不长,也不该写长。

License:  CC BY 4.0