LLM 代码生成的幻觉问题为什么最容易防
Simon Willison 分析 LLM 生成代码的多种错误类型,指出幻觉反而最容易被检测出来。对 AI 编程开发者的质量认知有重要参考价值。
Simon Willison 分析 LLM 生成代码的多种错误类型,指出幻觉反而最容易被检测出来。对 AI 编程开发者的质量认知有重要参考价值。
我经常看到一些尝试用 LLM 编写代码的开发者抱怨:他们遇到了幻觉——通常是 LLM 编造了一个不存在的方法,甚至是一整个不存在的软件库——于是彻底失去了对 LLM 作为编程工具的信心。如果这些东西会凭空捏造不存在的方法,谁还能高效地使用它们?
代码中的幻觉,是你可能遇到的模型幻觉中危害最小的一种。
(这里所说的幻觉,是指 LLM 编造出完全不真实的事实;在这个场景下,则是输出了根本不存在的代码引用。我认为,这与 bug 和其他错误是两类不同的问题,后者才是本文其余部分讨论的主题。)
使用 LLM 编写代码时,真正的风险在于:它会犯下那些无法被编译器或解释器立即捕获的错误。而这类错误一直都在发生!
只要你运行 LLM 生成的代码,任何凭空编造的方法都会立刻暴露出来:你会看到报错。你可以自己修复,也可以把错误信息反馈给 LLM,看着它自行纠正。
再对比一下普通文本中的幻觉:为了避免传播错误信息、直接损害自己的声誉,你需要保持批判性思维,拥有敏锐的直觉,以及成熟的事实核查能力。
而代码免费附赠了一种强大的事实核查机制:运行代码,看看它能不能工作。
在一些使用场景中——例如 ChatGPT Code Interpreter、Claude Code,以及越来越多会循环编写并执行代码的“Agentic”编程系统——LLM 系统本身就能发现错误并自动纠正。
如果你让 LLM 写代码,却连运行一下都不愿意,那你到底在做什么?
幻觉出来的方法只是微不足道的障碍。因此,每当有人拿这件事抱怨时,我都会觉得,他们几乎没花什么时间学习如何有效使用这些系统——遇到第一道坎就直接放弃了。
我愤世嫉俗的一面会怀疑,他们可能本来就在寻找否定这项技术的理由,于是一看到第一个借口便立刻抓住不放。
不那么愤世嫉俗的一面则认为,可能从来没有人提醒过他们:要想从这些系统中获得良好结果,必须投入大量精力去学习。我探索如何将它们用于编程已经两年多了,但直到现在,我几乎每天仍会学到新的技巧,也会发现它们新的优势和弱点。
代码看起来不错,而且运行时没有报错,并不意味着它真的做对了事情。无论多么细致地审查代码——甚至无论自动化测试多么全面——都无法以确凿无疑的方式证明代码做的就是正确的事。你必须亲自运行它!
证明代码能够正常工作,是你的责任。这也是我认为 LLM 不会让软件专业人士失业的诸多原因之一。
LLM 生成的代码通常看起来非常漂亮:变量名规范、注释令人信服、类型标注清晰,结构也符合逻辑。这很容易让你产生虚假的安全感,就像 ChatGPT 给出一个语法正确、语气自信的答案时,你可能会忍不住跳过事实核查,也不再用怀疑的眼光审视它。
避免这类问题的方法,与审查其他人编写的代码,或者检查自己编写的代码时完全相同:你需要主动运行和检验代码。你必须具备出色的手动 QA 能力。
编程有一条通用原则:在亲眼看到一段代码正常工作之前,绝不要相信它——更理想的情况是,先亲眼看到它失败,然后再把它修好。
纵观我的整个职业生涯,几乎每一次,当我没有主动执行代码就假设它能够正常工作时——比如某个极少触发的条件分支,或者某条我认为绝不会出现的错误信息——后来都会为这个假设感到后悔。
如果 LLM 为你生成的代码中确实充斥着大量幻觉细节,你可以采取很多办法来应对。
尝试不同的模型。另一个模型的训练数据可能更适合你所选择的平台。作为一名 Python 和 JavaScript 程序员,我目前最喜欢的模型是开启 thinking 的 Claude 3.7 Sonnet、OpenAI 的 o3-mini-high,以及配合 Code Interpreter 使用的 GPT-4o(用于 Python)。
学会使用 context。如果 LLM 不熟悉某个特定的库,通常只要向 context 中塞入几十行示例代码,就能解决这个问题。LLM 极其擅长模仿,也能从非常有限的示例中迅速掌握模式。现代模型的 context window 越来越大——我最近开始使用 Claude 新推出的 GitHub 集成,将整个代码仓库放进 context,效果非常出色。
选择无聊的技术。我确实发现,自己会特意选择那些已经存在了一段时间的库,部分原因就在于:这样一来,LLM 能够正确使用它们的概率会高得多。
最后,我想用一个相关的观察结束这番牢骚:我总是看到有人说:“如果 LLM 写的每一行代码都要由我审查,那我还不如自己写,反而更快!”
这些人等于是在大声宣布:他们对阅读、理解和审查他人代码这些关键能力的投入严重不足。我建议他们多加练习。审查 LLM 为你编写的代码,正是训练这些能力的绝佳方式。
额外部分:我请 Claude 3.7 Sonnet 的“extended thinking mode”审查了这篇文章的一个早期草稿——“审查一下我这篇充满牢骚的博客文章。我想知道它的论点是否有说服力,我可以做哪些小改动来改善它,以及是否遗漏了什么。”它提供了相当大的帮助,尤其是给出了一些建议,让初稿不再显得那么咄咄逼人!既然现在可以分享 Claude 对话,这里就是那次对话的完整记录。
2025 年 3 月 11 日更新:我写了一篇更长的文章,介绍自己如何使用 LLM 辅助编程。
OpenAI 意外对 Hugging Face 发起的网络攻击,是已经成为现实的科幻故事——2026 年 7 月 22 日
与 Claude Code 团队的 Cat 和 Thariq 炉边对谈——2026 年 7 月 21 日
Kimi K3,以及我们仍然可以从鹈鹕基准测试中学到什么——2026 年 7 月 16 日
本文是 Simon Willison 撰写的《代码中的幻觉是 LLM 错误中最不危险的一种》,发布于 2025 年 3 月 2 日。
下一篇:参加无障碍与 Gen AI 播客节目后的一些笔记
上一篇:使用 LLM schema 从非结构化内容中提取结构化数据
每月赞助我 10 美元,即可收到一份精心整理的邮件摘要,汇总当月最重要的 LLM 进展。
付钱让我少给你发点东西!