为什么大模型会说胡话 如何解决幻觉问题

模型与算力

讲清大模型为什么会说胡话,给开发者一套能落地的判断标准与缓解动作:先定位是哪类幻觉,再选检索、校验、提示、微调哪条路。

上线一个问答或助手功能,最怕的不是答得慢,而是答得一本正经但完全是错的。你手里的模型在演示时很稳,一到真实提问就开始编人名、编接口、编条款。这篇不聊玄学,只给你一套可操作的排查顺序:先分清幻觉属于哪一类,再按成本从低到高挑缓解手段,最后说清每招在什么场景下不适用。

先把「说胡话」拆成几类再谈解决

很多人一遇到模型答非所问,第一反应是「换个更强的模型」。但幻觉不是一个问题,是好几类问题凑在一起叫了同一个名字。先分清是哪一类,再谈怎么治;分错了类,换多少个模型都白搭,因为解法根本不在同一个地方。

类型典型表现根子在哪优先动作
知识缺失型问它没接触过或记不清的事实,它照样给一个像模像样的答案模型没有这块知识,也不肯说不知道改成允许拒答、外部资料补进去
指令误解型任务理解偏了,答得挺流畅但答的不是你要的约束没写清、优先级没说死把任务、边界、输出目标分开写
格式诱导型要求填表填 JSON,字段缺了就自己编一个补上格式压力大于事实压力给空值约定、允许留空
上下文污染型长对话里前后信息打架,它捡了错的那条用上下文里混进了过期或矛盾的信息清理上下文,明确以哪条为准

换三种问法,看答案漂不漂

分不清是知识缺失还是推理出错时,有个便宜好用的土办法:同一个问题换三种问法——换措辞、换顺序、把选项反过来问。如果三次答案大体一致,多半是它真有个稳定判断(对错另说);如果答案跟着问法漂移,尤其是反向提问时它也跟着反着答,那基本是知识缺失型,它在顺着你的语气编。

  • 换措辞:把同一件事用完全不同的词再问一遍;
  • 换顺序:把前提条件和问题调换先后问;
  • 反向问:把「是不是 A」改成「是不是非 A」,看它会不会跟着你倒;
  • 答案随问法变 → 优先按知识缺失处理,别急着怪推理能力;
  • 答案稳定但就是错 → 才轮到检查指令理解和上下文有没有混进脏数据

有几种情况不算幻觉

不是所有「对不上」都叫幻觉,硬当成故障去修,反而会把正常能力一起削掉。两种常见边界:一是知识截止之后才发生的新事实,模型答不出来是设计使然,不是它编;二是它明确说了「不确定」「可能」「据我了解」的推测,这是它在做风险管理,属于正常表达。真正需要修的是那些语气笃定、内容却无据可依的回答。概念边界拿不准时,到 /ai-dict/category/basics 对照看看当时的口径。

  1. 第一步 归类对着上表,先判断这条回答更像哪一类,别急着动手改 prompt。
  2. 第二步 验证用三种问法复测一遍,记下答案是否漂移,漂移就往知识缺失方向靠。
  3. 第三步 排除边界确认是不是知识截止之后的事、或属于模型已声明的推测,是就别当故障处理。
  4. 第四步 对症改知识缺失补资料或允许拒答;指令误解重写约束;格式诱导给空值约定;上下文污染清对话。

它为什么非编不可:三个机制层面的原因

很多人以为模型说胡话是「知识不够」。其实更多时候是它的训练目标从一开始就没把「说对」放在第一位。模型每写一个词,做的事只有一件:根据前面已有的内容,猜下一个最可能出现的词。这个目标奖励的是「接得顺」,不是「接得真」。顺畅和真实是两码事,一句话读起来毫无破绽,完全可能整句都是它顺着语感拼出来的。

下一个 token 预测
每一步只选概率上最合理的下一个词,不负责回头核对整句是否符合事实
流畅性奖励
训练时让句子更像人话就会得分,句子真假往往不在评分里
长尾知识
出现频率低、关系复杂的事实,模型见过名词但没真正记住它们之间的连线
语言习惯补全
关系记不清时,它会按常见搭配填一个「听起来对」的答案

第二层原因是语料分布。常见、反复出现的事实,模型记得相对牢;冷门的人名、型号、数字、时间关系,在语料里本来就稀。它见过某个名词,却没记住这个名词和另一个名词到底是怎么连的。这时候它不会停下来告诉你「我不确定」,而是按语言里常见的说法补一个合理搭配,于是就成了看着像那么回事、实际对不上的内容。

第三层原因常被忽略:问题本身带了错的前提。你在提示词或上下文里写了「既然 A 已经发生」,模型多半会顺着这个前提往下推,而不是先质疑 A 是否存在。这种情况下它不是在自创,是被你带偏了。判断办法很简单:把同样的错前提换成一个明显离谱的说法再问一次,如果它照样顺着编,那就是顺着上下文走,不是它内部知识出了问题。

表现更可能是哪种机制怎么快速验证
句子很顺但事实错下一个 token 预测的流畅优先要求它逐条给出依据来源,看是否对得上
冷门细节编得具体长尾知识密度低,按搭配补全换成同类常见问题再问,对照回答是否变稳
跟着你的错前提一路推被上下文带偏把错前提改成明显不合理的说法,看它是否照跟
换个问法答案就飘采样随机性放大倾向降低随机性重问同一题,看结论是否收敛

采样参数会把上面这些倾向放大。温度越高、候选范围放得越宽,模型越愿意选「不那么主流」的词,句子更活,但也更容易跑偏;调低则更保守、更重复。这不是说越低越好,写作类任务低参数会显得干巴。相关术语(温度、top-p、top-k 这些)到 /ai-dict/category/tips 查,先弄清每个参数到底在调什么,再决定怎么调。

  1. 先分清是「编」还是「被带偏」把问题里的前提全部删掉,只留中性提问重问一次;答案变正常,说明原来是被上下文带偏
  2. 再测是不是长尾知识问题同一件事换成更常见的问法,或者让模型只回答「知道 / 不知道」;两次差异大,说明它本来就没记牢
  3. 最后确认是不是参数放大了同一问题用不同随机性设置各问一遍,若结论发散,问题多半出在采样而非知识本身

排查顺序:先用最小成本定位幻觉来源

幻觉不是一个原因造成的,可能是模型自己编、检索喂了脏数据、格式约束逼出来的、提示词本身有歧义。挨个改提示词、换模型,大概率白忙。更省事的做法是按成本从低到高排个顺序,一步步缩小范围,先把「不是原因」的那几项排掉。

  1. 切断检索,只留模型答把知识库、联网、向量检索全关掉,只让模型裸答同一道题。还是错,说明锅主要在模型自身(知识缺失或推理偏差);反而答对了,说明问题出在检索召回这一环,去查切片、召回数量和相似度阈值。
  2. 把召回片段打印出来打开检索链路,把这次真正喂进上下文的原文片段贴到日志里逐段看。重点确认两件事:有没有过期文档被召回、有没有把表格或代码块切碎成没有主语的半句话。答案照着脏片段抄,就是数据侧的问题,不是模型在编。
  3. 剥离格式要求再问一遍把 JSON、固定字段、表格模板、字数限制这些约束全部去掉,用最白话的方式重新问一次。很多幻觉是格式压力逼出来的:模型为了填满 schema,会硬凑一个看起来合理的值。去掉约束后答对,说明要改的是输出结构设计。
  4. 同提示词换一个模型对照提示词一个字不改,换一个能力档位或不同厂商的模型跑同一道题。多个模型都对,说明是提示词写得含糊;多数模型都错,说明是知识盲区或任务本身超出能力。这一步只用来分锅,不要顺手把模型也换了,否则变量就混了。
现象先怀疑哪里下一步动作
关掉检索后仍然错模型自身检查提示词是否含糊、任务是否超出能力
关掉检索后就对了检索召回看切片粒度、相似度阈值、索引是否过期
去掉格式约束后对了输出结构简化 schema,或拆成两次生成
换模型后明显变好模型能力评估是否要换模型或做路由分流
换模型后还是一样错提示词或数据回到前两步,别急着换模型
  • 一次只改一个变量,改完立刻在同一道题上复跑,别一次动三处。
  • 每一步都留日志:原始问题、实际喂进上下文的片段、模型原始输出,三者对不上就说明链路有损耗。
  • 对照组的题要固定住,否则你分不清是改动生效还是题目本身变简单了。
  • 排查顺序不是流程文档,两步就能定位时不必走完四步。

想对照不同模型和不同接口在处理同一道题时的表现差异,可以去站内的模型与接口对比页面拉一张表;具体有哪些可选项和当时的参数说明,以页面呈现为准,不要靠印象拍脑袋。定位清楚来源之后,再决定是改提示词、改检索还是换接口,比一上来就折腾强得多。

优先做检索侧:让模型少有机会自由发挥

想压住幻觉,先别急着换更大的模型,先去翻检索这一侧。原因很直白:模型只能基于你喂进上下文的那点东西说话,喂进去的片段本身就串味、互相打架,它就只能靠「脑补」把话圆回来。把检索做扎实,等于提前把一半编造掐掉。

  • 强制引用:要求每条结论后面标出对应的来源片段编号,编号必须真实存在;找不到支撑就明确回「资料里没有」,不许硬答。
  • 切片策略:别让一个切片跨段落、跨表格。跨了,召回时常常把前半句和后半句拼成一句矛盾的话,答案自然打架。
  • 召回分层:先粗召回一批,再上重排模型精排,把明显不相关的片段挡在上下文之外,别一股脑全塞进去。
  • 留拒答口子:在提示里写清「无依据可答不知道」,比逼它必须给答案要安全得多。
  1. 定切片规则按语义单元切,表格单独成片,标题和正文尽量同片。切完抽查几条,确认没有把两个不相干段落粘在一起。
  2. 加召回层先粗召回一批候选片段,再用重排模型按与问题的相关度排序,只把靠前的几片送进上下文。
  3. 上强制引用在输出格式里要求每条结论带来源编号,编号指向真实片段。验证方法:随机抽几条回答,回查编号是否能对上原文。
  4. 测拒答行为专门问几个语料里没有的问题,看它是老实说「资料里没有」,还是编一段。编了就继续收紧提示和召回范围。
环节做对了会怎样做错了会怎样
切片片段语义完整,召回后能直接引用跨段落拼接,片段自相矛盾,答案跟着打架
召回粗召回保证覆盖率,不漏关键信息只靠单路召回,容易漏掉真正相关的片段
重排不相关片段被挡在外面,上下文干净噪声片段挤占上下文,模型被带偏
强制引用每条结论有据可查,编造明显减少没有编号约束,模型自由度太大,容易自由发挥

反过来说,检索这套不是万能药。如果任务本身就没有可检索的语料——开放式创作、头脑风暴、让模型帮你起名字想点子,硬塞一套检索流程,只会让输出变得拘谨、放不开,创意类任务该放的还是得放。判断标准很简单:答案对错的依据是不是存在于某份资料里。是,就上检索;不是,就别硬上。

提示与输出层:不改模型也能压住一部分

模型本身的参数、训练数据、推理方式,你在这个层面基本动不了;但提示怎么写、输出怎么要,是你能立刻控制的部分。这一层的思路不是让模型「变聪明」,而是把它逼到一个更容易说实话、更容易被检查的位置上。压低幻觉通常靠两条:约束它怎么说,以及改变它先做什么再做什么。

改前(软要求)改后(可执行约束)
请准确回答,不要出错不确定时必须明确说「不知道」,并指出缺哪条信息
帮我分析一下这个问题先列出你的假设,再给结论,每条结论后标注依据来源
给出最优方案列出 2 到 3 个方案,分别写适用条件和已知风险
尽量详细只回答与问题直接相关的部分,无关内容不要补充
  • 不确定时必须说不知道:把「答不上来」变成一种被允许、甚至被要求的输出,模型就不用硬编一个看�着合理的答案。
  • 必须列出假设:让隐含前提显式化,你一眼就能看出它是不是在脑补。
  • 必须给出依据:要求它指明依据来自你给的资料、常识推理还是猜测,猜测部分天然可被标注出来。
  • 减少开放式措辞:把「谈一谈」换成「从A、B两个角度各写一句」,出口越窄,跑偏空间越小。
  • 降低采样随机性:在提供这类参数的接口上把随机性调低,输出会更收敛、更贴原文。
  1. 第一步:只提取事实片段把问题拆成「先找料、再动脑」。让模型只输出与问题相关的事实片段,要求逐条列出、能对应到你给的原文或上下文;不给结论,不给建议。中间产物你可以人工扫一遍,也可以用关键词匹配、引用校验之类的规则筛一遍。
  2. 第二步:基于片段作答把上一步筛过的片段重新喂回去,明确要求「只使用这些片段作答,片段没提到的一律说不知道」。这样一旦它开始编,你能马上定位到是哪条片段被过度延伸了。
  3. 第三步:抽查与回填答案里凡是出现具体数字、名称、时间一类容易出错的点,回原文核对一遍。核不上就把该处标出来,作为下一轮提示的反例写进约束里。

也就是说,提示层的约束是一把偏科的刀:抽取、总结、问答、合规改写这类「有标准答案或至少可核对」的任务收益最大;开放式生成里它只能用来兜住明显的事实错误,别指望它提�高整体质量。另外,约束写得越死,模型越容易在真正需要它补常识的地方变得畏首畏尾——如果发现它开始频繁说「不知道」而问题其实很简单,说明约束过度了,需要放松一点。

下一步想知道提示层之外还有哪些抓手,以及各类中转站在输出稳定性和参数可控性上的差别,可以去站内相关页面按当时的检测结果核对,再决定用哪条线路跑你的抽取任务。

加一层校验:让错误在到达用户前被拦下

模型输出已经生成了,但还没到用户手里——这一层是最后一道防线。核心思路是:能用程序判定的就别靠人看,能靠多次采样对上的就别单次信。顺序上先上规则,再上交叉,最后用置信度兜底,成本从低到高,收益从高到低。

  • 规则校验:金额、单号、URL、代码能否跑通,全都能用脚本判,写一次用很久,误伤率可控;
  • 交叉验证:同一问题换措辞再问一次,或换一个模型问,两次答案冲突就降级;
  • 置信度兜底:模型自己给的把握低、或根本没给,就不硬答,直接给人工或官方入口;
  • 兜底动作要有明确出口:转人工、给官方链接、返回「暂时无法确认」,三选一,不要留空。
校验手段适合拦什么不适用的情况
规则校验金额、编号、链接格式、代码可执行性开放式建议、主观评价、文案润色
交叉验证事实型问答、参数类结论创作类任务、需要唯一正确答案的场景
置信度兜底模型自报把握低或缺失模型整体过度自信、置信度不可信时
  1. 先写规则白名单把金额、单号、域名、代码片段抽出来,用正则或解析器逐条验;每条规则配一条测试样例,改规则时先跑样例。
  2. 再加交叉采样同一问题换一种问法再跑一次,或切到第二个模型跑一次;两次结果不一致就标记冲突,不要自动选一个。
  3. 冲突转人工或降级命中冲突的输出不进正式回复,走人工队列,或返回「这条我拿不准,建议去官方渠道核实」的降级文案。
  4. 把冲突率挂上监控冲突率、规则拦截率、降级率都上报,按天看趋势;突然抬升说明上游模型或提示词变了,先查这个再查业务。
  5. 定期回看被拦内容从拦截记录里抽样,看有没有误杀正常输出;误杀多了就放宽规则,宁可先留痕也别一刀切。

落地时别一上来就搭一套大系统。先挑一条最要命的输出类型(比如带金额或带链接的),把规则校验跑通,看拦截量再决定要不要加交叉。工具类页面可以翻站内的 /tools/quality-check 和 /tools/quality-monitor,前者适合做单条输出的即时检查,后者适合挂长期指标看趋势。要提醒的是,这套东西对创作、闲聊、头脑风暴类场景会显得很碍事,那类场景更适合只监控不拦截。

什么时候才轮到微调与换模型

先说结论:微调不是用来补事实的,它是用来补「说话方式」的。如果你的模型是记错了政策条款、编了不存在的条款号,那属于知识没到位,微调一般救不回来;反过来,如果知识都在、只是输出格式乱七八糟、行业术语用不准、语气不像你们客服,那才是微调的菜。判断标准就一句话:错在「知道什么」还是错在「怎么说」。前者走检索和校验,后者才轮到微调。

你遇到的毛病该动的地方微调有没有用
答不出公司内部规定、编条款号检索把资料喂进去 + 引用来源基本没用,白花钱
答案对,但格式飘、字段缺提示词约束 + 输出校验兜底有用,且是主力手段
行业黑话老用错、语气不像行内人准备高质量样本做微调有用,但前提是事实已经对了
整类问题都答不对、逻辑也乱先换更强模型再谈微调换模型优先级高于微调

路径分界可以到 /stacks/fine-tuning 对着看,那边讲的是微调该怎么组织数据、怎么评估,这里只讲「什么时候才该走到这一步」。顺序上建议按这个排查链:先确认检索能不能覆盖这个知识,再改提示词把格式和边界讲清楚,然后加一层输出校验拦住明显瞎编的内容,最后才问一句「剩下的错误是不是都集中在领域表达上」。如果前三步做完错误类型还是五花八门,说明瓶颈不在表达,微调大概率无效。

  1. 把最近的坏例子归类翻出二十条左右典型错误,逐条标是「事实错」还是「表达错」。事实错占比高就别微调。
  2. 确认检索和提示已经到位检索没命中、提示没写清格式的情况下谈微调,等于用贵办法解决便宜问题。
  3. 检查剩余错误是否同质如果剩下的错都长得差不多(同一种术语、同一种口吻),才有微调的价值。
  4. 换模型前先做迁移验证同提示词、同评测集跑一遍新旧模型,别只看综合榜。读榜方法参考 /benchmarks 与 /benchmarks/registry。

换模型这件事,容易犯的错是只看一个总榜排名就下决定。榜单测的是通用能力,你的任务是具体场景,两者经常对不上。稳妥做法是固定一份自己的评测集,同一套提示词分别跑候选模型,看的是在你关心的那几类问题上谁更稳。成本敏感的话,可以先去 /models 按能力标签筛出几个候选,再到 /inference 比一比实际调用开销,最后才回到你的评测集上做终选。这样筛出来的模型不一定榜上最高,但更贴合你的场景。

微调改的是嘴,不是脑子;事实的事交给检索,表达的事才交给微调。

上线前的一份可勾选清单

前面的分析再到位,最后都要落到一张能打勾的纸上。上线前把下面几件事逐条过一遍,比事后看到用户截图再慌张地回滚要省事得多。这张清单不追求覆盖全部场景,只保底把幻觉高发的那几个口子先堵上。

可复现
同一个输入重复跑多次,错误答案应稳定出现,而不是碰运气才冒出来;偶发错误说明问题在采样或检索,不在模型本身
知识边界声明
模型对超出资料范围的问题要明确拒答或转兜底,而不是硬编一个听起来合理的答案
可追溯
每条涉及事实的输出都能指回具体来源片段;指不回去的,一律走兜底话术
检查项通过标准不通过时先查哪
高频问题的测试用例每个业务高频问题至少有一条固定用例,错误可复现用例覆盖是否漏了某类提问方式
知识边界声明越界问题稳定拒答或转兜底系统提示与拒答策略
事实输出的来源抽查的输出都能追到来源片段检索召回与片段拼接
兜底话术追不到来源时不说具体结论兜底逻辑是否被绕过
线上监控三项拒答率、引用命中率、人工纠错率有基线先看检索,再看模型
  1. 固化测试用例把业务里最容易出错的提问方式整理成固定用例集,每条都写明期望输出。跑的时候同一个问题连跑几次,看错误是否稳定复现,偶发错误要单独标出来查采样参数。
  2. 验证边界与来源挑一批明显超出资料范围的问题,确认模型拒答或转兜底而不是编答案;再从正常输出里随机抽几条涉及事实的,逐条往回追来源片段,追不到就记一笔。
  3. 盯住三项监控上线后持续看拒答率、引用命中率、人工纠错率。任一指标偏离基线,排查顺序是先检索后模型:先确认召回和片段是否正常,再怀疑模型本身。

清单不是一次性的。每次人工纠错积累到一定量,就回头补测试用例、收紧知识边界声明,让这张纸跟着业务一起长。具体的指标基线和历史波动,到站内监控与评测页面核对当时的数字,别凭记忆拍脑袋。

常见问题

把温度调到最低,幻觉就没了吗?

会减轻但不会消失。低温度只是让输出更保守、重复性更高,知识缺失时它照样会编,只是编得更稳定。对抽取、分类这类任务值得调低;对写作类任务会明显变呆。真正管用的还是检索与校验,参数只是辅助。

上了 RAG 是不是就不会说胡话了?

不是。RAG 把「没知识」换成了「检索质量」问题:召回错了、切片切断了、多个片段互相矛盾,模型照样会拼出一个错误答案。所以要单独监控召回命中率和引用是否真实存在,别把它当成万能挡板。

怎么判断一次错误是幻觉还是知识截止?

看知识时效性。如果错的内容在模型训练时间点之后才出现,属于知识截止;如果是它自己编了一个从不存在的事实、编号或引用,那是幻觉。两者处理方式不同,前者靠联网或更新知识库,后者要靠约束与校验,概念边界可到 /ai-dict 对照。

小团队没资源做全套,先做哪一步?

先做强制引用加拒答兜底。让模型必须指出来源片段,没有就回答「资料不足」,同时用规则校验金额、编号这类硬字段。这两件事工程量不大,但能拦住大量会直接伤到用户的错误答案。

知识库里的文档本身写错了怎么办?

那模型抄得理直气壮,属于数据问题不是模型问题。要在入库前做来源分级和更新时间标记,过期或来源不明的文档单独隔离,让检索优先命中有出处的内容。这部分治理比调模型划算得多。

本文依据各平台公开文档与官方公告整理,只做中文归纳;具体做法、参数与限制以官方文档为准。