前言

这篇文章讲清楚两件事:LLM 的"幻觉"到底怎么来的、怎么对抗它,以及一个真实案例——我凭印象坚信自己写的 Agent 项目有某个功能,结果 AI 查了三遍代码,把我的"记忆幻觉"按在地上摩擦。

故事是这样的。

我在做一个 Java 轻量级 Agent,对标 Claude Code,技术栈是 LangChain4j + DeepSeek。聊到"怎么对抗幻觉"时,我顺口问了一句:

我的 Agent 是不是会根据问题动态调 temperature?

我记得自己设计过这功能。AI 没顺着我说,而是去翻了我的代码。然后告诉我:没有,temperature 写死 0.7。

我不信,让它再查。它又查了一遍,更确定了。

我不死心,搬出"我不是有设置模型力度 effort 吗"。它继续查,发现我说的 effort 根本不存在,那其实是 maxRounds。

三回合,全程查代码、贴行号、列证据。最后我承认:是我记错了。

这件事有意思的地方在于——幻觉不是 AI 的专利,人也会。区别是 AI 学会了"查证据再回答",而我还在"凭印象张嘴"。


一、幻觉到底是怎么产生的

先把锅找对。幻觉不是 bug,是 LLM 的工作原理决定的。

本质:它是"概率续写",不是"查事实"。

模型干的事,是预测下一个最可能的 token。它追求的是"读起来通顺合理",不是"事实正确"。当它不知道答案时,不会默认说"我不知道",而是编一个最像答案的东西出来。

因为在训练里,"流畅地编"得到的奖励,往往比"诚实地认怂"更高。

具体到几个层面:

训练数据层面
  ├─ 语料本身有错误、过时、矛盾
  ├─ 长尾知识(冷门事实)样本太少 → 记不准就瞎编
  └─ 知识截止时间之后的事,它根本不知道,但照样硬答

生成层面
  ├─ temperature 越高越发散 → 越容易跑偏
  ├─ 对错误答案也用肯定语气,没有"不确定"标定
  └─ 长上下文中间信息被遗忘(lost in the middle)→ 前后矛盾

Prompt 层面
  ├─ 错误前提("介绍李白发明的电灯")→ 顺着错误编
  └─ 指令模糊 → 自由发挥空间过大

Agent 场景还有专属的坑:

  • 幻觉调用工具:编一个不存在的工具名,或者瞎传参数。
  • 错误累积:多步循环里,早期一个小错,会被后面的步骤当成事实,越滚越大。

二、怎么对抗幻觉

一句话总纲:

让它有据可依 + 给它说"不知道"的权利 + 对输出做校验。

拆开讲。

1. RAG —— 工业界第一选择

把外部知识库检索到的真实内容塞进上下文,让模型"基于给定材料回答",而不是凭记忆。

关键不在检索,在 prompt 的强约束:

只根据提供的资料回答,资料里没有就说不知道。

2. 让它有据可依、可溯源

要求模型给出引用、原文片段,无来源不作答。再对答案做 grounding 校验——检查回答能不能在材料里找到依据。

3. 降低随机性

事实类任务,temperature 调到接近 0。要稳,别让它发挥。

4. Prompt 工程:给它退路

明确告诉模型"不知道就说不知道"。给它一个"退出"的选项,它就不一定硬编。复杂问题拆步骤,减少一步到位的瞎猜。

5. 校验与反思(Agent 重点)

  • 工具参数 schema 校验,非法参数直接拦。
  • 工具白名单,调不存在的工具直接报错。
  • self-consistency:同一问题多次采样,取多数一致的。
  • reflection:让模型(或另一个模型)复查"这答案有没有依据"。

6. 用确定性系统兜底

数学、计算交给代码执行;事实交给搜索工具实时查。别让模型口算,也别让它猜今天的新闻。

回到开头那个故事——AI 没有掉进幻觉,靠的就是第 6 条:它没有凭"我记得他写过"来回答,而是调工具去查代码、贴行号。 这就是"查证据不靠记忆"。


三、人也会"记忆幻觉"

那次对话最让我警醒的,是我自己的表现。

我"记得"设计过动态温度。这个记忆很真实、很有画面感。但它是假的——我可能只是想过,或者在另一个项目里写过,记忆张冠李戴了。

这跟 LLM 的幻觉一模一样:

LLM 幻觉              人的记忆幻觉
─────────            ─────────
不知道也编一个       记不清也"想起"一个
语气很肯定           我也很肯定
不主动查证           懒得去翻代码

AI 比当时的我强的地方,只有一点:它会去查,我没有。

它查了三次,每次都把证据摆出来:temperature 只在 3 个地方出现、全是写死的 0.7;我说的 effort 全项目零命中,那是 maxRounds。

证据面前,记忆不堪一击。

对抗幻觉的终极武器不是"更聪明",是"更愿意查证据"。对 AI 如此,对人也一样。


四、专业 Agent 怎么做动态调节

故事的结尾是个反转:既然没有,那就把它做出来。

我用"路由法"补上了动态温度——每个用户回合,先用一次极小的 LLM 调用给问题分类,再按类型选温度:

code     → 0.0   代码/命令,要确定性
factual  → 0.2   事实/数学,低温减幻觉
chat     → 0.5   闲聊,折中
creative → 0.9   起名/文案,放开发散

省 token 的三个设计:

  1. 每回合只分类一次,温度作用于整个回合,不在主循环每轮都分类。
  2. 专用小模型,分类调用 maxTokens 压到 16,只让它吐一个词。
  3. 最小 prompt,只发用户那句话 + 一行指令,不带历史、不带系统提示。

单次分类约 50~100 token,相对一轮主对话的上千 token,可以忽略。

但做完我也想清楚了一件事:这套"按问题调温度",其实不是顶级 Agent 的主流做法。

像 Claude Code、Cursor 这类代码 Agent,基本全程低温甚至接近确定性。因为它们要的是"可复现、不跑偏",发散是负担。真正的动态调节,是这几个维度:

入门     规则法调温度(关键词判断)
进阶     LLM 路由调温度(我做的这个)
主流     模型路由 —— 按难度换模型(小模型分类,强模型推理)
前沿     动态 reasoning effort —— 按难度给"思考预算"
高级     闭环反馈 —— verifier 判定低质就升温/换模型重采样
  • 模型路由:简单任务用便宜的小模型,难题才上贵的强模型。OpenRouter 这类网关的核心卖点。
  • reasoning effort:推理模型时代的主旋律。按难度给思考预算,比调温度更直接——它控制的是"想多深"。
  • 闭环反馈:不是事前选参数,而是事中根据输出质量反调。这就是 evaluator-optimizer 模式。

我那个温度池的架构,稍微一改就能升级成模型池。这是它天然的延伸方向。


写在最后

这件事给我两个收获。

技术上:对抗幻觉的核心,是把"凭记忆生成"换成"凭证据生成"——RAG、工具兜底、校验反思,都是这一句话的不同实现。

认知上:AI 查代码戳穿我的那一刻,我意识到自己才是那个在产生幻觉的人。它只是比我多做了一步——去查。

下次你"很确定"某件事的时候,不妨也去翻一眼证据。


Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐