题图
(题图由AI生成)

今天是 10 月 24 日,程序员节,也叫 1024 节。那就来说说编程。

起因是我看到最新一期《科技爱好者周刊》,介绍了 Thorsten Ball 的文章《What I believe about the future of software development》,并使用了“编程已经面目全非”的标题。周刊评价其“观点很激进”:代码审查会消失,单元测试可能消失,代码风格和 linter 没意义,UI 变得不重要,Token 为王……

在我看来,AI 进了开发工具链,这是一条单行道,再难回到过去的古法,这一点没什么可争的。但过去几十年攒下来的软件工程实践,解决的大多是开发过程里“人”的问题:人会记不住太多线索,会在沟通中发生误解,会协调不过来,也会在赶进度时跳过检查。在 AI 时代,这些问题没消失,只是承担者从人扩到了人和 agent。变的主要是尺度,比如代码量、交付速度、系统复杂度;需求与实现的落差、bug 的产生和跟踪,不会一劳永逸地消失。

我的观点是:变的只是工具、做法和尺度,但做法要解决的问题、甚至做法本身的逻辑,却并没有变。下面挑几条具体说说。

一、逐行阅读代码会退场,但审查不会

人逐行阅读代码,这个具体做法确实维持不下去了。AI 一次吐出的量,早已超出人的阅读带宽,勉强读完,多半也只是“看过”,谈不上“审过”。但逐行阅读只是一种做法,并不等于审查本身。审查要做的是在合入前把错误拦下来,这件事没有替代品。AI 写得再快,也总得有人对“这份改动能不能进主干”负责。

它会往几个地方挪。一种是让另一个模型带着不同的上下文去审。自审的毛病在于,它会沿用生成时的假设,把同一个误解验证两遍;写测试的人和写实现的人分开,本来也是这个道理。另一种是把审查写成可执行的检查:类型、lint、测试、CI 门禁、模块边界,把“什么算错”提前写进规则里。我自己的博客仓库就是这样,文件名、slug、发布前的构建检查都写成了脚本,AI 改完必须跑过才算完。还有一种是按风险抽样,权限、资金、数据迁移这些地方,仍然要人看,而且得看懂。

原文认为,人以后只审“系统的组成”,那其实还是审查,只是尺度从行换成了结构。把审查内化到实现过程里,这个方向我赞成,但还得补一句:内化能覆盖模型想得到的错,覆盖不了它没想到的假设。这些假设的兜底,还得人来做。

二、单元测试会持续进行,不会消失

周刊中打了个比方来帮助解读原文:反正整栋楼要重建,何必检查单块砖头。可楼拆了重建,你总得知道新楼还满不满足原来的用途:门开得开,水管不漏,承重够。测试不是给砖头做体检,它验收的是整栋楼。

对 AI 来说,测试已经成了它实现过程的一部分:它是最便宜的“是/否”信号。模型实现功能时本来就要反复确认,让它读自己的代码来确认,成本高且不可靠,因为读到的仍是自己的假设。跑一遍测试,拿到的是一句确定的话。单元测试框架降低的,正是这个反复确认的难度。测试也把意图固定了下来:代码可以随时重写,但“这个输入该得到什么输出”得有个不随实现漂移的落点,否则每次重写都等于把需求重新猜一遍。

单元测试不会退出开发流程。代码越是一次性的,越需要测试一直跑。有了这层保证,AI 才敢动手重写。省掉这一步,省下的是写测试的时间,换来的是每次重写都少一份把握。我们都知道AI天生擅长“一本正经地胡说八道”,当缺少基本的单元测试验证,完全靠吐出一个个token的方式来生成的代码,仅凭AI拍胸脯信誓旦旦说“我写的这段代码绝对没问题”,你敢信吗?

三、代码风格仍然有用,只是标准变了

每行多少列、要不要换行,这些确实是形式问题,交给格式化工具就好。但命名、模块边界、错误处理的一致性、同一件事只用一个说法,决定的是代码能不能被低成本地读懂、被快速定位。

AI 读,不等于人不读。抽样审查、故障定位、交接、合规检查,这些场合人都得读。AI 读也有成本,前后不一致的写法会让上下文里的有效信息变稀。风格一致的代码,读起来省力,也省 token。再往下说,当代码由多个 agent、多个会话先后写出来,风格是它们之间唯一的协调协议,没有它,每次交接都要重新对齐约定。

“好代码”的标准没有消失,只是门槛更高了:以前只要人读着舒服,现在人和机器都得读得省力。linter 也不是用来管人的,而是把约定变成可执行的检查。

四、界面不只是给 AI 用的

给 AI 用的那部分界面,确实不需要做得精致,一个 API 就够了。但 API 也是一种 UI,只是用户换成了 agent。好 API 和好界面要解决的是同一类问题:能不能被正确理解,误用会不会造成破坏,出错时能不能看懂。

更要紧的是另一半。原文认为,UI 之所以存在,是因为软件听不懂你想要什么。这话有一半道理:需求不是先在脑子里成形、再被说出来的,人需要一个能看、能试、能改的表面,点两下才发现“我要的其实是按这个维度分组”。实时生成的 UI 也不会取消这个表面,只是把它抬高了一层:从操作控件,变成和 AI 对话、看它生成什么。交互反而更核心了。人得能看见它在做什么、随时打断、比较两个版本,可观察性本身就是 UI。

原文认为,智能机器需要的 UI 少得多,我觉得推得太远了。人是视觉动物,对反复使用的界面,优化过、美化过的,就是更容易让人有好感,也更愿意多打开几次。哪个产品被留下、被推荐、被反复使用,很大程度上还是人在挑。

一次性的软件会越来越多,未必需要多高的界面水准。这有点像生物演化里没受到选择压力的性状,长成什么样都行,甚至漂成什么样也无所谓。可只要界面要反复使用、被人比较,选择压力就回来了:好用、好看的会被更多人用;用的人多了,实现它更划算,AI 见得多、做得熟,复制也更容易;成本一低,它又更容易铺到别处去。所以 UI 未必变得不重要:一次性的工具可以粗糙,反复使用的界面还是会被越挑越精。机器不需要菜单和设置页,但决定用哪个软件的,还是人。

五、Token 只是成本

Token 这条最容易说过头。多花 token 通常能换来更好的结果,但它有拐点;过了某个点,多出来的是噪音、是绕圈、是把简单问题复杂化的倾向。花多花少不算数,得看这些 token 换回了什么。

该算的账是:在可承受的成本和风险下,最大程度地满足需要。成本不只是钱,还有延迟、出错的风险,以及你自己复核所花的时间。当“写”变便宜,瓶颈就移到了“验”:能花多少 token 生成,不构成优势;能多便宜地确认它对,才是优势。省 token 也不是目的:为了省钱把任务砍到做不成,跟为了效果把钱烧光,是同一种错误的两头。

六、有些约束不会松动

前面几条说的多是实践和成本,还有一层更硬的东西,是约束。

最典型的是算法上的下界。基于比较的排序,至少要比较 n log n 量级那么多次,也就是 Ω(n log n)。这不是哪个库写得不够聪明,而是在只允许比较的前提下,任何算法都绕不过去。计数排序、基数排序不用比较,能绕开这条下界,代价是要额外假定键的形态:计数排序要求键是范围有限的整数,范围一大,时间和空间都跟着涨;基数排序则要求键能按位拆开。类似的下界还有许多,通信、存储、并行加速比,各有各的天花板。可以把这些想成计算世界里的物理规则:AI 再强,也只能在规则之内找更优的解,改不掉规则本身。

所以“整栋楼推倒重建”这件事是有边界的:楼可以重画,重画之后仍然要满足同样的结构约束。AI 提高的是找到可行方案的速度,并不能把不可行的方案变可行。

另一类约束来自 AI 自己:有限的上下文、会衰减的注意力、按 token 计价的预算。它们决定了模型一次能考虑多大的范围、能记住多久之前的约定、能在多少轮里收敛。规模一大就丢细节,轮次一多就漂移。

七、判断还是得有人做

这些约束落到具体项目里,就变成一次次权衡。做的人换了,权衡本身没换:时间换空间还是空间换时间,一次做对还是分步验证,通用抽象还是就地解决,复杂度留在代码里还是留给人。这些没有标准答案,只能按场景定。而场景的约束,比如预算、延迟、可靠性、要维护多少年,不会因为写代码的是 AI 就消失。

这些实践针对的从来不是“手写代码”这个动作,而是有限主体之间的协作与验证。agent 同样会忘、会误解、会自信地犯错,也会在不同会话之间产生分歧。把主体从人换成 agent,问题只是换了个样子。

写代码变便宜了,判断反而更贵。审查、测试、风格、界面,都是在替判断兜底,预算则划定这套判断能做到什么程度;而算法下界这类物理规则,以及上下文长度、注意力这些现实约束,又决定了判断没法留到最后一次性做完。

回到原文,它最后也提到,这套变化要一代人的时间才会铺开,十年后仍会有人靠写代码吃饭,问题只是你想不想做那份工作。既然它自己都说要一代人的时间,现在就说“面目全非”,还是太早了。

所谓分工变化,其实不是人退到了什么新位置。定标准、验结果、担责任,这些本来就是人在做的事;只是过去大部分时间和精力,被技术细节、被反复敲代码改代码占着,真正重要的那部分反而被挤到角落,甚至没被当成工作本身。现在这些琐事由 AI 接过去,人才算回到本来就该站的地方。这个位置并不轻松,它要求你更清楚什么算对。

这个道理不只在写软件。做生信、做研究也一样:决定成败的,往往是问题提得对不对、方法选得对不对、结果信不信得过;可大量时间却花在装环境、调参数、改脚本、整理数据这些事上。AI 把这些接走,省下来的不只是时间,更是能重新放回判断上的精力。

关注点回到该在的地方,速度又快了起来,能走的路自然更远。以前不少想法,光实现就要耗掉几年,等做出来,时机和心气都过去了;现在同样的时间能多试几个方向,也就能更早看到结果。有些原本一辈子都够不着的东西,也许这几年就能看见。

某种程度上,我们是把世界的速度调快了。把速度拨快一点,也就等于把自己的生命拉长了一点。在并不直接研究生命的前提下,这波 AI 浪潮对所有行业的冲击,也算是程序员用自己的方式,使人类朝着永生目标,又前进了一步吧。

--- END ---

注:本文由AI辅助润色,文章内容与观点均由作者本人提出并复核。