不用再问大模型:hedgemony 用解释器揪出 AI 代码幻觉
hedgemony 通过 Python 解释器与包注册表,逐项验证 AI 生成代码中调用名、参数、示例的真伪,无需调用任…
随着大模型辅助编程普及,AI 生成代码里常见的「这个包我没装过、这个方法不存在」幻觉,成为开发者日常踩坑的来源。Show HN 上出现的 hedgemony 提出了一种颇为反直觉的解法:要找出 AI 的编造,不必再请一个 AI 来当裁判,只需让 Python 解释器自己说话。
核心思路:让解释器当法官
hedgemony 对每个文件做两遍扫描,第一遍不执行任何代码,第二遍只运行作者自己写下的示例。
- 第一遍(名字是否存在):将文件解析为语法树,把出现的每个名字交给实时运行的解释器去验证——
hasattr、inspect.signature这些 Python 自身使用的机制。math有没有median?json是否导出serialise?答案成为一条关于运行环境的事实陈述,而非推断。 - 第二遍(代码是否做到自述):若 docstring 中包含
>>>示例,就把示例跑一遍,比较代码是否兑现了作者自己声明的行为。这一步在受限的子进程中执行;没有任何>>>示例的文件完全不会被执行,避免了「为了检测幻觉而制造新风险」。
遇到无法判定的情况——未安装的包、类型模糊的变量、读不到签名的 C 扩展——工具选择沉默而非猜测。它刻意追求「误报」与「漏报」之间的不对称:误报会让你去修改本来就对的代码,而且你很难发现工具本身错了。
五类可判定问题,与两个不被使用的词
开发者刻意避开了「幻觉(hallucination)」与「说谎(lying)」这两个流行说法,原因在于:
- 「说谎」预设了欺骗意图,而模型没有意图,工具只报告真值,不揣测动机;
- 「幻觉」是含糊的总称,混入了不可判定的部分,hedgemony 只度量其中可被验证的前五类。
工具对每一个发现给出精确、可独立复核的命名:
- fabrication(总称):关于世界的一项陈述为假;
- invention:名字在任何地方都不存在,例如
import ghostlib; - misattribution:真实名字挂在错误的所有者上,例如
json.serialise; - malformation:目标真实,但调用方式不可能实现,例如
math.sqrt(2, 3); - contradiction:代码与其自身声明的示例相矛盾,例如 docstring 示例运行失败;
- confabulation(不检测):逻辑似是而非,又没有可对照的声明——这是不可判定的领域。
把「不可判定」变成「可判定」
对于 confabulation 这种「名字都对、逻辑可疑」的情况,工具不试图去猜,而把改造的主动权交还给作者。只需要在 def 下加一行 doctest 声明,把你期望的结果写下来,confabulation 就立刻变成可被自动捕获的 contradiction。
正是出于这一设计,工具对那些没有 doctest 的文件直接大声报告 NO_CONTRACT,而不是放行——它提示你:补上这一行,就能让文件具备被严格审查的条件。开发者解释,没有任何工具能读出「没记录过的意图」,诚实的目标是「让记录意图只花一行,写下后不打折执行」,这也是契约层存在的理由。
适合谁、怎么用
在终端一行命令即可对单个文件启动扫描,例如 hedgemony dashboard.py 会输出「21 行中 2 处编造,每 100 行 9.5 处」这样的统计,并在下方逐行列出具体问题。对于依赖 Copilot、Cursor、Claude Code 等工具批量生成代码的团队,这种解释器级的事实核查,是一种轻量、离线、可复现的补充防线。
