
一、规则写在纸面上执行时各凭理解shop订单服务的 AGENTS.md 已经运行了三个月文件不长四十行左右。最近一次评审会上两件事同时发生有人抱怨这个项目没有约定全靠猜另一个人翻出文件说明明写了’保持一致性’、‘注意数据一致性’、‘及时更新文档’。两边都没说错。文件里确实有这三条但它们在执行时各自被理解成了不同的东西。张三把保持一致性理解成命名风格统一于是顺手重命名了三个函数李四把它理解成新代码要参考附近代码的写法于是复制了一段已经过时的错误处理王五的改动把审计事件换成了异步发送理由是提升接口响应速度——而数据一致性这四个字没有任何人告诉他具体指什么。及时更新文档这条更微妙。什么叫及时文档指哪一份更新到什么程度三个月里没有人违反过这条规则因为它无法被违反——它也无法被遵守。这一篇处理的正是这种情况识别 AGENTS.md 里的坏规则把它们改写成真正能执行的形式。判断标准只有一句话一条规则如果无法被检查它就不是规则而是期望。期望可以留在心里写进文件的应该只有规则。二、先把几个词讲明白坏规则看起来像规定实际不能执行的句子。它的典型特征是动听、正确、无法检查。比如注意性能“保持简洁”“不要写出 bug”。触发条件这条规则在什么时候生效。比如修改接口返回值时“新增依赖之前”“写数据库操作时”。没有触发条件的规则读者不知道什么时候该想起它。动作触发之后具体要做什么。比如运行ruff check .““把状态变更与审计事件放进同一事务”。动作要具体到可以被执行而不是注意”“保证”。验证方式怎么证明动作做到了。可以是一条命令、一条测试、一次搜索、或者 diff 上的一处检查。没有验证方式的规则最后只能靠印象。可判定能得出做了或没做的结论。生活例子说房间要整洁不可判定说桌面上的书全部放进书柜、垃圾桶清空可判定。优先级多条规则同时适用时以哪条为准。坏规则常常不带优先级冲突时只能靠现场争论。例外规则适用的边界情形以及这些情形下应该怎么做。写清例外能让规则在真实工作里更稳也避免了遇到边界就跳过规则的习惯。规则与期望的区别规则描述动作与判定期望描述价值与方向。两者都值得存在但位置不同——期望适合写在项目介绍里规则写在 AGENTS.md 里。三、坏规则的六种形态3.1 口号型听起来正确无法判定典型句子“代码要优雅”“保持高质量”“注意可维护性”。它们全部正确也全部无法执行。危害不在说了错话而在占了位置文件里写着这些句子会让人产生我们有规则的错觉而真正需要的约束比如不新增依赖没有写。3.2 愿望型有方向没有动作典型句子“尽量减少重构范围”“尽量复用已有代码”“尽量不要改动公共接口”。三个尽量把规则变成了倾向倾向可以被解释也可以被跳过。改法是把尽量换成明确条件默认不改公共接口确需修改时先在 PR 说明里列出受影响的调用方。3.3 双关型词有歧义两种理解都成立典型句子“保持一致性”“注意数据一致性”。第一个一致性在不同人眼里是命名、格式、结构还是行为第二个数据一致性是事务、幂等、还是缓存与数据库的同步词本身没有错错在把它们当成规则使用——规则需要唯一解释。3.4 越界型管不了的事典型句子“不要引入 bug”“确保线上不出问题”“不要被安全问题影响”。这些事没有人能承诺bug 无法被保证不引入线上问题也无法被确保不发生。可以写成规则的版本是“每个改动必须附带失败用例或复现步骤”“涉及权限的改动必须走安全评审”。3.5 过期型对应的事物已经不存在典型句子“不要修改legacy_handler.py”文件早已删除“所有接口必须通过api-v1网关”已迁移到 v2。过期规则比没有规则更危险它会被当真执行造成方向性偏离。3.6 堆叠型规则互相矛盾没有优先级典型句子保持改动最小与顺手修复发现的问题同时存在。两条单独看都有道理同时存在时执行者只能自行取舍。修法是明确优先级默认最小改动发现问题时写进任务记录不在本次修改里处理。3.7 缺例外型只说必须不说什么时候可以不同典型句子“所有接口改动都必须更新文档”。听起来很严格但它没有回答一个常见问题如果这次改动只是修正文档里的错别字呢缺例外的规则在遇到边界情况时会产生两种后果要么被机械执行浪费精力要么被默默跳过破坏规则的可信度。处理方式是主动写一到两个例外并写清判断依据。比如上面这条可以补一句“仅修正错别字或格式时可以不更新接口文档但要在提交说明里注明”。例外的存在不会削弱规则反而让它更可信——因为它承认了现实中的不同情况并且给出了处理方式而不是要求执行者每次都停下来争论。例外还有一个进阶用法把例外写成需要额外动作的条件。比如确需修改公共接口时必须先在 PR 说明里列出受影响的调用方。这样例外本身也带着可检查的动作既保留了灵活性又不会因为例外三个字而失控。四、好规则的三件套触发、动作、验证把坏规则改写成好规则只需要补齐三件东西触发条件什么时候适用 动作具体做什么能被执行的动词 验证怎么检查做到没有举例说明这三种信息带来的差别。同一条注意数据一致性两种写法坏写法 注意数据一致性。 好写法 触发任何修改订单状态的操作 动作状态变更与审计事件必须在同一事务中提交 验证集成测试断言失败时两者都不留痕tests/orders/test_cancel.py::test_cancel_rollback好写法长一些但它带来了三样东西知道什么时候适用不会漏、知道做什么不会猜、知道怎么检查不会争。后面还会看到这三样东西同时也是评审的依据——评审时可以逐条问这条对应的检查过了吗而不是靠感觉。还有一条修正原则值得记住改写坏规则时优先把它变成命令或者测试。能写成命令的格式检查、静态检查、契约校验就不要写成文字能写成测试的行为断言就不要让人去记。文字规则留给那些暂时无法自动化的部分。这条原则带来的改写顺序也值得固定下来第一步先把能自动化的挑出来通常一半以上给它们配上命令和接入位置第二步处理剩下真正需要文字的部分写成三要素条目第三步才是删掉原来的口号。顺序按先补后删执行这样任何一条约束都不会出现空窗期。4.1 改写时容易忽略的一条删掉重复表述规则体检时经常发现同一条约束在文件里出现三次措辞略有不同。它们可能来自不同时间的补充最早是一句口号后来在怎么验证段加了一条命令再后来在不能做段加了一句禁令。三处都在说同一件事但没有任何一处是完整的。处理方式是合并成一条写在最合适的段落里其余位置删除。合并的标准是三要素触发、动作、验证写在同一条条目下不再分散。合并之后文件会明显变短而且读者包括代理不会得到这条很重要所以在多处强调的错误印象——实际上重复出现在任何文件里都会让人怀疑哪一处是最新的。五、完整例子把三条口号改成可执行规则5.1 改造前的三条shop项目的 AGENTS.md 里有三条被反复引用的规则示例保持代码风格一致。 注意数据一致性。 及时更新文档。三条都正确三条都不可执行。下面逐条改造改造的方向统一是补齐触发、动作、验证。5.2 第一条风格一致性先问三个问题什么时候适用具体要做什么怎么检查触发新增或修改任何 Python 文件时 动作提交前运行 ruff check . 和 ruff format --check . 验证本地命令以退出码 0 结束CI 上同一命令必须通过改造的关键是把一致这个形容词换成一个工具和两条命令。风格类规则的绝大多数内容都可以这样处理交给格式化与静态检查工具文件里只保留运行哪条命令、什么时候运行。剩下的部分工具覆盖不到的风格选择再写成少量具体条目比如模块内私有函数以下划线开头。改造后还有一个小收益这条规则现在可以被写进 CI。CI 跑同一命令规则从提醒变成了门禁。5.3 第二条数据一致性这一条最容易出错因为一致性这个词太宽。改造前必须先明确它在这个项目里到底指什么。对着订单取消流程梳理了一遍团队确认它包含三件事触发任何修改订单状态的操作 动作 1. 状态变更与审计事件在同一事务中提交 2. 重复请求不产生额外的审计事件幂等 3. 失败时状态与审计事件都不留下 验证 - 集成测试断言取消成功时审计事件恰好 1 条 - 测试重复取消不新增事件 - 测试事务失败时两者都不留痕改造过程本身暴露了一个以前被忽略的约定重复请求不新增审计事件。这条以前没有人写下来但它在评审里被反复讨论。把一致性拆成三条具体约定之后争议也随之减少——讨论从这样算不算一致变成了这条测试覆盖了没有。5.4 第三条及时更新文档这条的问题在文档和及时两个词上。改造分两步先定义哪些文档算数再定义什么时候更新。触发接口、字段、事件或运行命令发生变化时 动作同步更新以下材料之一按影响面选择 - docs/api/orders.md接口与响应字段 - docs/events.md事件类型与字段 - AGENTS.md 的怎么验证段命令变化时 验证评审清单中确认相关材料已更新CI 检查示例文件与实际响应结构一致注意按影响面选择这个设计它避免把三种文档都写成必更新减少了无谓的维护。改造后这条规则第一次变得可以被违反也第一次可以被检查——评审时能明确问接口字段变了docs/api/orders.md 更新了吗。5.5 改造前后对照改造前改造后新增的可检查性保持代码风格一致提交前运行两条命令CI 同命令通过退出码注意数据一致性三条具体约定 三条测试测试断言及时更新文档触发条件 三选一的更新对象评审清单 一致性检查对照表第三列是重点改造的产物不只是更长的文字而是更短的争论。每一条规则现在都指向一个动作和一次检查评审时可以逐条过不再依赖对词义的理解。5.6 发现坏规则的三个问题这套改造动作可以复制到整个文件逐条读对每条问三个问题——1. 什么时候适用触发 2. 具体做什么动作 3. 怎么检查做到了验证三个问题都能答上来这条规则合格有一个答不上来就是坏规则进入改造队列。三个问题本身的成本很低读一遍文件、逐条自问四十行文件大约十分钟。这个动作建议每季度做一次因为规则会随仓库变化而自然过期。5.7 一次完整的改写记录把一次改写的前后都记下来价值在下次遇到类似规则时可以照着走。下面是一条完整记录示例原规则注意数据一致性 风险场景取消订单失败时状态已经改了但审计事件没写或者重复请求写了第二条审计 改写后 触发任何修改订单状态的操作 动作状态与审计事件同一事务重复请求不新增事件失败时两者都不留 验证tests/orders/test_cancel.py 中三条断言 检查时机与责任人CI 运行测试评审人核对测试是否覆盖三种情形 关联材料docs/events.md事件字段说明 上线方式先补测试失败再改实现通过最后删除原口号记录里有两行常在别的流程里被忽略一是关联材料它把规则和文档连起来改代码时知道还有哪份材料要同步二是上线方式它规定了顺序——先补测试再改实现避免出现先改好、后来才补测试的情况那时测试往往是照着实现写的反而失去了独立检验的作用。有一点值得强调这条改写记录本身就是资产。下次有人想再写一条注意某某一致性时翻出这条记录就能看到把它写具体需要做多少工作以及写具体之后能换来什么。模板比劝说更有说服力。5.8 从体检到预防除了定期体检还有两种做法能让坏规则少出现。第一种给加新规则设一道门槛。任何人往 AGENTS.md 加规则时必须同时提交三要素和一个检查方式做不到的先放进讨论区不进文件。门槛的作用是把口头提议转成可执行条目很多想法在这一步会自然地消失——因为它们本来只是情绪表达。第二种让新规则从事故里长出来。每次出现测试全绿但出了问题的情况复盘时问一句如果当时有一条规则它应该长什么样从真实事故里提炼的规则命中率最高因为它对应的风险已经被验证过同时它天然带着验证方式——你正是通过那次检查发现的问题。两种做法合起来规则的增长就从灵感驱动变成了证据驱动写进去的每一条要么来自清晰的检查需求要么来自一次真实的代价。这样的文件不会很长但会很有分量。5.9 三个常见的改写后仍然不可用的例子改写也会失手。下面是三种看起来补齐了三要素、实际仍然不可用的情况值得对照自查。第一种验证方式写成了同义反复。比如把注意数据一致性改成验证时确认数据一致。三要素是齐了但验证那一栏没有落到具体检查上。判断方法验证栏里能不能找到命令、测试名、或者明确的检查对象找不到就是同义反复。第二种动作写成了判断。比如动作确保状态正确。确保不是动作它是结果描述。动作应该是读取订单状态若不为 PENDING 则抛出 OrderStateError这类可以被写下来的步骤。判断方法动作能否被翻译成一条断言或者一次调用。第三种触发条件写得过宽。比如触发所有改动。触发条件太宽会让规则失去指导意义——什么都要检查等于什么都没侧重。触发条件的正确粒度是能让你在动手前想起它比如修改接口返回值时就比所有改动有效得多。判断方法设想三个不同任务这条规则是否只对其中一个生效答案是否定的说明触发条件需要收窄。5.10 一条规则的生命周期把规则当成有生命周期的对象管理起来会容易很多。它的典型阶段是四个1. 起草来自一次事故、一次评审分歧或者一次复盘 2. 试点只在小范围使用比如只在新代码上检查观察两周 3. 生效接入检查CI / 评审清单成为默认要求 4. 退役对应条件消失模块下线、工具替代删除并说明原因四个阶段里最容易被忽略的是试点和退役。跳过试点会让新规则直接承受全部执行压力一旦它设计得不合适团队会记住规则总是折腾人跳过退役会让文件持续积累过期条目最终没人愿意读。补上这两个阶段并不费事试点就是在观察期内只在新代码上检查退役就是在删除时写一句说明并检查是否有其他规则引用了它。管理周期的另一个好处是可以回答这条规则为什么存在。生效阶段的规则应该都能追溯到起草的理由追溯不到理由的规则往往就是下一批要退役的对象。5.11 一个容易翻车的细节规则标题怎么写改写时标题往往被当作不重要的小事随手写。实际上标题决定了别人能不能在一次翻阅中找到它。好的标题包含场景例如修改接口返回值时比接口规则更容易被检索到提交前验证比质量要求更能说明动作。用一句话概括标题应该让人预判内容而不是像分类标签一样笼统。标题还影响引用。团队讨论时会说按那条’修改接口返回值时’的规则如果标题是接口规则同一句话会产生歧义——文件里可能有好几条都沾边。改写时顺带把标题改得具体成本只有几秒钟收益是长期的沟通效率。最后一个细节写完标题后把文件从上到下读一遍标题行。如果标题连起来能看出这份文件覆盖了哪些场景说明标题合格如果读起来像是规范、要求、注意事项、其他这种目录式的分类说明标题写得还不够具体值得再改一遍。5.12 用一条命令先筛出候选体检以逐条读为主但第一遍可以先用筛选减少工作量。做法是把常见含糊词列成一个列表扫出命中的行再逐条判断哪几行真的需要改。# scripts/find_vague_rules.pyimportrefrompathlibimportPath VAGUE(尽量,注意,保持,及时,确保,合理,优雅,适当)fori,lineinenumerate(Path(AGENTS.md).read_text(encodingutf-8).splitlines(),1):ifany(wordinlineforwordinVAGUE):print(f{i}:{line})对shop项目的文件跑一遍输出示例$ python scripts/find_vague_rules.py 12: 保持代码风格一致。 19: 注意数据一致性。 27: 及时更新文档。三行全部命中正好是这一节要改的三条。这里要认清筛选的性质它给出的是候选不是结论。命中不等于坏规则——例如保持改动最小这种带具体边界的表述补上触发条件和验证方式之后就合格反过来没命中的句子也可能是坏规则比如代码要写得让同事看懂。所以脚本的作用是先把注意力集中到最可能出问题的地方随后仍然要逐条做三问检查和反向测试。它省掉的是翻找一个四十行文件的力气省不掉判断。5.13 改完之后怎么验收改写不是写完就算。收尾时用四点检查过一遍几分钟就能完成示例[ ] 每条改写后的规则都有触发、动作、验证、检查时机 [ ] 每条验证栏都指向命令、测试名或明确的检查对象 [ ] 至少有一条规则从文字变成了自动检查 [ ] 原口号已删除且没有内容在别处重复出现第三点最容易被跳过。没有它这次改造的收益就停留在纸面上规则更好读了但违反它仍然不产生任何后果。最省事的落地方式是挑一条接进已有命令例如把格式化检查加进提交前的本地命令让它和业务测试一起跑。第四点对应前面讲过的重复表述问题。改完之后把旧措辞的关键词搜一遍确认它没有留在别的段落里更简单的做法是把规则名在文件里搜一次命中处应该只有一处。六、反例与代价四种改造中的常见失误6.1 反例一直接删掉坏规则做法发现注意数据一致性无法执行删掉文件看起来干净了。它为什么看起来能行删掉的口号确实不再引起歧义文件也变短了。短期看一切正常——直到下一次改动把状态与审计事件拆到两个事务里。最后的代价是约束消失。口号虽然没有可执行性但它至少提示了这里有一个需要注意的地方删掉之后连提示都没有了。改造的正确方向是先补具体规则再删口号把一致性拆成三条可检查的约定写进文件或者测试然后再把口号删掉。顺序颠倒会造成一段无人看管的空窗期。6.2 反例二把规则改得过细锁死实现做法为了让规则可检查把实现方式写进规则里必须用某个类、必须走某条 SQL、必须按某个顺序调用方法。它为什么看起来能行越具体越可检查这个直觉在大多数场景里成立。最后的代价是规则变成了实现说明书。它排除了更好的方案也让评审的注意力从行为对不对转移到写法对不对。判断边界的方法和前面几篇一致这条规则对应的行为能不能被外部观察到能就写行为不能就删掉或者把它降级成建议而不是规则。6.3 反例三改写之后没有指定责任人和检查时机做法把三条口号改写成了漂亮的三要素条目存进文件但没有说明谁来检查“什么时候检查”。它为什么看起来能行条目本身是合格的格式完整读起来专业。最后的代价是它仍然停留在纸面上。规则要生效需要两个额外信息谁负责触发检查评审人、CI、还是任务执行者以及在哪个环节检查提交前、评审时、还是合并后。没有这两项规则会被以后再说消化掉。最省事的做法是把它绑定到已有环节能进 CI 的进 CI不能进 CI 的进评审清单都不行的写进任务交付要求“交付时附上检查结果”。6.4 反例四一次改造所有规则改完没人用做法一次性把四十行文件重写加入大量新规则提交。它为什么看起来能行趁热打铁一次改到位效率最高。最后的代价是新规则太多、彼此关系未经验证一周之内就会出现两类问题规则与实际工作方式冲突于是被违反以及规则之间语义重叠于是要反复讨论按哪条做。更稳的做法是分批先改造三条最常被引用的用两周时间观察是否被执行确认有效之后再改下一批。改造的目标是每条规则都活着不是文件看起来完整。七、落地步骤一次规则体检第一步完整读一遍文件。不跳过、不略读从头读到尾给每条规则编个号。为什么先编号因为后面的讨论需要指代说第 7 条比说那个关于文档的精确得多。怎么检查文件里有没有你读到一半就走神的地方——那通常就是坏规则所在。第二步逐条问三个问题。触发、动作、验证各答一次。为什么这一步不能合并因为三种信息缺失的表现不同缺触发的规则会被忘记缺动作的规则会被解读缺验证的规则会被争议。怎么检查三个问题里有没有嗯……大概这样的迟疑。第三步按四类处置。留已经合格、改可救、删完全失效、移该放别处比如一次性要求移到任务单、个人偏好移到全局层。为什么要分类而不是只改因为不同类的动作不同改是补三要素删是移除移是换位置混在一起容易越改越乱。怎么检查每条规则最后都落在四类之一没有先放着。第四步优先把能自动化的规则自动化。格式、静态检查、契约校验能进命令的写进怎么验证段并接到 CI。为什么优先自动化因为自动检查不依赖人的记性也不会因为忙而跳过。怎么检查改造后的规则有多少进入了命令或者测试。第五步给剩余的文字规则配上检查时机。人工检查的部分写清在哪个环节、由谁确认。为什么必须写因为文字规则最容易在忙碌时被省略。怎么检查每条文字规则都能回答什么时候检查。第六步分批上线并观察。每批不超过三到五条观察两周。为什么要分批因为规则的真正成本在执行上一次性加入太多会让人分不清哪条有用、哪条添乱。怎么检查两周内有没有出现过这条规则与实际做法冲突的情况。第七步把体检写进周期。每季度重复第 1 到第 5 步。为什么需要周期因为过期型坏规则会持续产生而它们的共同特征是没人记得它对应的事物已经消失。怎么检查上一次体检列出的问题这一期有没有复发。改写模板可直接套用### 规则名 - 触发什么时候适用 - 动作具体做什么动词开头 - 验证命令 / 测试 / 检查清单项 - 检查时机与责任人CI / 评审人 / 任务执行者 - 关联材料相关文件、测试或文档链接八、常见问题问怎么快速判断一条规则是不是坏规则最快的办法是反向测试设想一个违反它的场景问自己怎么才能知道有人违反了。答不出来就是坏规则。举例“保持代码风格一致”——设想张三用四个空格、李四用两个空格你能检查出来吗能用格式化工具那这条规则就该写成运行格式化命令。“注意数据一致性”——设想有人在一个事务外写审计事件你能检查出来吗能用集成测试那就把它写成三条具体约定加三条测试。反向测试还有一个附带好处它直接把验证方式问出来了。问坏规则一定要改吗有些只是写给人看的方向性描述。方向性描述可以保留但要放对位置。做法是分两段文件开头用一两句写这个项目的取舍偏好比如优先使用标准库“偏好显式代码”明确标注它是背景而非检查项后面再写可执行的规则。这样读者不会把方向当成规则去执行也不会因为方向段的不可判定而质疑整份文件。真正需要清理的是那些混在规则中间的期望句——它们的位置会让人误以为必须遵守。问改写之后规则变长了很多文件会不会臃肿会变长但可以用迁移控制总体积。三条原则能自动化的尽量不写成文字一行命令代替一段描述重复出现的检查方式合并多条规则共用运行 pytest -q tests/orders这一条验证模块专有规则移到子目录文件。三招用完通常你会发现总行数增加不多但每条都得可执行。如果确实膨胀到一屏以上就按层拆分而不是回去删验证——验证是规则的心脏删掉它等于退回口号。问规则之间冲突时是删一条还是写优先级先看冲突是真的冲突还是适用范围不同。真正的冲突同一情形下两条规则给出不同动作必须处理方式是保留更具体、更接近代码的那条删掉被覆盖的那条。适用范围不同的一个管新代码、一个管历史代码则写明边界即可。只有在两者确实都成立、只是场景不同时才引入优先级说明。避免把优先级当万能药规则一多优先级表会变成一张新的需要解释的文件那是把问题从一层挪到了另一层。问谁来负责改写这些规则由最常引用它的那个人来改。理由很直接他知道这条规则实际在防什么也最容易验证改写后的版本是否够用。团队层面的动作是提供模板和评审口径三要素齐不齐、能不能检查而不是把改写集中给某一个人。如果没有人愿意改某条规则通常说明它本来就不重要——这是一个有用的信号说明它可以进入删除队列。问测试覆盖了行为规则还需要写吗需要但写法不同。测试负责证明行为正确规则负责让执行者在动手前知道应该做什么。没有规则代理或新同事在写代码时不知道要同步更新审计事件只能通过读测试猜——而测试往往只覆盖了一部分场景。正确的配合是规则写动作和触发测试写对应的验证两者用同一句描述串起来规则里的验证一栏指向那条测试。这样规则和测试一一对应既不重复描述也不会有一方缺位。问如果一条规则暂时没法自动化怎么办给它配一个人工检查点。写法是在哪个环节、由谁、看什么。举例无法自动检查事件字段说明是否同步更新那就写在评审时由评审人确认 docs/events.md 是否更新。人工检查点的关键是要有明确的检查对象哪个文件、哪些字段和检查时机没有这两项人工检查会退化成看着差不多。另外一个技巧是把它转成半自动让任务执行者在交付说明里附上已更新的材料清单评审人只需核对清单是否与实际改动一致。问改写一次之后规则还会再次变坏吗会。规则变坏的路径通常有三条对应的代码变化命令失效、模块下线、团队习惯变化新的验证方式出现、以及需求变化旧约束不再必要。这三条都不罕见所以体检必须是周期性的而不是一次性的。可以把体检和已有节奏绑定每当测试命令调整、目录结构变化、或者一次回顾会之后顺手检查一遍相关规则。绑定之后体检不再依赖有人记得这件事。问如果一个团队暂时没有 CI这套做法还能用吗能用只是把自动检查换成固定时机的检查。没有 CI 时把能跑的检查放在提交前并把命令写进任务的交付要求“交付时附上命令和输出”评审清单里加两条验证命令是否跑过、相关材料是否更新。这样做的可靠性低于 CI依赖人的执行但胜于没有。等有了 CI把已经跑顺的命令直接搬进去即可——所以没有 CI 的团队也应该尽量把检查写成命令的形式为将来的迁移留好接口。问一份文件里理想的规则数量是多少没有固定数字但有一个可用的判断每一条都应该能对应到一次真实的返工或分歧。按这个标准数一数多数项目的第一版会落在五到十条之间。超过二十条时先别急着庆祝覆盖全面而是重新做一遍三问检查——数量多往往意味着其中有大量是无法检查的句子或者把同一件约束拆成了好几条。另外注意分布验证相关的规则命令、测试通常占多数禁令次之风格类最少。分布严重偏向后两者时说明文件正在从操作手册退化成价值观清单。问能不能用一份示例文件作为团队的起点可以而且推荐。做法是找一份结构清晰、条目精简的公开示例或者用本篇 5.5 节的改造对照表先照着它的结构填充自己项目的内容再用三问检查逐条筛一遍。用示例起点的好处是结构不会跑偏四段式、三要素、清单化都是被验证过的形状。需要提醒的只有一点不要连内容一起抄——别人的验证命令、禁令和目录约定都基于他们自己的仓库抄过来只会制造过期规则。抄结构不抄内容。问怎么让团队愿意执行这些改写后的规则让检查成本尽量低并且让检查结果可见。具体做法能进 CI 的进 CI不通过就合不了不能进 CI 的写进评审清单评审时逐条勾选再剩下的写进任务交付要求附上证据。三条通道里越是靠近 CI 的越可靠因为它不依赖人的自觉。除此之外把违反规则导致的返工记录一两次写在团队简报里也有效——用真实代价说话比重复强调规则更重要。问能不能给坏规则加一条检查让评审阶段直接报错可以做成提示型检查但要慎用硬门禁。把含糊词扫描接进评审流程、作为提醒输出是合适的它不阻断提交只是把候选条目摆到评审人面前。不适合做硬门禁的原因很直接判断一条规则是不是坏规则需要理解上下文而脚本只能识别词汇。“保持改动最小包含保持”却是可以救活的好规则机械拦截会制造误报久而久之大家就学会绕过它。判定明确的规则命令、测试、静态检查适合做门禁含糊词扫描更适合做提示。问规则改了措辞要不要在文件里保留旧版本做对照不需要放在正文里。文件本身走版本管理旧措辞在提交历史里都能查到正文里同时留着新旧两种说法读者会分不清哪一句是现行约定这正是坏规则的成因之一。把对照放到提交说明里更合适一句话写清原措辞是什么、为什么不够用、改成什么。需要追溯时看那次提交日常读到的是当前的唯一版本。问给代理用的规则和给新人看的规则写法一样吗大部分相同有一处必须不同出口。新人遇到不清楚的地方可以看周围人怎么做、可以直接问同事代理只会读手里这份文字所以什么情况下停下来问必须写出来。具体做法是在文件里加一小段出口条件例如遇到需要修改接口签名、需要新增依赖、需求与现有测试冲突这三种情况时先停止并提问。这一段的成本只有几行收益是把几类高风险动作从默认继续改成默认停下。问一次体检应该安排多长时间四十行的文件通读加三问检查大约十分钟改写一条几分钟。真正花时间的部分不在写而在确认验证方式把注意数据一致性落到三条测试上需要先看现有测试覆盖了什么、缺哪一条。这部分时间值得花因为它才是改造的实质内容。如果一次抽不出整块时间可以拆成两个动作先做筛选和标记再单独安排一次改写。拆开的好处是标记结果可以留着下次接着做代价是中间会出现已标记未改写的状态所以标记要带日期免得它慢慢变成新的过期条目。九、动手练习与小结练习把三条口号改写成可操作指令这次练习的产出很具体三条改写后的规则条目加上一次生效验证。第一步找出三条口号。打开你项目的 AGENTS.md没有的话用最近一次评审里被反复提到的三句话代替挑出最像口号的三条。挑选标准是三问里至少有两个答不上来。第二步为每条写下它到底在防什么。不要直接改写先写清楚风险场景这条规则如果被违反会发生什么具体后果这一步很关键因为它决定了改写后动作的方向。比如注意数据一致性防的可能是失败时留下半截数据也可能是重复请求写两条审计方向不同动作和验证都不同。第三步按模板补齐三要素。触发、动作、验证各写一行再补一行检查时机与责任人。写动作时用动词开头运行、写入、更新、停止写验证时尽量落到命令或者测试名上。第四步把能自动化的部分接上。有格式化工具、测试、契约校验的把它们接进 CI 或者本地命令不能自动化的写进评审清单。这一步的目标是让至少一条规则从文字变成自动检查。第五步做一次生效验证。故意违反其中一条在本地或一个测试分支上看检查是否能拦住你命令是否变红、评审清单是否覆盖它。拦住说明改写成功没拦住回头看是验证写得不够具体还是检查时机没接对。做完之后把三份产出归档改写后的条目、检查接入位置、生效验证记录。下次体检时这三份材料就是起点。小结坏规则的共同特征不是写得不好而是无法被检查。它们有六种常见形态口号型、愿望型、双关型、越界型、过期型、堆叠型对应的修法都是补齐三件套——触发条件、具体动作、验证方式。改写时守住两条次序先补具体规则再删口号先做能自动化的再处理只能人工检查的。判断一条规则是否合格最快的方法是反向测试设想一个违反场景问怎么才能知道有人违反了。答不出检查方式就是坏规则。这个测试不需要工具读文件时就能做四十行文件大约十分钟。改造之后还有两个收尾动作容易被跳过给每条规则指定检查时机与责任人把体检写进周期每季度一次或绑定到测试命令与目录结构变化时。规则不是写完就稳的东西它会随仓库变化而过期——定期体检是它保持有效的唯一方式。和前后篇的关系上一篇讲第一份 AGENTS.md 怎么写重点在内容和结构这一篇讲写下去的规则怎么保持可执行重点在判定和改写。下一篇继续沿着规则这条线走一条规则写成文件之后测试和 CI 里还要不要重复写三者各管什么怎样配合才算不重复。补充体检清单可直接复制[ ] 逐条编号读完文件没有跳过任何一条 [ ] 每条规则都回答了三个问题触发 / 动作 / 验证 [ ] 每条规则都能通过反向测试设想违反场景能说出怎么发现 [ ] 能自动化的规则已经接上命令本地或 CI [ ] 不能自动化的规则写清了检查时机与责任人 [ ] 每条规则指定了明确位置留 / 改 / 删 / 移 [ ] 本批改造不超过五条并约定了两周后的观察点 [ ] 体检时间已写进团队周期季度或事件触发清单的用法和前面几篇的清单一致不是给人交作业用而是给讨论提供一个共同的检查顺序。每次体检结束后把这份清单存进任务记录下一期体检从它开始就能看出哪些问题反复出现——重复出现的问题通常指向一个需要改变的习惯而不只是一条需要改写的规则。补充和任务单的分工一个常见困惑是同一条约束应该写在 AGENTS.md 里还是任务单里判断方法是看它的有效期。条目的生命周期超过一个季度的验证命令、目录约定、长期禁令写进 AGENTS.md只对某次任务有效的本次不改前端、本次不动迁移文件写进任务单的范围或不做。如果拿不准先写进任务单当它在第三个任务里再次出现时再升级到 AGENTS.md——这条三次法则能有效避免把一次性要求固化成长期规则。反过来也有一条AGENTS.md 里出现本次“这一版”最近这类词时几乎可以确定它写错了地方。这类词天然只对一段时间有效而文件是长期存在的。体检时把它们挑出来移到任务单或者直接删除。