vault backup: 2026-05-17 01:53:32

This commit is contained in:
thinkbook 2026-05-17 01:53:32 +08:00
parent a3406eeb1b
commit e40b2cf7cf
1 changed files with 257 additions and 0 deletions

View File

@ -0,0 +1,257 @@
# AI 是银弹吗?浅谈人工智能时代下的软件工程
> **声明**:我目前还没有、也不打算将 AI 编程用于生产系统。本文讨论的是我在非生产项目中对 AI 辅助软件工程方法的探索与思考。
---
## TL;DR
AI 能写代码、能设计、能做测试,但也能量产 bug——而且是那种"你来解释一下你的代码里为什么出现一句俄文"的诡异 bug。本文不讨论"AI 会不会取代程序员",而是探讨一个更实际的问题:**当编写代码不再是瓶颈,软件工程的瓶颈变成了什么?** 答案是:变成了"确定性"——如何让大模型输出的不确定性,转化为生产系统要求的质量的确定性。我们目前还没找到这个问题的答案。
---
## 一、引言——一次"银弹"级别的震撼
2025 年初Cursor 大火。我试了,效果很差。每出一个提示词,改出来的几十上百行代码表面像模像样,实际多不能跑。感觉 AI 编程就是个 demo 级噱头,唬外行没问题,但干事不行。
2026 年开年,事情变了。我重新尝试 AI 编程,但这次优先选了自己熟悉的语言和框架。可控。写完一段,我看一遍,像 code review 那样。一切都还在掌握之中。
但掌控感没有持续太久。
渐渐的我发现 code review 做不下去了。两个原因。一个是效率——AI 输出的速度快于我阅读的速度我成了瓶颈。另一个更致命——review 效果很差,我根本看不出 AI 写的代码有什么问题。许多 bug 藏得不动声色:逻辑看着对,跑起来才露馅。你让我肉眼去扫,我承认我不行。
但看不出问题不代表没有问题。
再后来,设计阶段我也慢慢把主动权让给了 AI。我作为需求提出方让 AI 以 interview 的方式对我提问,一层一层澄清需求——"这个接口的幂等性要求是什么?""当上游超时时,下游是重试还是失败?"——许多问题我自己未必第一时间能想到。澄清完成后AI 将结果沉淀为设计文档。然后,对着文档写代码。
效果非常震撼。我们大约有三个人共建了一个分布式微服务系统。接口文档定好后,各自对着文档让 AI 开发,一遍过。那一刻,你很难不产生一种错觉——这他妈是银弹吧?
然后就被现实教育了。
按下葫芦浮起瓢。改功能 A功能 B 挂了。原因很朴素AGENT.md 的内容太多Agent 每个新 session 不会阅读全量文档。它改代码时不知道另一块功能的上下文于是打地鼠游戏开始了。改好一个弹起来一个。我的日常工作从写代码变成了测试、测试、测试。AI 产出的 bug我来兜底。
我尝试自救。
让 Hermes 操控 ComoFox 浏览器,根据需求文档自由探索页面,将有价值的交互场景固化为 Playwright 脚本。自动化测试,听起来很丝滑对吧?实际是:页面里的 CodeMirror 编辑器Hermes 用尽办法输不了文字。Shadow DOM 里的元素定位不到。动态加载的模态框,直到超时都等不到。最后靠直接调用 JS API、注入脚本、硬设等待——能绕过但每一个坑都要花掉半天。
整个过程不是滑滑梯,是在泥地里连滚带爬。但这仍是我当前主攻的方向。
1986 年Fred Brooks 发表了一篇著名的论文叫《没有银弹》(*No Silver Bullet*。他在文中论证没有任何单一技术或管理手段能在软件工程领域带来一个数量级的生产力提升。40 年后的今天AI 是那发银弹吗?这篇文章想谈谈我在泥地里的答案。
---
## 二、回溯——Brooks 说没有银弹,那 AI 算什么?
Brooks 的核心区分,放在今天读仍然准得让人不安。
他把软件工程的复杂性分为两类。**本质复杂性**essential complexity来自问题域本身——这个系统要解决什么业务问题边界在哪里异常路径怎么处理这些是"软件困难的本质部分",与你用什么语言、什么框架无关。**偶发复杂性**accidental complexity则来自实现手段——语法怎么写工具链怎么配部署脚本怎么调这些是会随技术进步而逐渐消解的。
Brooks 的结论冷酷而精确:
> "The complexity of software is an essential property, not an accidental one." —— 软件的复杂性是本质属性,而非偶然属性。
所以没有银弹。没有任何单一突破能在十年内带来一个数量级的飞跃。因为——
> "A project spends well more than half its time in thought, and no tool, however advanced, can do your thinking for you." —— 一个项目上远超半数的时间是在思考,而没有任何工具,无论多先进,能替你思考。
这话在 1986 年说出口的时候,编译器还不怎么聪明。到了 1999 年他仍然坚持这个判断。到了现在呢?
AI 确实在突破这个界限。它不仅消除了偶发复杂性——样板代码、正则表达式、配置文件模板这些已经被碾压了——它还开始触及本质复杂性。GPT-5.5 能独立完成 SWE-Bench Pro 中 58.6% 的任务2026 年 4 月发布)。它不是只能在你提示下一行一行补全,它能根据几页需求文档搭建完整系统、做架构决策、调试自己的 bug。118 万开发者在使用 Codex。OpenAI 内部 95% 的工程师每周使用 CodexPR 数量增加了约 70%。
这些数字很难不让 Brooks 的读者产生动摇——"没有任何工具能替你思考"这句话,是不是快过保鲜期了?
但仔细看Brooks 的论点并没有被推翻。AI 只是**抬高了抽象的层次**,而非消除了本质复杂性。
以前本质复杂性体现在"怎么写代码"——你怎么组织模块、怎么设计接口、怎么处理边界条件。现在AI 把这些变成了执行细节,本质复杂性转移到了"怎么描述需求"——你怎么写出足够精确、足够完整的规格说明,让 AI 不跑偏。问题换了一张脸,但难度本身没有消失。
OpenAI 自己在介绍 GPT-5.3-Codex 时写了一段话,几乎是 Brooks 的隔空回响:
> "核心挑战已从 agent 能做什么,转变为人们如何指导、监督并与之协作。"
40 年前Brooks 说本质复杂性无法被工具消除。40 年后,最好的 AI 实验室告诉你,最难的仍然是"指导、监督与协作"。如果你觉得 AI 自动化了一切——那你恐怕还没真正用过它。
---
## 三、AI 强于从零创造,弱于存量维护
AI 模型进化的速度有目共睹,大家快听麻了。这一节我们不列 benchmark 数字——那些"漂亮的数字"你随便搜一篇评测文章就能看到,而且比我能列的全。
我想谈一个容易被漂亮数字掩埋的趋势:**信任度在下降**。
Stack Overflow 2025 年开发者调查显示,对 AI 工具的正面评价从 2023、2024 年的 70% 以上,下降到了 2025 年的 60%。46% 的开发者积极不信任 AI 输出的准确度,只有 33% 选择信任——而"高度信任"者仅占 3%。最让开发者郁闷的不是 AI 完全不懂,是"几乎正确但不完全对"——66% 的受访者将此选为首要挫败感来源。45% 表示调试 AI 生成的代码比调试自己写的更耗时。
越有经验的开发者越不信任。10 年以上的老手,"高度不信任"的比例最高,达到 20.7%。
为什么会这样arxiv 上一篇叫 *Safer Builders, Risky Maintainers* 的论文给出了一个重要线索AI agent 在**新建代码**时引入的破坏性变更3.45%比人类7.40%)少——它从零开始造轮子确实比人稳。但在**维护 / 重构**任务中AI 的表现显著更差(引入破坏性变更 6.72%~9.35%。Agent 提交的 PR 合并冲突率高达 27.67%。另一篇论文 *Engineering Pitfalls in AI Coding Tools* 分析了 3800 多个 AI 编码工具的 bug发现 67% 是功能性缺陷。
这恰好解释了"按下葫芦浮起瓢"的真实原因AI 在无状态的"从零构建"场景中很强,在有状态的"存量上下文"场景中很弱。AGENT.md 的内容太多Agent 每个新 session 懒得读完。改功能 A 时不知道功能 B 的约束。于是 bug 就像打地鼠——按下这个,弹起那个。
但公平地说,这不完全是 AI 的问题。
软件维护对人类来说也是极其困难的一件事。花几天从零造一个新轮子是一回事,在一个已运行三年的系统里修一个 bug、同时不引入三个新 bug是另一回事。作为组件团队的一员日常维护各种基础设施——今天这个 registry 挂了,明天那个 service 超时了,你修好一个,那边塌一个,每天不是在救火,就是在救火的路上。维护工作本就比创造工作难得多。
但有一点让我警惕。当前有一种危险的声音,来自不写代码的外行:"看我花几天就造了一个什么什么东西出来——软件开发也没那么难嘛。"拉倒吧。软件行业最有欺骗性的地方在于:**造一个能跑的 demo 只需要三天,把它维护到能稳定服务三年需要一百倍的时间**。很多从零搭建的"AI 作品"随着功能迭代和缺陷修复会变得越来越完蛋。OpenClaw 项目就在这条末路上狂奔——当我看见它的一个 PR 没有通过回归测试却强行合并之后,我就和它说再见了。
这不是 AI 的问题。这是一个缩影:连人类维护都如此艰难的事,交给 AI 只会更糟。
---
## 四、从"代码中心"到"规格中心"
Andrej Karpathy 在 2025 年初提出了一个概念叫 **Vibe Coding**(氛围编程)。大意是:"I just see stuff, say stuff, run stuff, and copy paste stuff, and it mostly works." 你不需要理解代码你只需要描述你想要什么AI 给你。你跑一下,不对就再描述一遍。全凭感觉。
听起来很美。但 Stack Overflow 2025 调查显示72% 的开发者在工作中不使用 Vibe Coding。为什么因为它适合 demo不适合生产。"气氛对了"能跑,"气氛不对"就不知道哪里出 bug。没有文档、没有规格、没有追溯——只有感觉。而感觉是不能交付给用户的。
这引出一个更深层的问题:**文档在软件工程中到底应该处于什么位置?**
在 AI 时代之前,就我个人经历而言,设计文档从来不是完善的。三个原因。
第一,设计会频繁变动。不同部分交叉引用,总有一处忘了更新。起初大家还在意,改完代码顺手改文档。但时间一长,总有一两次遗漏。漏一次没人发现,漏两次也没人发现。推到第三次,文档就成了"仅供参考"的历史文物。
第二,没有人因为文档写得好而给产品一个好评价。文档的重要性在商业上永远不能和代码相提并论。产品能用,用户点赞;文档漂亮,只有下一个接手维护的倒霉蛋会感激——他还不一定有机会说出口。这是一道天然的价值排序。
第三,更残酷的事实是:代码只要能跑、能通过测试,它就是"正确"的。而文档写得再漂亮,也无法自证正确性——你无法像跑单元测试一样跑文档。它的验证成本天然比代码高。在 deadline 面前,完善文档永远是第一个被牺牲的项目。
但 AI 时代,文档的地位变了。
以前,代码是唯一真相源。编译器只认代码,不认文档。无论你的设计文档画得多漂亮,最终决定程序行为的,是那几万行 .c 文件。
现在不是了。
> **之前**:人类输入 = 代码 → 编译器(确定性的)→ 二进制文件
> **现在**:人类输入 = 文档 → AI不确定性的→ 代码
这是一个根本性的翻转。文档不再是辅助品,它是 AI 的"源代码"。输入的质量直接决定产出的质量。arxiv 上的论文 *Context-Augmented Code Generation* 用实验数据证实了这一点:当 AI coding agent 获得完整的产品上下文(规格说明、约束条件、客户信号)时,决策遵从率从 46% 提高到 95%,提升了 49 个百分点。
于是,我开始尝试一种新的协作方式:**Interview 驱动设计**。
我不写规格说明。我让 AI 来 interview 我。我作为需求方描述我想要什么AI 作为分析师,通过多轮提问逐层澄清。"这个接口的幂等性要求是什么?""上游超时时,下游应该重试还是失败?""并发写同一个资源时的冲突策略?"——这些问题我自己未必第一时间能想到,但 AI 会追问。如果我对某个问题没有答案,我会反过来说"你给几种方案,告诉我 trade-off",然后 AI 列出来,我做选择。
最终,这些对话沉淀为一份设计文档和若干接口文档。设计文档锁死上下文,接口文档定义服务间的契约。三个人并行开发一个分布式微服务系统,各自的 AI agent 对着同一份契约束工作,一遍过。
不是 AI 强。是上下文被锁死在文档里了。
但文档本身也有天花板。AGENT.md 越来越长几百行Agent 每个新 session 最多瞟一眼开头。文档的"完整"和"可用"之间存在根本张力。你写得越全,它越不看。
另外即使文档完美Agent 也完美遵循——改功能 A 还是可能搞坏功能 B。文档锁不住所有东西。
这一点,下一节来谈。
---
## 五、瓶颈转移——当测试成了最想甩掉的活
在人脑编码时代,我写一个东西的时候,直觉上知道可能碰坏哪一个其他功能。心里有底。那种感觉很难描述——你对你自己设计的东西有一种"体感"。你知道改了这个方法,哪个 service 可能受影响,因为那个 service 是你写的,你记得它的调用链。
AI 编码时代,这种体感消失了。
你不知道它改了什么、为什么这么改、会波及哪里。把车交给一个陌生的代驾,他开得确实比你快,但你全程闭着眼。每次到站你才睁开眼看车是不是还在。
代码产出的速度翻了数倍,但验证速度没有。
以前一天写 200 行,自己跑一跑,心里有数。现在 AI 在十分钟内吐出一大坨代码交给你。以前一天提两个 PR节奏是自己的——写一段想一段测一段。现在一天可能面对 10 个 PR 等着你测。工作密度不是提高了,是被暴力拉高了。这是让人崩溃的一个原因。
另一个原因是精神折磨,而不只是工作量。
举一个真实的例子。前端有两个按钮没对齐。Opus 4.6 反复改了半个小时——半个小时内它尝试了五六种方案没有一种完全正确。原因是这两个按钮用了第三方组件库CSS 存在继承关系。组件库自带一套默认样式,全局主题覆盖了一部分,组件级的 scoped style 又覆盖了一部分。这几个来源相互交叠,效果还不正交——改属性 A 影响元素 B 的表现,调整 B 又牵动 A而 A 和 B 并不在同一个样式层级中。AI 不去深入读组件库的源码,确实很难判断出为什么按钮偏了 4 个像素。
但我呢F12 打开浏览器调试工具,在 Computed Styles 面板里一眼就能看到最终生效的规则链。人类一眼能看穿的事AI 做了半小时——不是因为它"笨",是因为**很多调试工具是人类为自己设计的AI 很难使用**。最后还是我手工改好的。如果对面是个真人,做出这种事,我早顺着网线过去喷他了。
还有更离谱的。有些 bug 带着明显的 AI 特征——代码里无缘无故出现一句俄语注释;调用一个根本不存在的 API一段逻辑"乍看是对的",但你仔细想一下语义,就会发现它完全理解歪了。你问 AI 怎么回事,它说:"这是我的疏忽。" 但你没法靠"你下次别疏忽了"来保证质量。
更可怕的是静默破坏——不报错,不崩溃,只是行为悄悄变了。一个接口的默认参数被改了;一个条件判断少了一个分支;一个缓存 key 的生成方式变了。系统不报警,只是用户数据会在某些边缘情况下悄悄算错。你只能在浏览器里一个一个页面点过去,祈祷别踩到地雷。
所以我开始尝试自动化测试。
让 Hermes 操控 ComoFox 浏览器,根据需求文档自由探索页面,将有价值的交互场景固化为 Playwright 脚本。思路是对的AI 代码的量级变了,手工验证跟不上了,自动化验证是唯一可能跟上的手段。
但实践起来是另一个世界。CodeMirror 编辑器 —— 这是一个广泛使用的基于 contenteditable 的 Markdown 编辑器 —— Hermes 用尽办法在它里面输入不了文字。正常的 `fill()` 不生效,模拟键盘事件也白搭,因为 CodeMirror 内部有自己的事件处理机制。Shadow DOM 里的元素定位不到。动态加载的模态框,等待条件设了又设,直到超时也没等到。每个坑都要花掉半天。
最后靠直接调用底层 JavaScript API、在浏览器控制台注入脚本、硬设等待超时——能绕过但不是优雅的解决方案。这个体验也让我意识到一件事**很多基础库和前端工具最初设计的时候,并没有考虑到一个 AI agent 会通过浏览器来自动化操作它们**。这个问题需要整个生态共同改善,不是一个人能解决的。
但即使是在泥地里连滚带爬这个方向我仍然坚持。不是因为它舒服是因为没有更好的选择。AI 已经改变了代码产出的量级,手工验证这条路线是死路。
---
## 六、我们需要什么——让不确定的输出变为确定的质量
到这里,核心矛盾已经浮出了水面。
AI 的输出本质是不确定的。同一个 prompt、同一个模型、同一个 session你让它生成两遍可能得到两段不同的代码。这本身不是问题 —— 很多创意工作欢迎这种多样性。但生产系统要求质量是确定的 —— 不能"有时能跑、有时不能"。**如何让大模型输出的不确定性,转化为生产系统要求的质量的确定性?** 这是当前最大的工程挑战。
目前有三种思路。
**思路一:更强的模型。** 直觉反应模型越强bug 越少。确实如此——GPT-5.5 比 GPT-5.1 的 benchmark 成绩更高。但 Brooks 式的反驳:软件复杂度也会随着模型能力水涨船高。你能交给 GPT-5.1 的东西和你能交给 GPT-5.5 的东西根本不是同一个量级。模型越强,你对它的期待越高,你交给它的任务越复杂。只靠模型升级是军备竞赛,永远没有终点。
**思路二更好的文档spec-driven development。** 这是我目前在做的——用设计文档锁定上下文,用接口文档定义契约。论文 *Context-Augmented Code Generation* 证明,完整的产品上下文能把 AI 的决策遵从率从 46% 拉到 95%。但正如前面所说AGENT.md 越长Agent 越懒得读。一个可能的方向是模块化文档——不是一份大而全的 AGENT.md而是按功能域拆分、在 Agent 需要时按需注入最小上下文。有点像人类的"按需学习"。但目前还没有成熟的实践方案。
**思路三:更密更快的验证。** 自动化测试、AI 代码审查、持续集成扫描。让 AI 的产出接受更频繁的、更全面的验证,在问题进到"生产"之前就拦住。OpenAI 的 Codex 内置了代码审查功能,但他们自己也说:"Codex 应被视为额外的审查者,而非人类审查的替代品。" arxiv 上有一个综述叫 *From Code-Centric to Intent-Centric Software Engineering*,提出了一个关键框架:在新范式下,软件工程的三个支柱正在被重新定义——
- **Specification**(意图描述):不再是可选的文档,而是 AI 的"源代码"。
- **Verification**(意图验证):从人肉测试转向自动化验证,而且必须跟得上 AI 的产出速度。
- **Accountability**(责任归属):当 AI 独立产出了 bug责任在谁另一个研究 *Accountable Agents in Software Engineering* 分析了主流 AI 编码工具的 Terms of Service发现责任**一致地转移到了用户身上**。这个答案是否合理,可能需要整个行业重新审视。
三种思路都有道理,也都不够。
所以我对生产系统的态度,就写在最开头了:**不会用效率换取生产可靠性**。在其他项目中,我积极探索如何让 AI 获取更大的自主权——spec-driven development、更聪明的上下文注入、自动化测试、甚至让 AI reviewer 去 review AI coder 的产出。但生产系统不在此列。
---
## 七、结语——修理机器的人
回到 Brooks。1986 年他说没有银弹。2026 年仍然没有。
AI 没有消除软件工程的本质复杂性。它把复杂性从"怎么写"转移到了"写什么"。以前你要想怎么实现,现在你要想怎么描述。以前你的对手是编译器——一个逻辑精确、不会撒谎的无情裁判。现在你的对手是概率分布——诚实的、善意的,但也不能保证不出错。
但事情确实变了。
没有银弹不代表没有进步。AI 正在重新定义软件工程中"人"的位置:从编码者,转变为意图的描述者和验证者。
《查理和巧克力工厂》有一个结局我印象很深。Charlie 的爸爸在一家牙膏厂工作,每天的工作是手工给牙膏管拧上盖子。拧了一辈子。有一天,工厂引进了一台机器,咔嚓一下就能把盖子拧好。于是他失业了。
但在故事的结尾,他又被请了回去——以更高的薪水,作为**修理这台机器的人**。
我觉得我们的角色也在发生类似的转变。以前我们是拧瓶盖的工人——一行一行写代码。机器来了,拧得比我们快多了。但机器会坏,会出错,会按下葫芦浮起瓢。我们的新角色,是修机器的人:设计上下文、定义契约、搭建验证体系、在泥地里连滚带爬地让自动化测试真正跑起来。
AI 是银弹吗?不是。但也许银弹这个词,从 Brooks 写下它的那天起就暗示了一个答案:你不需要一把能解决所有问题的神奇子弹。你需要的是一个工具箱,以及知道什么时候用什么工具的脑子。
---
*2026 年 5 月*
---
## 参考资料
**经典著作:**
- Fred Brooks, *No Silver Bullet — Essence and Accident in Software Engineering*, 1986.(收录于《人月神话》周年纪念版)
- Eric S. Raymond, 《大教堂与集市》(*The Cathedral and the Bazaar*), 1999.
- Paul Graham, 《黑客与画家》(*Hackers and Painters*), 2004.
- Roald Dahl, 《查理和巧克力工厂》(*Charlie and the Chocolate Factory*).
**OpenAI 官方博客:**
- *Introducing GPT-5.5*, 2026年4月 — https://openai.com/index/introducing-gpt-5-5/
- *Introducing GPT-5.3-Codex*, 2026年2月 — https://openai.com/index/introducing-gpt-5-3-codex/
- *Introducing the Codex App*, 2026年2月 — https://openai.com/index/introducing-the-codex-app/
- *Introducing GPT-5.2-Codex*, 2025年12月 — https://openai.com/index/introducing-gpt-5-2-codex/
- *GPT-5.1-Codex-Max*, 2025年11月 — https://openai.com/index/gpt-5-1-codex-max/
**行业调查与研究:**
- Stack Overflow, *2025 Developer Survey* — https://survey.stackoverflow.co/2025/
- GitHub, *Quantifying GitHub Copilot's Impact on Code Quality*, 2024年11月 — https://github.blog/news-insights/research/research-quantifying-github-copilots-impact-on-code-quality/
**arXiv 论文:**
- *Safer Builders, Risky Maintainers: Are AI Agents Ready to Maintain Software?*, arXiv:2603.27524, 2026年3月 — https://arxiv.org/abs/2603.27524
- *Engineering Pitfalls in AI Coding Tools*, arXiv:2603.20847, 2026年3月 — https://arxiv.org/abs/2603.20847
- *Context-Augmented Code Generation*, arXiv:2605.08112, 2026年5月 — https://arxiv.org/abs/2605.08112
- *From Code-Centric to Intent-Centric Software Engineering*, arXiv:2605.11027, 2026年5月 — https://arxiv.org/abs/2605.11027
- *Accountable Agents in Software Engineering*, arXiv:2605.04532, 2026年5月 — https://arxiv.org/abs/2605.04532
- *Agentic AI in Software Engineering: A Comprehensive Survey*, arXiv:2604.26275, 2026年4月 — https://arxiv.org/abs/2604.26275
**其他:**
- Andrej Karpathy, Vibe Coding 概念提出, 2025年初.