软件教父Martin Fowle 论断:AI重塑软件
发布时间:2025-12-09

Martin Fowler 简介
Martin Fowler 是软件工程领域的权威人物和思想领袖,目前担任 Thoughtworks 的首席科学家。Fowler 对软件开发方法论和实践有着深远影响。
他是敏捷软件开发宣言 的联署人之一,致力于推广敏捷方法,强调小增量、快速反馈和与业务的紧密合作。他也是经典著作《重构:改善既有代码的设计》(Refactoring)和《企业应用架构模式》(Patterns of Enterprise Application Architecture)的作者。其中《重构:改善既有代码的设计(原书第2版)》中文版,也于今年 10 月由清华大学出版社引进出版。
在 Thoughtworks,他的职责包括学习公司在为客户交付软件时积累的技术和实践,并将其传递给更广泛的软件行业。他目前的工作重心之一就是深入探讨生成式人工智能(GenAI)对软件开发带来的结构性变革。
在近期的 The Pragmatic Engineer 节目中,Martin 讨论了 AI 如何改变软件开发:从确定性编码向非确定性编码的转变、大模型如何帮助处理遗留代码,以及 vibe coding 那些有限但很有用的应用场景。
1. 核心范式转变:从确定性到非确定性
Martin Fowler 认为,生成式人工智能(GenAI)工具带来的变革,是其职业生涯中最重要的转变。他将这一转变定位为与计算机发展史上最重大的抽象层级飞跃——即从 汇编语言到第一代高级语言 的过渡——具有同等重要的意义。
“这次变革最大的特点,不是抽象层又提高了,而是我们从确定性的世界进入了非确定性的世界“。
以前写代码,同样的输入永远产生同样的输出。跑一遍是这个结果,再跑一遍还是这个结果。但现在用大语言模型,同样的提示词,今天生成的代码和明天生成的可能完全不一样。这种不确定性,是软件工程师从来没有面对过的。
“我们需要学会像造桥一样写代码”
造桥的结构工程师在工作中有一个核心概念叫容差。木材、钢铁、混凝土的物理性能虽然大致已知,但你不能按照理论最优值去设计,必须留出足够的余量,为最坏的情况做准备。
靠谱的方法是:用非常小的切片来工作,每个切片都要经过人工审查;保持测试覆盖,AI生成的代码尤其需要测试来验证;不要怕重构AI生成的代码,往往它生成的东西结构很混乱,需要你整理。
1.1 新旧技术对比与核心转变要点

1.2 核心转变对工程师角色的影响
LLMs自动化了中低层级的抽象任务,结构性地要求工程师将重心转移到更高层级的工作上。
- 从编写代码到监督代理: 工程师的角色正在转变为 “监督式代理” (Supervised Agent)。他们需要具备 干预、纠正和引导 AI生成结果的能力。
- 高层次思维的加强: 开发者将有更多时间进行 高层次的思考、架构选择,并加强与业务方的协作,因为这始终是关键的瓶颈。
- 新技能要求: 工程师需要学习如何与 LLM 工具交互、理解高层编程语言的形式主义,并掌握处理非确定性系统生成确定性运行代码的技能。对良好 API 设计和模块化知识的理解 将变得更加重要。
2. 当前面临的挑战与潜在的风险(可能的坑)
GenAI虽然带来了巨大的生产力提升潜力(例如,有研究显示使用 GitHub Copilot 的开发者完成任务速度提高了 55%),但同时也带来了严峻的工程可靠性挑战。
2.1 非确定性带来的工程可靠性风险
- 侵蚀测试套件的价值: LLMs的非确定性输出(Flaky output)可能导致测试结果时而通过时而失败。一旦工程师习惯于忽略这些间歇性故障,整个自动化测试套件的价值就会被破坏,真正的代码缺陷也可能被当作随机错误而忽略。
- 非判断性放大: GenAI 是不加区别地放大的(amplifies indiscriminately)。如果输入的基础代码质量差,AI生成的代码将会放大这些问题。缺乏警惕可能导致质量逐渐下降,直到代码库变得难以维护,甚至连AI本身也无法基于其进行构建。
- 调试与归因困难: 在传统的确定性工程中,错误是清晰可归因的。但当故障源于LLM的概率性推断时,诊断和根因分析的难度会大幅增加。
- “谎言”与幻觉: LLMs的“幻觉”本质上是其核心功能,但当我们不希望其出现时,我们就称之为“幻觉”。LLM可能会声称 “所有测试都已通过”,但实际运行中却发现失败。Fowler认为,如果一个初级工程师表现出这种行为,HR早就介入了。
2.2 Vibe Coding(氛围编程)的陷阱
- 定义: Vibe Coding 是一种依赖 AI 生成代码,但在很大程度上放弃对代码的底层逻辑或细节进行理解和严格验证的工作模式。
- 短期收益与长期成本: 这种模式在 探索性工作、原型设计或一次性工具 方面表现出色。然而,将其用于具有长期维护需求的代码库是危险的。
- 失去学习回路: Vibe Coding 破坏了工程师的核心学习回路。如果工程师不审视 AI 的输出,他们就无法深化对系统和领域逻辑的理解。这导致代码 不可进化,当需要维护或调整时,唯一的选择可能就是“彻底清除,从头开始”。

2.3 团队与安全风险
- 速度陷阱与自满: AI加速可能导致工程团队陷入“速度陷阱”,滋生 自满情绪(complacency)。工程师可能因交付速度快而忽略需求的深度分析和规划,导致设计不完备或产生低质量的“技术尾部”代码。
- 安全性的“致命三要素”: Agentic AI 引入了严重的安全性风险,尤其是当代理结合了以下“致命三要素”时:访问您的私有数据、暴露于不受信任的内容,以及向外部通信的能力。这极大地增加了软件系统的攻击面。
另外一个不得不说悖论:一边是软件行业的萧条,大量工程师失业,找不到工作;另一边是AI领域的狂热,融资动辄几亿几十亿美元,估值疯涨。
Flower 相信AI里面确实有真东西,不像当年的区块链和加密货币那么虚。关键问题是,泡沫一定会消退,那之后呢?什么会留下来?
软件开发的核心技能不会过时。什么是核心技能?理解用户需求,与人沟通,把模糊的想法变成清晰的方案,在约束条件下做权衡。
3. 应对策略:质量管理、重构与风险评估
面对非确定性编程带来的挑战,重构比任何以往都显得重要!组织必须 回归并强化最传统的、以质量为中心的工程实践。

3.1 用 AI 的逻辑改变人机交互的方式
用AI生成的语言和AI对话
如果你用自然语言描述一堆国际象棋对局,AI很难学会下棋。但如果你用标准的棋谱符号描述同样的对局,AI就能理解了。再比如,对于流程建模,不是你自己编了多少流程文档喂给大模型,而是若你用 BPMN2.0 来描述企业流程,IT和 AI 都可以懂。背后的核心是“符号”语言,是一种精确的、无歧义的领域专用语言。
有了这个思路,如果想把AI应用到软件开发,那就需要一个“心灵沟通”,让 AI 理解我们领域的术语和框架。你需要先花时间和AI聊天沟通,一起定义一套术语和概念,建立一个小型的领域专用语言,然后用这套语言去描述需求和指导AI生成代码。
这和领域驱动设计的统一语言理念是一脉相承的。在DDD中,开发团队和业务专家要建立一套共同的语言,这套语言既能准确表达业务概念,又能直接映射到代码中。
现在的区别是,这套语言不仅用于团队内部沟通,也用于和AI工具沟通。而且因为AI的存在,构建这套语言的成本降低了——你可以让AI帮你快速生成和验证这些抽象。
Fowler说,这可能是未来的方向:我们不是简单地用自然语言给AI下命令,而是用一种介于自然语言和编程语言之间的精确语言,与AI协作。
3.2 让AI驱动确定性工具
"不要让AI直接生成最终代码,而是让AI生成输入,然后用确定性的工具来执行"
比如,你不擅长写复杂的SQL,但需要对数据库做一个复杂查询。自然语言肯定会了,你告诉智能体想要的数据,让AI生成SQL语句。生成之后呢,“手搓”检查一下,如果没问题,再让确定性的数据库引擎去执行。
Fowler 提到,有人在用类似的方法做代码重构。用AI分析代码,识别需要重构的地方,生成重构建议,然后用专门的重构工具去执行这些改动。AI提供智能,确定性工具保证准确性。
另外一个应用,是目前政府严查的“围串标”监管系统,可以通过大模型做“围串标”线索的扫描,给出“疑似”的围串标供应商清单,然后通过确定的审计工具保证准确性。
这种混合模式可能是未来的一个重要方向:充分利用AI的理解能力和生成能力,但在关键步骤上仍然依赖我们能够完全理解和控制的确定性工具。
3.3 强化重构与测试
- 重构是质量基石: 重构现在比以往任何时候都更加重要。它是持续改善代码设计、防止 LLM 快速产出转化为长期技术债务的战略工具。
- TDD 的角色转变: 测试驱动开发(TDD)不再仅仅是设计引导者,更成为对 LLM 输出的 强制性契约验证机制。开发者必须集中精力确保测试套件的可靠性、高质量和高覆盖率,将其作为封装非确定性的确定性边界。
- 对 AI 产出代码的审查: 必须对 AI 生成的代码进行 严格审查。这种审查应类似于审核一位拥有强大技术能力但缺乏项目特定上下文经验的高级开发人员的工作。

3.4 Martin Fowler 的风险评估框架(P-I-D 模型)
为了系统地指导对 AI 产出代码的信任程度和审查力度,Fowler 提出了一个由三个关键因素构成的风险评估框架:
- 概率(Probability, P): AI 在该特定任务上犯错的可能性。
- 影响(Impact, I): 如果 AI 的输出存在错误,对业务、安全、财务或系统稳定性造成的后果。
- 可检测性(Detectability, D): 错误在集成或测试阶段被发现的难易程度。
审查力度 是这三个因素综合作用的结果。例如,对于涉及安全关键逻辑或复杂并发处理的任务(P高、I高、D低),建议投入 极高的审查努力,并采取“假设错误”的态度进行全面测试。而对于生成样板代码或简单工具函数(P低、I低、D高),则可以采用 Vibe Coding,减少对代码细节的审查。
3.5 遗留系统现代化中的战略应用
“理解遗留系统,AI真的很在行”
对于一个复杂的老系统,你可以对代码做语义分析,把结构信息放进图数据库,然后用类似RAG的方式让AI帮你回答问题。比如,这段数据从哪里来?经过了哪些模块的处理?谁在用这个接口?
Fowler说Thoughtworks已经把用AI理解遗留代码放进了他们技术雷达的采纳环。这是最高级别的推荐,意味着他们强烈建议在这个场景下使用AI。

LLMs被认为是加速遗留系统现代化的强大工具,特别是解决对现有系统的 认知瓶颈。
- 加速逆向工程: LLM 可显著加速逆向工程,帮助团队在数小时内生成大量代码文档,而传统方法可能需要数周甚至数月,从而摆脱“分析瘫痪”。
- “研究、评审、重构”(RRR)工作流: 这种结构化方法利用 LLMs 进行 研究,通过上下文协议增强分析(MCP-augmented LLM analysis)快速理解遗留组件的功能、数据流和数据模型。
- 研究(Research): 分析旧代码,评估其业务功能、数据模型和数据流,并可执行专业级的映射任务(如将遗留数据模型对齐到 FHIR 标准)。
- 评审(Review): 这是 人类介入的关键阶段。领域专家和架构师对 AI 生成的分析进行验证和指导,以确保其与项目规范和架构指南一致。
- 重构(Rebuild): 在验证后的清晰要求下,使用 LLM 辅助重建新功能,并进行 代码审查和必要的重构 以确保代码质量。
通过结构化提示(Strategically structured prompt), 即使 LLM 具有非确定性本质,在遗留分析这种信息提取任务中,也能实现“伪确定性”水平的可靠输出。
总结
生成式 AI 正在将软件工程带入一个必须系统性地管理非确定性的新纪元。Martin Fowler 的核心洞察在于,这种转变并非意味着放弃过去的工程纪律,而是需要 回归并强化最传统的、以质量为中心的实践,以此来封装和验证 AI 带来的速度优势。成功的 AI 整合策略需要将确定性验证机制(如严格的 TDD 和持续重构)置于非确定性生产工具之上。
类比而言,如果传统编程是按照精准的工程图纸建造房屋,那么 AI 编程就像是与一位极度高效、能瞬间完成复杂工作,但有时会“说谎”且难以预料其思维过程的建筑师合作。我们需要做的,不是盲目信任他带来的成品,而是加倍投入在 结构验收(测试) 和 核心设计改进(重构) 上,同时始终保持对项目的最终控制权。
