ARTICLE · 1023174
在 Coding Agent 时代,软件工程的基本功还重要吗?《Clean Code》作者 Uncle Bob 这样回答
字数 5945,阅读大约需 30 分钟

最近,Matt Pocock 邀请 Robert C. Martin(Uncle Bob)做了一场接近一小时的对谈,主题非常直接:
在 Coding Agent 时代,软件工程的基本功还重要吗?
这并不是一次简单的“AI 会不会取代程序员”的讨论。两个人真正讨论的是一个更具体、也更值得工程师关注的问题:
当 Agent 已经可以高速完成编码、测试、修 Bug 和重构时,过去那些关于架构、模块化、测试、复杂度和代码质量的原则,到底还剩下多少价值?
Uncle Bob 给出的答案并不是“AI 不行”,恰恰相反,他已经深度使用 Coding Agent,并且承认 Agent 的代码生产能力极强。
但问题也恰恰由此产生:
AI 可以极大降低写代码的成本,却没有同时降低软件系统本身的复杂度。
于是,一个新的矛盾出现了:
AI Coding代码生成成本 ↓↓↓ │ ↓单位时间产生的代码 ↑↑↑ │ ↓系统复杂度并不会自动下降 │ ↓错误、耦合、技术债积累速度 ↑ │ ↓软件工程基本功反而更加重要这场对谈真正值得关注的地方,也就在这里。
一、AI Coding 真正改变的,是“代码生产成本”
过去,一个程序员写 1000 行代码,可能需要几个小时甚至几天。

现在,一个 Coding Agent 可以在很短时间内完成大量代码生成,并且能够继续运行测试、分析报错、修改代码,再重复这个过程。
从生产效率的角度看,这是一种非常明显的变化。
但软件开发有一个容易被忽视的问题:
代码不是最终产品,软件系统才是。
代码只是构建软件系统的材料。
如果把软件开发理解成建筑,那么 AI 更像是一台极其强大的施工机器。它能够快速砌墙、铺管道、安装设备,但这并不意味着:
• 建筑结构自动合理; • 房间边界自动清晰; • 管线之间不会互相干扰; • 后续修改一定不会牵一发动全身。
因此,真正值得警惕的并不是“AI 写不出代码”,而是:
AI 写代码太容易了。
当生产成本大幅下降以后,人类很容易开始接受过去无法接受的代码冗余、重复逻辑、过度耦合和临时补丁。
过去一天产生几百行技术债,问题可能还能被及时发现。
如果 Agent 一天产生几千、几万行代码,那么问题的量级就完全不同了。
所以 AI Coding 带来的一个副作用是:
软件开发从“代码生产不足”,逐渐进入“代码生产过剩”的阶段。
二、Agent 也会被“烂代码”拖垮
这是这场访谈中一个非常重要的观察。

很多人认为,只要 Agent 足够聪明,那么代码写得乱一点其实没关系。
因为 Agent 又不会像人类程序员一样抱怨“这段代码我看不懂”。
但 Uncle Bob 在自己的 Agent 实践中发现,事情并不是这样。
当代码库逐渐变得混乱以后,Agent 同样会受到影响:
代码结构混乱 ↓依赖关系复杂 ↓修改一个地方影响多个模块 ↓Agent 判断失误 ↓修复一个问题 ↓引入新的问题 ↓再次修复 ↓循环往复最终,Agent 可能出现一种典型状态:
越修越乱。
这其实并不神秘。
Agent 的核心能力仍然建立在它对当前代码库、上下文和依赖关系的理解之上。
代码结构越清晰,Agent 越容易建立正确的模型。
代码结构越混乱,Agent 就越容易陷入局部修补。
于是,一个过去主要针对人类程序员的工程原则,在 AI 时代出现了新的受益者:
好的代码结构不仅帮助人理解系统,也帮助 Agent 理解系统。
三、Clean Architecture 为什么没有失效,反而更有价值
这里容易产生一个误区。
既然未来大量代码由 AI 生成,那么是不是意味着:
“代码是否优雅已经不重要了,反正最后都是机器维护。”
实际上恰恰相反。
软件设计中很多经典思想,本质上解决的并不是“人类喜欢不喜欢某种代码风格”,而是:
如何限制复杂度传播。
例如模块化、低耦合、明确职责、稳定接口、依赖方向等原则,最终都在解决一个问题:
变化发生在一个地方 ↓影响范围是否可控?好的设计希望得到:
Module A │ └── Interface │ ↓ Module BA 的内部变化 ↓B 基本不受影响而糟糕的设计则可能变成:
A ↔ B ↔ C ↔ D ↔ E \ \ \ / ↘ ↘ ↘ ↘修改一个模块 ↓整个系统重新摇摆对于人类来说,这种系统已经很难维护。
对于 Agent 来说同样如此。
所以在 AI Coding 时代,架构的价值并没有消失,而是发生了一层新的变化:
架构不仅是给人看的,也是给 Agent 提供认知边界的。
四、真正危险的,不是 Prompt 不够长,而是约束不够硬
这是整场对谈里最值得带回实际工程的一条经验。
很多人在使用 Coding Agent 时,会不断往 CLAUDE.md、AGENTS.md 或系统 Prompt 中添加规则:
必须遵守模块边界必须写测试不要修改这些目录不要使用这个 API必须保持低复杂度不要产生重复代码……这种方式当然有价值。
但它存在一个根本问题:
Prompt 是建议,工具才是约束。
模型可以理解规则,但不能保证始终严格执行规则。
而一个真正的工程约束应该尽可能变成机器可以判定的东西。
例如:
Agent │ ├── 编写代码 │ ↓编译 │ ├── 失败 → 返回 Agent 修复 │ ↓单元测试 │ ├── 失败 → 返回 Agent 修复 │ ↓复杂度检查 │ ├── 超标 → 返回 Agent 修复 │ ↓架构依赖检查 │ ├── 违规 → 返回 Agent 修复 │ ↓Mutation Testing │ ├── 测试无法发现变异 → 返回 Agent 修复 │ ↓QA │ └── 通过这和传统软件工程的 CI/CD 思想非常接近。
区别在于:
以前这些检查主要用来约束人类程序员,现在它们开始成为约束 Agent 的基础设施。
五、Uncle Bob 重新关注了两个“老工具”:CRAP 与 Mutation Testing
这部分是整场讨论中特别有意思的地方。
1. CRAP:不要只看测试覆盖率
CRAP 是一个结合代码复杂度与测试覆盖率的指标,用来识别风险较高的代码。
这背后的思想很简单:
高复杂度 +低测试覆盖 =高风险代码因为仅仅说:
“我们的测试覆盖率有 90%。”
并不能证明代码就安全。
一段复杂度非常高、逻辑分支非常多的代码,即使有不错的覆盖率,也可能仍然很脆弱。
Uncle Bob 在讨论 Agent 工作流时,把这类指标重新放到了更核心的位置,因为现在 Agent 可以持续执行这些检查,并根据结果继续修改代码。相关转写资料也提到,他尝试针对 Agent 设置比过去人工维护更宽松的复杂度阈值。
这里真正值得借鉴的并不是某一个固定数字,而是:
把“代码质量”从主观评价,逐渐转化为可以自动测量的工程信号。
2. Mutation Testing:故意把代码改坏
Mutation Testing 的思路更加直接:
故意制造错误,然后检查测试能不能发现。
例如:
if (count > 100)自动变成:
if (count >= 100)或者:
a + b变成:
a - b然后重新运行测试。
如果测试失败:
Mutation killed说明测试确实抓住了问题。
如果测试全部通过:
Mutation survived说明测试没有真正验证这段行为。
Mutation Testing 很早就被认为是一种非常有价值的测试方法,但过去最大的障碍之一是成本。
因为需要制造大量 mutation,再不断执行测试。
对于人类程序员而言,这种流程往往太慢。
而 Agent 恰恰改变了成本模型:
生成 Mutation ↓运行测试 ↓分析结果 ↓修改代码 / 补测试 ↓再次运行Agent 可以不停重复这个循环。
于是,一个过去“理论上很好,但实践成本过高”的工程手段,在 AI 时代开始变得更加现实。相关视频摘要和转写均把 Mutation Testing 列为这场讨论的重要部分。
这其实说明了一件非常重要的事情:
AI 不一定创造新的软件工程原则,它有时只是把旧原则的执行成本降到了可以接受的程度。
六、TDD 可能需要变化,但它解决的问题没有消失
Uncle Bob 本身就是 TDD 的重要倡导者,因此一个非常值得关注的问题是:
Agent 时代还需要严格照搬人类程序员的 TDD 流程吗?
答案并不是简单的“是”或者“否”。
因为 TDD 中包含两类东西。
第一类是工程价值:
• 行为可验证; • 反馈快速; • 小步迭代; • 降低回归风险; • 让设计在反馈中逐步形成。
这些价值依然成立。
第二类则是具体的开发节奏和仪式:
Red↓Green↓Refactor↓重复这一套节奏,本来就是围绕人类程序员的工作方式形成的。
而 Agent 的工作方式完全不同:
高速生成自动执行自动测试自动修改持续循环所以真正值得思考的不是:
“Agent 必须严格模仿人类 TDD。”
而应该是:
哪些工程价值必须保留,哪些工作流程可以重新设计?
这也是 AI Coding 时代一个非常重要的原则:
不要迷信流程本身,要保留流程背后的工程价值。
七、从“提示 Agent”转向“构建 Agent 的反馈系统”
如果把上面的讨论进一步抽象,就会得到一个非常重要的变化:
过去我们习惯:
程序员 ↓写代码 ↓自己测试 ↓自己判断现在逐渐变成:
Human ↓定义目标与边界 ↓Agent ↓生成实现 ↓Deterministic Checks ↓反馈 ↓Agent 修复 ↓再次验证也就是说:
Agent 的核心能力越来越不是“一次写对”,而是“在反馈中不断修正”。
这与现代软件工程其实高度一致。
一个好的 Agent 系统,本质上应该拥有一套足够强的:
Observe → Act → Verify → Repair
闭环。
因此,未来真正有价值的 Agent Harness,可能并不是把 Prompt 写得越来越长,而是把:
• 编译器 • 测试系统 • Linter • Static Analysis • Complexity Checker • Architecture Checker • Mutation Testing • Integration Test • UI QA
这些确定性能力组织成一套完整的反馈回路。
八、为什么长 Prompt 不是解决一切问题的答案
另一个很值得注意的观点,是对上下文的重新认识。
很多 Agent 使用者很容易产生一种直觉:
“既然模型上下文越来越大,那就把更多规则、文档、规范、架构说明全部塞进去。”
但上下文长度变大,并不意味着模型能够同等有效地利用所有信息。
在长上下文场景中,一个典型现象就是:
信息很多,但模型对不同位置的信息关注程度并不完全一致。
因此:
Context 越大 ≠有效信息越多对于 Agent 来说,一个非常现实的工程目标是:
尽量让真正关键的信息靠近任务本身,并减少无关上下文。
这也解释了为什么一些成熟的 Agent 工作流越来越强调:
• 小而明确的指令; • 任务范围清晰; • 工具自动验证; • 将规则转化为可执行检查。
相比于:
20000 字 Agent 操作手册很多时候,一个:
“必须通过 architecture-check”再配合真正存在的检查工具,反而更加可靠。
相关访谈整理也明确提到了长规则文件和“lost in the middle”问题。
九、Agent 最擅长的是 Tactical Programming,而不是 Strategic Programming
这大概是整场对谈中最值得程序员思考的一层。
可以把软件开发粗略分成两个层次。
Tactical:战术层
例如:
实现一个接口增加一个字段修复一个 Bug补一个测试重构一个函数修改 SQL调整 UI这些工作天然适合 Agent。
因为它们通常:
• 边界明确; • 反馈明确; • 可以自动验证; • 可以局部执行。
Strategic:战略层
真正困难的则是:
这个系统应该怎么拆?哪些模块应该存在?边界在哪里?依赖方向如何?哪些东西应该隔离?未来变化最大的地方在哪里?什么规则必须成为系统约束?这些问题远比“写一个函数”困难。
也因此,未来程序员真正需要强化的能力,可能越来越集中在:
Problem Definition ↓System Design ↓Architecture ↓Constraints ↓Verification ↓Agent Execution而不是:
Syntax ↓Typing ↓Boilerplate十、于是,一个非常尖锐的问题出现了
如果 Agent 已经可以完成大量 Tactical Programming:
新人程序员怎么成长?
Matt Pocock 在访谈中实际上追问了这个问题。
过去,程序员通常是在大量具体编码中逐渐积累经验:
写代码 ↓踩坑 ↓修 Bug ↓理解设计 ↓逐渐形成架构能力但如果未来:
Agent 写代码Agent 修 BugAgent 重构Agent 写测试那么新人是否会失去最重要的学习过程?
这可能是 AI Coding 时代比“程序员会不会失业”更值得讨论的问题。
Uncle Bob 给出的思路之一,是让程序员真正进入 Agent 工作流,而不是完全远离编码,让自己逐渐承担更高层次的设计和控制工作。公开视频的摘要也明确将“开发者需要学会与 AI 协作,并不断保持编码实践”作为重要结论之一。
这里其实存在一个值得警惕的风险:
如果一个人从一开始就只会向 Agent 提需求,而自己完全不知道代码为什么这样工作,那么他可能不是在升级,而是在失去形成软件工程判断力的机会。
因此,“会用 Agent”与“懂软件工程”仍然是两回事。
十一、“人不看代码”不能被简单理解成“代码不重要”
Uncle Bob 在自己的 Agent 工作流中提出了一个非常激进的目标:
让 Agent 完成大量实现,人主要通过测试、指标和确定性检查判断结果,而不是逐行阅读所有生成代码。
这个观点非常有冲击力。
但这里必须区分:
这是一个特定工作流中的工程目标,而不是“未来程序员都不需要理解代码”的证明。
两者完全不同。
更准确的理解应该是:
过去:Human ↓阅读大量代码 ↓发现问题逐渐可能变成:
Human ↓定义质量标准 ↓Agent ↓执行大量实现 ↓自动验证 ↓Human 审查关键结果也就是说:
人工审查的粒度正在变化。
不是从:
“我必须看每一行代码。”
变成:
“我必须保证系统具有足够可靠的验证机制,并能对关键结果进行审查。”
这更像是一种软件开发中的“抽象层提升”。
十二、真正值得学习的,是 Uncle Bob 的“五道关卡”思路
根据视频中的讨论和公开转写资料,Uncle Bob 展示的 Agent 工作流可以概括成一条多阶段流水线:
Human Intent ↓Specifier ↓Implementer ↓Cleaner ↓Hardener ↓QA每一个阶段承担不同责任。
Specifier
把人的需求转化成更加明确的行为描述、验收场景和测试条件。
Implementer
负责具体实现,包括代码和相关测试。
Cleaner
进行重构,并检查复杂度等指标。
Hardener
通过测试覆盖率、Mutation Testing 等手段增强实现的可靠性。
QA
从用户视角执行系统级验证。
这套设计真正重要的并不是“必须使用五个 Agent”。
而是它体现了一种非常关键的思想:
不要让一个 Agent 同时扮演需求分析、实现、审查、测试和验收的所有角色。
可以把不同职责拆成不同的阶段,让系统形成类似软件生产线的结构。
这与现代 AI Agent Engineering 越来越强调的 workflow、harness、verification loop 是高度一致的。
十三、未来的软件工程,可能从“写代码”转向“设计反馈回路”
把整场访谈再抽象一层,可以得到一个非常有意思的结论。

过去的软件工程核心问题是:
如何让程序员更高效地写出正确的软件?
而 Agent 时代开始逐渐变成:
如何让 Agent 在高速生成代码的同时,不断得到可靠反馈?
于是软件工程的核心结构可能逐渐变成:
Human │ Intent / Goal │ ↓ AI Agent │ Generate │ ↓ ┌─────────────────┐ │ Verification │ ├─────────────────┤ │ Compile │ │ Unit Test │ │ Integration Test│ │ Static Analysis │ │ Complexity │ │ Architecture │ │ Mutation Test │ │ QA │ └────────┬────────┘ │ Feedback │ ↓ Agent │ Repair │ └──────→ 再验证这个结构里,LLM 并不是唯一的核心。
真正重要的是:
模型 + 工具 + 约束 + 反馈 + 状态
共同构成了一个可以持续运行的软件生产系统。
十四、那么,AI 时代的“软件基本功”到底是什么?
如果重新定义今天的软件基本功,它可能已经不应该只是:
语法设计模式数据结构算法API更重要的是:
第一,控制复杂度
知道什么时候应该拆模块,什么时候应该抽象,什么时候应该拒绝继续堆代码。
第二,建立清晰边界
知道一个模块应该负责什么,也知道它不应该负责什么。
第三,构建可验证系统
代码不是“看起来没问题”就够了,而应该拥有能够证明其行为的测试和检查。
第四,建立确定性约束
尽可能让重要规则从 Prompt 变成:
CompilerTestLinterStatic AnalyzerArchitecture RuleCI Gate第五,理解系统而不仅仅是理解代码
真正高级的程序员,关注的已经不是某一个函数怎么写,而是整个系统为什么这样组织。
十五、这场访谈真正值得带走的,不是“AI 会不会写代码”
如果只把这场访谈理解成:
“Uncle Bob 说 AI 时代软件基本功仍然重要。”
其实还是有些表面。
它更深层的价值在于,它重新提醒了一个经常被 AI Coding 热潮掩盖的问题:
代码生成能力的增长,与软件系统质量的增长,并不是同一个事情。
可以用一个非常简单的公式表示:
AI=Coding Cost ↓↓↓但:
AI≠Software Complexity ↓甚至在某些情况下:
Coding Cost ↓↓↓ +Code Production ↑↑↑ ↓Complexity Risk ↑所以 AI 越强,越需要工程约束。
这也是为什么软件基本功并没有因为 Agent 出现而失去价值。
恰恰相反:
当代码越来越容易生成时,真正稀缺的就不再是“把代码写出来”,而是判断哪些代码应该存在,以及如何证明它是正确的。
十六、给正在使用 Coding Agent 的程序员三个实际建议
这场访谈如果要真正落到日常开发,我认为可以从三个方向开始。
1. 少写一点 Prompt,多增加一点自动检查
不要把所有规则都写进:
CLAUDE.mdAGENTS.mdSystem Prompt更应该问:
这个规则能不能变成一个自动检查?
例如:
禁止跨层依赖 ↓Architecture Checker函数复杂度不能超过阈值 ↓Static Analysis关键逻辑必须覆盖 ↓Coverage测试必须真正有杀伤力 ↓Mutation Testing能自动判定的东西,就不要只靠模型记忆。
2. 把 Agent 从“代码生成器”变成“闭环工程系统”
不要只是:
Prompt ↓Generate ↓Done而应该逐渐建立:
Plan ↓Implement ↓Test ↓Review ↓Verify ↓Repair ↓Verify AgainAgent 的价值不只是帮你写第一版代码,而是帮助你高速完成整个工程闭环。
3. 自己不要放弃“理解系统”的能力
AI 越强,越不能把:
“代码由我写出来”
等同于:
“系统是我理解的”。
真正需要保留的能力,是:
为什么这么设计?为什么要这么拆?这个边界合理吗?这个测试证明了什么?还有什么没有被证明?这个变化的影响范围在哪里?因为未来最有价值的问题,很可能不再是:
“这段代码怎么写?”
而是:
“为什么系统应该这样存在?”
结语:AI 不会杀死软件工程,它只是把软件工程的问题放大了
Uncle Bob 这场访谈最有价值的地方,并不是告诉我们:
“程序员要继续学习 Clean Code。”
它真正指出的是一个更现实的变化:
过去软件工程最大的效率瓶颈之一,是人写代码太慢。
今天,这个瓶颈正在迅速被 AI 攻克。
但软件开发还有另一个更深层的瓶颈:
我们如何控制复杂度、验证正确性,并让系统能够持续演进。
这个问题不会因为 Agent 出现而消失。
相反,当 Agent 可以一分钟生成过去一天才能写完的代码时,这个问题会变得更加尖锐。

所以 AI 时代真正重要的并不是:
人写代码还是AI 写代码而是:
人定义目标 ↓Agent 高速实现 ↓工程体系持续验证 ↓系统保持可理解、可修改、可演进从这个角度看,软件工程基本功并没有过时。
它只是从“帮助人写好代码”,逐渐变成了“帮助人和 AI 一起控制复杂度”。
而这可能才是 Coding Agent 时代,软件工程真正发生的变化。