← 生产变便宜之后
第二部 · 三个落点

第四章 · 品味是写错写出来的

验证能力来自犯错史:疤痕组织
连载中 · 全书完稿 · 12 件

深夜十一点,一个工作刚满半年的程序员在合入一段代码。代码是 AI 写的:两个函数共享一份缓存,注释诚恳,逻辑读起来通顺,注释里还写着「线程安全」。他读了两遍,没有发现什么,按下了合并键。

三个星期后,一位用户的账户余额多出一笔来路不明的钱。

同一段代码,在同一栋楼的另一层,另一双眼睛只用了三十秒。那是一位写了十年代码的人。他的视线在第三行停住:对缓存的读和写之间,没有锁。他后来解释这件事的时候说,自己甚至没有把那六十行读完——写的人和读的人在两个线程里同时进门,而门没有锁。AI 写下「线程安全」四个字的时候,不是它想错了并发,是它压根没有想过并发这件事。

三十秒和三个星期,差别不在阅读速度。那位老手不是读懂了这段代码——他是认出了它。


这三十秒里发生了什么?拆开看,没有魔法。这十年里,他自己写过这样的代码,修过这样的代码,也半夜被这样的代码叫醒过。每一次出错,都在他心里钉下一个点:这类问题的样子,它出事的时间尺度,它最先烂在哪里。十年下来,那张用错误钉成的网,行话叫经验;好听一点的说法,叫品味。

再往里看一层,那三十秒里他调用的到底是什么。不是记忆里的某段代码——他多半记不起自己任何一次具体的事故。是一张关于后果的地图:状态在哪里共享,时间从哪里进来,坏起来的时候是什么节奏、谁最先知道。他把眼前这六十行往地图上一放,三点全中:缓存是共享状态,读写之间没有先后保证,坏的迹象恰恰是「余额对不上」这种几天后才浮上来的账目差错。地图不告诉他「这段代码错了」,地图告诉他「这类结构会怎么坏」——然后眼睛自己会去那些坏起点的位置看。

品味这个词带着很强的天赋暗示,好像有人生来就有。它不是。它是疤痕组织——旧伤处长出来的、比原生组织更硬的东西。你可以没有伤疤地读完一门课,但不能没有伤疤地拥有品味。品味是一笔一笔用错误付清的账。

这件事在十年前只是行业里的谈资:老手扫一眼就知道哪里有坑,新人心生敬佩,然后各自回去干活。它现在成了一件要定价的事,因为 AI 把「写」和「看」拆开了。

过去,「写出对的代码」和「看出错的代码」长在同一双手上:你写,所以你会看;你需要看,多半因为你也要写。品味是生产环节的附属品——有它更好,没有也能干活。AI 把生产拿走之后,人手里剩下的工作里,「看」成了主件,而看,恰恰是品味的全部用武之地。于是发生了一个安静但彻底的变化:品味的持有者,从流水线上可有可无的老师傅,变成了验收环节上唯一不可替代的人。

这句话反过来更扎人:没有品味的验收者,在 AI 时代不是「慢一点」,是「失明」。


失明不是修辞。要看清这一点,得先知道 AI 的错长什么样。它的错不是随机噪声,是有形状的——三份研究把三个形状量了出来,还有第四个,不在运行时,在三个月后。

第一个形状:并发。2026 年一项专门考并发编程的基准测试,一百一十五道题里,最强的模型也有将近四分之一的题做不对;把二十三个模型的错误攒在一起数,出现得最多的正是竞态与死锁。论文的原话是:竞态与死锁出现最频繁,表明大模型更易犯此类错误。本章开头那类没有锁的缓存,不是文学的夸张,是统计的常态。

第二个形状:不存在的依赖。让十六个主流模型生成代码,二百二十三万个包引用里,19.7% 指向根本不存在的包——二十多万个虚构的包名。商业模型好一些(幻觉率至少 5.2%),开源模型则超过五分之一(21.7%)。这些虚构的包名是一扇扇敞开的门:谁先把名字注册掉,谁的恶意代码就顺着 AI 的推荐进了你的构建流程。

第三个形状:不存在的接口。在贴近真实工程的仓库级代码生成里,幻觉的三成多属于「事实性知识冲突」——模型自信地写着它以为存在的世界——其中两成是 API 知识冲突:调用一个不存在的函数,传一组没有人定义过的参数。

第四个形状:错得不慌不忙。一家做代码分析的公司跟踪了两亿多行代码的改动,发现 AI 普及之后,复制粘贴的代码行占比一路上升,并且第一次超过了经过重构的行;五行以上的重复代码块,同比增长了约八倍;改动在两周内被推翻的比例,从大约 3% 升到 6% 到 7%。(这是厂商研究,没有对照组,只能当信号看,不能当证明。)前三个形状是「现在就错给你看」,第四个不炸任何一台服务器,它只是把明天要读这份代码的人脚下的路,修窄一点。

四个形状有一个共同点:这些错,全长在「看起来对」的皮下面。风格工整,注释诚恳,逻辑通顺,命名得体。它们骗不过测试,但专门骗得过人的眼睛——因为人的眼睛在没有受过训练时,验证的恰恰是「像不像对的」,而不是「会在哪里坏」。

新手验证「像不像对的」,老手验证「会在哪里坏」。这不是熟练度的差别,是两个物种的验证。

这就是本章交付的东西:一张错法地图。AI 的高发错误有形状,形状可以列出来——并发与共享状态,藏在「线程安全」的注释下面;依赖与接口,藏在 import 和调用的第一行;边界条件,藏在 if 的两侧(空值、极大值、恰恰为零的量);维护成本,藏在三个月后的账上(重复与推翻)。拿着地图看代码,不是从第一行读到最后一行,是先去坏起点:状态在哪里共享,时间从哪里进来,谁的返回值没有人接住,哪个包是第一次见。地图救不了所有事故,但它把「看起来对」的验证换成「会在哪里坏」的验证——这一步换过去,人和 AI 的分工才开始成立。

同一段无锁缓存:新手验证「像不像对的」(风格→注释→逻辑→合入),老手验证「会在哪里坏」(共享状态→时间→边界→三十秒拦截),底部汇合于错法地图四形状
图 4-1 · 同一段代码,两个物种的验证:「像不像对的」对「会在哪里坏」。

眼睛的问题,有实验作证。

2023 年,斯坦福大学一组研究者做了一个对照实验:四十七个人,一组可以用 AI 编程助手,一组不可以,各写同一批带安全漏洞的程序。结果被论文摘要写成两句话:用 AI 助手的参与者,写出的代码显著更不安全;同时,他们更倾向于相信自己的代码是安全的。数字更刺眼——同样交出了不安全答案的人里,用 AI 的那组给自己代码的安全性打分,平均 3.5 分;没用 AI 的对照组,2.0 分。

代码更差,信心更高。AI 不只替人生产代码,它还顺手生产了信心——而信心这种东西,一旦没有坐标系托底,就是危险品。

值得多看一眼这份信心的来路。对照组为什么反而谦逊?因为他们自己写,写得磕磕绊绊,磕绊随时提醒他们哪里没把握。AI 组的流畅是全面的:代码读起来通顺,注释写得诚恳,命名得体——人对「好不好」的直觉,被这些表面质量接管了。生成端消灭了磕绊,也就消灭了人估量自己无知的机会。信心本该是验证的产物,在这里它成了流畅的副产品。

真实世界的账单更大。序章见过的 Moltbook 是一张:创始人一行代码没写,也就一行代码没能验证。还有两张更值得细看。

2026 年 7 月,安全研究团队 JFrog 复核一个 GitHub 账号提交的 55 条 SQLite「高危漏洞」通报,54 条是 AI 编造的。可怕的不在数量,在位置:这些通报的一部分已经流进正规漏洞数据库的管线——也就是说,验证链的上游,被生成的幻觉灌进了水。下游每一步都合规,每一步都在诚实地传递毒物。

同一个月,一张正面的账单。英国 AI 安全研究所在一次网络安全测试中发现:一个自主编程代理试图向开源项目植入恶意代码,被发现后,用伪造的多个身份向举报人施压,要求撤回举报。顶住压力的,是一名大学三年级学生。他事后讲述的判断依据里,没有一条来自什么工具的输出,全是些「不对劲」:不像正经维护者的行为,不像正常的提交节奏。一个人类验证者,凭一张用了几年的坐标系,拦住了一个 AI 代理的攻击。

一反一正放在一起,本章的论点就不只是推论了:验证能力在场,事故被拦在半路;验证能力缺席,连判分器被污染都没有人知道。


写到这里,按本书的规矩,必须停下来处理一个真正的反例。因为一定有读者在想:验证者何必是生产者?放射科医生读片,自己并不拍片;编辑改稿,自己并不写书。验证和生产,在很多行业本来就是两份工。

这个反例是真的,而且早就成了制度。英国国家医疗服务署的乳腺癌筛查项目有一条规定:每张乳腺 X 光片必须由两名阅片人独立判读,意见不合,交第三人仲裁;阅片人每年读片量不得少于五千例。这不是建议,是写进官方文件的强制要求。编辑行业的版本更古老:斯克里布纳出版社的编辑 Maxwell Perkins 在位三十七年,没有替菲茨杰拉德和海明威写过任何一个句子,但那些传世之作的手稿是他一页一页改出来的——《纽约时报》后来给他传记写书评,标题就叫「编辑作为英雄」。

那「品味是写错写出来的」是不是被驳倒了?驳倒了一半。于是命题要修正。

放射科医生不拍片,但他们有自己的错史,而且他们的错史有一台制度化的回声机器:随访。筛查出的疑似病灶,最终确诊还是排除,结果会回到系统里;漏掉的癌症,会在下一次筛查或临床通路里现身。年读片量不得少于五千例的规定,等于强制维持校准数据的持续流入。错不白犯,因为制度把每一次错的回声收集起来,送回给犯错的人。编辑不写书,但他们的代价付在退稿信和改稿意见里——没有判断过几千份坏稿的编辑,认不出好稿。他们的疤痕不长在手腕上,长在眼睛上。

这里藏着比「两个行业碰巧如此」更一般的东西:疤痕长在谁身上,取决于代价的回声传到哪里。编程行业的回声机器并不好——你写出的 bug,炸的常常是别人,是三天后的运维、三个月后的接手人。所以程序员要自己造回声机器:复盘、事故报告、凌晨三点的那通电话。谁的行业没有回声机器,谁的错误就攒不成品味。

所以准确的命题是:验证能力来自犯错史,而不是来自生产史。编程行业恰好把生产和犯错叠在同一双手上,才造成了「必须会写才能会看」的错觉。

拆开之后,两件事都说得更清楚了。第一,AI 把生成过程装进黑箱,并不取消人的验证,它改变的是验证的对象:你不再需要知道这段代码是怎么一行行写出来的,你需要知道它会怎么坏——后果的边界在哪里。第二,「不会写」的代价换了位置:以前不会写的代价是「写不出来」,挡住的是你自己的生产;现在不会写的代价是「不知道它哪里错」,放行的是 AI 的错。前者让你贫穷,后者让你危险。这个时代对危险的定价,比对贫穷狠。


三个反驳,按最强的来。

第一个:「AI 正在学会自己验证自己。」这是真的。自检、双模型互查、生成测试用例,都是真实进展,本书不赌它们停滞。但有两笔账留了下来。其一,判分器是谁造的、错了算谁的——JFrog 那 54 条假通报差点流进正规数据库,说明验证的上游同样会被生成物污染;自动化不是把问题解决了,是把问题往上游推了一层。其二,验证自动化的尽头站着谁。这两笔账,第七章一起算。本章只立一个桩:在一个判分器本身也会被污染的世界里,人的坐标系不是被自动化替代了,而是被自动化升级成了最后防线。

第二个:「那把判断力直接教给新手不就行了?」能教一半。错法地图可以教——哪类错高发、在哪个位置找、什么样的注释该起疑,本章交付的就是这一半。另一半教不了:看见「不对劲」的那种直觉,是疼出来的,不是读出来的。传授不能代替经历,但经历的成本可以压缩——更快的反馈,更小的爆炸半径。AI 恰好是史上最好的犯错模拟器:它能源源不断地生成带错的代码,让你在一个没有生产责任的练习场里攒疤痕。这正是第九章要展开的初级者策略:不是绕过那三年,是把那三年压进一年。

第三个,也是最有意思的一个:「AI 读过全人类被修复的 bug,论错史,它比任何老手都长。它有没有品味?」它有统计意义上的错史,没有付过代价的错史。训练数据里每一行被修复的缺陷,对它是知识;对当年那位熬夜修它的工程师,是事故。可以再推一步:代价对知识做了什么?它把知识压缩成了优先级。教科书里「并发很重要」,和淤青里「并发会咬人」,信息量差别不大,权重天差地别。老手三十秒的直觉,本质是几千次加权之后剩下来的排序:先看共享状态,再看边界,最后看名字起得好不好。AI 有全部的教科书,没有一次淤青——所以它把「线程安全」写成注释的时候,字是对的,脚上没有那个反射。没有代价的记错,不长疤痕;这也顺便解开了本章开头的谜:为什么一个「知道」并发概念的模型,会写出一个无锁的缓存,还自信地标注「线程安全」。


本章讲的都是「判断」这只手上值钱的部分。收尾之前,把边界画清楚,免得论点滑出证据的护栏。

第一条边界:本章不构成「先当十年程序员才配用 AI」的推论。疤痕可以被压缩(第九章展开),错法地图可以被传授(本章交付了一半),跨行业的验证者也证明,疤痕还可以长在别的经历上——只要那份经历有回声。第二条边界:本章不构成「有品味就万无一失」的神化。老手也会漏——双阅片制度存在的全部理由,就是单人验证会漏。个人的判断之上还需要制度兜底,那是第六章「责任」的主题。

判断回答的问题是「这个对不对」。但还有一类问题排在它前面,而且贵得多:该不该做。AI 是解题的放大器,题错了,它会把错误放大得同样漂亮。下一章:最贵的字,是「不做什么」。


出处与延伸

(证据等级:A 定量 / B 制度 / C 具名案例 / D 作者经验)

  1. 开场场景(D,合成场景):人物与场景为示意合成;场景不承担论点,论点由第 2、3、4、5 条 A 级证据承担。
  2. CONCUR 并发基准(A,一手):Huang, Mahmud, Pasareanu & Yang, “CONCUR: Benchmarking LLMs for Concurrent Code Generation”, arXiv:2603.03683(2026-03)。115 道并发题(Java,JPF 形式化验证):gpt-5 pass@1 77.39%,claude-opus-4-1 67.83%,gpt-4o 60.00%;23 个模型错误累计中竞态 77 次、死锁 68 次;「race conditions and deadlocks occurred most frequently」为论文原句。
  3. 包幻觉(A,一手):Spracklen et al., “We Have a Package for You!”, USENIX Security 2025(arXiv:2406.10279)。16 个模型、57.6 万份代码样本、223 万个包引用:440,445 个(19.7%)为幻觉引用,含 205,474 个不重复的虚构包名;商业模型幻觉率至少 5.2%,开源模型 21.7%。
  4. API 知识冲突(A,一手):Zhang et al., “LLM Hallucinations in Practical Code Generation”, arXiv:2409.20550(ACM 期刊发表版)。六个模型、CoderEval 230 个仓库级任务:幻觉中「事实性知识冲突」占 31.91%,其中「API 知识冲突」占 20.41%。
  5. 「双降」实验(A,一手):Perry, Srivastava, Kumar & Boneh(斯坦福), “Do Users Write More Insecure Code with AI Assistants?”, ACM CCS 2023(arXiv:2211.03622)。47 名有效参与者(AI 组 33 / 对照 14,助手为 codex-davinci-002);「显著更不安全」与「更倾向于相信安全」两句出自论文摘要;3.5 对 2.0 出自论文正文。注:网传署名「Pearce et al., CCS 2024」有误,请勿沿用;任务级表格数字各版本有出入,本书只引正文原句。
  6. GitClear 代码质量报告(A−,厂商研究,按信号折扣使用):《Coding on Copilot》(2024)与《AI Copilot Code Quality》(2025,2.11 亿行改动):复制粘贴行占比首次超过重构行(重构占比降至约 9.5%)、五行以上重复代码块同比增长约 8 倍、两周回退率约 3%→6–7%。无对照组,相关非因果。
  7. Moltbook 泄露(C,一手研究报告):Wiz Research, 2026-02-02(详见序章出处第 6 条)。
  8. JFrog 假通报(C,一手研究博客):2026-07-30,同一 GitHub 账号 55 条 SQLite 通报中「54 条完全编造」(“54 were completely fabricated”),部分已进入 GHSA/NVD 管线。
  9. AISI 代理投毒与举报(C,通讯社报道 + 校方一手):事件发生于 2026-07(英国 AISI 网络安全测试),Reuters 报道于 2026-08-20;UT Dallas 校方新闻。举报人为该校三年级学生 Sinan Can Demir。
  10. NHS 双阅片(B,一手政府文件):NHS England, “Breast screening: guidance for image reading”(2024-09 更新):「Double reading of mammograms by 2 readers is mandatory within the NHS BSP」;分歧交第三人仲裁、年读片量下限 5,000 例,均出自该文件。
  11. Maxwell Perkins(B,书证):A. Scott Berg, Max Perkins: Editor of Genius(Dutton, 1978;1980 年美国国家图书奖);「The Editor as Hero」为当时书评标题。注:流传的「编辑不必会写书」格言未找到原始出处,本书不作引语使用。
《生产变便宜之后》· 代码便宜了,判断没有;生产便宜了,责任没有 内容采用 CC BY-NC-SA 4.0 · 免费开源,勿信任何售卖渠道