Rag系統的發展歷程,從樸素、高級到模塊化

1 評論 2387 瀏覽 6 收藏 30 分鐘

Rag系統它通過結合信息檢索和自然語言生成技術,顯著提高了信息處理的效率和準確性。然而,隨著應用的深入,Rag系統的局限性也逐漸顯現。本文將深入探討Rag系統的發展、存在的問題及其優化方案,希望能為相關領域的研究者和開發者提供參考和啟示。

前段時間,風叔發表了《聊聊炙手可熱的Rag:產生原因、基本原理與實施路徑》,有讀者反饋希望多講講Rag系統現存的問題和優化方案,今天風叔就來談談這個話題。

從2020年Meta AI 的研究人員提出檢索增強生成(RAG)方法,Rag系統也在不斷地優化和迭代。

總結來說,Rag的發展經歷了三個發展階段,從最初的Naive Rag(樸素Rag),再到Advance Rag(高級Rag),最后再演變為Modular Rag(模塊化Rag)。

下面,風叔詳細介紹下這三個階段的Rag系統都遇到了哪些問題,以及這些問題是如何被解決的。

一、樸素Rag

RAG發展初期,其核心框架由索引、檢索和生成構成,這種范式被稱作樸素RAG。樸素Rag的原理非常簡單,包括以下三個步驟。

  1. 索引:這一過程通常在離線狀態下進行,將原始文檔或數據進行清洗并分塊,然后將分塊后的知識通過embedding模型生成語義向量,并創建索引。
  2. 檢索:對用戶輸入的Query問題,使用相同的embedding模型,計算Query嵌入和文檔塊嵌入之間的向量相似度,然后選擇相似度最高的前N個文檔塊作為當前問題的增強上下文信息。
  3. 生成:將原始Query和相關文檔合并為新的提示,然后由大型語言模型基于提供的信息回答問題。如果有歷史對話信息,也可以合并到提示中,用于進行多輪對話。

Rag系統的發展歷程,從樸素、高級到模塊化

樸素RAG是一個非常簡單的框架,也很易于理解,但是在實際應用中自然而然地出現了以下挑戰。

  • 索引環節:在構建索引的過程中,核心關鍵詞可能被湮沒在大量的無效信息中,導致建立的索引,核心知識占的比重比較小,無效信息占的比重大,從而影響生成答案的質量。同時,內容塊的語義信息容易受分割方式影響,在較長的語境中,會出現重要信息丟失或掩蓋的問題。
  • 檢索環節:在使用用戶原始query做檢索時,由于語義的復雜性以及需要用到專業詞匯時,無法準確地理解用戶的真實需求,導致用戶query和知識索引不能很好匹配。同時,查詢Query和文檔塊之間的語義相似度并非總是高度一致,僅依靠相似度計算進行檢索,缺乏對查詢Query與文檔間關系的深度探究,導致檢索質量不高。另外,樸素rag會將所有檢索到的塊直接輸入到大模型,但是過多的冗余和噪聲信息會干擾大模型對關鍵信息的識別,增加生成錯誤。
  • 生成環節:當沒有檢索到相關知識或檢索知識質量比較差時,大模型會自主對用戶Query進行回答,導致幻覺問題產生?;蛘叱霈F回答內容空洞,無法直接使用的問題。

要解決上面的問題,需要在檢索前和檢索后做一些優化,于是就產生了高級RAG。

二、高級Rag

高級RAG相比于樸素RAG,增加了檢索前、檢索中和檢索后的優化策略,用于解決索引、檢索和生成的問題。

Rag系統的發展歷程,從樸素、高級到模塊化

下圖是更直觀的對比,可以看到相比樸素Rag,高級Rag主要優化了黑框中的三個環節。

Rag系統的發展歷程,從樸素、高級到模塊化

2.1 Pre-Retrieval 檢索前

檢索前主要有兩個事項,建立索引和處理查詢。

1)建立索引(Indexing)

在建立索引的環節,為了解決核心關鍵詞被無效信息淹沒以及內容分割受語義影響較大的問題,高級Rag引入了索引降噪、知識切分和元數據。

  • 索引降噪:是根據業務特點,去除索引數據中的無效成分,突出其核心知識,降低噪音的干擾。比如原文檔內容是“How can I download source code from github.com”,其核心內容是“download source code、github”,其他噪音可以忽略。
  • 知識切分:先訓練專門的語義理解小模型,然后把較長的文本,按照語義內聚性的分析切成小塊,解決核心知識湮沒以及語義截斷的問題。
  • 元數據:增加內容摘要、時間戳、用戶可能提出的問題等附加信息來豐富知識庫,元數據不需要被向量化。此外還可以添加諸如章節或小節的引用,文本的關鍵信息、小節標題或關鍵詞等作為元數據,有助于改進知識檢索的準確性。

2)處理查詢(Query)

在處理查詢的環節,為了解決用戶真實意圖識別不準確的問題,高級Rag引入了Query改寫的方法,但是對語義相似度的計算,仍然沿用了Embedding模型向量計算的方法。

Query改寫:Query改寫就是把用戶原始的問題轉換成適合知識庫檢索的問題,從而提高檢索的精準程度。Query改寫的方法主要有Query分解和Query擴展,Query分解是將一個問題分解為多個子問題,Query擴展則是將一個問題轉化成多種不同的問法。

2.2 Retrieval 檢索中

檢索階段的目標是召回知識庫中最相關知識,在樸素Rag中,檢索完全基于向量搜索,通過計算查詢與索引數據之間的語義相似性,從而獲取最相關的內容塊,但是存在查詢Query和文檔塊之間的語義相似度并非總是高度一致的問題。

嵌入模型微調:相比樸素Rag,高級Rag仍然沿用了使用Embedding模型計算相似度的方式,但是對嵌入模型做了微調,將嵌入模型定制為特定領域的上下文,特別是對于一些專業術語濃度比較高的場景。

2.3 Post-Retrieval 檢索后

在樸素Rag中,會將所有檢索到的塊直接輸入到大模型,導致冗余信息過載,從而干擾大模型對關鍵信息的識別。在高級Rag中,針對這一問題做了相關優化。

  • 提示壓縮:對于檢索到的內容塊,不要直接輸入大模型,而是先刪除無關內容并突出重要上下文,從而減少整體提示長度,降低冗余信息對大模型的干擾。
  • 重新排序:對于檢索到的內容塊,使用專門的排序模型,重新計算上下文的相關性得分。這些排序模型會考慮更多的特征,如查詢意圖、詞匯的多重語義、用戶的歷史行為和上下文信息等,比如Cohere模型。

盡管高級RAG有所改進,但是仍然與實際應用與需求之間存在差距。比如數據源的質量問題,“Garbage in Garbage out”,如果本身原始數據或文檔的質量就很差,最終生成的結果也不會好。

再比如對于結構化數據的處理,隨著應用場景越來越豐富,不再局限于單一的非結構化文本數據源類型,而是拓展至涵蓋諸如表格之類的半結構化數據,以及像數據庫、知識圖譜這樣的結構化數據。即便是高級Rag,也沒法有效捕捉實體之間的復雜關系和層次結構,比如分析一本書的主旨,或者分析某篇長論文的概念之間的關系。

隨著 RAG 技術的發展,客戶的期望值和需求持續演變,應用的設置也變得更為復雜。在這樣的背景下,高級Rag又進一步演變為模塊化Rag。

三、模塊化Rag

模塊化RAG并不是突然出現的,三個范式之間是繼承與發展的關系,高級RAG是模塊化RAG的一種特例形式,而樸素RAG則是高級RAG的一種特例。

所以,模塊化Rag其實仍然是一種Advance Rag,但是模塊劃分更清晰,對于系統的管理也更加直觀。如下圖所示,模塊化Rag的框架仍然和高級Rag類似,包括索引、檢索前、檢索中、檢索后和生成,同時增加了一個編排環節,一共是六大環節。

同時,對每個環節的能力做了模塊化分割,比如索引環節包括了塊優化(chunk optimization)、結構組織(structural organization),比如預檢索環節包括了查詢轉化(Query Transformation)、查詢擴展(Query Expansion)、查詢構建(Query Construction)等等。

Rag系統的發展歷程,從樸素、高級到模塊化

模塊化Rag基本上涵蓋了Rag系統的方方面面,下面風叔就圍繞模塊化Rag的每個模塊,詳細闡述每個模塊遇到的問題和解決方案。

3.1 索引

在早期的Rag中,索引環節仍然面臨著三個主要難題。首先,內容表述不完整,內容塊的語義信息受分割方式影響,致使在較長的語境中,重要信息被丟失或被掩蓋。

其次,塊相似性搜索不準確,隨著數據量增多,檢索中的噪聲增大,導致頻繁與錯誤數據匹配,使得檢索系統脆弱且不可靠。

最后,參考軌跡不明晰,檢索到的內容塊可能來自任何文檔,沒有引用痕跡,可能出現來自多個不同文檔的塊,盡管語義相似,但包含的卻是完全不同主題的內容。

針對索引環節的問題,模塊化Rag將其區分成了兩個領域,塊優化和結構組織,從而從兩個不同的方向來解決索引的問題。

1)塊優化(chunk optimizaition)

在內容分塊的時候,分塊大小對索引結果會有很大的影響。較大的塊能捕捉更多的上下文,但也會產生更多噪聲,需要更長的處理時間和更高的成本;而較小的塊噪聲更小,但可能無法完整傳達必要的上下文。

塊優化仍然維持了原有的內容分塊的處理方式,主要有三種優化方案。

  1. 滑動窗口:將文檔分割為多個滑動段落窗口,每個窗口包括多個連續的句子,前個窗口和后個窗口中存在重疊的句子,然后為每個窗口創造嵌入向量。這種方法能有效優化上下文丟失的問題,但也存在上下文大小控制不精準、單詞或句子可能被截斷等問題。
  2. 增加元數據:塊可以用元數據(比如頁碼、文件名、作者、時間戳、摘要或問題)進行豐富,讓索引更加精準。這個優化方案在高級Rag中即有使用,被繼承到了模塊化Rag中。
  3. 從小到大:將用于檢索的塊和用于合成的塊區分開,在檢索的時候用較小的塊,在合成的時候用較大的塊。

2) 結構組織

結構組織顧名思義,即改變索引的組織結構,從而提升RAG 系統對于相關數據的檢索和處理的速度和準確性。主要有以下幾種結構組織優化方式。

  • 多級索引:是指創建兩個索引,一個由文檔摘要組成,另一個由文檔塊組成,并分兩步搜索,首先通過摘要過濾掉相關文檔,然后只在這個相關組內進行搜索。這種多重索引策略使RAG系統能夠根據查詢的性質和上下文,選擇最合適的索引進行數據檢索,從而提升檢索質量和響應速度。但為了引入多重索引技術,我們還需配套加入多級路由機制,比如對于查詢“最新發表的Rag論文推薦”,RAG系統首先將其路由至論文專題的索引,然后根據時間篩選最新的Rag相關論文。
  • 知識圖譜:嵌入模型雖然簡單,但是沒法有效捕捉實體之間的復雜關系和層次結構,所以導致傳統RAG在面對復雜查詢的時候特別吃力。比如,用戶詢問“《跨越鴻溝》這本書的主旨是什么”,傳統Rag技術是肯定回答不出來的。但是知識圖譜技術可以做到,因為利用知識圖譜對數據集建立索引的時候,會做提取實體(Entity)以及實體之間的關系(Relationship),這樣就能構建一種全局性的優勢,從而提升RAG的精確度。

3.2 預檢索

在樸素Rag中,往往直接使用原始query進行檢索,可能會存在三個問題。

第一,原始query的措辭不當,尤其是涉及到很多專業詞匯時,query可能存在概念使用錯誤的問題;

第二,往往知識庫內的數據無法直接回答,需要組合知識才能找到答案;

第三,當query涉及比較多的細節時,由于檢索效率有限,大模型往往無法進行高質量的回答。

在高級Rag中,提出了Query改寫的解決思路,模塊化Rag對于這一思路做了細化,主要從三個方向進行優化,查詢擴展、查詢轉換和查詢構建。

1)查詢擴展(Query Expansion)

查詢擴展就是將單個查詢拓展為多個查詢,這樣可以豐富查詢內容,為潛在的Query內容缺失提供更多上下文,從而確保生成答案的最佳相關性。

多查詢(Multi-Query):借助提示工程通過大型語言模型來擴展查詢,將原始Query擴展成多個相似的Query,然后并行執行。

目前有一種叫Rag-fusion的有效方案,首先對用戶的原始query進行擴充,即使用 LLM 模型對用戶的初始查詢,進行改寫生成多個查詢;然后對每個生成的查詢進行基于向量的搜索,形成多路搜索召回;接著應用倒數排名融合算法,根據文檔在多個查詢中的相關性重新排列文檔,生成最終輸出。

Rag系統的發展歷程,從樸素、高級到模塊化

子查詢:通過分解和規劃復雜問題,將原始Query分解成為多個子問題。比如原始Query的問題是“請詳細且全面的介紹Rag“,這個問題就可以拆解為幾個子問題,”Rag的概念是什么?“,”為什么會產生Rag?“,”Rag的原理是怎樣的?“,”Rag有哪些使用場景“等等。

2) 查詢轉換(Query Transformation)

查詢轉換是將用戶的原始查詢轉換成一種新的查詢內容后,再進行檢索和生成,相比前面講的查詢擴展,并沒有增加查詢的數量。

  • 查詢重寫:即直接利用LLM大模型重新表述問題。在進行多輪對話時,用戶提問中的某些內容可能會指代上文中的部分信息,可以將歷史信息和用戶提問一并交給LLM大模型進行重新表述。
  • HYDE:全稱是Hypothetical Document Embeddings,用LLM生成一個“假設”答案,將其和問題一起進行檢索。HyDE的核心思想是接收用戶提問后,先讓LLM在沒有外部知識的情況下生成一個假設性的回復。然后,將這個假設性回復和原始查詢一起用于向量檢索。假設回復可能包含虛假信息,但蘊含著LLM認為相關的信息和文檔模式,有助于在知識庫中尋找類似的文檔。
  • Step-Back Prompting:如果果原始查詢太復雜或返回的信息太廣泛,我們可以選擇生成一個抽象層次更高的“退后”問題,與原始問題一起用于檢索,以增加返回結果的數量。例如,對于問題“勒布朗詹姆斯在2005年至2010年在哪些球隊?”這個問題因為有時間范圍的詳細限制,比較難直接解決,可以提出一個后退問題“勒布朗詹姆斯的職業生涯是怎么樣的?”,從這個回答的召回結果中再檢索上一個問題的答案。

3) 查詢構建(Query Construction)

和查詢擴展與查詢轉化不一樣,查詢構建主要是為了將自然語言的Query,轉化為某種特定機器或軟件能理解的語言。因為隨著大模型在各行各業的滲透,除文本數據外,諸如表格和圖形數據等越來越多的結構化數據正被融入 RAG 系統。

比如在一些ChatBI的場景下,就需要將用戶的Query內容,轉化為SQL語句,進行數據庫查詢,這就是Text-to-SQL。

再比如工業設計場景下,可能需要將用戶的Query轉化為設計指令,或者設備控制指令,這就是Text-to-Cypher。

3.3 檢索

在檢索環節,模塊化Rag主要設置了兩個優化方向,檢索器選擇和檢索器微調。

1) 檢索器選擇(RetriverSelection)

檢索器本質上是一種計算Query和內容塊相似性的算子,這種算子最原始的形態就是基于Embedding模型的向量相似性,但可以通過轉化算子的方式進行優化。

  1. 稀疏檢索器:用統計方法將查詢和文檔轉化為稀疏向量。其優勢在于處理大型數據集時效率高,只關注非零元素。但在捕捉復雜語義方面,可能不如密集向量有效
  2. 密集檢索器:使用預訓練的語言模型(PLMs)為查詢和文檔提供密集表示。盡管計算和存儲成本較高,卻能提供更復雜的語義表示

可以構建這兩種檢索器,然后通過編排模塊,在特定Query的時候采用最合適的檢索器

2)檢索器微調(RetriverFine-tune)

在上下文可能與預訓練語料庫有差異的情況下,尤其是在存在大量專有術語的高度專業化領域,需要對檢索器進行微調。

  • 監督微調:基于有標記的領域數據微調檢索模型,通常借助對比學習來實現。
  • LM 監督檢索器:與直接從數據集中構建微調數據集不同,該方法借助語言模型生成的結果作為監督信號,在RAG流程中對嵌入模型進行微調。
  • 適配器:適配器是一種輕量級的模塊,可以在不改變原始模型結構的情況下,為模型增加新功能或調整模型行為,可以更好的和下游任務相適配。

3.4 檢索后

在樸素Rag中,系統會將所有檢索到的塊直接輸入到 LLM生成回答,導致出現中間內容丟失、噪聲占比過高、上下文長度限制等問題。

高級Rag針對這個問題,提出了提示壓縮和重新排序的解決思路,模塊化Rag也同樣繼承了這類方法,并將其分成了三個模塊,重排序、壓縮和選擇。

1)重排序(Rerank)

對于檢索到的內容塊,使用專門的排序模型,重新計算上下文的相關性得分。這些排序模型會考慮更多的特征,如查詢意圖、詞匯的多重語義、用戶的歷史行為和上下文信息等,比如Cohere模型。

2) 壓縮(Compression)

對于檢索到的內容塊,不要直接輸入大模型,而是先刪除無關內容并突出重要上下文,從而減少整體提示長度,降低冗余信息對大模型的干擾。

3) 選擇(Selection)

與壓縮文檔內容不同,選擇是直接移除無關的文檔塊。通過識別并剔除輸入上下文中的冗余內容,可以精煉輸入,從而提升語言模型的推理效率。有一種有效的選擇方法叫做LLM-Critique,是在生成最終答案前,通過LLM批評機制,過濾掉相關性不高的文檔。

3.5 生成

在樸素Rag和高級Rag的生成環節,可能會出現以下問題:第一,當系統忽略了以特定格式(例如表格或列表)提取信息的指令時,輸出可能會出現格式錯誤;第二,輸出錯誤或者輸出不完整,比如對于一些比較類問題的處理往往不盡人意,以及可能出現的幻覺問題;第三,可能會輸出一些不太符合人類/社會偏好,政治不正確的回答。

對于這類問題,模塊化Rag將解決思路分成了兩個方向,生成器微調和驗證。

1) 生成器微調(Generator Fine-tune)

  • 指令微調:當大模型在特定領域缺少數據時,可以通過微調為其提供額外的知識。同時,微調可以調整模型的輸入和輸出,使大模型適應特定的數據格式和風格。
  • 強化學習:通過強化學習來讓大模型的輸出與人類偏好相契合,對最終生成的答案進行手動標注,然后借助強化學習給予反饋。
  • Prompt優化:RAG系統中的prompt應明確指出回答僅基于搜索結果,不要添加任何其他信息,避免大模型自主回答問題。

2) 驗證(Verification)

  • 知識庫驗證:通過外部知識直接對大型語言模型生成的響應進行驗證。
  • 基于模型的驗證:運用小型語言模型來驗證大型語言模型生成的響應。給定輸入問題、檢索到的知識和生成的答案,訓練一個小型語言模型來判別生成的答案是否正確反映了檢索到的知識。

3.6 編排

編排模塊,是模塊化Rag和高級Rag相比最大的不同。因為有了編排模塊,模塊化Rag就可以在關鍵節點進行決策,并依據先前的結果動態選擇后續步驟,實現處理流程的自適應。比如對于特定的Query,應該選擇哪個知識庫、選擇哪種檢索器、適配器和生成器等等。

按照功能的不同,模塊化Rag將編排環節分成了路由、調度和融合三個模塊。

1)路由(Routing)

路由的作用,是為每個Query選擇最合適的處理管道,以及依據來自模型的輸入或補充的元數據,來確定將啟用哪些模塊。比如在索引環節引入多重索引技術后,就需要使用多級路由機制,根據Query引導至最合適的父級索引。

2)調度(Scheduling)

調度模塊在模塊化 RAG 中發揮著關鍵作用,尤其是在需要相對復雜規劃和反思的場景下,何時需要遞歸、何時需要迭代、何時需要反饋、何時停止循環,都是由調度模塊來控制的。

  • 規則判斷:即提前確定好固定規則,由規則來進行調度,比如設定一個閾值,當評估分數超過閾值時,進行某一后續動作。
  • 知識圖譜判斷:從知識圖譜中提取與問題相關的信息,構建一個由邏輯上相互關聯的節點組成的推理鏈,每個節點都承載著解決問題的關鍵信息,可以分別進行信息檢索和內容生成
  • Agentic-Rag:RAG應用退化成一個Agent使用的知識工具。我們可以針對一個文檔/知識庫構建多種不同的RAG引擎,比如使用向量索引來回答事實性問題;使用摘要索引來回答總結性問題;使用知識圖譜索引來回答需要更多關聯性的問題等。

3)融合(Fusion)

隨著RAG進程的發展,已經超越了單一的線性流程,經常需要擴大檢索范圍或通過探索多條流水線來增加多樣性。融合模塊的作用不僅僅是合并答案,還要確保最終輸出內容豐富,并且能夠反映出問題的多維度特性。

LLM融合:先對每個分支的答案進行總結,提取關鍵信息,然后再將其輸入到LLM中,以確保即使在長度受限的情況下也能保留最重要的內容。

互反排名融合:將多個檢索結果的排名合并成一個統一的列表,然后用加權平均方法來提高整體的預測性能和排名精度。

四、總結

本篇文章重點介紹了Rag技術的發展歷程、每個階段面臨的短板和解決方案。Rag系統上手很容易,但是要做好,還是很不容易的。所有的理論知識,都不如大家在實際項目中去摸索和實踐。

作者:風叔,微信公眾號:風叔云

本文由@風叔 原創發布于人人都是產品經理,未經作者許可,禁止轉載。

題圖來自Unsplash,基于CC0協議。

該文觀點僅代表作者本人,人人都是產品經理平臺僅提供信息存儲空間服務。

更多精彩內容,請關注人人都是產品經理微信公眾號或下載App
評論
評論請登錄
  1. 關注公眾號“風叔云”,回復關鍵詞“rag優化方案”,獲得rag完整的問題和優化資料

    來自浙江 回復