RAG場景、資料、應用難點與解決

hjy1995發表於2024-11-24

RAG基礎

RAG也在很多行業積極實踐中,在【RAG行業交流中發現的一些問題和改進方法】提到了,RAG應該算是核心底層,適配各行各業,依然需要基礎元件和各行業的適配應用:

img

如果我們需要傾向於獲取外部知識和重視透明度,RAG是我們的首選。另一方面,如果我們正在使用穩定的標記資料,並旨在使模型更接近特定需求,則微調是更好的選擇。

img

RAG產品的使用者旅程總結

img

RAG 適用場景:

  • 第一:私有資料存在一定頻率的動態更新的;
  • 第二:需要給出引用原文的;
  • 第三:硬體資源(GPU)不是太充足的(即使用RAG也需要微調,但一次微調處處可用,遠比每個企業私有庫微調一個模型成本低的多)

RAG任務幾個具體問題場景【RAG行業交流中發現的一些問題和改進方法】:

  1. 不擅長小範圍的描述性問題回答。例如,哪個主體具有某些特徵?
  2. 不擅長關係推理,即尋找從實體A到實體B的路徑或識別實體集團。
  3. 不擅長時間跨度很長的總結。例如,“列出所有哈利波特的戰鬥”或“哈利波特有多少次戰鬥?”

RAG應用程式在這類任務上的表現很差,因為只有少數chunk可以輸入到LLM中,而且這些chunk是分散的。LLM會缺少很多輔助資訊,比如後設資料和世界知識。為RAG尋找最適合的領域,避免強行進入錯誤的地方,比如千萬別讓RAG去寫詩,它的算數能力也很差。

在【瀚海方舟:ChatGPT應用:如何征服市場眼中的“萬能RAG”】一文中提到了非常多針對性的解決方式:

  • 內容切片不夠好,容易切碎,於是有了段落智慧劃分;
  • 向量生成的質量不可控,於是有了可根據不同QA場景動態生成向量的Instructor;
  • 隱式的動態向量不夠過癮,再用HyDE做箇中間層:先生成一些虛擬文件/假設文件再做召回,提升召回率;
  • 如果向量這一路召回不夠,再上關鍵詞召回,傳統BM25+向量HNSW融合各召回通路;
  • 召回的太多容易干擾答案生成,探究一下Lost in the Middle,搞一搞trick,或者用LLMLingua壓縮;
  • 嫌召回太麻煩?直接擴到100k視窗全量懟進大模型,LongLoRA橫空出世;
  • 剛才提到的各個環節需要改進的點太多,懶得手工做,直接交給大模型,用Self-RAG替你完成每個步驟

按照上述的內容全部擼一遍,但是仍然有非常多的問題,然後又需要:

  • 要建立元資料過濾單元,不是一上來就全文檢索,要有更精細化的索引,根據查詢需求先做一遍過濾,比如時間、內容源等等;
  • 要建立全文處理單元,解決由於切割帶來的資訊損耗,需要從離線、線上兩部分同時考慮,離線預計算覆蓋高頻需求,線上覆蓋長尾需求;
  • 要建立數值計算單元,彌補大模型在做數學題上的缺陷,並且補充足夠的金融行業計算公式或企業自定義計算公式;
  • 要建立資料庫查詢單元,區別於“數值計算”,這裡主要是指NL2Sql,有些資訊查詢需要走資料庫而不僅僅是文章內容;
  • 要建立意圖澄清單元,我們允許使用者發起五花八門的查詢請求,但當查詢需求不明確時,系統要有能力幫助使用者改進查詢語言

RAG應用難點

  1. 資料難點:文件種類多

    有doc、ppt、excel、pdf,pdf也有掃描版和文字版,抽取出來的文字資訊,呈現碎片化、不完整的特點。

  2. 資料難點:不同文件結構影響,需要不同的切片方式

    這個可是老大難問題了,不好的切片方式會造成:

    • 如果切片太大,查詢精準度會低
    • 一段完整的話可能被切成好幾塊,每一段文字包含的語義資訊實際上也是不夠完整的
    • 一些雞肋切片,其實可以刪掉
  3. 資料難點:內部知識專有名詞不好查詢

    目前較多的方式是向量查詢,對於專有名詞非常不友好;影響了生成向量的精準度,以及大模型輸出的效果。

  4. 使用者提問的隨意性 + 大眾對RAG的定位混亂

    大部分使用者在提問時,寫下的query是較為模糊籠統的,其實際的意圖埋藏在了心裡,而沒有完整體現在query中。使得檢索出來的文字段落並不能完全命中使用者想要的內容,大模型根據這些文字段落也不能輸出合適的答案。

  5. 公域與私域知識混淆難定位

    提問:乙烯和丙烯的關係是什麼?
    

    大模型應該回答兩者都屬於有機化合物,還是根據近期產業資訊回答,兩者的價格均在上漲?

  6. 新舊版本文件同時存在

  7. 多條件約束失效

    提問:昨天《獨家新聞》統計的化學制品行業的關注度排名第幾?
    

    加上約束之後,如何讓大模型讀懂什麼叫“昨天”,又有哪段內容屬於《獨家新聞》?

  8. 全文/多文類意圖失效

    提問:近期《獨家新聞》系列文章對哪些行業關注度最高?
    

    受限於文件切割,遇到橫跨多篇文章,或全篇文章的提問,基本上涼涼了

  9. 複雜邏輯推理

    提問:近期碳酸鋰和硫酸鎳同時下跌的時候,哪個在上漲?
    

    除非原文中有顯性且密集型相關內容,大模型可能能夠直接回答正確,否則涼涼的機率極高。

    而使用者在提問這類問題時,往往是無法在某一段落中直接找到答案的,需要深層次推理。

  10. 金融行業公式計算

    提問:昨天哪些股票發生了漲停?
    

    如何讓大模型理解“漲停”意味著 (收盤價/昨日收盤價-1)≥10%

  11. 人工搜尋效率低下

    人類並不擅長在搜尋系統中輸入他們想要的東西,比如打字錯誤、模糊的查詢或有限的詞彙,這通常會導致錯過明顯的頂級搜尋結果之外的大量資訊。雖然RAG有所幫助,但它並沒有完全解決這個問題。

  12. 長下文長度

    檢索內容過多,超過視窗限制怎麼辦 ?如果 LLMs 的上下文視窗不再受限制,RAG 應該如何改進?

  13. 向量檢索的弊端

    向量檢索是基於詞向量的相似度計算

    如果查詢語句太短,比如只有一個ID、一個雜湊碼或者一個產品名稱,那麼它們的詞向量可能無法反映出它們的真實含義,也無法和其他相關的文件進行有效的匹配。這樣就會導致向量檢索的結果不準確,甚至出現一些完全不相關的內容。類似的,如果我們查詢“8XLARGE64”,“99.9%”,這樣的一些關鍵字時,向量搜尋會得出一些毫不相干的內容,以至於讓背後的大模型毫無用武之地,甚至可能被誤導

解決方案

知識庫文件預處理

在載入知識庫檔案的時候,直接上傳文件雖然能實現基礎的問答,但是,其效果並不能發揮到最佳水平。因此,我們建議開發者對知識庫檔案做出以下的預處理。 以下方式的預處理如果執行了,有機率提升模型的召回率。

  1. 使用TXT / Markdown 等格式化檔案,並按照要點排版

  2. 減少檔案中衝突的內容,分門別類存放資料

  3. 減少具有歧義的句子

  4. 減少單個檔案的大小,減少檔案中的特殊符號

  5. 結構複雜的先根據大模型以問答對的形式輸出

  6. 對文件合理分塊

    不合理的分塊會導致很多問題,過小的chunk導致上下文資訊的缺失;連貫文章因為chunk而進行拆分

  7. 資料清洗

文件智慧分塊與解析

  1. 文件版面佈局(Layout)分析

  2. 圖片的資訊抽取

  3. PDF 解析

搜尋架構、索引構建、Embedding

檢索的主要方式還是這幾種:

  • 相似度檢索:前面我已經寫過那篇文章《大模型應用中大部分人真正需要去關心的核心——Embedding》種有提到六種相似度演算法,包括歐氏距離、曼哈頓距離、餘弦等。
  • 關鍵詞檢索:這是很傳統的檢索方式,但是有時候也很重要。剛才我們說的後設資料過濾是一種,還有一種就是先把chunk做摘要,再透過關鍵詞檢索找到可能相關的chunk,增加檢索效率。據說Claude.ai也是這麼做的;
  • SQL檢索:這就更加傳統了,但是對於一些本地化的企業應用來說,SQL查詢是必不可少的一步,比如我前面提到的銷售資料,就需要先做SQL檢索。

query改造、轉換、意圖識別

  1. Query transformations:Query拆解,如果查詢很複雜,LLM 可以將其分解為多個子查詢。

  2. HyDE,生成相似的,或者更標準的prompt模板,然後去檢索文件chunk

  3. Query向量化/文件向量化前加特定的Prompt

  4. query邏輯鏈的多跳實現

  5. 增加追問機制

    這裡是透過Prompt就可以實現的功能,只要在Prompt中加入“如果無法從背景知識回答使用者的問題,則根據背景知識內容,對使用者進行追問,問題限制在3個以內”。這個機制並沒有什麼技術含量,主要依靠大模型的能力。不過大大改善了使用者體驗,使用者在多輪引導中逐步明確了自己的問題,從而能夠得到合適的答案。

  6. 歷史聊天融入成為統一的Prompt

  7. 意圖識別模組

RAG的路由 + 代理

路由其實有一點意圖識別 + 分發任務的意味,本節參考【RAG 高效應用指南 04:語義路由】,有幾種路由方式:

  • 元件路由:路由到不同的元件型別,比如將查詢傳遞給 Agent、Vector Store,或者直接傳遞給 LLM 進行處理
  • Prompt 路由:根據 question 的不同路由到不同的 prompt template

RAG路由的實現:

  • 基於大語言模型(LLM)識別使用者意圖
  • 基於傳統的 NLP 技術,訓練一個分類模型,對使用者的查詢型別進行分類
  • 根據使用者查詢與預設話術模板的相似性進行匹配
  1. LLM Prompt

    基於 LLM Prompt,就是透過 prompt 來判斷使用者的 query 屬於哪個意圖,當然,我們不可能窮舉使用者 query 的所有意圖,所以對於不在預設意圖的使用者 query,我們一般還會進行兜底處理。

響應合成Response synthesiser

這是任何 RAG 管道的最後一步 - 根據我們仔細檢索的所有上下文和初始使用者查詢生成答案。
最簡單的方法是將所有獲取的上下文(高於某個相關閾值)與查詢一起連線並立即提供給 LLM。
但是,一如既往,還有其他更復雜的選項,涉及多個 LLM 呼叫,以細化檢索到的上下文並生成更好的答案。

響應合成的主要方法是:

  1. 透過將檢索到的上下文逐塊傳送到 LLM 來迭代完善答案
  2. 將query的上下文一起丟進來以適應提示
  3. 根據不同的上下文塊生成多個答案,然後連線或總結它們

query 意圖識別+意圖補充+意圖修復 環節

  1. 意圖識別方式一:多關鍵詞/主題詞提取與檢索

大致方案羅列:

  • 基於傳統 NLP 的成分句法分析,提取名詞短語;再透過短語間的依存關係,生成關鍵詞列表

  • 從完整語句的 Embedding,切換為關鍵詞 Embedding:

    • 知識庫構建時。基於單知識點入庫,入庫時提取關鍵詞列表進行 Embedding,用於檢索。
    • 查詢時。對使用者的問題提取關鍵詞列表進行 Embedding 後,從本地知識庫命中多條記錄。
  • 將單問句中的多知識點拆解後檢索,將召回的多條記錄交付給 LLM 整合。

該方法的優勢在於:

  • 相比傳統 Embedding,大幅提升召回精準度。
  • 支援單次互動,對多知識點進行聚合處理。而不必讓使用者,手動分別查詢單個知識點,然後讓 LLM 對會話歷史中的單個知識點進行彙總。
  • 使用傳統 NLP 在專項問題處理上,相比 LLM 提供更好的精度和效能。
  • 減少了對 LLM 的互動頻次;提升了交付給 LLM 的有效資訊密度;大大提升問答系統的互動速度。
  1. 意圖識別方式二:中心化大模型做語義識別

透過 System Role 告知LLM 需要提取槽位資訊,讓 LLM透過多輪對話引導使用者給出所有槽位資訊。

  1. 意圖補充、修復、改寫

  2. 多輪對話意圖繼承能力

  3. 過長提問的總結

  4. 拒絕回覆

面對使用者提問的內容並不是目前我們預期支援的領域,我們就需要進行拒絕,並給使用者一些回覆,讓使用者不至於那麼不舒服。常見的策略一般有這些:

  • 一句寫死的回覆:“哎呀,這方面的問題我還不太懂,需要學習下”。
  • 用大模型生成,例如藉助prompt引導生成一些安撫性的回覆,“對不起,你問的[]問題,我好像還不太懂。你可以試試問問別的”。
  • 使用推薦問或者追問的策略。(你是否在找以下幾個問題XX;你描述的我好像不太懂,能再補充補充嗎)

相關文章