在最近的一篇博客中,作者Isaak Tsalicoglou分享了他使用大语言模型(LLM)为Erlang NIF编写C代码的经历。
原本他希望通过Grok 3生成C代码,并借助GPT-5和Gemini 2.5 Flash进行代码审查,最终实现一个跨平台的磁盘空间检测库。
然而,这个看似“高效”的开发流程却让他深感恶心与后悔——不仅因为整个过程繁琐至极,更因为他事后发现:这一切本就不该发生。
:disksup.get_disk_info/1这个函数本身就提供了实时数据,无需任何自定义NIF。换句话说,他花了大量时间用最复杂的工具解决了一个根本不存在的问题。这种“用火箭送外卖”的行为,正是所谓“氛围编程”(Vibe Coding)的典型写照。
所谓“氛围编程”,指的是开发者依赖LLM生成代码,追求快速出成果的“感觉”而非扎实的工程实践。它不关心代码是否安全、可维护或真正符合需求,只在乎“看起来像是在高效开发”。
而作者通过亲身实验发现,这种模式不仅低效,而且危险。它让人陷入无尽的试错循环,把人降格为“错误搬运工”,在GitHub Actions的日志与LLM回复之间来回复制粘贴,身心俱疲。
更讽刺的是,当他把这段经历发布到Hacker News后,评论区迅速撕开了这层“高效”的伪装。有人指出他根本没读文档;有人质疑为何不用Rust或Zig这类更安全的语言;还有人直言:“让LLM碰C代码?如果你不能自己检查内存安全,那你根本不该写NIF。”
这些批评像一盆冷水,浇醒了作者:你不是在“用AI提升生产力”,而是在用AI掩盖无知。
作者在实验中选择了C语言作为NIF的实现语言,这本身就是一个高风险决策。C语言以灵活著称,但也以容易出错闻名——尤其是内存管理、指针操作和类型安全方面。而LLM虽然能生成语法正确的代码,却无法保证语义正确性,更不具备运行时验证能力。结果就是,Grok 3生成的C代码充满了内存泄漏、类型不匹配和空指针返回等问题。
使用splint工具分析后,作者发现了数十个严重警告,包括未释放的内存块、非布尔值用于逻辑判断、以及非法的位运算比较。这些问题在生产环境中可能导致崩溃、数据损坏甚至安全漏洞。
更可怕的是,这些错误并非偶然,而是LLM在缺乏上下文理解下的必然产物。它不知道Erlang NIF的内存生命周期规则,不了解Windows API的调用约定,也不清楚enif_make_binary这类函数的责任边界。
这暴露了一个根本问题:LLM不是编译器,也不是静态分析器,更不是经验丰富的系统程序员。
它可以模仿代码样式,但无法承担工程责任。当你把关键系统组件交给LLM生成时,你实际上是在赌它的训练数据中恰好包含了正确的模式——而这是一场必输的赌局。正如一位评论者所说:“如果你需要LLM帮你写基本的系统调用,那你大概率也无法判断它写的是否安全。”
意识到C语言的风险后,作者决定“升级”实验:改用Rust + Rustler来重写NIF。
Rust以其内存安全著称,理论上更适合与LLM协作。他让Grok 4将C代码转换为Rust,再由GPT-5和Gemini 2.5 Pro进行审查。
初看之下,一切顺利:mix compile一次通过,Linux和macOS构建成功,测试通过。
然而,Windows平台再次成为噩梦的起点。
面对Windows特有的API(如GetDiskFreeSpaceExW)、字符编码(宽字符 vs UTF-8)、以及链接器问题,Grok 4陷入了典型的“修一个坏三个”的怪圈。它会修复某个错误,却引入新的依赖缺失或类型定义错误。
作者不得不重启“氛围编程循环”:查看CI日志 → 复制错误 → 提交给LLM → 获取建议 → 手动修改 → 再次推送 → 等待构建 → 重复。这个过程持续数小时,令人作呕。
有趣的是,尽管最终所有平台都构建成功,但作者并未因此感到成就感,反而更加确信:这不是开发,这是人机协作的“炼狱式调试”。LLM没有真正理解问题的本质,只是在“拟合”错误模式。而人类开发者则沦为“反馈中介”,在自动化承诺的幻象中消耗精力。
这种模式下,进步不是来自理解,而是来自试错次数的堆叠——而这正是工程进步的最大敌人。
作者曾是一名涡轮增压器设计工程师,亲历过传统工程中的“试错地狱”:修改参数 → 手动准备输入文件 → 提交CFD/FEA模拟 → 等待数小时甚至一天 → 分析结果 → 再次修改。这个过程极其缓慢,且高度依赖人工操作。但他没有接受这种低效,而是用Python编写了一套自动化优化系统,结合粒子群算法与低精度快速评估,大幅提升了设计效率。
相比之下,当前流行的“氛围编程”恰恰是另一种极端:完全自动化,但无人理解过程。就像某些仿真软件鼓吹“一键优化”,实则将工程师降级为按钮操作员,只为消耗更多许可证。今天的LLM工具链也在重演这一幕:Claude Code、GitHub Copilot等“智能代理”被包装成“全自动编程神器”,诱使开发者交出控制权,换来虚假的生产力幻觉。
真正的工程进步,从来不是“去人化”,而是“增强人”。作者强调,他当年的自动化系统始终保留人类在环(human-in-the-loop),关键决策由人做出,机器只负责执行重复任务。而“氛围编程”恰恰相反:人类只负责提供prompt和搬运错误,真正的“思考”被外包给了黑箱模型。长此以往,开发者将失去对系统底层逻辑的理解能力,沦为“会敲命令的文员”。
作者尖锐指出:“氛围编程”不是工程,它是对工程责任的逃避。真正的工程涉及需求分析、架构设计、权衡取舍、风险评估和持续学习。而“氛围编程”追求的是“快速出结果”的表象,忽视了代码质量、安全性、可维护性和团队协作等核心维度。
他特别批评了当前科技圈的两种极端:一种是盲目崇拜AI的“新手信徒”,他们相信“Claude能写一切”,却连HTTP基础都不懂;另一种是追逐风口的“战略家”,他们用“AI转型”包装PPT,实则对技术一无所知。两者共同构成了一个“愚蠢的供应链”:LLM厂商卖token,云厂商卖算力,咨询公司卖方案,而真正的价值创造者——理解问题本质的工程师——却被边缘化。
作者提醒我们:工具再先进,也无法替代人的判断力。LLM可以帮你快速了解一个领域,但它不能告诉你客户真正想要什么,也不能帮你决定是否该用微服务还是单体架构。这些决策需要与人对话、理解上下文、处理模糊与矛盾——而这正是人类工程师不可替代的价值。
文章最后,作者表达了他对LLM技术本身的欣赏:从早期的NLTK到今天的GPT,自然语言处理的进步令人惊叹。但他坚决反对将LLM视为“万能解药”。他引用了一句希腊谚语:“摩擦材料才能获得真知”(friction with the material)。真正的技能,来自于亲手解决问题、犯错、调试、反思的过程。
他总结道:LLM是强大的工具,但工具不会让傻瓜变聪明。你可以用它加速学习、辅助设计、生成模板,但绝不能让它代替你思考。否则,你终将成为那个“拿着顶级IDE却写不出安全代码”的可悲角色。
至于他是否会再次“氛围编程”?答案很明确:不会,除非别无选择。因为他已经明白,真正的效率,来自深度理解,而不是表面速度。而真正的创新,永远属于那些愿意深入材料、直面复杂性的人。