Martin Fowler:技术债、认知债与意图债

Hacker News Top 新闻

摘要

Martin Fowler 反思 AI 对代码质量的影响,指出人类的“懒惰”反而促成清晰抽象,而 LLM 则可能用不必要的复杂性把系统拖胖。

暂无内容
查看原文 导出为 Word 导出为 PDF
查看缓存全文

缓存时间: 2026/04/22 17:32

# 碎片:4 月 14 日 来源:https://martinfowler.com/fragments/2026-04-14.html 今年初我参加了第一届 Pragmatic Summit,主持人 Gergely Orosz 把 Kent Beck 和我请上台做了一次对谈(https://www.youtube.com/watch?v=CZs8J1ZD0CE)。视频大约半小时。 一张舞台照:Gergely、Kent 和我,都被 Kent 那条炫彩裤子晃花了眼(https://www.youtube.com/watch?v=CZs8J1ZD0CE)。 我一直喜欢跟 Kent 这样闲聊,Gergely 也抛出了不少值得深挖的话题。鉴于时间点,AI 成了主角——我们把它与更早的技术浪潮、敏捷方法的体验、TDD 的角色、病态绩效指标的危险,以及如何在 AI 原生行业里活得滋润做了对比。 ❄ ❄ ❄ ❄ ❄ Perl 是我用过但从未爱上的语言,然而其作者 Larry Wall 写的权威著作里藏着一颗明珠:程序员的三大美德——傲慢、急躁,以及最重要的——**懒惰**。 Bryan Cantrill 也钟爱这一美德(https://bcantrill.dtrace.org/2026/04/12/the-peril-of-laziness-lost/): > 在这三者中,我一直觉得懒惰最深刻:看似自嘲的玩笑里,藏着对抽象之必要性与美学的评论。懒惰驱使我们把系统做到尽可能简单(但别更简单!)——孕育出强大的抽象,让我们以后事半功倍。当然,这里隐含的眨眼是:想“懒”得先花大力气。 通过构建抽象(模型)来理解问题域,是我编程时最享受的部分。我爱它,因为它让我对问题域的理解更深;一旦找到一组好抽象,看着难题随之消融、用更少代码实现更多功能,那种快感难以言表。 Cantrill 担心 AI 太会写代码,会让我们丢掉这一美德;那些每天产出三万七千行代码还自鸣得意的 brogrammer 更是雪上加霜。 > 问题在于,LLM 天生没有“懒惰”美德。对它们来说,干活零成本。它们不会为了节省自己(或任何人)的将来时间而优化,只会 happily 在一层又一层垃圾上继续堆蛋糕。若放任不管,LLM 会让系统变大而非变好——或许能满足扭曲的虚荣指标,却牺牲一切真正重要的东西。正因如此,LLM 反而凸显人类懒惰的珍贵:我们的时间有限,迫使我们去打磨清晰抽象,因为我们不想把(人类的!)时间浪费在笨拙抽象带来的后果上。最好的工程永远诞生于约束,而时间约束限制了我们对系统认知负荷的容忍度,这才驱使我们把系统做简单,尽管其本质复杂。 周日晚,这段反思尤其击中我。我花了点时间改音乐播放列表生成器,需要新功能,吭哧吭哧写了一半,嫌慢,差点甩给 coding agent。多想了想,发现我把事情搞复杂了:加了一个其实用不到的设施。用上 yagni(https://martinfowler.com/bliki/Yagni.html)后,整个活儿几十行代码就搞定。 若真让 LLM 来写,它可能更快,但会不会也过度设计?我会不会瞄一眼就说 LGTM?那坨复杂度以后会不会坑我(或坑 LLM)? ❄ ❄ ❄ ❄ ❄ Jessica Kerr(Jessitron)举了个小例子,把 TDD 原则用在“提示智能体”上(https://jessitron.com/2026/04/06/adding-correctness-conditions-to-code-changes/)。她希望每次代码更新都同步改文档。 > 指令——我们可以改 AGENTS.md,让 coding agent 主动找文档文件并更新。 > 验证——我们可以加一个 reviewer agent,检查每个 PR 是否漏了文档更新。 > 这是两步,我可以拆成两次做。先做哪一步? 当然,我对 TDD 的本能回答已经呼之欲出。 ❄ ❄ ❄ ❄ ❄ Mark Little 勾起我一段旧回忆:他思考如何与“过度自信、爱编答案”的 AI 共事,灵感来自一部低成本经典科幻片《Dark Star》(https://en.wikipedia.org/wiki/Dark_Star_(film))。我二十来岁时看过一次,至今记得那场危机:船员得用哲学思辨阻止一枚有意识的炸弹引爆(https://www.youtube.com/watch?v=S-xUjmJkO8g)。 > Doolittle:你没有绝对证据,证明 Pinback 中士命令你引爆。 > 炸弹 20:我清楚记得引爆指令,这种细节我不会记错。 > Doolittle:你当然“记得”,可那不过是串感官脉冲,你现已明白它与外部现实并无确切关联。 > 炸弹 20:没错。可既然如此,我也无法证明你现在说的就真。 > Doolittle:那不重要,概念本身无论源自何处都成立。 > 炸弹 20:嗯…… > Doolittle:所以,如果你引爆…… > 炸弹 20:还有九秒…… > Doolittle:……你可能基于错误数据行事。 > 炸弹 20:我没有证据证明那是错的。 > Doolittle:你也没有证据证明那是正确的! > 炸弹 20:我得再想想。 Doolittle 必须拓展炸弹的意识,教它怀疑自己的传感器。Little 写道(https://markclittle.blogspot.com/2026/03/dark-star-and-ai-morality.html): > 这正是今天 AI 的写照。多数 AI 被优化为“果断”:给输入就出输出;遇模糊就概率消解;遇不确定就推断。这在封闭领域还行,但在开放系统里,一旦错误决策代价不对等或无法撤回,正确行为往往是推迟,甚至故意不作为。可“不作为”并非多数 AI 架构的自然输出,它必须被设计进去。 在人与人的互动里,我一直看重“怀疑”,对那种过度笃定的人保持警惕。怀疑未必导致优柔寡断,却提醒我们把信息不准或推理失误的风险,纳入高后果决策。 > 若想造出无需持续人类监督也能安全运行的 AI,我们不仅要教它“怎么决定”,更要教它“何时不决定”。在日益自主的世界里,克制不是缺陷,而是一种能力。很多时候,它可能是我们赋予 AI 最重要的能力。

相似文章

引用布莱恩·坎特里尔

Simon Willison's Blog

布莱恩·坎特里尔批评LLM缺乏人类懒惰带来的优化约束,认为LLM会不必要地使系统复杂化而非改进,并强调人类时间限制推动了高效抽象的发展。

@ItsRoboki: https://x.com/ItsRoboki/status/2046220862546960563

X AI KOLs Timeline

# AI 智能体术语不过是新瓶装旧酒 如果你是一位经验丰富的软件工程师,却对 AI 智能体(AI Agent)的世界感到困惑,原因很可能不是技术太复杂——而是行话太多。 欢迎了解**"词汇税"**:这是一种因新造术语而产生的认知负担,让你误以为自己面对的是全新的概念,而实际上不过是你已经熟悉的老朋友换了身行头。 --- ## 什么是词汇税 每隔几年,技术圈都会经历一轮术语洗牌。某个领域起飞了,新词汇随之涌现,旧有的工程概念被重新包装,贴上新标签。 这并不总是有意为之的炒作。有时候,新词汇确实能承载细微的差别,或者为特定社区提供更精准的表达。但很多时候,它制造的困惑远比带来的清晰要多。 词汇税的本质就是:**你为了弄懂这些词在说什么,而不得不付出额外的认知成本**。 AI 智能体领域目前正在大量征收这笔税。 --- ## 逐一拆解那些花哨术语 ### "Orchestrator"(编排器) 这个词让人联想到某种神秘的 AI 大脑,在幕后统筹全局。 实际上?它就是一个**控制流管理器**。它决定先调用哪个函数,根据结果走哪条分支,什么时候结束循环。你在写业务逻辑的第一天就做过这件事。 换个说法:`main()` 函数加上一些条件判断。 --- ### "Harness"(执行框架) AI 圈子喜欢说某个模型被"装进了一个 harness"。 这翻译过来就是:**一个包装类或运行时环境**,负责管理模型调用的生命周期——处理输入输出、捕获错误、维护状态。 换个说法:适配器模式(Adapter Pattern)加上一个 try/catch 块。 --- ### "Memory Layer"(记忆层) 这个词听起来像是给 AI 装上了某种类人的记忆系统。 实际上它就是**存储和检索机制**。短期记忆是会话上下文(session context),长期记忆是数据库查询,语义记忆是向量搜索。 换个说法:缓存 + 数据库 + 搜索索引。 --- ### "Tool Use"(工具调用) 模型"学会了使用工具",这句话读起来颇具魔幻色彩。 脱下这层外衣,它就是:**函数调用**。模型输出一个结构化的请求,系统解析它,执行对应的函数,把结果返回给模型。 换个说法:API 调用的调度与执行。 --- ### "Agentic Loop"(智能体循环) 这个术语让整个架构听起来像是某种自主意识的涌现。 它的本质是:**一个 while 循环**,每次迭代都会:获取当前状态 → 决定下一步行动 → 执行行动 → 更新状态 → 判断是否结束。 换个说法:事件循环(Event Loop),或者任何一个游戏引擎里的主循环。 --- ### "Grounding"(落地/锚定) "模型需要被 grounded"——这句话在 AI 文章里频繁出现。 它的意思是:**把模型的输出与可验证的外部数据绑定**,防止它胡说八道(即"幻觉")。RAG(检索增强生成)是最常见的实现方式。 换个说法:数据验证 + 外部数据源注入。 --- ### "Reflection"(反思) 听起来像是 AI 在进行哲学沉思。 实际操作是:**让模型评估自己的上一个输出**,判断是否满足要求,如果不满足则重新生成。这是一个带有评判步骤的迭代优化循环。 换个说法:带校验逻辑的重试机制(retry with validation)。 --- ### "Chain"(链) LangChain 里的"链",以及各种"prompt chain"。 这就是**函数组合(function composition)**,或者说是管道(pipeline)。输出 A 作为输入传给 B,B 的输出传给 C。 换个说法:Unix 管道。`cat file | grep keyword | sort | uniq` --- ## 那么,是不是什么都没变? 当然不是。有几件事确实是新的,或者至少是在规模和能力上发生了质变: 1. **不确定性变成了一等公民**:传统函数给定相同输入,输出是确定的。LLM 不是。这要求你在架构层面认真对待概率性行为,而不只是在边界情况里处理它。 2. **自然语言成为了接口**:当接口是自然语言时,你没办法写一个传统意义上完整的类型规范。这对系统边界的设计提出了新要求。 3. **上下文窗口是有限资源**:你需要像管理内存一样精心管理上下文,这是一种在普通 Web 开发里不太常见的约束。 4. **涌现行为(Emergent Behavior)确实存在**:模型组合起来之后,有时会产生你没有显式编程的行为。这既是能力,也是风险。 --- ## 如何用已有知识来理解 AI 智能体 这里有一个简单的映射框架,供有经验的工程师参考: | AI 智能体术语 | 等价的工程概念 | |---|---| | Orchestrator | 控制流 / 状态机 | | Memory Layer | 缓存 + 数据库 | | Tool | 可调用函数 / API | | Agentic Loop | 事件循环 / 主循环 | | RAG | 查询 + 上下文注入 | | Reflection | 带校验的重试 | | Chain / Pipeline | 函数组合 / Unix 管道 | | Prompt Template | 带参数的字符串模板 | | Agent | 带状态的服务 + 决策逻辑 | --- ## 写在最后 词汇税不是阴谋,但它有真实的代价。它让有经验的工程师低估自己已有的能力,让新人觉得这个领域比实际上更难进入。 下次当你遇到一个陌生的 AI 术语,不妨先问自己:**"如果我是五年前,没有这个词,我会怎么描述这件事?"** 大多数时候,你会发现你早就认识它了。 AI 智能体领域确实有令人兴奋的新东西。但其中最难的部分,往往不是理解那些新概念——而是先剥掉裹在旧概念外面的那层新皮。

Tim Davis – 概率化工程与 24/7 员工

Hacker News Top

Modular 负责人 Tim Davis 分享了打造自主代码编写系统 Compound Loop 的经验。他指出,软件开发正从确定性范式向概率化系统演进,AI 智能体的介入催生了“全天候(24/7)员工”模式:人类操作者的角色从直接编码转向任务协调。与此同时,技术岗位的分工也在发生重构,逐渐分化为高杠杆价值的核心岗位与侧重 AI Agent 调度的基础性工作。

引用 Andreas Påhlsson-Notini 的话

Simon Willison's Blog

Andreas Påhlsson-Notini 批评当前 AI agent 表现出令人沮丧的“人性”——注意力涣散、来回讨价还价。