没有银弹
布鲁克斯(Frederick P. Brooks Jr.)在 1986 年发表了论文《没有银弹:软件工程的本质与次要问题》(No Silver Bullet: Essence and Accidents of Software Engineering),后来收入《人月神话》二十周年纪念版。论文的核心论断是:
在十年之内,没有任何一项单独的技术或管理方法,能让软件的生产率、可靠性或简洁性提高一个数量级。
下面先讲布鲁克斯的论证,再用它看 AI Agent,以及在 Agent 时代为什么还要学编程和算法。
一、两种复杂度
布鲁克斯把软件开发的困难分成两类。
偶然复杂度来自工具。用 C 语言写程序要手动分配和释放内存,忘了释放会泄漏,释放错了会崩溃,这些麻烦和业务本身无关。高级语言、垃圾回收、IDE、Web 框架、云服务,一步步把这类复杂度压了下去。
本质复杂度来自问题本身,换什么工具都要面对。布鲁克斯认为它源于软件的四个固有特性。
- 复杂性。现实的规则本来就多而杂。跨国税务系统要处理各国不同的税法和抵扣规则,任何框架都不能让这些规则变少。
- 一致性。软件要适配已有的环境,包括老旧的硬件接口、设计糟糕的第三方 API、不合逻辑的用户习惯。这些约束不由开发者决定。
- 可变性。现实在变,需求就跟着变。人们期望软件容易修改,所以会不断地改它。
- 不可见性。软件没有物理形态,不能像建筑图纸那样一眼看清结构,团队之间沟通和理解都很难。
几十年来高级语言、面向对象、敏捷开发带来的进步,主要消除的是偶然复杂度。偶然复杂度已经被压得很低,剩下的大头是本质复杂度,它不会因为工具更好而消失。所以不会有哪一项技术单独带来十倍的提升。
二、AI Agent 改变了什么
Agent 能拆解问题、设计架构、写出完整代码,但本质复杂度还在,只是换了一种方式落到人身上。
需求要讲清楚。用户常常只有一个模糊的想法,比如“做一个像淘宝那样的购物网站,但更高端”。需求缺了细节,Agent 只能按训练数据里最常见的做法去补,补出来的是通用方案,不是你的业务逻辑。要让它做对,你得把业务规则、边界条件和异常处理一条条讲清楚。过去用代码描述逻辑,现在用自然语言描述,对严密性的要求没有降低。
现实约束要交代。你的系统可能要对接一个十年前写的、没有文档、经常宕机的内部系统,业务流程里可能有部门之间妥协出来的规矩。Agent 有大量通用知识,但没有你公司的上下文,给出的方案往往默认环境是理想的。这些约束只能由你梳理出来告诉它。
验证的负担变重了。Agent 可以很快生成一整套微服务拆分、表结构、接口设计和几万行代码,接下来的问题是怎么确认它是对的,有没有在哪里埋下逻辑错误。自己一行行写代码时,复杂度在构建过程中被逐步消化;现在构建很快完成,人要做的是审查和测试。审查一个不是自己设计的大系统,认知负担常常比自己从头设计还重。
Agent 真正消除的是偶然复杂度。语法错误、查 API 文档、写样板代码,基本都交给了它。它还能把大任务拆成常见的小任务,因为这类拆法在训练数据里大量出现。在消除偶然复杂度这件事上,它是目前最强的工具。
所以人的工作重心移到了把模糊的现实整理成严密的逻辑上:系统运行在什么环境里,给谁用,出了故障怎么处理,预算多少。这些判断仍然要人来做,也要人来负责。
三、为什么还要学编程和算法
工具替你写代码以后,理解代码的能力更重要了,原因有四个。
- 你审查不了自己看不懂的东西。Agent 写了一段处理海量数据的代码,不懂算法的人看它能跑就接受了,懂算法的人会先看时间和空间复杂度。没有底层知识,就只能相信 AI 的输出,也发现不了它的错误。
- 编程训练的是把现实问题拆成严密步骤的能力。学编程和算法,会让人习惯去找边界条件、异常分支和状态变化。没受过这种训练的人写给 Agent 的需求往往发散、有漏洞;受过训练的人会先把输入、输出、约束和异常处理定义清楚。复杂工程要靠后一种需求描述才能推进。
- AI 给出的通常是最常见的方案。它从历史数据里学习,擅长给出被大量使用过的做法。做常规的管理后台,这已经够用。做高频交易、游戏引擎、资源受限的嵌入式设备时,需要常见方案达不到的性能和结构,这要靠扎实的算法和底层原理去设计。
- 系统出故障时要有人定位。生产环境里的内存泄漏、死锁和并发竞争,Agent 很难只凭几行报错日志找到根因。这时需要对操作系统、网络协议和数据结构的深入理解,才能从零散的线索里找到原因。
计算器是一个合适的类比。计算器普及以后,手算加减乘除、开方、查对数表都不需要了,但数学没有因此变得不重要。计算器只给出结果,不会告诉你该建什么模型,也不会教你用微积分描述物理现象。Agent 在软件工程里的角色和计算器相似。代码语法相当于算术,编程思维、算法设计和系统架构相当于微积分和线性代数。
学编程和算法的目的,从写出代码变成了能判断、指挥和纠正 AI 写的代码。