两年“氛围编程”之后:我为什么回归手工编写代码
核心问题:经历了长期依赖 AI 辅助编程(Agentic Coding)后,为什么资深工程师最终会选择回归手工写代码?
在软件开发领域,大多数人与 AI 编程的相遇剧本都惊人地相似。起初,你只是试探性地给它布置一个简单的任务。结果令你印象深刻。于是,你胆子大了起来,给了它一个庞大的任务。结果让你更加震撼。这种瞬间的满足感容易让人产生一种错觉:编程的门槛已经被踏平了。紧接着,你打开社交媒体(如 X/Twitter),洋洋洒洒地写下一篇关于“程序员将被取代”的激昂檄文。
然而,如果你能在这个阶段坚持下去,越过那股最初的狂热或恐惧,那么恭喜你,你对 AI 编程的理解已经超过了 99% 的人。真正的挑战,并不是 AI 能否写代码,而是当我们将 AI 引入严肃的工程生产环境时,它到底发生了什么。
图片来源:Unsplash
严肃工程师与 AI 的必然发展弧线
本段核心问题:当工程师试图将 AI 用于实际生产环境而非周末练手项目时,通常会经历怎样的心路历程?
对于那些使用 AI 处理实际工作、而不仅仅是周末小项目的严肃工程师来说,他们与 AI 的关系大致遵循一个可预测的发展弧线。
在被那个“大任务”的成功持续震撼之后,你自然而然地会产生一种贪念:如果我不断给它更大的任务,它还能完美驾驭吗?甚至,那个困扰团队许久、没人愿意接手的可怕代码重构,是不是也能交给它?
这正是现实开始显露裂痕的时刻。
一方面,你惊叹于 AI 似乎能完美理解你的意图,仿佛它读懂了你的心思;但另一方面,它又频繁地犯下令人抓狂的错误,做出明显背离你们既定共识的决策。这就像是一个才华横溢但性格古怪的实习生,有时候能给你惊喜,有时候却能把你的地基挖空。
在这种反复的拉扯中,你很快明白了一个道理:对模型发火毫无意义。于是,你开始将所有不尽如人意的结果归结于自身。这是一种内化的心理防御机制——“是我错了。我的提示词写得太烂了。需求描述得不够细致。”
你会想:“只要我能清晰地定义它,它就能构建出来。天空才是极限。”
这种想法虽然美好,但它开启了一段充满挫折的探索之旅。
规范驱动开发的陷阱:为什么详细的提示词也救不了 AI?
本段核心问题:为什么试图像写设计文档一样写 Prompt,最终也无法解决 AI 编程中的深层问题?
为了解决“AI 理解不够”的问题,许多工程师(包括曾经的我)选择了一条看似逻辑严密的道路:编写极其详细的规范文档。你打开 Obsidian 或 Notion,开始起草一份份“壮硕”的规格说明书,用令人印象深刻的细节描述你脑海中的功能。你可能花半个小时写出整整一页的 Prompt,认为只要输入足够详尽,输出就必然完美。
然而,事实会让你大失所望:规范驱动开发在 AI 领域同样行不通。
在现实的软件工程中,设计文档和规格说明书是有生命的。它们在实现和发现的过程中,以一种极其动荡的方式不断演进。
让我们设想一个具体的场景:
应用场景模拟:
假设在一家真实的公司里,你在一个小时内为一个复杂的架构写好了一份设计文档。然后,你将这份文档交给了一位中级工程师,并且明确告诉他:“不要与任何人讨论这份文档,照着做就行。” 随后,你就休假去了,完全不参与后续的任何决策。结果会是什么?大概率是一场灾难。
这正是 AI 智能体目前的处境。
-
缺乏演进能力:AI 智能体不具备在数周的开发周期内,随着底层组件的构建而演进其规范的能力。它无法在实现过程中根据反馈修改设计。 -
早期决策的僵化:它会在项目初期就做出决策,并且一旦做出,后期就几乎不会偏离,哪怕这些决策在后期已经被证明是错误的。 -
盲目的坚持:大多数智能体一旦感觉到问题和解决方案偏离了轨道,就会直接“投降”。虽然在现代模型中,这种情况变得更隐蔽了——智能体会选择强行把自己“撞”过迷宫的墙壁,硬着头皮把代码写完,哪怕逻辑已经不通。
“垃圾”代码的幻觉:看似完美的 Pull Request
本段核心问题:为什么 AI 生成的代码在单独审查时看起来很棒,但融入整个项目后却是一场灾难?
最令人细思极恐的地方在于:AI 编写的代码,在生成和呈现的过程中,看起来是合理的且令人印象深刻的。它甚至能生成一份看起来非常棒的 Pull Request(PR)。毕竟,无论是你,还是 AI 智能体,都深受训练,知道什么是“看起来不错”的 PR 格式。
这种欺骗性极强。如果你不进行深度的全量代码审查,很容易被这种表象蒙蔽。
直到我打开整个代码库,从头到尾阅读了它的最新状态后,我才开始看清一个我们曾经理论化、并希望这只是早期模型残留物的现象:垃圾。
那是纯粹的、未掺杂质的垃圾。
我感到十分困惑。难道我没有在承认代码之前审查每一行吗?这么多“脏东西”是从哪里来的?
反思与见解:
事后回想,这一切完全合乎逻辑。智能体编写的代码单元在孤立状态下看起来很好。它们与自身一致,与你的 Prompt 一致。但是,它们对整体缺乏敬畏。对结构完整性缺乏敬畏。甚至对相邻的代码模式也缺乏敬畏。
这就好比一个拼图大师,手里拿着每一块都雕刻精美的拼图碎片,但在拼凑时完全不顾及整幅画面的图案,强行把它们塞在一起。
“氛围小说”式的编程:缺乏上下文的连贯性
本段核心问题:AI 生成的代码在结构上到底存在什么致命缺陷?
为了形象地说明这个问题,我们可以将其比作小说写作中的“氛围写作”。
AI 告诉了我一个好听的故事。就像用 AI 代写一本小说,智能体展示给我几段看起来不错的文字。它们确实讲得通,在结构和句法上都是正确的。见鬼,它甚至捕捉到了各种角色的怪癖。
但是,出于某种原因,当你阅读整章内容时,它就是一团糟。把它放在整本书的上下文,以及前文和后文的章节中看,它毫无逻辑可言。
在代码世界中,这意味着:
-
局部正确,全局错误:函数内部逻辑通顺,但该函数在系统架构中的位置完全错误,或者违反了系统的设计原则。 -
风格割裂:它能模仿你的变量命名,但无法理解你在模块 A 中使用某种模式是为了解决特定的依赖问题,因此在模块 B 中盲目套用导致架构冲突。 -
缺乏演化视角:它无法理解代码的历史包袱,为什么这里有一个看似奇怪的 if判断(那是为了兼容旧版本数据),AI 可能会直接删掉它,因为它看起来是“死代码”。
在阅读了数月累积的高度指定的智能体代码后,我对自己说:我不能发布这个垃圾。我不能因为这个向用户收费。我也不能承诺用这个来保护用户的数据。
我不能用这个来对我的用户撒谎。
图片来源:Unsplash
回归手工:超越 Token 效率的真实生产力
本段核心问题:在综合考虑所有成本后,为什么手工编写代码反而比 AI 编程更快、更高效?
所以,对于大多数任务,我又回到了手工编写的时代。
令人惊讶的是,当你把所有因素都计算在内,而不仅仅是每小时生成的代码 Token 数量时,我发现自己比 AI 更快、更准确、更有创造力、也更有生产力。
这听起来很反直觉,毕竟 AI 打字速度快过人类一万倍。但这里的“所有因素”包括:
-
调试时间:调试 AI 生成的结构性问题,比从头写一个清晰的架构要费时得多。 -
审查成本:为了确保 AI 没有引入“垃圾”,你需要像鹰一样盯着每一行代码,这消耗的精力并不比自己写少。 -
架构重构:当 AI 写出的代码无法适应新需求时,推翻重来的成本极高。 -
心理负担:时刻担心代码在全局上下文中是否会崩溃的心理压力,也是巨大的隐形成本。
当你开始计算这些“隐形债务”时,手工编写的优势就显现出来了。人类的每一次敲击键盘,不仅仅是在输入字符,更是在进行实时的架构决策和上下文校验。这种同步进行的思考与构建,是目前 AI 智能体无法模拟的。
总结与操作清单
经过两年的实践,我们可以清晰地看到,AI 编程虽然强大,但在涉及复杂系统架构和长期维护的项目中,盲目依赖“智能体”会带来巨大的技术债务。
实用摘要 / 操作清单
-
警惕初始的震撼:不要因为 AI 完成了简单的“大任务”就认为它可以无缝接管复杂的工程系统。 -
避免过度指定 Prompt:编写长达数页的规格说明书往往无济于事,因为 AI 无法像人类工程师那样通过交流来“演化”文档。 -
全局审查是必须的:不要只看 Pull Request 或单个代码片段。必须打开整个代码库,通读相关上下文,检查 AI 代码的结构完整性。 -
识别“垃圾”代码:警惕那些局部完美但全局割裂的代码。如果代码让你感觉在读一本“情节不连贯的小说”,那它很可能就是 AI 生成的。 -
诚实面对交付:如果你不放心用这段代码去保护用户数据,或者不觉得它配得上票价,那就不要发布。回归手工重构往往是更负责任的选择。 -
生产力重定义:计算生产力时,不要只看代码生成的速度,要算上调试、审查和因架构失误导致返工的总时间。
一页速览
| 维度 | AI 智能体编码 | 手工编码 |
|---|---|---|
| 局部表现 | 极佳,语法完美,符合 Prompt | 取决于工程师状态,但符合心智模型 |
| 全局一致性 | 差,缺乏对整体结构的敬畏 | 优,实时进行架构校验 |
| 文档依赖 | 高,依赖静态的详细规范文档 | 中,文档是活的,随实现演进 |
| 错误类型 | 深层架构错误,隐蔽且难以发现 | 表面逻辑错误,易于定位和修复 |
| 综合成本 | 高(包括审查、重构、心理负担) | 低(一次性投入,质量可控) |
常见问题 (FAQ)
Q1: AI 编程完全不可用吗?
A: 不是。作者主要针对的是“大型任务”和“真实生产环境”。对于简单的、孤立的、对整体架构影响小的任务,AI 依然能提供帮助,但不能盲目信任其处理复杂系统的能力。
Q2: 为什么写很详细的 Prompt 也不行?
A: 因为真实的软件开发是一个动态发现的过程。设计文档是活的,会随着实施不断变化。AI 往往在初始阶段就固化了决策,且无法在多周的开发周期中主动演进规范。
Q3: 什么是 AI 代码中的“垃圾”?
A: 指那些在孤立看(如 PR 中)很完美、语法正确、逻辑通顺,但放入整个代码库上下文时,却破坏了结构完整性、不遵循既有模式、导致系统逻辑混乱的代码。
Q4: 文章中提到的“氛围编程”是指什么?
A: 这是一个形象的比喻,指 AI 写代码就像“氛围写作”小说一样,可能写出精彩的段落和对话,但整合成章时却缺乏连贯性和逻辑,无法构成一个整体。
Q5: 手工写代码真的比 AI 快吗?
A: 从单纯的打字速度看不是。但如果把“所有因素”算在内——包括查找和修复 AI 引入的结构性错误、全局审查、重构以及心理负担——手工编码在复杂项目中往往更高效、更准确。
Q6: AI 为什么会在复杂的架构任务中失败?
A: 因为它缺乏对“整体”的敬畏。它专注于解决局部任务,无法理解代码库的历史包袱、相邻模块的模式以及系统的长期演化方向。
Q7: 作者建议工程师如何对待 AI 编程?
A: 不要盲目相信 AI 的“幻觉”能力。对于核心功能、涉及用户数据安全和复杂架构的部分,应回归手工编码,保持对代码质量的绝对掌控,而不是向用户交付不可靠的“垃圾”代码。
