Martin Fowler 深度剖析:AI对软件工程的颠覆性冲击与我们必须坚守的核心原则 Best Partners TV 2025-12-10

殿堂级人物的视角:AI是职业生涯中最大的变革

前两周,Martin Fowler(殿堂级软件工程师:敏捷宣言签署者之一,著有《重构》等经典著作)做客了《The Pragmatic Engineer》播客节目,与主持人进行了长达110分钟的深度对话。可能很多人对这个名字不太熟悉,但是在程序员圈子里,Martin Fowler绝对是殿堂级的人物。他写的《重构》和《企业应用架构模式》是无数开发者的入门必读书,还是2001年敏捷宣言的签署者之一。可以说,他见证了软件行业过去四十年的几乎所有重大变革。在这期访谈中,两人主要聊的是AI对软件开发的冲击。有趣的是,作为一个从汇编语言(Assembly Language: 最接近机器码的低级编程语言)时代走过来的老兵,Fowler对AI的态度既不盲目乐观,也不一味悲观,而是带着一种经历过大风大浪之后的冷静。

从确定性到非确定性世界的跃迁

访谈一开始,主持人就问了一个很直接的问题:在你几十年的职业生涯中,有什么变革能和AI相提并论?Fowler直接回答道:这是我职业生涯中最大的一次。如果要在整个软件发展史上找一个可以类比的,那就是从汇编语言到高级语言的那次跃迁。程序员不再需要关心每个寄存器、每条机器指令,可以用更接近人类思维的方式写代码,这是一次巨大的抽象层提升。但是Fowler紧接着说道,这次变革最大的特点,不是抽象层又提高了,而是我们从确定性的世界进入了非确定性的世界。以前我们写代码,同样的输入永远会产生同样的输出,但是现在用大语言模型,同样的提示词,两次生成的代码可能完全不一样。这种不确定性,是软件工程师从来没有面对过的。

结构工程的“容差”思维对软件工程师的警示

Fowler提到,他的妻子是结构工程师,负责设计桥梁和建筑。结构工程师在工作中有一个核心概念,叫做容差(Tolerance: 结构工程中为最坏情况预留的余量)。木材、钢铁、混凝土的物理性能虽然大致都是已知的,但是你不能按照理论上的最优值去设计,必须留出足够的余量,为最坏的情况做准备。软件工程师以前是不太需要这种思维的,代码要么对,要么错,没有什么中间状态。但是现在,当我们越来越依赖AI工具来辅助写代码,这种确定性就被打破了。Fowler担心的是,很多人还没意识到这个变化的严重性,还在用老的思路来用新的工具。他预感在安全领域会出现一些很明显的翻车事故,因为人们对AI工具的非确定性过于大意了。

Vibe Coding:快速原型与学习循环的断裂

访谈接着聊到了现在很火的vibe coding(氛围编程:仅凭感觉和描述让AI生成代码,不深究实现细节的做法)。简单说就是你告诉AI想要什么,它直接给你生成代码,你甚至不用完全看懂它写了什么,只要能跑起来就行。Fowler讲了一个亲身经历的小故事:他的同事用AI生成了一张简单的示意图,就是那种用几条曲线说明问题的伪图表。Fowler想微调一下,比如把标签挪得离曲线近一点,结果打开SVG文件一看,傻眼了。他自己以前手写过类似的图,也就十几行代码,但是AI生成的这个,复杂得离谱,完全没法改。这就是vibe coding的问题:你可以让AI快速生成一个能用的东西,但是你完全不理解它是怎么实现的,你想修改一点点,却发现根本做不到,只能整个扔掉重新生成。更关键的是,Fowler指出这种方式会切断学习循环。编程的本质是,你有一个想法,写成代码,看电脑的反馈,再调整想法,如此反复,这个过程中你在不断学习。但是如果你从来不看AI生成的代码,你就什么都没学到。所以他的结论是,vibe coding适合做原型、做一次性的小工具、做探索性的尝试,但是任何需要长期维护和迭代的东西,都不能这么干。

AI在遗留代码理解中的应用:最高级别的推荐

Fowler还在访谈中提出了一个观点:说Thoughtworks已经把用AI理解遗留代码放进了他们技术雷达的采纳环,这是最高级别的推荐,意味着他们强烈建议在这个场景下使用AI。这个应用场景是这样的:对于一个复杂的老系统,你可以对代码做语义分析,把结构信息放进图数据库,然后用类似RAG(Retrieval-Augmented Generation: 检索增强生成,一种让AI模型结合外部知识库回答问题的技术)的方式让AI帮你来回答问题。比如,这段数据从哪里来?经过了哪些模块的处理?谁在用这个接口?任何在大公司待过的人都知道,理解遗留系统有多么痛苦。代码可能是十年前写的,当时的人早就离职了,文档要么没有,要么过时,你只能一行一行去读。而有了AI的辅助,至少你可以更快地建立起对系统的整体理解。Fowler还提到一个故事,有人从创业公司跳槽到一家老牌银行,任务是推动技术的现代化,干了三年之后,这人说了一句话:“我觉得我现在大概能理解这个问题了。”瞧瞧,三年,只是刚刚理解问题,还没开始解决呢。大公司的复杂性很多时候不是技术造成的,而是人为造成的。比如张三和李四当年关系好,所以选了A方案,后来张三调走了,王五上来改成了自己喜欢的B方案。这些决策层层叠加,最后就变成了一团乱麻。AI不能帮你解决这种人为的复杂性,但至少能帮你更快地看清代码层面发生了什么。

将AI代码视为实习生PR:审查、测试与重构

在如何与AI工具协同工作这个话题上,Fowler的建议很实在。他说,要把AI生成的代码,当作是一个能力很强,但是不太靠谱的实习生提交的PR。这意味着,你需要仔细审查每一处的改动,不能因为AI生成的代码看起来挺像那么回事,就直接合并进主分支。他提到了几个具体的做法:比如用非常小的代码片段来工作,每个片段都要经过人工审查;保持测试覆盖,尤其是对于AI生成的代码,需要测试来进行验证;以及不要害怕重构(Refactoring: 在不改变软件外部行为的前提下,改善其内部结构)AI生成的代码,往往它生成的东西结构很混乱,需要你自己去整理。

传统工具的效率优势与Stack Overflow的教训

访谈中还有一个很有趣的细节:Fowler说他的同事James Lewis用Cursor尝试重命名一个类,结果花了一个半小时,用掉了10%的月度token配额。但是这个任务如果用传统IDE的重构功能,也就几秒钟的事。这说明,AI在处理某些传统工具已经解决得很好的问题时,反而会变得效率低下。所以说,知道什么时候该用AI,什么时候该用传统工具,这本身就是一种需要培养的判断力。

这个情境和十几年前,Stack Overflow刚出现的时候很类似。在Stack Overflow之前,网上搜代码答案是一件很痛苦的事。你可能会进到Experts Exchange这种网站,虽然看到了问题,但是答案要付费,大部分学生和初级开发者就只能干着急。而Stack Overflow出现之后,情况就变得完全不同了。你搜一个问题,几乎总能找到可以直接拷贝的代码片段。于是很多人,尤其是新手,就养成了一个习惯:遇到问题,搜一下,拷代码,跑起来,搞定。虽然一些资深工程师会劝你,要理解这段代码为什么能工作,不能只是拷过来用,但是实际上很多人是做不到的。有一个著名的例子,Stack Overflow上有个关于邮箱验证的问题,得票最高的答案其实不完全正确,结果大量软件都用了那段代码,导致某些合法的邮箱地址被错误的拒绝。Fowler说,AI辅助编程和当年的Stack Overflow是同一种问题,只是规模更大了。Stack Overflow是拷贝一个函数,现在是AI生成一整个文件,因此风险也更大了,因为AI生成的东西更复杂,更难看出问题。但是其实解决方案还是一样的:那就是你必须看懂代码,必须理解它在做什么,以及必须保持学习。

重构在AI时代的回归与重要性

Fowler还提出了一个反直觉的观点:当AI能够快速生成大量代码的时候,重构反而变得更重要了。重构的价值在于,它让你能够在保持功能不变的前提下,改善代码的内部结构。AI生成一堆乱七八糟的代码,你通过重构把它整理成你能理解和维护的样子。Fowler一直强调重构的两个关键特征:分别是小步骤和可组合性。每一步改动都极其微小,小到几乎不值得做,但是这些小步骤可以组合起来,完成很大的改动,而且因为每步都很小,所以不容易出错。他提到了一个有趣的对比,20年前,JetBrains推出了ReSharper插件,提供自动重构的功能,大家愿意花200美元一年去买。现在这些功能已经成为IDE的标配。但是AI工具在重构方面,还远远不如这些传统工具。所以他的建议是,AI生成代码之后,人工介入,用小步骤重构成可维护的形式,这个过程也是学习的过程。

迈向精确协作:构建领域专用语言

还有一个很前沿的想法来自Fowler的同事:与其让AI直接生成代码,不如先和AI一起构建一种领域专用语言(Domain-Specific Language, DSL: 针对特定应用领域设计的、比通用编程语言更精确的语言),然后用这种语言更精确地描述问题。这个想法源于一个发现:如果你用自然语言描述一堆国际象棋对局,AI很难学会下棋。但是如果你用标准的棋谱符号描述同样的对局,AI就能理解了。背后的道理其实很简单:棋谱符号是一种精确的、无歧义的领域专用语言,每个符号都有明确的含义,相比之下,自然语言太模糊,同样的意思可以有无数种表达方式。如果把这个思路应用到软件开发中,那就可以先花时间和AI一起定义一套术语和概念,建立一个小型的领域专用语言,然后用这套语言去描述需求和指导AI生成代码。其实这和领域驱动设计 (DDD)(Domain-Driven Design: 一种软件设计方法论,强调将核心业务概念融入模型和代码中)的理念是一脉相承的。在DDD中,开发团队和业务专家要建立一套共同的语言,这套语言既能准确表达业务概念,又能直接映射到代码中。现在的区别是,这套语言不仅用于团队内部沟通,也用于和AI工具沟通,而且因为AI的存在,构建这套语言的成本降低了。你可以让AI帮你快速生成和验证这些抽象。Fowler说,这可能是一个未来的方向:我们不是简单地用自然语言给AI下命令,而是用一种介于自然语言和编程语言之间的精确语言与AI协作。

混合执行模式:AI理解,确定性工具保证准确性

还有一个很实用的思路,那就是不要让AI直接生成最终的代码,而是让AI生成输入,然后用确定性的工具来执行。什么意思呢?比如说,你不太会写SQL,但是需要对数据库做一个复杂查询。你可以用自然语言描述你要什么数据,让AI生成SQL语句。生成之后,你检查一下,觉得没问题,再让确定性的数据库引擎去执行。这样做的好处是,AI只负责理解你的意图和生成查询,真正的执行是由完全确定性的系统完成的。你能清楚地看到AI生成了什么,也能预测数据库会做什么。Fowler提到,有人在用类似的方法来做代码重构,比如用AI分析代码,识别需要重构的地方,生成重构建议,然后用专门的重构工具去执行这些改动。这样一来,AI负责提供智能,确定性工具来保证准确性。Fowler认为,这种混合模式可能也是未来的一个重要方向,那就是充分利用AI的理解能力和生成能力,但是在关键步骤上,仍然要依赖我们能够完全理解和控制的确定性工具。

敏捷理念:迭代更频繁,方向盘在人手里

聊到敏捷开发,Fowler提出了自己更多的思考。2001年,Fowler和另外16个人在犹他州的雪山里开了个会,搞出了敏捷宣言。当时谁也没想到这个宣言会有那么大影响。Fowler说他当时的想法很简单:写这个宣言的过程会很有意思,能让大家互相理解,至于宣言本身?估计没人会在意。结果完全出乎意料。现在AI来了,有人问:敏捷那一套还有用吗?Fowler的答案是,核心理念不仅有用,而且更重要了。敏捷的本质是小的代码片段,快速循环,人在回路中验证,每次代码改动都很小,可以快速得到反馈,然后根据反馈调整方向。很多人觉得有了AI,应该在每个迭代里做更多事情,但是Fowler说不对,应该是迭代变得更频繁,把原来两周的工作切成四个小节,每个小节三四天就上线。这才是正确的方向。为什么?因为软件开发的核心难题从来不是写代码慢,而是搞不清楚该写什么。用户需求会变,市场会变,技术环境会变。你花两个月憋个大招,等上线的时候,可能方向已经错了。小步快跑的好处是,你可以快速试错。这个功能用户是不是不喜欢?没关系,赶紧调整,试下一个想法。他提到,Anthropic的一个开发者,用Claude Code在两天内做了20个交互原型,每个都录了视频,记录了具体的提示词和输出。这就是敏捷精神在AI时代的体现:不是做一个完美的设计,而是快速尝试多个方向,从反馈中学习。Fowler特别强调一点:不管工具多强大,人的判断不能缺席。每个小迭代都需要人来验证,确保走在正确的方向上。简单来说,AI可以让你跑得更快,但方向盘必须握在人手里。

设计模式的转移:从通用到业务特定

不知道大家是否还有印象,90年代末2000年代初,设计模式是个很热的话题。比如Gang of Four的《设计模式》,Fowler的《企业应用架构模式》,到处都在讨论工厂模式、单例模式、观察者模式。面试的时候,面试官也经常会问到设计模式的相关问题。后来,这些讨论逐渐少了。现在的年轻程序员很多都不太了解设计模式,也不觉得有必要学。为什么会这样?Fowler和格雷迪·布奇Grady Booch讨论过这个问题。Booch是UML的创始人之一,对软件架构有很深的研究。他给出了一个有趣的观察:可能是云服务商解决了架构问题。什么意思呢?以前你要设计一个系统,得从头考虑很多东西:数据怎么存?怎么缓存?怎么处理并发?怎么容错?每个问题都需要你了解相关的模式,做出权衡,实现出来。现在呢?你用AWS或者Google Cloud,直接用Dynamo或者Cloud SQL来存数据,用Redis做缓存,用Lambda处理事件。这些服务都是精心设计过的,架构问题它们已经帮你解决了,你只需要知道怎么用这些构建块就行。某种程度上来说,云服务商把一些通用的架构模式固化成了产品。你不需要自己实现观察者模式了,直接用消息队列就行了;也不需要自己设计缓存的失效策略了,Redis已经提供了几种方案。但是Fowler也指出,模式思维并没有消失,只是转移了。在组织内部,人们仍然在创造术语和模式,只不过这些术语是针对具体业务的,而不是通用的设计模式。比如在Uber,可能有银行emoji服务、Gulfstream系统、Payment Profile服务这些名字,每个都代表了一种特定的架构决策和职责划分。新人加入需要学习这套内部语言才能融入团队。而模式的本质,其实就是一套共享的词汇表,让人们能更有效地讨论复杂的概念,这个需求永远存在,只是形式在变化。

行业冲击的真正原因:零利率时代的结束

聊到现在的行业形势,Fowler说了一个出人意料的观点:真正冲击软件行业就业的不是AI,是零利率时代的结束。过去十几年,利率极低,钱很便宜,创业公司疯狂烧钱,大公司疯狂扩张。Thoughtworks一度每年增长20%。2021年之后,一切都变了,利率上升,融资困难,客户收紧预算。裁员潮开始的时候,AI还没有现在这么火。现在诡异的是,一边是软件行业的萧条,大量工程师失业,找不到工作;另一边是AI领域的狂热,融资动辄几亿几十亿美元,估值疯涨。两个世界,同时存在。Fowler经历过90年代末的互联网泡沫,他说现在的AI泡沫规模更大。泡沫一定会破,但是什么时候破,不知道;破了之后会怎样,也不知道。不过,他也看到,AI里面确实有真东西,不像当年的区块链和加密货币那么虚。关键问题是,泡沫消退之后,什么会留下来?这很难预测。互联网泡沫破裂后,无数公司倒闭,但是活下来的那些,比如亚马逊和谷歌,后来改变了世界。AI领域可能也会如此。

对年轻开发者的建议:导师、概率思维与优秀范本

对个人来说,现在入行的时机确实不如2005年。但是Fowler认为,软件开发作为一个职业,长期来看是安全的。为什么?因为需求永远大于供给,人们对软件的需求不会减少,只会增加。就算AI让开发者的生产力提高了10倍,我们仍然需要团队来构建大型系统。原来100人的项目变成10人的项目,但是同时会出现100个新的项目需求。而且,软件开发的核心技能不会过时。什么是核心技能?就是理解用户的需求,与人沟通,把模糊的想法变成清晰的方案,然后在约束条件下做权衡。这些能力,AI还帮不了我们。

在访谈快结束时,主持人问对刚入行的年轻开发者有什么建议?Fowler的回答很朴素,那就是找一个好的导师。这听起来像是老生常谈,但是他说的很真诚。他自己职业生涯的早期遇到了James Odell,对他影响巨大;后来和Kent Beck共事,学到了极限编程和重构。Fowler说,好的导师能帮你判断什么是好代码,什么是坏代码,能帮你理解为什么这样做,而不只是怎么做。当我们用AI工具的时候,这种判断力更重要。AI会给你答案,但是答案是否合适?是否有更好的选择?这些问题,新手很难自己判断。他建议,使用AI的时候要保持怀疑,把AI当成一个能力很强、但是会撒谎的助手。它给你一段代码,你要问:为什么这么写?有没有其他办法?这个方案的前提假设是什么?多问为什么,多追问信息来源,多尝试理解背后的道理。

Fowler还推荐了诺贝尔奖得主丹尼尔·卡尼曼的著作《思考,快与慢》。这本书讲的是人类思维的两个系统,以及我们在概率和统计方面常犯的错误。为什么推荐这本书?因为软件开发中充满了需要用概率思维的场景:这个bug多久会出现一次?这个性能优化值不值得做?用户会怎么使用这个功能?所以,培养概率思维,能让你做出更好的决策,而且这不仅对写代码有用,对理解整个世界也有用。他还推荐了罗伯特·卡罗的《权力掮客》一书,讲的是纽约一个从未当选的官员,如何在40年间掌握了比市长和州长更大的权力。这本书展示了权力在民主社会中如何运作,同时也是写作的典范。Fowler说,要成为更好的写作者,就要读真正优秀的作品,而清晰的写作能力,对程序员来说也很重要。

边用边学:面对新事物最好的姿态

听完这期访谈,我最大的感受是:技术在巨变,但是思考的方式比具体的技术更重要。Fowler见证了从汇编语言到高级语言的转变,见证了互联网的兴起,见证了敏捷开发的流行,现在又在见证AI对软件行业的冲击。每一次变革都有人喊天要变了,旧的一切都要被淘汰,但是他依然在做同样的事情:观察、思考、写作、分享。他说自己学习AI的方式很简单,那就是用它。遇到问题就试试AI能不能帮上忙,在实际使用中积累对工具的理解,边用边学,而不是先读一堆论文尝试去搞懂原理。这个方法听起来很朴素,但也可能是面对任何新事物最好的姿态:不急着下结论,不急着站队,先用起来,在实践中形成自己的判断。如今,Fowler已经年过六旬,他说自己当年进入这个行业纯属偶然,因为自己手笨,干不了需要体力的工程活,写代码刚好不需要力气。谁能想到,这个偶然的选择,让他见证了软件工程,这个人类历史上发展最快的行业的几乎全部历程。而这一次,我们又站在了巨变的起点上。

关键字: code non-determinism principle refactoring-importance vibe-coding