我让 AI 审计一个视频生成平台:281 行报告,帮我守住交付一致性
让 AI 读代码审计视频平台交付链路,交出 281 行报告、修复 12 个问题。经验:AI 不缺能力,缺可执行判据。
一次把“模糊要求”变成“可执行判据”的开发记录
这是我在自己产品上的一次真实经历。这一轮动的不是新功能,而是视频生成任务里的交付一致性:分镜怎么拆、积分怎么扣、失败怎么补、成片怎么算完整。
事情本身不复杂。导演台会把用户文案拆成 N 个分镜,每个分镜调一次云端视频接口,最后拼成片。一个 4 镜任务,就按 4 镜扣积分。问题出在失败处理上:4 个镜成功 3 个、失败 1 个,系统会“很聪明”地把 3 个镜拼成一版成片交付。可用户要的是 4 镜,拿到的是不完整成片。
比技术更难的是口径:缺镜算不算完成?积分怎么返还?补跑入口怎么设计?更麻烦的是,代码里并没有一个地方能明确回答“这版成片到底完整不完整”。
修之前,我先做了一个决定,它改变了整轮对话的质量。
一、不让 AI“设计方案”,让它“取证”
我给 AI 的指令大意是:把发起任务、扣减积分、排队、取消、完整性检验、结算这几条链路完整扫一遍,基于代码现实逻辑,而不是凭记忆或方案设计,给我一份事实审计报告。
真正起作用的就是那句“而不是凭记忆或方案设计”。
原因很简单:AI 的默认模式是给你一个看起来合理的方案。它凭训练数据里的“典型架构”,就能写得像模像样。但真实的 bug 不长在架构里,长在实现细节里:谁先写内存谁后落库、哪个分支没重算状态、哪次重试会重复处理。你不逼它读代码,它就凭记忆回答你。而在交付一致性这种问题上,“凭记忆”很危险。
它交回一份 281 行的报告。几个特征让我建立信任:每个结论都带代码位置,我能逐条复核;明确写了“没做的部分”;敢说“没发现死循环”;也敢说某件事“不是 bug,是业务可接受的成本”。
我的经验是:让 AI 做可验证的任务,比如读代码、列事实、给证据、标注不确定,比让它做开放式设计,产出质量高一个档次。因为可验证意味着可被反驳,而可被反驳正是质量的来源。
二、它揪出的 12 个问题
报告按严重度分档。和交付、权益直接相关的,主要有三类不一致:
第一,并发创建批次时缺少校验,极端情况下任务状态和积分记录可能对不上;第二,某些关闭开关或规则停用的分支,会让返还流程提前返回成功,调用方以为已经处理,实际上不会再重试;第三,扣减和返还使用不同时刻的规则,时间差可能导致数额不一致。
此外还有:合成失败后任务永久卡在“合成中”;向已取消批次追加,导致任务从不执行;网络请求没有超时;排队默认无限等待等等。
我特别想说这份报告的形态:它不是“我觉得这里可以优化”,而是“第 437 行,积分关闭时直接 return true,调用方据此标记已结算,所以这笔返还永远不会再重试”。能落到这个粒度的结论,才是能直接开工的结论。
当然,这些问题如果不处理,影响的是用户对交付完整性的信任。所以我的目标不是等反馈,而是在发布前主动把边界逐一收紧。
三、两句话定口径,它替我做完了所有取舍
看完修复顺序,我给的交代很朴素:
延迟就延迟,核心是公平公正 + 严谨……一点都不能出错。
以及最关键的产品口径:
- 按实际扣减的流水返还。
- 缺镜时不出成片,只给“缺 N 镜 + 补跑”入口。
这几十个字,等于把“产品价值观”编译成了技术判据。之后几乎所有的分支判断都不用再问我:扣多少就返多少,所以必须记录实际扣减金额,而不是返还时重算;有可用片段不退,一个镜都没成功才全退;缺镜宁可不出成片,也只给补跑入口;已提交云端的任务不能取消,因为外部服务可能已经开始处理。
这是全篇我最想让你记住的一点:AI 不缺能力,缺判据。 你要是只说“优化一下失败处理”,它会给你三种都不算错的方案,然后你花三轮挑一个。你要是把“什么算公平”写清楚,它一轮就能把口径落到每一个分支上。“一点都不能出错”听起来像情绪,实际是最高效的需求描述——它把“必须逐分支核对”的默认行为打开了。
四、几个我最想让人抄走的判断
第一,涉及结算和权益的系统,必须区分“失败”和“未知”。 云端接口是提交即处理,而且没有查询、没有取消。所以提交请求超时后,你不知道对方到底收没收到:可能没收到,重试安全;也可能已经收了,重试就会重复处理。通用逻辑会把 timeout 归进“瞬时错误”自动重试,这是“为了健壮性反而制造不一致”。正确做法是把它单独建模成「提交结果未知」:不自动重试、不自动补跑,只记告警,把入口留给人工。
第二,一条约束要堵在每一个出口,而不是主路径。 落地“缺镜不出成片”时,我要求把所有能产出成片的路径都过一遍:服务端自动合成、服务端接手失败合成、客户端回传、用户手动重拼。只堵主路径等于没堵——用户点一下“重新拼接”,残片照样出来。
第三,性能优化的第一步是分类,不是缓存。 有个问题是每次进度变化都把整份批次状态写库一次。修法不是加缓存,而是分类:进度类,比如百分比、排队位置,合并写,几百毫秒落最后一次;权益和终结态,比如扣减、返还、结算、成功失败,永远立即写。为省几次写而丢掉不可丢的状态,是最贵的优化。
五、顺序交给它,发令权留给我
它给的修复顺序不是按代码位置,而是按“风险 ÷ 改动量”排。我看完只回了两个字:“开工修。”
之后它一个逻辑一个提交,32 个提交里有 22 个直接落在任务和权益链路。这意味着哪一条改错了,我可以只回退那一条。回滚粒度就是风险控制的粒度,这是我坚持拆提交的原因。验证门禁也很朴素:类型检查和 lint 全过,关键逻辑写一次性验证脚本,跑通即删。
我还特意追问过一件事:这些改动,桌面客户端要不要跟着改?这很容易凭感觉答“应该要改吧”,我要的是一份逐条断言的核查。结论是客户端不需要改,服务端的兜底已经把老客户端拦住了,最后只在桌面端加了一个很小的提示。
先证明“不用改”,再改那一处真该改的,比“顺手都改一遍”省得多。
六、三条红线,和一条关于自动化边界的经验
这一轮我划了三条红线:生产数据库只读,查真实流水,但不许改;只提交、不推送,对外可见的动作必须由我发起;构建不等于发布,构建可逆、发布不可逆,中间我说了“先停下,不发版”。
还有一条更微妙的:桌面提示,任务超过 45 分钟没进展才出现,但它只提醒、绝不自动取消任务。因为取消是“放弃已提交任务”的决策,必须由人做。系统的职责是让人知道,而不是替人做决定。
七、发布:不要相信工具自己的“成功”
发布脚本最后会打印“✅ 发布流程完成”。但我坚持独立复验,站在客户端视角自己发请求:更新端点能不能给老客户端返回正确版本、下载的整包 sha256 与本地是否逐字节一致、公开文案是否和本地一致。
复验里我踩过一个假警报:脚本按猜测的字段读“产物明细”,打印出“产物 0 个”,看着像包没传上去。实际是那个端点本来就不返回产物明细——包到底在不在,由“端点能给出下载 URL”和“下载字节 sha256 全等”证明。
教训:看结论要看证据链,不要看仪表盘。尤其在用 AI 的时候——它会给你一个漂亮的汇总表,但决定成败的是那几条能独立复现的证据。
结语:执行力变便宜之后,贵的是判断力
这一轮它读了一个 2400 行的接口文件,列了完整链路,写了 281 行报告,按风险排序修完 12 项,写了验证脚本、文档和用户文案,构建签名了桌面端,发布后做了 4 项独立复验。这些活它不累、不烦、不遗漏——过去“执行力”最贵的地方,现在变便宜了。
而这轮里我做的事,几乎全是判断:什么算公平、什么算严谨、什么代价可以接受、什么时候该发布、哪些话不该写给用户看,以及“一点都不能出错”这条底线。
所以我的结论是:别把 AI 当“更快的程序员”用。把它当“不会疲倦的审计员 + 极度听话的执行者”用——它会把你模糊的意图放大成代码,又快又准,包括放错。它真正需要的输入,是你先把“什么是对的”写成它能执行的样子。
AI 不缺能力,缺判据。判据在你这儿。
非常好的经验,感谢分享。