AI 为什么永远还能再找出一个 P0?
两套开源 Skill
业务结果:先固定业务承诺,再检查资金、资格和时间限制能否覆盖完整生命周期。
证据执行:读完整调用路径以后再判定缺陷;没有被违反的契约和可达证据,就不能升级为 P0。
我接入微信支付时,做的是有效期 90 天的团购券。当时的方案是,顾客付款后先冻结资金;顾客到店核销以后,平台再把钱分给商家。这套方案成立有一个前提:只要团购券仍可退款,商家就不能随时转走这笔钱。
支付产品的控制期限无法满足这个前提。普通服务商分账资金默认冻结 30 天,团购券却有 90 天有效期。第 31 天以后,如果商家转走余额,平台仍要为尚未到期的券处理退款,届时可能已经没有钱可扣。微信支付的分账文档明确写明,普通服务商应在支付成功后的 30 天内发起分账,否则待分账资金会自动解冻。普通服务商分账
我在设计阶段发现了这项风险,当时没有真的发生商家提现或顾客退款。平台准备出售一张 90 天内可以退款的券,就必须保证这 90 天里始终有可用的退款资金。现有支付能力只覆盖前 30 天,已经不满足上线条件。
AI 很快找到了分账接口,并确认支付后可以冻结资金。接口和参数都没有错,结论却漏掉了 30 天上限。AI 只证明了这笔钱此刻可以冻结,没有继续检查冻结期限能否覆盖 90 天券期。
经过几轮追问,AI 建议改用平台收付通。官方文档写明,这类订单资金默认冻结 180 天,时间上足够;但平台收付通要求平台和二级商户按相应模式进件,我当时不具备所需条件。平台收付通、接入准备
我后来又查了预售报备。预售报备只能说明订单尚未履约,核销以后仍要上传实际发货信息,不能延长普通服务商分账资金的冻结期。特殊发货报备、发货信息录入
第一次审查漏掉了真正影响上线的资金风险。后来检查退款代码时,AI 又犯了相反方向的错误:它把一处正常逻辑定成 P0。
顾客提交主动退款申请后,系统不会立即调用微信退款。系统先保存一条待处理记录,等待商家审核。商家审核通过后,后台才向微信发起退款;收到微信回调后,系统再写入最终结果。券到期后的自动退款由自动退款任务直接发起,不需要商家再次操作。
AI 只读了顾客提交申请的入口。在这个入口里,系统确实只写入一条待处理记录。但 AI 没有继续检查商家审核通过后如何处理退款申请,而是参照了自动退款任务的写法。由于自动退款任务会直接调用微信,AI 便认定主动退款缺少执行入口。
这两次判断方向相反,原因却相同。60 天资金空档跨过了支付产品的控制期限,单看一个接口找不到;退款入口缺少直接调用则很像常见代码缺陷,局部代码足以制造怀疑。AI 都在一个容易观察的局部目标上过早结束了调查。
继续让 AI 审查,新的 P0、P1、P2 还会出现。券的数量、多门店范围或取餐号生成时机,都能被改写成整改意见。只要任务仍是“继续找问题”,生成一条新问题往往比确认“现有设计没有缺陷”更符合代码审查的常见形式。
模型首先学会什么像答案
基础语言模型根据前文预测下一个 token。预训练目标通常写成:
是训练语料, 是文本在第 个位置实际出现的 token, 是它前面的内容。 表示模型给正确 token 分配的概率, 是模型参数。
训练会让语料中实际出现的续写获得更高概率。正确 token 的概率越低, 带来的惩罚越大。这个目标能让模型压缩并复用代码、文档和讨论中的规律,却没有直接观察“一条建议三个月后是否造成退款损失”。GPT-3 使用了这种自回归语言建模目标;Language Modeling Is Compression 从压缩角度说明了语言建模与模式学习的关系。
我把 LLM 称作“范式拟合器”,指的是模型会复用当前上下文中的高概率输出模式。看到退款入口,模型更容易生成退款接口的常见结构;看到全面审查,模型更容易生成按严重度排列的问题清单。这里的“范式”不是模型只能照抄,而是某些输出在当前上下文中具有更高概率。
这能解释为什么审查报告很容易继续写下去,不能单独解释 Coding Agent 为什么会打开文件、执行命令并修改代码。后训练和执行环境又增加了另一层选择。
测试只能奖励已经覆盖的行为
Coding Agent 的训练材料可以包含整段执行轨迹:
是第 步看到的仓库状态或命令输出, 是随后采取的动作。成功轨迹可以用于监督微调;强化学习还会让 Agent 自己尝试,再由环境给整段轨迹一个奖励:
决定什么叫成功。若奖励来自单元测试,模型会提高那些最终通过测试的操作路径的概率。测试比“这段代码看起来不错”更接近程序事实,但它仍然只检查测试写进去的行为。
SWE-Gym 提供了 2,438 个带真实仓库、运行环境和单元测试的软件任务。用这些环境训练 Agent,论文报告 SWE-bench Verified 和 Lite 的解决率最多提高 19 个百分点;再让 verifier 从候选轨迹中选择,Verified 成绩达到 32.0%。这个结果同时证明了两件事:执行反馈确实能提高 Coding 能力,最终分数也取决于模型之外的测试环境和候选选择机制。
因此,Coding benchmark 上升不能直接推出模型更理解业务。编译器能发现语法错误,单元测试能检查被覆盖的状态转换,仓库 verifier 能判断补丁是否满足既定断言。普通服务商第 31 天以后是否仍然控制退款资金,不在这些断言里。除非业务期限被写进测试或验收条件,模型做对再多道代码题,也不会因为第 60 天可能发生退款而受到惩罚。
Agent 分数还受到 harness、推理预算和尝试次数影响。SWE-Gym 中 verifier 带来的增益已经说明,同一项评测测到的是模型与执行系统的组合。关于轨迹训练、厂商系统卡和 benchmark 变量的详细拆分,见《Coding Agent 分数上涨,测到的究竟是什么?》。
评审能评价报告,不能观察三个月后的退款
通用助手还会根据人类偏好调整输出。InstructGPT 先收集标注员编写的示范,再让标注员比较不同回答,最后用这些排序训练模型。Training language models to follow instructions with human feedback
若回答 胜过 ,常见的奖励模型会学习:
是奖励模型根据已有偏好数据学出的分数。它拟合“评审者更可能选哪一份回答”,不等于事实正确率。评审者能看到报告是否完整、结论是否醒目,却无法在标注时直接观察三个月后的商家余额。
格式偏好已有直接证据。ACL 2025 的实验发现,人类评审、GPT-4 和多种奖励模型会受到列表、链接、粗体等形式影响;不到 1% 的有偏数据就能向奖励模型注入明显的格式偏好,而后续的 best-of-n 和迭代 DPO 还会利用这种偏差。From Lists to Emojis 另一项 ICML 研究发现,继续优化代理奖励时,代表真实质量的“金标准”得分可能停止改善甚至下降。Scaling Laws for Reward Model Overoptimization
这些研究不能证明模型曾经因为“多报一个 P0”直接得到奖励。它们能支持的结论更窄:容易观察的形式可能进入代理分数,而代理分数继续上升不保证真实质量同步上升。把这项机制用于解释无限 review,是结合实际行为作出的推断。
在开放式审查里,编号完整、覆盖模块多、严重度醒目,都容易让报告显得认真。误报的代价却发生在后面:团队要重新读代码,产品负责人要解释既有决策,错误补丁还可能改变用户权利。这些损失没有自动进入生成下一条审查意见时的奖励。
“继续 review”不会自己停下来
一个功能的相关测试已经通过,再让 AI 审查,它仍能生成一批候选问题。修完其中有证据的部分,再说一次“继续深入”,下一轮还会出现新的候选项。有些来自刚才的修改,有些只是另一种产品偏好。
轮次增加只说明候选集合变大,不说明真实缺陷正在减少。开放式提示没有给模型一份有限的缺陷全集,也没有定义什么时候可以返回空结果。只要还能生成一段符合审查文体的文字,任务就没有自然终点。
代码审查中的误报不是抽象担忧。IJCNLP-AACL 2025 对代码变更说明任务的研究发现,约 50% 的模型生成代码审查评论包含幻觉。Hallucinations in Code Change to Natural Language Generation EMNLP 2024 的 LLMSAN 要求模型给出数据流路径,再用程序属性验证路径,缺陷检测精度因此提高 21.99%。Sanitizing LLMs in Bug Detection with Data-Flow 后一项研究的重要之处不在于让模型“再想一遍”,而在于加入了可以推翻候选问题的外部验证。
所以,重复 review 必须保存上一轮结论。每条候选项都要标记为已确认缺陷、已排除、产品选择、可选改进或尚未解决。被证据排除的问题不能换一种措辞重新出现。只有代码发生变化、出现新证据,或仍有验收条件没有结论时,下一轮才有理由开始。
当前指令只是系统的一次变更
局部判断还会出现在 feature 开发中。用户说“增加退款进度”,这句话只描述本次变化,没有重新定义退款状态,也没有取消商家的审核权。若 Agent 只修改最接近的页面或接口,一段能运行的代码仍可能破坏原来的产品含义。
命令行 Agent 可以访问整个仓库,但它必须主动决定搜什么。长上下文也不能保证旧信息被稳定使用。TACL 2024 的实验发现,关键信息处在长上下文中间时,模型表现会明显下降。Lost in the Middle ICLR 2025 的 RepoGraph 则从软件工程一侧给出证据:给多种方法补充仓库级结构以后,SWE-bench 表现都有提升,说明仓库导航本身就是任务的一部分。RepoGraph
这两项研究不能证明所有 CLI Agent 都会忽略原系统。它们足以否定一个常见假设:仓库可访问、上下文窗口够长,不等于控制当前行为的契约已经被找到并正确采用。
用户的新指令应被视为既有系统上的变更量。动手以前要找到控制当前行为的代码和产品规则,确认哪些状态与权限不能改变。测试既要证明新功能可用,也要证明依赖旧含义的相邻路径仍然成立。
P0 之前,先证明它是缺陷
一条候选问题要被定性为缺陷,至少要通过四道门:
要求存在可复核证据,例如代码、运行结果或官方规则; 要求问题处在真实可达的执行路径; 要求当前行为违反一项已经确认的需求或业务契约; 要求问题属于本次授权范围。四项缺一,候选项就不能叫缺陷。候选项仍可能是一项风险或可选改进,但不能先贴上 P0,再要求业务自证清白。
60 天资金空档可以通过这道门。30 天自动解冻有官方文档,90 天券确实可能进入第 31 天。届时平台无法保证退款资金仍受控制,违反“可退款期间始终有钱可退”这项上线条件。
退款误报过不了这道门。顾客入口没有直接调用微信退款,只是一条局部证据。商家审核、后台退款和微信回调共同构成了完整路径,当前实现也没有违反产品规则。
确认缺陷以后,才能讨论严重度。影响很大但路径不可达,不是 P0;单笔影响有限却覆盖大量真实订单,也可能需要优先处理。严重度必须建立在已确认缺陷上,不能反过来用一个吓人的最坏情况证明缺陷存在。
停止条件同样属于审查契约。相关路径已经查完,最强的反解释得到验证,用户要求的验收条件已有结论,就应该停止。空缺陷列表是合法结果。
Skill 把规程放进当前上下文
Skill 不会更新模型权重,只会改变模型这一次生成时看到的条件:
加入 后,模型可能更容易先查业务契约,沿完整路径寻找反证,再决定是否修改。参数 没有变化,预训练和后训练形成的偏好仍然存在。规则太长、与仓库不匹配或没有被正确采用时,Skill 也可能增加成本,甚至降低结果。
业务 Skill 处理微信支付案例中的第一种失误。它先固定业务承诺,再把商品期限与支付产品的控制期限放到同一条时间线上。一个产品即使存在于官方文档,只要当前主体没有资格使用,就不能算可行方案。
执行 Skill 处理退款误报和无限 review。当前指令只是变更量;Agent 要先读取控制行为的契约和相邻路径。候选问题必须指出被违反的契约,被排除的结论则进入审查记录,避免下一轮重新包装。
这两份 Skill 在微信支付案例中给出的结论很具体:当时没有平台收付通资格,也没有商家不能单方面转走的独立退款资金,因此不能上线 90 天团购券。把券期改成 30 天会改变商品本身,不能伪装成同一个方案的技术修复。退款审核链路已经完整,不需要因为入口没有直接退款而重写产品规则。
Skill 的公开评测并不总是提升。SkillsBench 报告了明显的平均增益,SWE-Skills-Bench 中大多数软件工程 Skill 却没有提高通过率;我自己的困难任务配对实验也没有测到提升。具体数据与验证器问题见《Skill 到底有没有用?一次没有提升的编程基准实验》。这些结果限制了文章能声称的范围:Skill 是推理时规程,不是模型已经获得业务责任的证据。
允许审查以“无需修改”结束
微信支付案例里的两次误判,缺少的是同一个判断标准:90 天内可退款,是整个系统必须持续满足的业务承诺。
资金冻结接口存在,却只能控制 30 天,因此不能支撑 90 天券。顾客入口没有直接退款,但商家审核通过后,后台已经会调用微信退款,因此不能据此判定退款断了。前一个问题真正违反了上线条件,后一个判断只是局部代码造成的错觉。
对业务负责不等于列出更多问题。每条结论都要回答:哪项契约被违反,证据在哪里,完整执行路径是什么,这次修改是否获得授权。四个问题都没有答案时,P0 只是一个醒目的标签。
代码没有变化,验收条件已经满足,也没有新证据时,下一轮 review 不应开始。审查可以、也应该以“无需修改”结束。
相关文章
- 中文“AI 味”是怎样被训练出来的?:为什么多种模型会反复写出相似的中文?本文从训练数据和偏好选择追溯原因,也说明标注外包、跨模型蒸馏的公开证据到哪里为止。
- Skill 到底有没有用?一次没有提升的编程基准实验:公开 Skill benchmark 的结论并不一致。本文对照 SkillsBench、SWE-Skills-Bench 和困难编程任务实测,说明没有提升时应怎样解释结果。
- CLI Agent 的长任务为什么越做越不可靠:CLI Agent 在长任务中失控,不是模型参数逐步变差,而是当前上下文偏离了项目的可验证状态。缩短未验证跨度,比单纯扩大窗口更重要。