开源库sqlite-utils的维护者Simon Willison在发布4.0正式版前,用Anthropic的编码代理Claude Fable做了一次最终审查,结果揪出五个"发布阻断级"问题,其中最严重的一个足以让用户在毫无察觉的情况下丢失整张数据表。这轮审查前后进行了37次对话、改动30个文件,估算成本149.25美元——数字不大,但它牵出一个更有意思的问题:用AI做代码把关,到底是稳定可复制的工作方式,还是一次被资深维护者的操作方式精心兜住的运气。
delete_where()埋了多久的雷
Fable这次揪出的核心bug是Table.delete_where()方法(位于db.py:2948)从不提交事务,还会"毒化"整个数据库连接:执行一次delete_where()后,连接停留在事务状态里,后续所有db.atomic()调用都会误判自己身处已有事务,转而走保存点分支,永远等不到真正的commit。复现结果很直白——删除一行、插入一行新记录、甚至另一张完全无关的表,数据库重新打开后全部消失。
对照同一个类里的Table.delete()(db.py:2944),它老老实实用atomic()包了一层,从没出过这个问题。这不是隐蔽到需要专家才能发现的逻辑漏洞,而是同一份代码里两种写法留下的落差——恰恰是这种"看起来能跑、关掉连接才炸雷"的问题,最容易在人工审查里被放过。
SemVer洁癖撑住的最后一道闸
Willison长期维护sqlite-utils,是Datasette生态绕不开的底层工具,他一直按SemVer规矩走:大版本号意味着不兼容改动,越少越好,一旦发出去就没法悄悄改回来。这也是他宁可临发布前再拉一轮AI审查、也不肯让delete_where()这种bug带进4.0正式版的原因——放进4.0.x补丁包没问题,放进4.0首个正式版,就是要背一整个大版本周期的设计缺陷。
这轮审查最终牵出的改动不止一个bug:写操作的自动提交逻辑、db.query()改成调用时立即执行、Python 3.12引入的connection autocommit参数几乎让整个测试套件跑不过——这些都被塞进同一版4.0rc2里,一起重写了事务文档。这次改动力度最大的一块,恐怕就是事务模型本身。
一个方法漏包了atomic(),差点拖垮整条4.0发布线
被重新发现的老问题
delete_where()的事务问题并不是这次才第一次暴露出来——独立开发者alexwlchan此前就记录过类似的现象:delete_where()执行完之后,数据并没有真正持久化。Fable真正做的事,不是从零发现了一个前所未见的bug,而是把根因精确钉到了具体行号和触发机制上——连接被"毒化"之后为什么后续所有atomic()调用都跟着失效,这条因果链此前没人讲得这么清楚。
- 结论.AI审查的价值往往不在"发现新bug",而在把已知的模糊症状变成可定位、可复现的根因
149美元,谁在复制这套流程
Willison把这次审查的耗时和花费都公开了:37次prompt、34次commit、跨30个文件的改动,估算成本149.25美元——便宜到他愿意为此多花每月100美元,升级到Claude Max 200美元套餐。但同一时间的Reddit讨论区里,对Claude Fable的评价并不统一:有人测评花费约11,081.12美元后仍认为它能力顶尖但"拒绝执行"任务拖累效率,也有人直接吐槽它慢、生成的代码不安全、定价"烧钱"。
这两种叙事说的其实是同一个模型,差别在于用法。Willison的操作路径是分步给出37条具体指令、每一步都亲自过一遍PR和文档、还专门找GPT-5.5回头挑刺——这套"人工分步督工+多模型互审"的流程本身就是一层隐藏成本,普通开发者未必愿意、也未必有精力照做。把149.25美元当成"AI审代码"的标准报价,大概率是算错了账。
- 风险.低成本高效的案例更依赖审查者的经验和耐心,而非工具本身普遍可复现
4.0正式版发布后,真正该盯的是两件事:那些依赖旧的手动commit行为的下游脚本,会不会在事务模型变更后中招;还有这套"一个模型写、另一个模型挑刺"的互审流程,能不能在没有Willison这种资深维护者亲自把关的项目里跑得动。
