读书笔记

AI 写代码

为什么大模型偏偏在写代码上跑得最快——因为代码有裁判。也正因为如此,用好它的关键不在提示词,在你的验货能力。

约 24 分钟专题技术工作

大模型在写代码上的进步远快于别的领域,最根本的原因只有一条:代码有裁判。 能不能编译、测试过不过、跑起来对不对,机器自己就能判定——于是"生成 → 验证 → 打分"这个循环可以无人值守地跑几百万次。

写文章、做咨询、出方案没有这样的自动裁判,只能靠人打分,而人是最贵、最慢、最不一致的裁判。这一页第一节讲这个机制,第二节泼冷水(进步很不均匀),第三节讲工作中怎么用。 需要先声明:写这一页的是 Claude,我在评价自己所属的技术,这个位置本身就有偏向,详见页末灰框。

一、为什么偏偏是写代码

可验证性决定了能不能自动化训练

代码有裁判,作文没有这是最根本的一条

这一轮能力跃升的主引擎是强化学习——让模型自己产生大量尝试,对的加强、错的削弱。这套办法的前提是有人(或有东西)能判断对错。

代码恰好是复杂认知任务里唯一一类判定几乎完全自动化的:编译器会报错,测试会红绿,程序跑起来结果对不对一目了然。裁判不要钱、不睡觉、不会累、判得还一致。

反过来看别的任务就明白了:一篇文案写得好不好、一个战略建议靠不靠谱,没有编译器。只能找人来评,而人评一条要几分钟、几十块,还两个人两个意见。训练规模上就差了几个数量级。

工作里的样子

同样是"生成一段东西",代码能自己检查作业。 生成一个函数,跑一下测试就知道行不行;生成一段营销文案,谁来说它对不对?

改完代码跑 CI。 这个动作对人是质检,对模型训练就是免费的标注员。

LeetCode 式的题目最早被攻克。 因为输入输出完全确定,是最纯粹的可验证任务。

同一个模型,写 SQL 比写周报可靠。 不是因为 SQL 更简单,是因为 SQL 错了会报错,周报错了没人报错。

做数学题的进步和写代码几乎同步。 原因一样——答案可以自动核对。这两块一起突飞猛进,不是巧合。

判断"AI 在某个领域会不会快速变强",先问一句:这个领域的对错,机器能自动判定吗? 能,就快;不能,就慢。这条规律的解释力比任何其他因素都强。

别的行业羡慕不来

报错信息是天上掉下来的监督信号又快又准,还免费

代码有一个别的领域几乎没有的奢侈品:出错的时候,系统会告诉你哪一行错了、错在哪、期待的是什么。

这个信号又快(秒级)、又准(定位到行)、又结构化(有类型有栈)。人类工程师就是靠它学会编程的,模型也一样——而且模型可以在一小时里经历人类几年才能碰到的报错量。

工作里的样子

栈追踪(stack trace)。 它直接指出了因果链。想象一下如果写方案也能有栈追踪。

类型检查器。 在跑之前就能拦下一大批错误,等于免费的预审。

测试失败的那一行 diff。 "期待 3,实际 5"——这是极其精确的纠错信息。

Lint 规则。 连风格问题都能自动指出来。别的行业只有"我感觉这里不太对"。

而且是形式语言,歧义少

代码仓库天然是"问题 → 解法"的配对数据质量高得离谱

训练需要大量"这样问、那样答"的配对数据。大多数领域要花大价钱人工构造,代码领域是白捡的:

每一个 commit 都是一次"问题 → 改动"的记录,附带人写的说明;每一个 issue 加上修复它的 PR,就是一对完整的题目和答案;Stack Overflow 上是几千万条"我遇到这个错怎么办"。

再加上一点常被忽略的:代码是形式语言,歧义远小于自然语言。 同一个意思的中文有一百种写法且边界模糊,而一段代码的语义是确定的。

工作里的样子

git log。 一部人类如何修 bug 的编年史,且每条都有前后对照。

PR review 的评论。 "这里应该用 X 不是 Y"——这是极高质量的偏好数据。

开源生态。 几十年积累、公开可取、还带许可证。医疗、法律、金融的数据都锁在墙内。

错了可以回滚,现实世界不行

唯一能安全试错的复杂任务沙箱

让模型自己动手做事(agent),最大的障碍是试错的代价。让它操作真实的银行账户、真实的生产设备,错一次就是事故。

代码不一样:在容器里跑、跑挂了重来、改错了 git 还原。 这是唯一一类可以让模型放开手脚练几百万次而不伤到任何人的复杂任务。

工作里的样子

Docker 容器。 里面把系统搞崩了,删掉重建就行。

git 分支。 改废了切回去,成本接近零。

测试环境。 软件工程几十年积累下来的这套隔离设施,恰好成了 AI 的训练场——这是软件行业的意外红利。

对比一下机器人。 摔坏一个机械臂几万块,且不能重来。所以具身智能的进展比写代码慢得多——不是算法不行,是试错太贵。

这个市场的结构太理想了

掏钱的人恰好是能验货的人商业飞轮

最后一条是经济上的:AI 编程的用户是开发者,而开发者是所有用户里最理想的那种——

他们付得起钱(软件行业工资高)、能自己验货(看得懂输出对不对)、容忍早期缺陷(习惯了工具不完美)、而且会主动反馈(提 issue 是本能)。于是收入最先在这里跑出来,投入随之集中过来,能力又变强——飞轮转起来了。

工作里的样子

公司愿意为开发者的工具付费。 因为省下的时间能直接折算成钱。

开发者会自己写 prompt、自己调工作流。 别的行业的用户不会。

出了问题他们能判断是模型的错还是自己的错。 这个反馈质量极高。

把五条连起来看:可自动判定对错 + 报错信号精确 + 数据天然配对 + 试错无代价 + 客户能验货。 你很难再找出第二个五项全中的领域——这就是为什么它跑得这么快,也说明这种速度不会自动复制到别的行业去。

二、先泼盆冷水:进步很不均匀

榜单强 ≠ 你的活干得了

涨得最快的和几乎没动的,差别巨大别被平均值骗了

"突飞猛进"是真的,但它集中在特定形状的任务上。分清楚这一点,比记住任何具体能力都重要。

一个编码任务
进步巨大的那一类

边界清楚、能独立完成的函数

几乎没怎么动的那一类

需要横跨十几个服务才能理解的改动

进步巨大的那一类

有明确验收标准(测试/报错)

几乎没怎么动的那一类

验收标准是"业务上说得通"

进步巨大的那一类

上下文能塞进去

几乎没怎么动的那一类

关键约束在三年前的会议纪要里

进步巨大的那一类

常见技术栈、公开资料多

几乎没怎么动的那一类

公司内部框架、祖传中间件

进步巨大的那一类

错了能立刻发现

几乎没怎么动的那一类

错了三个月后才在结算时暴露

进步巨大的那一类

写新代码

几乎没怎么动的那一类

判断这段祖传代码为什么不能删

工作里的样子

写一个工具函数、补测试、写正则、迁移语法。 这类现在又快又好,收益立竿见影。

"为什么这里要 sleep 500ms。" 答案在某个离职同事的脑子里,代码里没有,模型也变不出来。

动一个没人敢动的老模块。 难点不是写代码,是判断有谁在依赖它——这是考古,不是编程。

跨系统的隐性约定。 "这个字段下游按逗号分隔解析",没写在任何文档里。

性能问题。 需要真实负载、真实数据分布才能定位,光看代码看不出来。

你该看的是自己的活

榜单有水分,别拿它当验收benchmark 的局限

公开评测(SWE-bench 之类)确实推动了进步,但有几个已知问题:题目可能进过训练数据(污染)、题型偏向能自动判定的那类(否则没法评)、分数接近饱和后区分度下降。

更实际的一点是:榜单测的是"能不能解出题",你关心的是"在我们这个屎山里能不能干活"。 这两件事的相关性没有想象中高。

别信任何笼统的"能不能用"。拿你们自己仓库里三个真实的、已经关闭的 issue 让它做一遍,跟当初人写的方案比。这个测试花半天,但结论比看十篇评测都准。

三、工作中怎么用好

打字不再是瓶颈

你的工作变了:从写代码,变成给上下文 + 验货这是最大的一次角色转变

以前一个需求的时间大头是把想法翻译成代码。现在这一步快了几倍,于是瓶颈移到了两头:前面是把上下文讲清楚,后面是判断产出对不对。

这意味着过去被认为"不产出"的那些活,现在是核心工作:把需求想清楚、把约束说明白、把验收标准定下来、把结果审仔细。

工作里的样子

给它一句"优化一下这个接口"。 它不知道你的"优化"是指延迟、吞吐还是可读性,也不知道哪些行为绝对不能变。产出多半跑偏。

给它"这个接口 p99 要压到 200ms 以内,返回结构不能变,这三个调用方在依赖字段顺序"。 结果完全不同。

它不知道你们为什么当初那么写。 那段丑代码可能是为了绕过某个线上事故。不说,它就会"顺手优化掉"。

它不知道你们的部署方式、灰度策略、数据规模。 这些恰恰决定了方案选型。

你花十分钟写清楚背景,能省两小时返工。 这个交换比在大多数任务上都成立。

把任务交出去之前,先花两分钟回答三个问题:目标是什么、什么绝对不能改、怎么算做完了。 说不清这三条,说明你自己也没想清楚——这时候先别急着让它写。

看不懂的领域,它是负资产

收益 = 生成速度 × 你的验证能力这一页最重要的一条

这条决定了你该在哪儿用它、哪儿不该用。

在你懂的领域,它是纯粹的放大器:它写得快,你一眼看出哪里不对,改掉就能用,净赚。

在你不懂的领域,情况反过来:它写的东西你没有能力判断对错,而它的输出总是看起来很合理。你把看不懂的代码合进主干,等于往系统里埋了一个自己都不知道在哪的雷。

所以那句常见的说法"不懂编程也能做软件了",在能跑起来的层面是真的,在能维护、能上线、出了事能修的层面是假的。

工作里的样子

后端工程师让它写前端页面。 能跑,但可能有一堆你看不出来的可访问性和状态管理问题。小工具无所谓,正式产品要人审。

让它写一段加密/鉴权代码。 这是最危险的一类:安全代码"看起来对"和"真的对"之间差得非常远,而且错了不会报错。这类必须由懂的人审,或者干脆用成熟库。

让它写正则。 你至少要能造几个用例验证,否则边界情况一定出问题。

让它改配置文件、写 SQL 迁移。 这两类的破坏力远大于普通代码,必须自己看懂每一行再执行。

用它学新东西。 这是好用法——但要在沙箱里学,别把学习过程的产物直接交付。

交付之前问自己一句:如果这段代码半夜出问题,我能不能自己修? 答不上来,就说明这段不该以现在这个状态合进去——要么读懂它,要么找懂的人审。

它的错误"长得很有道理"

审查的重点变了,因为 AI 的错法跟人不一样别用老 review 习惯

人写错代码,通常是粗心(漏个边界、写错变量名),错得比较"难看",容易被看出来。

模型写错代码,通常是自信地合理但错:结构工整、命名规范、注释齐全,看上去比人写的还专业,但某个前提不成立。这种错更难被 review 抓到,因为它不触发你的警觉。

不存在的 API
名字和风格都很像真的,但那个方法/参数根本不存在,或者在你用的版本里不存在。
版本错配
用了新版的写法,而你们锁在老版本上。这类问题很常见。
不符合本项目约定
语言层面完全正确,但和你们的分层、错误处理、命名规范全不一样。
悄悄改了语义
让它"重构",结果边界条件的行为变了,测试没覆盖到就溜过去了。
过度工程
三行能解决的事,给你一个工厂加策略模式加接口。
补丁式修复
它会顺着你的描述修表象。你说"这里报空指针",它就加个判空——根因还在。
删掉"看起来没用"的东西
那行 sleep、那个看似多余的 try,可能是踩过坑加的。
测试写成同义反复
让它补测试,容易得到一堆"跑了但什么都没断言"的测试,覆盖率好看,防不住 bug。
工作里的样子

"改完了,测试都过了。" 先看看测试是不是它自己写的、断言了什么。

diff 很大的时候格外小心。 一次改二十个文件,人是审不动的——审不动就等于没审。

它道歉后给出的第二版。 常常只是换了个说法,问题没解决。别因为它认错就放松。

连续三次没修好同一个 bug。 这时候该停下来自己看,而不是让它再试一次。(这条和《博弈论》里"一个方向连撞几次就该换思路"是一回事。)

把改动切小:一次一个关注点,diff 控制在你能一屏看完的量级。大改动拆成小改动,是目前最有效的防线——比任何审查技巧都管用。

差距会拉开

有测试的项目被放大,没测试的项目被加速欠债测试是杠杆

AI 让写代码变快了,但它没让"判断代码对不对"变快——除非你有测试。

于是同样用 AI,两种项目的结局完全相反:有好测试的项目,AI 产出能被自动验证,迭代飞快;没有测试的项目,AI 只是让你更快地往里堆没人验证过的代码——技术债的积累速度跟着一起提升了。

工作里的样子

先让它补测试,再让它改代码。 顺序换一下,安全性差别很大。

改老代码之前,先给它加一层"当前行为"的测试。 哪怕这个行为本身是错的——你要的是别改坏。

测试是给 AI 的验收标准。 你把"怎么算做完了"写成测试,它就有了可自动判定的目标——这正好用上了第一节说的那个机制。

覆盖率不等于有效。 让它补出来的测试要抽查断言,别只看数字。

如果你们测试很少,别急着大规模上 AI 改造存量代码。先在新代码和边缘工具上用,同时把关键路径的测试补起来。顺序错了,AI 放大的是风险不是效率。

对人也有用

把项目的隐性规矩写下来意外的正外部性

模型不知道你们团队"心照不宣"的那些规矩:错误怎么处理、日志怎么打、目录怎么分、什么能改什么不能碰。这些东西过去靠口口相传和 code review 传递。

要用好 AI,就得把它们显式地写下来(放在项目里的规范文件、README、约定文档里)。有意思的是:这件事对新来的人类同事同样有价值——很多团队是被 AI 逼着,才第一次把隐性知识落成文字。

工作里的样子

"这个项目不许引第三方库。" 不写下来,它每次都会给你 import 一个。

"数据库改动必须走迁移脚本。" 不写下来,它会直接给你改表结构的 SQL。

"这几个目录是历史遗留,别动。" 这类禁区最该写清楚。

写完之后新人上手也快了。 这是顺带的好处,很多团队反馈这一条的价值不亚于 AI 本身。

在仓库根目录放一个约定文件,写三类东西:这个项目是干什么的、有哪些不能碰的雷、代码风格和分层的规矩。 一页纸就够,但它会持续生效。

四、几个真实的坑

把不懂的代码合进主干
排第一。出事时你没有任何抓手,连从哪查起都不知道。
拿它绕过学习
对新手最危险。基础没打好而产出看起来不错,能力和产出会长期背离,代价在几年后才显现。
大批量自动改动
一次让它改几十个文件然后"看着还行就合了"。审不动的改动等于没审。
把敏感信息贴进去
密钥、客户数据、内部文档。先确认你用的工具怎么处理数据、公司政策允许什么。
盲信它的自我评价
"我已经修复了""测试都通过了"——必须自己跑一遍。它没有能力可靠地判断自己是不是真的做完了。
用它做架构决策
它能列出所有方案的优缺点,但选型依赖你们的团队规模、运维能力、历史包袱——这些它不知道。
一直追加提示
一个方向连试三次不成,多半是问题本身没说清或方法不对,该停下来自己想,而不是换个说法再来一遍。
忘了自己是最终负责人
代码合进去、线上挂了,责任是你的。工具不承担责任。

它解释不了什么

它解释不了"接下来会怎样"。 这一页讲的是已经发生的进步为什么发生(可验证、能试错、数据好),不是预测。用同一套机制去外推未来几年,是超出证据的。

能力强 ≠ 你们团队能用好。 组织的瓶颈往往在流程、审查能力和测试基建上,而不在模型上。同一个工具,不同团队的实际收益差好几倍。

它不解决"该做什么"。 写代码变快之后,做错方向的成本也变高了——你能更快地造出一个没人要的东西。需求判断的重要性反而上升了。

这一页不谈就业。 那个问题牵涉宏观经济、行业结构和政策,我没有能力给出可靠判断,与其含糊地说两句,不如不说。

也不谈"AI 会不会取代程序员"。 同上——现在能观察到的是工作内容在变(写得少了,审得多了,说明白需求的比重上升了),至于总量怎么变,我不知道。

  1. 判断 AI 在一个领域会不会快速变强,先问:这个领域的对错,机器能自动判定吗?
  2. 你的收益等于生成速度乘以你的验证能力——看不懂的领域,它是负资产。
  3. 人写错代码错得难看,模型写错代码错得体面,所以后者更难被审出来。
  4. 有测试的项目被放大,没测试的项目只是更快地欠债。

这一页和站里其他页不同:别的页多少在转述外部的东西,这一页几乎全是判断。所以它的"可信度结构"也不一样——第一节的机制是可以验证的(去看哪些任务进步快),第三节的建议只能自己试。 读的时候分开对待。