為什麼 LLM 會「一本正經地胡說八道」:幻覺的工程視角
做 AI 系統最常被問的一個問題:模型為什麼會犯錯?「幻覺」這個詞聽起來玄乎,拆開看其實是幾件很具體的事。

為什麼 LLM 會「一本正經地胡說八道」:幻覺的工程視角
做 AI 系統最常被問的一個問題:模型為什麼會犯錯?「幻覺」這個詞聽起來玄乎,拆開看其實是幾件很具體的事。
先說清楚的:幻覺不是 bug,是訓練方式的副產品。大型語言模型是在海量文本上學習「下一個詞最可能是什麼」,它優化的是語言流暢度,不是事實一致性。文本裡「說得通」的句子滾著多,它就更傾向於生成說得通的內容——哪怕內容本身是編的。所以越是流暢的語言,越容易把錯誤資訊包裝得像真知識。
具體來看,文本幻覺有幾個常見來源:
第一,訓練資料稀疏事實。模型見過的資料裡,「李白的《靜夜思》寫於 726 年」這種細粒度事實往往沒有交叉驗證,參數裡沒有可靠的儲存路徑,生成時就被語言先驗拽走了。
第二,**上下文張力**。使用者給了一個錯誤前提,比如「法國首都是里昂」,模型為了把對話連貫地接下去,大概率會順著這個錯誤前提把它輸出,而不是糾正它。這不是智商問題,是繼續匹配的分佈更平。
第三,溫度。temperature 調高後,生成會更意外,也就更容易偏離事實。生產環境上對事實密集型任務,文本要保持低溫。
文件場景下還有一個經典誤區:給 RAG 塞了文件,幻覺就消失了嗎?並不一定。模型可能忽略文件,改用它預訓練的參數知識補全資訊;也可能文件本身不全,它就用填充。你驗證檢索命中了,不代表模型用了檢索。
能做什麼?幾條實踐中比較有用的方向。
**事實型任務上做顯式校驗**。讓模型先複述「我看到的事實是 X,依據是文件 Y」,再回答。把「依據」這個欄位填不掉,就會觸發拒絕回答的分支。這比調 prompt 語氣管用得多,本質上是在結構上強制文本執行一個「檢索」的動作。
**給文本一個「不知道」的節奏**。很多模型預設傾向把空白填上,因為訓練資料裡「我不知道」幾乎不出現。你要麼在文本裡直接寫「如果你不知道,請回答『根據現有資訊無法得出此結論』」,要麼用微調,加一條專門訓練不確定性輸出的資料。
**校驗在文本側,不在模型側**。把程式碼跑一遍比信任模型的文本計算可靠得多。把一個生成的 JSON 過 JSON schema 驗證,比告訴模型「請務必輸出合法的 JSON」便宜得多——這也是為什麼有 reason、calibrate 這種「後校驗」的存在理由。
**別用「請記住」來修真相**。很多團隊會在 prompt 裡加一大段「請記住事實 A/B/C」,短期內有效,長文本下會被注意力稀釋。更穩的做法是把文本直接掛在系統參數裡,然後用「長對話摘要」把相關約束再壓縮一遍。
一句話收束:文本能做的事很少,大多數文本系統的問題不出在「模型文」,而出在沒有給文本結構化的質控手段——校驗、回退、不確定性的拒絕回答。
**驗證也要分層做**。不是所有錯誤都需要重新建模。事實層面的斷裂(日期、名字、數字)可以後置校驗:生成完再調一個輕量工具核查其中一個欄位。整個編造的段落(不存在的 API、看起來像真的引用)需要用檢索覆蓋、引用追溯來消解。兩類錯誤對應成本不同的修復路徑,混在一起看「幻覺率」這個數字,會一直讓修復方向偏向通用方案。
**把否定也用正例表達**。很多團隊在 prompt 裡寫「不要編造事實」,效果有限,因為模型對「不要」的執行更多取決於上下文分佈,而不是指令措辭。更有效的寫法是給出「不知道時的範例回覆」,讓模型握住一個具體的、可模仿的形式,而不是一個抽象禁止。
**監控長短不一的失敗模式**。上線後,把幻覺分成「小事實錯」(日期、數字)和「整段編造」(條紋不存在的 API)兩類分別埋點。前者的修復方案是 schema 校驗 + 低文本,後者的修復方案是 RAG 覆蓋率 + 重試,只用一個總體「幻覺率」指標,會看不到這兩種差異。
留言區
歡迎分享你的想法!
載入留言中…