RAG依據(jù)性驗證的自動化方案)
上周幫一位做企業(yè)問答系統(tǒng)的朋友排查線上工單現(xiàn)象很典型用戶問“去年 Q3 各區(qū)域營收分別是多少”系統(tǒng)檢索到了正確的財報片段生成的答案數(shù)據(jù)也完全對但對著一張三列的表格模型只挑了兩列回答。從傳統(tǒng) ROUGE 指標(biāo)看答案質(zhì)量分很高從業(yè)務(wù)角度講這個回答等于漏報了一半信息。這類問題在 RAG 落地里太常見了——檢索到了但不一定用全、用對了。業(yè)界把它叫做 groundedness依據(jù)性驗證目前也是各種幻覺檢測方案最想解決的核心問題之一。最近一支由云廠商與兩所高校聯(lián)合的研究團隊放出了一個叫 Auto-GDA 的工作方向很對我的胃口他們用自動化的數(shù)據(jù)合成流程訓(xùn)練輕量級模型讓參數(shù)量小了至少一個數(shù)量級的小模型在 RAG 依據(jù)性判別上逼近大模型水平推理速度提升約 10 倍。這篇文章我把它的技術(shù)思路、數(shù)據(jù)構(gòu)造方法、輕量模型訓(xùn)練細節(jié)和工程接入方式完整拆一遍并補上我自己復(fù)現(xiàn)和落地時踩過的一些坑。適合正在做 RAG 生產(chǎn)系統(tǒng)、幻覺治理或者想給生成式應(yīng)用加一道質(zhì)量閘門的讀者。1. 為什么“依據(jù)性驗證”成了 RAG 落地最難啃的骨頭1.1 一個典型事故答案看著對其實在“漏說”和“胡說”之間反復(fù)橫跳RAG 系統(tǒng)的幻覺問題很多人以為只是“模型不懂裝懂”。實際接入過生產(chǎn)環(huán)境的人會告訴你更隱蔽的是“答案里的每一句單獨挑出來都對但組合在一起就超出了檢索文檔支持的范圍”。比如我問“某產(chǎn)品的主要競爭對手有哪些”檢索到的文檔只提了兩家模型在列舉時自作主張地補上了一家它“印象中”的對手。對的那部分掩蓋了錯的那部分自動化評估很難抓。這類問題之所以難解是因為它發(fā)生在“檢索到的證據(jù)”和“生成的文字”之間的夾縫里。傳統(tǒng)方法要么只看檢索相關(guān)度用向量距離判斷但向量相關(guān)和語義被支持是兩回事要么整體評估生成質(zhì)量用一個打分模型看答案好不好但整體分掩蓋了局部的不忠實。直到今天團隊里做質(zhì)量評估的人最頭疼的依然是怎么讓機器明確告訴你“這句有依據(jù)、那句沒依據(jù)”。1.2 依據(jù)性“三分類”標(biāo)簽體系支持、部分支持、不支持從業(yè)界主流做法看依據(jù)性驗證最實用的是把問題拆成一個離散分類任務(wù)而不是讓模型輸出長串解釋。Auto-GDA 延續(xù)了類似 Self-RAG 反思機制和 CRAG 可信度分類的思路把“答案與檢索上下文是否對得上”分成三類支持Fully Supported答案中的所有關(guān)鍵實體、數(shù)據(jù)、結(jié)論都能在檢索上下文中找到對應(yīng)證據(jù)沒有超出文檔的額外信息。部分支持Partially Supported答案的某些片段有依據(jù)但至少一個關(guān)鍵信息點缺失或與文檔矛盾。無支持Not Supported答案的核心主張在上下文中找不到任何證據(jù)屬于純粹的模型記憶性生成。為什么不用連續(xù)分?jǐn)?shù)而用離散標(biāo)簽我在實際評測里發(fā)現(xiàn)連續(xù)分?jǐn)?shù)很難標(biāo)定閾值不同領(lǐng)域、不同文檔風(fēng)格下同樣的分?jǐn)?shù)含義不一樣。三類標(biāo)簽天然對應(yīng)三種動作——放行、降級重寫、阻斷重新檢索——生產(chǎn)管線里可以直接映射成策略不用再做一層模糊判斷。1.3 為什么大模型能做、小模型做不好如果你把這個問題丟給一個大參數(shù)模型讓它判斷“以上答案是否被文檔支持”它能做得不錯原因是長上下文理解、跨句推理、實體級比對這些能力需要足夠的模型容量。但問題是在線服務(wù)的預(yù)算撐不住每個生成結(jié)果都跑一遍大模型校驗。生成已經(jīng)花了 2 秒校驗又花 3 秒延遲直接翻倍。而小模型做這件事的難度在于依據(jù)性驗證不是“記住知識”是“比對知識”。它要求模型同時理解一段長上下文和一個多句答案找出其中的矛盾點。這不但是理解任務(wù)更是對齊任務(wù)。純靠小模型在通用語料上學(xué)到的能力很難穩(wěn)定勝任。Auto-GDA 整個設(shè)計圍繞的核心就是一件事——怎么把大模型的“比對能力”遷移給一個足以跑在線推理的小模型同時不依賴昂貴的人工標(biāo)注。2. Auto-GDA 的思路拆解它到底“自動”在哪里2.1 從公開信息看為什么團隊強調(diào)“合成數(shù)據(jù)”我最初看到這個項目名時第一反應(yīng)是它大概率又是一個“大模型生成訓(xùn)練數(shù)據(jù)小模型蒸餾學(xué)習(xí)”的流程。從目前放出的信息看核心沒有脫離這條主線但有幾處設(shè)計很講究。所謂“Auto”我理解包含兩層含義一是訓(xùn)練數(shù)據(jù)不需要人工標(biāo)注完全用大模型自動產(chǎn)出二是數(shù)據(jù)構(gòu)造和標(biāo)簽生成都是自動管線可以批量擴展到任意領(lǐng)域。這里有一個很現(xiàn)實的背景想訓(xùn)練一個能用的依據(jù)性判別模型少說要幾萬條標(biāo)注樣本。如果靠人工標(biāo)注標(biāo)注員需要讀一遍檢索文檔再對照答案逐句打標(biāo)簽平均一條成本幾十塊幾萬條就是幾十上百萬。而且跨領(lǐng)域還要重標(biāo)。所以團隊選擇用大模型做自動標(biāo)注模型成本可能只有人工的幾十分之一。2.2 關(guān)鍵點不是“蒸餾答案”而是“蒸餾判斷”很多蒸餾工作會把大模型的推理過程或答案文本直接當(dāng)作訓(xùn)練目標(biāo)比如讓小模型學(xué)大模型寫的解釋。Auto-GDA 的做法在我看來更偏“行為對齊”大模型的角色不是給答案而是給groundedness 標(biāo)簽。小模型學(xué)的不是“說什么”而是“怎么判斷有沒有依據(jù)”。這個差異很關(guān)鍵因為判斷任務(wù)本身輸出空間很小三個標(biāo)簽大部分信息不在標(biāo)簽里而在“什么樣的輸入組合推出這個標(biāo)簽”的映射關(guān)系里。換句話說訓(xùn)練數(shù)據(jù)真正值錢的地方是什么樣的 query、什么樣的檢索上下文、什么樣的生成答案組合在一起會讓答案落入“部分支持”這個類。這種邊界樣本才是判別模型能力的來源。所以在數(shù)據(jù)構(gòu)造上團隊花了更多心思在制造邊界情況上——答案只差一個數(shù)字、多了一句推測、漏了一個限定詞。這些樣本決定了模型上線后會不會在模糊地帶頻繁誤判。2.3 為什么不直接拿大模型做在線推理這是工程上繞不開的問題。即使大模型判斷準(zhǔn)確在線調(diào)用依然要面對幾個現(xiàn)實瓶頸單次推理的 GPU 顯存占用、token 級延遲、并發(fā)吞吐上限。一批 70B 級模型做依據(jù)性校驗每秒鐘能處理的請求數(shù)極其有限放到高并發(fā)問答系統(tǒng)里根本扛不住。Auto-GDA 選擇把判別能力沉淀到 1B 以下的輕量模型付出少量準(zhǔn)確率代價換來約 10 倍的推理加速。這個“10 倍”的來源也很直接小模型單次前向傳播的浮點運算量低、顯存占用小、可以在同一張 GPU 上同時跑多個實例做批量推理。從成本賬看一個 70B 模型 GPU 推理的價格和一個 1B 模型的價格差距遠不止 10 倍省下來的是實打?qū)嵉倪\營成本。3. 訓(xùn)練數(shù)據(jù)是怎么“造”出來的四步合成流程3.1 第一步構(gòu)造 query 與檢索上下文的配對合成數(shù)據(jù)的起點是一批語料文檔。一個常見做法是先收集一個大型文本語料庫用反向生成的方式制造 query——讓大模型讀一段文檔然后提出一個“該段文檔可以回答的問題”。這種方式能保證每個 query 都能在對應(yīng)文檔里找到答案天然就是正樣本的基礎(chǔ)。但這里有個動作很關(guān)鍵不能只做“文檔-問題-答案”的一一配對。真實 RAG 場景中檢索系統(tǒng)拿回來的上下文經(jīng)常是多篇文檔拼接的其中有相關(guān)片段也有干擾片段。所以 Auto-GDA 在構(gòu)造訓(xùn)練數(shù)據(jù)時會把相關(guān)文檔與隨機采樣或語義相似的干擾文檔混合模擬檢索召回結(jié)果不純的情況。模型學(xué)到的就是對“混著噪聲的證據(jù)”做判斷而不是總面對干凈上下文。3.2 第二步大模型多次采樣生成答案制造天然對比同一個 query配上不同的溫度參數(shù)和不同的上下文生成多個版本的答案。由于大模型生成有隨機性同樣的文檔下采樣的答案質(zhì)量會上下浮動有的忠實引用文檔數(shù)字有的憑印象加工細節(jié)有的干脆跑偏。這些不同版本恰好構(gòu)成“支持/部分支持/不支持”的天然候選集。具體操作上溫度一般設(shè) 0.7 到 1.0 之間每個 query 采樣 3-5 次。采樣后的答案會和文檔一起交給另一個大模型做標(biāo)注標(biāo)注指令寫得非常細要求模型先判斷答案中每個獨立的“語義片段”而不是全篇是否有對應(yīng)的文檔證據(jù)再根據(jù)出現(xiàn)問題的片段數(shù)量判斷整體類別。這個過程相當(dāng)于把粗粒度三分類拆成了“先微觀、再宏觀”的兩層標(biāo)注準(zhǔn)確率會比直接讀全文打一個分?jǐn)?shù)高很多。3.3 第三步刻意制造“邊界樣本”和“負(fù)樣本”只靠模型自然采樣出來的錯誤答案邊界分布可能不夠豐富。比如答案多了一個年份、少了一句限定、把 A 公司的數(shù)據(jù)安到 B 公司頭上——這些細小的替換大模型采樣時不一定每次都出現(xiàn)。團隊在數(shù)據(jù)管線里會額外做一步自動改寫。具體做法是把原始答案中的關(guān)鍵實體、數(shù)字、限定詞做替換或刪除比如把“2025 年營收 1.2 億”改成“2025 年營收 2.1 億”或者刪掉某個前提條件。改造后的答案和原文檔組合在一起就變成了高質(zhì)量的“不支持”或“部分支持”樣本。這類樣本的價值在于它讓模型注意到了“實體級錯位”和“數(shù)字替換”這些最典型的幻覺形式而不是只學(xué)會判斷“有沒有相關(guān)內(nèi)容”。3.4 第四步置信度過濾與數(shù)據(jù)分布校準(zhǔn)大模型自動標(biāo)注不是萬無一失的。有些邊界樣本大模型自己也會犯迷糊比如文檔里模棱兩可、答案里有一半對一半錯時標(biāo)注可能隨機落在“部分支持”或“不支持”上。團隊的處理方式是讓標(biāo)注模型輸出一個置信度或打分低于閾值的樣本直接丟棄。這個過濾步驟很容易被忽略但影響很大。如果訓(xùn)練集里有 5%-10% 的標(biāo)簽是錯的小模型的準(zhǔn)確率會掉得比想象中快。為了控制成本也可以用兩個大模型對同一批樣本分別標(biāo)注只保留兩者一致的樣本一致性過濾比單一模型置信度過濾更穩(wěn)定。我在自己的小規(guī)模復(fù)現(xiàn)里試過雙模型一致率大概在 85% 左右取交集后數(shù)據(jù)量雖然有折損但下游模型準(zhǔn)確率能漲 2-3 個點。4. 輕量模型選型與訓(xùn)練細節(jié)判別式永遠比生成式劃算4.1 兩條技術(shù)路線生成式理由 vs 判別式標(biāo)簽把依據(jù)性驗證做成一個生成任務(wù)讓模型輸出“這段答案是否被支持的判斷理由”優(yōu)點是可解釋性強結(jié)果能追溯到具體句子。但代價是輸出一串 token推理慢而且小模型的自由文本生成本身不穩(wěn)定可能自己邊寫邊“編理由”。Auto-GDA 走的是判別式路線訓(xùn)練一個帶分類頭的輕量模型輸入是“檢索上下文 生成答案”輸出是三分類 logits。這種方式有兩個直接好處第一推理時只需要一次前向傳播不需要自回歸解碼延遲是生成式方案的幾十分之一第二訓(xùn)練更穩(wěn)定目標(biāo)函數(shù)就是交叉熵不會出現(xiàn)生成模型那種“理由寫得好但結(jié)論判斷錯”的情況。4.2 輸入拼接方式與分類頭設(shè)計我復(fù)現(xiàn)時把輸入設(shè)計成如下結(jié)構(gòu)[CLS] 檢索上下文: {chunk_text} [SEP] 生成答案: {answer_text} [SEP]上下文和答案之間用顯式的分隔符拆開讓模型清楚知道哪部分是證據(jù)、哪部分是待檢驗對象。編碼器選 encoder-only 的小模型結(jié)構(gòu)參數(shù)量在 500M-1B 之間輸出取[CLS]向量接一個三層 MLP 分類頭。訓(xùn)練時學(xué)習(xí)率用 2e-5batch size 按單卡顯存盡量放滿線性 warmup 加余弦衰減這些和常規(guī)分類任務(wù)沒有太大區(qū)別。有一點值得提醒輸入長度非常影響推理時延。如果上下文動輒三四千 tokenencoder 的注意力計算量會指數(shù)級上漲。我的經(jīng)驗是把上下文限制在 1024-1536 token 內(nèi)超出部分按文本塊滑動窗口處理先對每個窗口分別判一次再綜合判整體。雖然多跑了幾次前向總延遲仍然遠低于生成式方案。4.3 推理提速 10 倍的成本賬本到底怎么算很多讀者看到“10 倍”會追問這個數(shù)字怎么來的。我按一個典型場景算筆賬。假設(shè)用 70B 級模型做依據(jù)性校驗輸入 1500 token輸出 100 token 的判斷理由單次推理耗時約 2.8 秒一張 A 系列 GPU 上并發(fā)開到 8并發(fā)吞吐約 2.8 req/s。換成 1B 級判別模型輸入 1500 token輸出 3 個 logits單次推理耗時約 280 毫秒同樣一張卡并發(fā)能開到 64吞吐大約 45 req/s。吞吐提升接近 16 倍如果算端到端延遲則大約是 10 倍標(biāo)題里說的 10 倍是合理且保守的。更重要的是單位成本。在線服務(wù)計費是按 GPU 小時算的同樣的校驗吞吐量用 1B 模型需要的 GPU 數(shù)量比用 70B 模型少一個數(shù)量級以上。當(dāng)一個系統(tǒng)每天有幾百萬次請求時這一項的年度成本差異可能是幾百萬與幾十萬的區(qū)別。對比項70B 生成式校驗1B 判別式校驗輸入長度1500 token1500 token輸出方式自回歸生成約 100 token直接輸出 3 分類 logits單次推理延遲約 2.8 秒約 280 毫秒單卡并發(fā)約 8 路約 64 路有效吞吐約 2.8 req/s約 45 req/s部署成本需要多卡集群單卡可覆蓋5. 工程落地把 Auto-GDA 接進 RAG 管線5.1 第一種接入方式放在檢索之后、生成之前如果你的場景是“想在沒有依據(jù)時不讓模型硬答”可以把判別模型放在 RAG 的檢索和生成中間系統(tǒng)先把召回的文檔切塊、重排然后讓 Auto-GDA 判斷這些文檔是否能充分回答用戶的問題。注意這里和標(biāo)準(zhǔn)流程有個關(guān)鍵差異——不是判斷“文檔相關(guān)”而是判斷“文檔對這個問題是否構(gòu)成完整依據(jù)”。比如用戶問“諾基亞手機現(xiàn)在的市場份額”檢索回來的文檔可能只有一條新聞提到該品牌在歐洲市場的情況向量相關(guān)分很高但作為答案依據(jù)并不完整。Auto-GDA 如果輸出“不支持”或“部分支持”系統(tǒng)可以觸發(fā)二次檢索、擴大召回范圍或者直接告訴用戶“信息不足請細化問題”。這種方式的好處是避免了模型已經(jīng)生成錯誤答案才事后彌補的尷尬但代價是你必須額外訓(xùn)練一個“文檔-問題”層級的判別模型而不是簡單的“答案-文檔”驗證模型。5.2 第二種接入方式放在生成之后做最后一道閘門大部分團隊會先做這條路模型生成答案后把“檢索上下文”和“最終答案”一起喂給 Auto-GDA輸出三類標(biāo)簽。對應(yīng)動作很直接支持直接返回用戶。部分支持把對應(yīng)句標(biāo)記為低置信觸發(fā)一次局部重寫只重寫無依據(jù)的句子或者讓大模型補充檢索后再生成一次。無支持阻斷答案重新檢索或返回“無法回答”。這個流程的好處是不改動原有生成鏈路推理層完全隔離。缺點是已經(jīng)浪費了一次生成算力。但在上線初期、不想動主鏈路的階段這是最穩(wěn)妥的灰度方式。我建議先做這一層跑通數(shù)據(jù)回流和指標(biāo)監(jiān)控再考慮前移到檢索后階段。5.3 閾值與兜底策略寧可漏報也不誤殺三分類和閾值配套使用時有個容易被忽視的問題softmax 輸出的概率不等于真實置信度。我見過直接拿“不支持”類的概率超過 0.5 就阻斷的做法結(jié)果真實場景中誤殺率很高。因為訓(xùn)練數(shù)據(jù)的標(biāo)簽分布和線上分布往往不一致線上“不發(fā)生幻覺”的樣本占比明顯更高。實操中更穩(wěn)的做法是留一個不確定性區(qū)間。比如“支持”類的概率低于 0.7、且“不支持”類的概率低于 0.5就把它當(dāng)作“不確定樣本”走人工審核或降級處理而不是直接放行或阻斷。誤殺一個本來正確的答案對用戶體驗的傷害遠大于放掉一個幻覺。6. 實操中的坑與調(diào)優(yōu)經(jīng)驗6.1 長文本跨塊引用引發(fā)的“部分支持”誤判我在自己的數(shù)據(jù)集上復(fù)用時最先遇到的是長答案跨多個檢索塊的問題。一個答案有四句話其中三句在第一個文檔塊里有證據(jù)剩下一句在第二個文檔塊里才有證據(jù)。如果模型只看了第一個塊判斷結(jié)果是“部分支持”看了兩個塊又變成“支持”。同一套答案接入方式不同結(jié)論完全不一樣。解決思路是不要把文檔簡單切成固定長度塊而是保留塊之間的重疊和引用關(guān)系。對答案按句子粒度切分后每一句單獨定位它命中的文檔塊再把這些與答案相關(guān)的塊拼接進模型上下文。這樣模型面對的是“該看的那部分證據(jù)”而不是“檢索回來的全部內(nèi)容”。代價是實現(xiàn)復(fù)雜度略高但能顯著降低跨塊場景的誤判率。6.2 領(lǐng)域語料分布漂移通用訓(xùn)練數(shù)據(jù)上線后“失靈”Auto-GDA 這類模型最大的軟肋是訓(xùn)練數(shù)據(jù)分布。如果團隊用通用語料合成數(shù)據(jù)訓(xùn)練塞到垂直領(lǐng)域比如醫(yī)療、法律、某個公司的內(nèi)部知識庫里模型會開始大面積輸出“部分支持”。原因是垂直領(lǐng)域的文檔里專業(yè)術(shù)語密度高、數(shù)字多、隱含前提多模型在通用語料上學(xué)到的“證據(jù)比對模式”不足以應(yīng)對。應(yīng)對方案是領(lǐng)域微調(diào)用目標(biāo)領(lǐng)域的小規(guī)模語料幾千到幾萬篇文檔重新跑一遍合成數(shù)據(jù)管線生成領(lǐng)域相關(guān)的訓(xùn)練樣本然后在原模型基礎(chǔ)上繼續(xù)訓(xùn)練。不需要從頭訓(xùn)幾千條帶標(biāo)簽的領(lǐng)域數(shù)據(jù)就能把誤判率拉回正常水平。如果領(lǐng)域語料都不好拿至少要做在線 shadow 模式把線上預(yù)測結(jié)果導(dǎo)出來人工抽檢不斷沉淀壞樣本。6.3 如何調(diào)閾值才不犧牲召回判別模型的標(biāo)簽分布天然不均衡通常“支持”占絕大部分。這時只盯著整體準(zhǔn)確率沒有意義更值得關(guān)注的是“幻覺召回率”——有多少真正無依據(jù)的回答被攔下來了。我的做法是在一個采樣的驗證集上分別畫出三類標(biāo)簽的 PR 曲線然后選擇一個對“不支持”類召回較高、但對“部分支持”類誤判可控的閾值點。比如我會要求“不支持”類的召回至少達到 85%然后在這個約束下盡量選擇讓“支持”類精確率最高的閾值。這樣可能有一小部分“部分支持”的答案被放過去了但至少嚴(yán)重幻覺不會漏。實際跑下來一個經(jīng)過調(diào)閾值的判別模型在線上看到的體驗比單看準(zhǔn)確率要好很多——因為用戶最無法接受的是“一本正經(jīng)地胡說八道”而不是“漏了一些細節(jié)”。最后分享一個我在接入時的小技巧不要只用最終拼接的輸入做單次推理可以用 2-3 個不同的文檔塊組合各跑一次再做投票式整合。這樣雖然推理次數(shù)翻倍但因為單次推理本身已經(jīng)很快總延遲增加有限換來的是對“證據(jù)選擇偏差”的明顯抵抗能力。Auto-GDA 把依據(jù)性驗證從“不可能在線做”變成了“可以批處理做”這個能力遷移本身比單一模型的點數(shù)提升更值得關(guān)注。