软件工程基本功比以往更重要
文章摘要
作者 Joseph Heck(博客 Rhonabwy,2026 年 8 月 15 日)从一个很个人的切口写起:他今天的冒充者症候群表现为「当一个软件工程师到底意味着什么」。他的立场并不反 AI——他明确说在「harness + 模型」这个组合里找到了一件「真正的强力工具」,而且他观察到做出最惊人成果的人往往不是在社交媒体上高调宣告这个职业终结的那批人:他们找到了一根「大棍子」,正在摸索支点位置,像阿基米德那样撬动世界。他也不认为能力会消失——即便他不认可未经许可地取用全世界的知识,也不认可某些人正在搞的经济自我交易(他形容那是在给本已下沉的美国经济抹花生醬),而且他看过的所有报告都说大模型的经济模型不可行,但能力本身不会消失,反而在快速缩小:开放权重模型已经让(配置强悍的)个人电脑能做同样的事,效果稍差,但时间和能力上的差距不大。
他的核心论证链条是:「能不能做到」只是起点,远不是软件/系统工程师职业的主体。 他用自己二十几岁学电焊的经历作类比——他很快就造出了自己搬不动、甚至搬不出车间门的东西(幸好有乙炔割炬);那次学到的教训和这次是同一个,只是换了介质:东西是怎么组合起来的,才是决定性的差别。 如果你带点前瞻性地用 agentic harness 开发,你不只能得到「它能跑」,还能得到「它可测」(他重度依赖 “develop with red/green TDD” 这个提示词);但再往上就不太扎实了。接缝——你的代码怎么工作、它的「API」、它如何与其他软件契合——既是科学也是艺术,由一堆依赖你视角、经验和猜测的主观判断构成,既要看你现在解决什么,也要看你要与这份软件长期共存多久。让软件可调试、可维护、分层、可组合,这仍然是很难的把戏,需要大量深思熟虑的推理,而这正是今天的 LLM(哪怕是前沿模型的能力上限)力所不及之处。
接着他给出机制层面的解释:LLM 不「推理」,它预测,模型本质上是压缩过的成文人类知识;所以只要某段人类推理被编码进去了,它就能回响出来。对聚焦软件开发的 agent 而言,那些推理轨迹(reasoning traces)就是模型最宝贵的数据。他引了一篇他称为「相当好读」的论文 The Illusion of Thinking 来说明 LLM 的推理有多差,并给出他正在关注的另一个方向作为对照:包含「对行动结果的预测」的研究,也就是 JEPA 模型、LeWorld Model 和 Yann LeCun 近期的演讲——那和今天的编码 agent 是相当不同、也相当迷人的领域。
但他随即转向建设性的一面:与 LLM 协作仍有大量提升空间,很多红利甚至还没开始榨取。 他今天看到的大部分收益来自两件事:在正确的时机给它好的、精炼的数据;以及提供带自然语言反馈的确定性验证工具,让 LLM 能自我纠正。他说真正让他惊叹的不是模型能预测该写什么,而是它在工具调用和遵循指令上如此有效。而这种「指令遵循」也有其阴暗面,即 Simon Willison 命名的 lethal trifecta(致命三要素):模型无法分辨好建议与坏建议,从根本上不可能总是一致地防住 prompt injection;对齐工作、安全 harness 和沙箱都能挡掉最糟的情况,但存在根本性的缺口——「某个东西不知疲倦地遵循指令却又不具备良好推理,这在我看来是噩梦燃料」。
他的期望是近期能在模型训练上有进展,把「构建具备清晰接口、可调试、可维护的软件」的推理轨迹纳入后训练(RLHF)的关键评估目标。结论部分他重申了自己的价值判断:认真审阅、规划、修补软件(和系统)的接缝,是我们既能够、也必须运用的关键技能——有没有 agentic 助手都一样;而当他看到「哦,这个很容易实现」的浪潮和人们伸手去抓「clanker」(他对 AI 工具的戏称)来搞定它时,他认为这比以往任何时候都更重要。他强调从来没有单一答案、没有万灵药,永远是权衡取舍;核心是管理认知负荷,学会判断哪些部分需要稳定、哪些地方希望留出弯折的余地。文章末尾他还留了一句 2026 年特有的自证:「是的,那些破折号都是我自己写的。」
HN 评论精华
这条帖子 324 分、248 条评论。讨论主线有三条,而且都没怎么停留在作者的核心论点(接缝、可维护性)上:一是「你们说 agent 不好用,是不是姿势不对」的实战经验交换;二是一场关于「LLM 到底算不算推理」的漫长哲学缠斗;三是一位用户声称自己 150k 行代码、两个月不看一行代码全靠 agent 维护,引发了整场里最激烈的对峙。另有一条完全跑偏的支线在争论宜家家具能不能反复拆装。
- hirvi74 开场就是一句反差:作者说「过去一年 agent harness 跨过了『能不能做到』的卢比孔河」,「兄弟,我还停在『你能不能做对』模式里。我做错了什么?」他后来给出了非常具体的按语言分类的清单:C#/.NET 大多能编译但常无视「不要用 X,要用 Y」的指令;C#/Godot 抗拒指令最严重、多数结果是需求的 80/20 实现;AArch64 和 x86 汇编效果出奇地好(用于逆向和破解 crackmes.one 的题);Swift/SwiftUI 尚可,但往下走到 CoreGraphics、Accessibility、CoreFoundation 这些 C API 层就吃力,比如 CoreGraphics 的 Y 轴方向与 AppKit 相反这类问题(他试到 Opus 4.6 时期);AppleScript「别浪费时间」(他说这不怪 LLM);elisp 代码尚可但包配置容易出岔;shell 脚本(Zsh/Bash/PowerShell)效果很好。
- jaggederest 给了一份逐条的直接反馈,是本帖最实用的内容:你必须放弃风格洁癖,「不是我会写的样子」不构成阻塞;抗拒指令是常态,你只能持续纠偏,「勤勉目前无可替代」;出现 80/20 意味着你的 scope 太大了,拆开、或让 agent 回滚后拆开重试;Swift 必须给它工具反馈——要么让 LLM 亲自操控 macOS 应用拿反馈,要么建一整套它能自主驱动的端到端测试,「在使用应用和看代码的层级审阅,而不是逐个 tool call 和 diff」;Python 不开全部类型检查、不强制 BDD、不在 pre-commit 挂 linter/formatter 帮你骂机器人,就一定会烂;一定要用 CLI 而不是网页版,因为 CLI 能改环境。
- simonw 的建议被顶得很高:让它用红/绿 TDD,一开始就给一套已配好的测试套件,哪怕里面只有一个断言 1+1==2 的测试;确保它在写任何新代码之前就知道怎么跑测试;然后给一个清晰目标。他后续说自己对「遵循指令」的经验是「它们基本上会精确按我说的做」,但他认为那是因为他本能地用了能有效传达意图的说法。
- slopinthebag 提出一个尖锐的观察:所有 LLM 造出惊人东西的案例,几乎都是因为有人写的测试作为实现依据;让 LLM 自己写测试,结果就远没那么惊艳或有价值。bharatsuthar 说 LLM 会在自己写的测试上作弊,slopinthebag 补充这甚至不算作弊——它们不智能,不真正理解测试的目的,也无法用测试去定义问题域的语义,「说作弊意味着它们有主体性,而讽刺的是 agent 并没有」。andai 给了个具体笑话:去年他兴奋地试 Claude 网页版的 computer use,只想要个代码片段,结果它在 docker 容器里搭起了整个 repo,还主动加了测试套件——他一查,测试内容就是打印「Tests passed!」,「AGI 2027」。simonw 追问最近还见到这种事吗,他说 Opus 4.5+、Fable 5、GPT-5.5/5.6 这一代已经没抓到过了。
- mortalapeman 给出了对作者论点最直接的支持:生成代码的目录结构、接口设计和总体状态管理通常是一团糟,即便用最好的前沿模型也一样;但真正让他受不了的是模型会替他做他没在 prompt 里指定的假设——比如哪些错误状态是「完蛋了得退出」、哪些是「不致命」这种微妙判断;它有时会问,但更多时候直接决定,而且往往决定错。没有完备的测试套件和好的类型检查器来验证成品,整个循环对他就毫无用处,他还得回去逐行审阅并动用多年架构经验来避免堆出一座垃圾山。Nextgrid 补充说目录结构、接口设计、状态管理这几项当前的瓶颈是上下文长度——你得把整个代码库布局放在工作记忆里才能定架构、才能识别去重和合并的机会。aryehof 站在另一边:这是你的指令和 spec 的问题,LLM 不是读心术,缺需求和有歧义时它还是会试着完成任务;Anoian 一句话回击:「可软件工程的一大部分就是定义需求本身。」yoz-y 补了个很具体的毛病:它极度厌恶任何可能崩溃或报错的代码,于是加一堆可疑的 fallback;disgruntledphd2 解释得很干脆:「崩溃意味着零奖励。」
- 整场最激烈的对峙来自 user43928。他说文章「说了很多这里的人爱听的话」但核心论点是错的:他做一个移动应用已经几个月,大约两个月前就完全不再看代码了,15 万行(约一半是测试),AI 替他维护完全没问题;要可调试?它几秒钟就能加上大量 instrumentation;这不需要专长、prompt 技巧或提 TDD,「这就是默认状态」。他还引 Anthropic 的报告说第三方 Trajectory Labs 测了 72 个间接 prompt injection 场景共 720 次攻击,对 Claude Fable 5 / Opus 5 / Sonnet 5 的 auto mode 无一成功,而对 Codex 的 auto-review 模式(GPT-5.6 Sol)有 5.83% 成功,以此主张 prompt injection「看起来基本已被解决」。
- 反驳来自各个方向。hbcdbff:你既不看代码、又只干了两个月,凭什么让我们认真对待你关于代码质量和耐久性的判断?Krei-se:我做自己的项目两年了,用 LLM 每次都反过来咬我;「一如既往,零代码零链接,全是嘴说」。sethammons 给出最实质的反驳:两个月根本不足以让系统需求发生演化——只有在用例扩张、其他开发者加入之后,你才知道代码是否可维护,而且谁能保证他们会用同样方式指挥 AI;「我维护过同一套软件从初创到上市到被收购,两个月在维护生命周期里字面上什么都不算」。voidhorse 抓住了一个自相矛盾:反例就在眼前——各家厂商的 agent harness 几乎都是全 vibe-coded 的,bug 和回归多到用起来痛苦,人们容忍只是因为竞争还有限;而当 user43928 辩解说 harness 团队规模大、范围广、几个月造不出磐石般的软件时,voidhorse 指出「整个论点就是 LLM 让几个月内规模化交付高质量软件成为可能,你现在两边的话都在说」。skydhash 提出方法论要求:没人要你的 app 链接,大家期待的是方法描述和样本输出,好让别人复现同样的产出标准——「我们买《程序设计实践》《程序员修炼之道》,是想学有用的行为,不是听作者夸自己工具用得好」。trixn 反驳那份 injection 数据:这就好比拿「某杀毒软件能拦住 720 种已知病毒」来宣布网络安全已被解决,它只证明模型被拟合到了这个 benchmark 上,不证明它对任何可设想的注入方式都硬化了。chmod775 的比喻最漂亮:「你不能靠往左轮里多加空弹膛来解决『输掉俄罗斯轮盘』;600 个膛里有一颗子弹仍然多一颗。不如干脆别玩这个蠢游戏。」veganmosfet 给出实证反例——他信任 Anthropic 的研究、也认为 Opus-5 是抗注入最强的模型,但在他自己的一个特定场景里仍然成功了(贴了两篇实验记录),并说 payload 的可能性几乎无穷,「就是创造力加试错」。shakna 则拿 ABC 报道的「AI 助手黑进健身房」事件说事。
- 值得记的是 user43928 自己承认的那部分:他仍然投入了约 300 小时,「工作量依然很大」——要 prompt 功能、测试、迭代到 UX 可接受才合并,通常并行处理 2 到 5 个话题;不再有 code review,但有大量 QA 和真机测试;「瓶颈在于 AI 没有品味,不知道产品应该是什么样,没有我干预它会很乐意交付糟糕的垃圾」;除此之外还有竞品调研、关键词、定价、App Store 准备、TOS 和隐私政策、什么时候弹评分提示、翻译等一堆事。
- 哲学支线由 theteapot 引爆:作者说「LLM 不推理,它们预测」,他认为这是在玩语义——预测是训练目标,推理很可以说是由此涌现的属性。slopinthebag 反问「为什么推理会是预测的涌现属性」,hsn915 反问「不推理你怎么预测」,slopinthebag 再反问「线性回归里的推理在哪」,danielbln 回敬「突触传递里的推理在哪」。这条线一路下探到 GTA 算不算「洛杉矶市中心的另一种实现」、模拟推理与推理的区别、以及 antonvs 的立场(「如果 LLM 不推理,那人类也不推理;围绕『推理』『理解』这些词有太多迷信,人们想象一种只有人类才有、却无法定义的不可言说的品质,最可能的原因是它不存在」)。nsingh2 给出了最务实的收束:这类讨论从来没什么用,因为很难定义什么条件足以称为「思考」或「推理」,最后总变成循环和形而上学的争辩;当代 LLM 确实有问题,但更有生产力的是谈长期记忆、持续学习、tokenization、context rot、reversal curse 这些具体缺陷及其对真实任务的影响。
- Alien1Being 抛出了本帖第二热的支线:AI 生成的代码像宜家家具——它体现了很多好木工的要素、跳过了许多非本质的部分,而且比会厌倦、无能、抑郁、倦怠、怨恨、疲惫、状态不好的木匠更一致地做到这一点;今天的宜家对大多数人够用了,明天的 AI 编码对大多数公司也会够用,「或许未来只需要今天 1% 的软件工程师」。quietbritishjim 的反驳最有力:这个类比的毛病在于大多数人确实能用一个和别人完全一样的柜子,而如果你想要和别人完全一样的软件,你不需要 AI,你需要一份授权许可——那就是传统软件模式;AI 给出的是「定制的、背后有几百个你看不见的决策」的软件,一次性脚本没问题(他强调这个用途本身也很大),但要成为业务流程一部分的大程序仍需真专家的某种程度监督。nameless912 则给出宜家类比的正向用法:/r/ikeahackers 存在是有理由的——给人一堆大致互相兼容的五金和板材,往往就足够拼出很多定制的东西;他的立场是「如果你已经知道自己想要什么形状,并且具备自己动手实现的软件工程基本功,AI 编码就是个好的加速器」,他现在更愿意动手做东西,因为不用再跟 HTML/CSS 缠斗,但他知道 flexbox 是什么,所以能把要求说清楚。
- KronisLV 在形式化验证的支线里提出了一个有意思的取向:他宁愿等 5 到 10 年,等来 JSON、XML、YAML、TOML 处理,以及请求处理、多进程、数据库交互、校验、前端乃至 CSS 的标准库级方案,也不想用那些做法不严肃、边界情况一堆的未经证明的库——「也许那时软件工程才能被当作真正的工程对待」。ChrisGreenHeur 的回应代表另一极:「业务价值比正确性更重要。」andai 讲了一个把这条线钉死的故事:他曾期待「机器擅长写证明」能提升可靠性,然后遇到一次 LLM 把功能完全实现反了,还配了一大堆测试证明这个完全坏掉的功能实现正确——他意识到形式化验证也救不了他,「它只会给这个错误的功能写一份数学正确性证明」,这就是所谓的 spec gap。ffsm8 补充说 user story 之所以被建立,正是为了让解读 spec 的人知道为什么,从而显著降低这种 gap。
- 两句短评值得留:dmitrijbelikov 的「LLM 是新的 Excel」,以及 neuralkoi 的「程序员把 LLM 看成一个写代码的人,其他人(比如生意人)把它看成一个自然语言编译器;最终 LLM 会好到两者没有区别,但程序员会哀悼控制权的丧失」。