上篇聊了团队级 Code Review Skill 的落地------四个人的审查规则合并成一个仓库,PR 流程自然演变成"AI 审 AI"。但跑了一个多月之后,一个新问题出现了:AI 标的警告,什么时候可以不修?
不是"怎么修"。是怎么判断"可以不修"。这是两件完全不同的事。
我们遇到过最典型的一次:紧急修复支付回调,AI 标了三条警告------
- 事务边界过宽,外部调用在
@Transactional内 - 缺少幂等保护,重复回调没有去重
- 绕过业务校验层,直接操作数据库
三条全部手动忽略。热修复上线,正常。但事后复盘,我发现做决策的时候靠的是直觉------没有框架,没有checklist,换个人来可能做完全相反的判断。
于是我逼自己总结了一套手动忽略 AI 警告的四个决策问题。每次点"忽略"之前,四个问题必须全部能回答。缺一个,就停。
问题一:最坏会怎样?说出上限才配说"可以忽略"
核心不是"评估风险",是检验你对系统的熟悉程度。
事务边界过宽那条警告,按 transaction.md 规则(afterCommit 回调处理外部调用)该判违规。但在这个场景下:
- 回调处理失败 → 订单状态停留"待支付"
- 系统自动补偿机制每 5 分钟重查支付状态
- 不会多扣钱、不会重复发货、不会丢数据
最坏后果:一个客服工单。 这是明确的上限。
能说出这个上限的前提:你知道同一笔订单的回调被路由到单线程队列处理(不存在并发死锁)、你知道补偿机制的间隔和触发条件、你知道跳过的校验字段上游已经完成。这些东西不在代码里------在你对这个模块的理解深度里。
说不清最坏后果的人,没资格点忽略。
问题二:为什么现在不能修?"来不及"和"不想修"是两回事
幂等保护那条,Redis 去重 + 数据库唯一约束兜底,写代码十分钟的事------代码层面并不复杂。
但真正的瓶颈不在开发,在测试。支付回调的幂等测试需要覆盖:正常回调、重复回调、乱序回调、补偿回调、极端延迟回调。环境准备半天,QA 排期至少一天。用户已经等了两个小时。
"来不及"成立的条件:你能指着具体的约束条件说------QA 排期?依赖接口没 ready?灰度窗口过了?
指不出来?那就是"不想修"。
我们团队有一条硬约定:说"来不及"必须带约束条件。这条约定的执行效果远好于任何技术方案。
问题三:谁来拍板?这个人的上下文深度决定判断质量
绕过业务校验直接写库是最危险的一步。整条校验链是:网关校验(支付渠道适配层的签名/格式校验,非基础设施 API 网关)→业务校验→模型校验→数据库约束。这次跳过了中间两层------入口的签名校验没动,落库靠数据库约束兜底。
能拍这个板的前提:
- 业务流程:知道回调状态机的完整路径,知道跳过校验不会产生脏状态
- 数据库约束 :知道
order_status有状态范围约束、amount非负、gmt_modified自动填充 - 运维窗口:知道权限服务何时恢复,确认跳过只是临时降级
三者缺一不可。拍板的人必须是对这段代码所处的系统上下文最熟的人------不是职级最高的人,不是代码作者,是上下文最全的人。
如果团队里没有一个人同时掌握这三个维度,那就不能忽略。
问题四:怎么保证不会忘?决策当下就要绑定修复计划
那三条警告后来全处理了:
- 直接操作数据库 (当天修复):权限服务恢复后加了一条降级路径------正常校验失败且确认是依赖不可用才走直写。把临时手段变成有条件降级策略。
- 幂等保护(排进下个迭代):JIRA 挂负责人 + 截止日期。不是追责------而是怕没人认领,"回头补"就会变成一行永远不会有人看的 TODO。
- 事务边界(不修但补规则):回调场景两个外部调用总耗时 < 200ms,压测 P99 < 500ms。给规则加临时豁免:单事务耗时 < 500ms、DB QPS 低于阈值、且有事务耗时监控兜底。
第一条"直接操作数据库"的降级路径,核心代码长这样:
java
public void handleCallback(PayCallback cb) {
try {
// 正常路径:走完整业务校验再更新订单
bizValidator.validate(cb);
orderService.markPaid(cb.getOrderId(), cb.getAmount());
} catch (ValidateServiceUnavailableException e) {
// 危险:仅当确认是权限服务不可用,才允许降级直写
if (degradeConfig.callbackDirectWriteOn()
&& !permissionClient.healthy()) {
log.warn("业务校验降级,直写订单 orderId={}", cb.getOrderId());
// 兜底靠数据库约束:order_status 状态范围、amount 非负
orderMapper.markPaidDirect(cb.getOrderId(), cb.getAmount());
} else {
throw e; // 其他校验失败一律不降级
}
}
}
关键是补的时机 :不是在下一个 sprint 开头,是在做忽略决策的当下。PR 评论里直接 @负责人 + 预计修复时间 + 最小修复方案;同时在代码对应位置加一条 TODO(#规则ID) 注释。这套联动靠的是我们自建的 Skill 规则,不是 Claude Code 的原生功能------下次它扫描同一段代码,TODO 注释和 PR 评论会一起被重新标出。
反面案例:框架不能替你查漏,但能让复盘有据
老张做过一个数据同步接口,AI 标 HashMap 并发不安全。他判断冲突率不到千分之一,不值得换 ConcurrentHashMap。
判断没错------正常情况下。但他漏了一个条件:上游凌晨有批量任务,会瞬间打 800 个并发请求。
结果:并发写入破坏了 HashMap 内部结构,数据错乱丢失,同步任务校验失败后陷入重试风暴,CPU 打满,下游报表延迟四十分钟。
复盘时他能清楚定位错在哪一步------不是因为框架救了他,是因为按四个问题做的决策记录留下了完整的判断链路。框架不能替代你的判断,它只能让判断过程可见、可讨论、可复盘。
这引出一个修正:"最坏会怎样"不是"通常情况下会怎样"------必须覆盖所有已知触发条件,哪怕看起来不会同时发生。
一个可落地的 PR 评论模板
如果你也想在团队里用起来,可以直接复制下面这个模板,填在每条被忽略的 AI 警告下面:
markdown
**忽略原因**:权限服务重启,业务校验层不可用,数据库约束完整兜底。
**最坏后果**:订单状态停留在"待支付",5 分钟后自动补偿重查,最多一张客服工单。
**为什么现在不能修**:QA 排期到明天,用户已等待 2 小时。
**负责人**:@老周
**预计修复时间**:2026-07-16 18:00
**最小修复方案**:权限服务恢复后,回调先走正常校验,校验失败且依赖不可用才降级直写库。
**TODO**:// TODO(#transaction-rule-05): 评估 500ms 豁免是否需要长期保留
把这套东西写进 PR 评论 + 代码 TODO------这套联动靠的是我们自建的 Skill 规则,不是 Claude Code 原生功能。下次任何人改到这段代码,都能把这条记录重新带出来。(模板里的日期只是示例,按实际情况填。)
决策速查表
| 问题 | 核心检验 | 不通过就停 |
|---|---|---|
| 最坏会怎样? | 能否说出明确的上限后果,且覆盖所有已知触发条件? | 说不出→读代码 |
| 为什么不能现在修? | 能否指着具体约束条件说? | 指不出→马上修 |
| 谁来拍板? | 这个人对上下文熟不熟? | 不熟→找最熟的人 |
| 怎么保证不忘记? | 当下就指定负责人和截止时间? | 没有→别合 PR |
规则是给 AI 的,判断才是给人的。 AI 适合做规则的执行者------每条 PR 过一个,不漏一条。但规则的边界在哪、什么时候规则不适用、什么时候两害相权取其轻------这些变量不在代码里,在业务压力、排期约束、系统上下文、团队承受力里。
手动忽略的真正边界,不是"能不能忽略",是"你能不能说清楚你为什么忽略"。
系列最后一篇在写:五个月 AI 审查跑下来,团队里每个人对"写好代码"这件事的理解,到底变了多少。
GitHub 仓库 wangheng19901021/skills 持续更新,团队 Skill 模板和示例代码均已开源。