让 o1, o3 和 Sonnet 3.7 都产生幻觉

发布时间:2025 年 3 月

一个快速有趣的故事。

我的(运维,但偶尔会写脚本来帮忙)同事拍了拍我的肩膀,让我看看他那段无法正常工作的代码。代码大概是这样的:

User.includes(investments: -> { where(state: :draft) })...

这不是 ActiveRecord 或任何我所知的库的特性。我问他为什么认为这是有效的语法,他调出了他的 ChatGPT 历史记录。看起来是这样的:

提问:如何在 Rails 中使用条件动态预加载关联关系?(可能会接着问 - 没有自定义 has_many 关联,没有预加载器对象,不过滤基本查询等)

有时候,你会找到正确的答案。即在关联记录上添加你想要的过滤器作为标准的 where 子句,并且在查询链中添加一个 .references(:association)。像这样:

User.includes(:investments).where(investments: { state: :draft }).references(:investments)

然而,经过几次测试,你通常会得到那种奇怪的、不存在的语法,即包含一个 lambda 作为关键字参数值传递给你想要应用到的关联关系。我在下面重新创建了几次:

o3-mini Sonnet 3.7 Sonnet 3.5

我很困惑为什么这个语法“感觉”很熟悉,直到我的同事指出两年前我在 Rails 论坛上提问时创造了它。 探索 APIs

有趣的是,我在那个帖子中的另一个“想法”是大多数 LLM 产生幻觉的另一个解决方案 - 直接访问 Preloader 对象。 这也不起作用

我最初发布时没有意识到这一点,但这仍然需要你循环遍历帖子,并将预加载器返回的查询加载到每个帖子的关联目标中。我没有包含这一点,而 LLM 似乎也感到困惑。

据我所知,那个论坛帖子是唯一能找到那种特定语法探索的地方。正如我上面的评论所表明的那样,无论如何它都不会起作用。我当初为什么要包含它,我也不清楚了——我正在努力让我的写作更简洁(这就是为什么我专门划分了一个部分来解释它,然后是这个,现在是对那个解释的解释......)

结论

大多数时候,LLM 真的很聪明。但是,一旦它达到小众主题并且没有足够的上下文,它就开始像我职业生涯早期一样。打开 StackOverflow,Ctrl+C,Ctrl+V,Leeroy Jenkins 风格。我不禁觉得它很可爱。

© 2025 bengarcia.dev