如何最佳化 RAG 系統的效能表現?10 條實用策略
編者按: 檢索增強生成(RAG)系統最近備受關注,ChatGPT的火爆更讓這類系統成為廣泛討論的熱點。我們今天為大家帶來的這篇文章,作者Matt Ambrogi的核心觀點是:構建一個基本可用的RAG系統非常簡單,但要使其達到實際生產可用的程度則異常困難,需要我們投入大量精力。
為此,作者詳細介紹了10種策略,包括 清洗資料、嘗試不同索引型別、最佳化分塊策略、使用 Base Prompt、使用後設資料過濾、使用查詢路由、研究重排序、使用查詢轉換、微調嵌入模型、使用 LLM 生態相關工具等,這些策略都可能不同程度地提高RAG系統的效能。
總體而言,本文對於RAG系統開發者極具參考價值,值得仔細閱讀和實踐。
作者 | Matt Ambrogi
編譯 | 嶽揚
01 快速入門指南,但只閱讀本節是不夠的
檢索增強生成(Retrieval Augmented Generation)是將使用者輸入的資訊補充到 ChatGPT 等大語言模型(LLM)中的過程,這些資訊是使用者(或系統)從其他地方檢索到的。然後,LLM 可以使用這些資訊來增強其回覆內容的生成。— Cory Zue
“Retrieval augmented generation is the process of supplementing a user’s input to a large language model (LLM) like ChatGPT with additional information that you (the system) have retrieved from somewhere else. The LLM can then use that information to augment the response that it generates.” — Cory Zue
LLM(大語言模型) 是一項了不起的發明,但容易出現一個比較嚴重的問題——它們會憑空捏造資訊。RAG 在對使用者的問題或 query 進行回答的過程中提供問題背景,從而使得 LLM 更加實用。
透過 LangChain 或 LlamaIndex 等框架的快速入門指南,任何人都可以構建一個簡單的 RAG 系統,比如僅用大約五行程式碼就能構建一個用於文件的chatbot。
但是,用這五行程式碼構建的 chatbot 效果不會很好。RAG 很容易設計系統原型,但要實際投入生產卻非常困難——也就是說,很難達到使用者滿意的程度。 這些基礎的使用方式能夠讓 RAG 的效果達到 80%,但接下來那 20%的效果,往往需要進一步實驗。 RAG 的最 佳實踐還有待完善,而且會因使用情況而異。但找出 RAG 的最 佳實踐絕對值得我們付出時間,因為 RAG 可能是使用 LLM 的最有效方式之一了。
本文將探討一些有關改進 RAG 系統質量的策略,專為那些希望縮小基本配置(能用)與可投入生產環境(可用、好用)之間效能差距的 RAG 系統開發者量身定製。 原文標題所說的“ Improve(改進)”意思是增加 RAG 系統能夠:(1)找到相關的上下文,(2)並生成相關回復的使用者查詢(query)比例。本文假設讀者已經瞭解了 RAG 的工作原理。如若沒有,建議閱讀 Cory Zue 的這篇文章 ( 《 RAG (檢索增強生成)技術詳解:揭秘基於垂直領域專有資料的Chatbots是如何實現的 》 ) 。本文還會假設讀者對用於構建這些 RAG 工具的常見框架——LangChain[1] 和 LlamaIndex[2] 有一些基本瞭解。然而,本文討論的相關內容基本上是與這些框架無關的。
我不會深入探討如何準確實施我所介紹的每種策略的細節,而是嘗試讓讀者瞭解何時以及為什麼這可能有用。考慮到該領域的發展速度之快,我不可能提供詳盡無遺或完全最新的最 佳 RAG 實踐大全。相反,本文的目標是概述一些開發者在嘗試和改進 RAG APP 時可能會考慮和嘗試的事情。
02 提高檢索增強生成系統效能的 10 種方法
2.1 清洗資料
RAG 將 LLM 的功能與我們的資料連線起來。如果資料在內容或佈局上混亂,那麼 RAG 系統就會受到影響。如果使用的資料存在衝突的或冗餘的資訊,那麼檢索系統將很難找到正確的上下文。而若比較幸運,找到了正確的上下文,LLM 所執行的生成步驟可能會不理想。比如說,假設你正在為公司的幫助文件構建一個 chatbot,但發現它的效果不佳。這時應該 首先檢查的是輸入系統的資料。topics 是否被合理地劃分?topics 是集中在一處還是分散在多處?如果你作為人類都不能輕鬆地判斷出需要查閱哪個文件才能來回答常見的 queries,那麼檢索系統也無法做到。(譯者注:"topics" 在這裡是指文件中的主要內容或討論的重點。"queries" 在這裡是指使用者可能會提出的問題或查詢。)
這個過程可以很簡單,只需手動合併同一主題的文件即可,但還可以更進一步。我見過的一種更有創意的方法,是使用 LLM 來為所有文件建立摘要。然後檢索系統可以首先在這些摘要上進行檢索,只有在必要時才深入文件細節。一些框架甚至內建了這種使用LLM建立摘要並進行搜尋的功能。
2.2 探索各種不同的索引型別
索引是 LlamaIndex 和 LangChain 的核心支柱,它也是支撐檢索系統的“擎天柱”。RAG 的通用標準方法涉及嵌入(embeddings)和相似性搜尋(similarity search)。將上下文資料分塊,然後將所有內容轉換為嵌入向量,當接收到查詢(query)時,從上下文中找到相似的片段。這種方法效果非常好,但並非適用於每種情況。如若我們遇到查詢特定內容(比如網店中的商品)的需求,對此種情況,我們可能會希望探索基於關鍵詞的搜尋。但這些技術不一定是非此即彼的, 許多應用程式都使用混合搜尋方式。 例如,可以對涉及特定內容的 query 使用基於關鍵詞的索引,但對一般客戶的支援則依賴嵌入。
2.3 嘗試不同的文件分塊方法
將上下文資料進行分塊是構建 RAG 系統的核心步驟。這些 RAG 框架將分塊過程抽象化了,讓我們不必理解該過程就可直接使用。但我們應該理解該過程,分塊(chunking)大小的確定很重要。我們應該探索對於我們的 RAG APP 來說最有效的方法。 一般來說,較小的分塊大小通常能夠提高檢索效果,但可能會導致生成的內容缺乏上下文關聯。 分塊的方法有很多,但盲目地進行分塊是行不通的。來自 PineCone 的這篇文章[3]介紹了一些可供參考的策略。我這裡有一組測試問題樣例,可透過實驗[4]來處理這個問題。用小、中、大三種分塊大小對每組問題迴圈進行了一次測試,結果發現小的分塊大小是最好的。
2.4 嘗試使用 Base Prompt
LlamaIndex 中使用Base Prompt(譯者注:是指在使用大語言模型時所提供的初始 prompt 或指令,用於引導模型生成相應的文字或回答)的一個經典案例是:
“下面是上下文資訊。請根據上下文資訊,在不考慮已有知識的情況下,回答相關查詢"。”
‘Context information is below. Given the context information and not prior knowledge, answer the query.’
我們可以使用其他 prompt 替換上面這個 prompt,甚至還可以修改 RAG,以便在上下文(context)中找不到優質的相關資訊時,允許 LLM 依賴自己的知識。可以透過修改 prompt 的方式,影響模型對於不同型別問題的接受程度和回答方式,例如,指示它以某種方式回答主觀性問題。至少,修改提示語,讓 LLM 知道它在做什麼工作,是十分有幫助的。例如:
“你是一名 customer support agent 。你的目標是,回答問題時要儘量提供準確的資訊,並且儘可能地幫助提問者解決問題。你應當保持友善,但不要過於囉嗦。下面是提供的上下文資訊。請根據上下文資訊,在不考慮已有知識的情況下,回答相關查詢。”
‘You are a customer support agent. You are designed to be as helpful as possible while providing only factual information. You should be friendly, but not overly chatty. Context information is below. Given the context information and not prior knowledge, answer the query.’
2.5 嘗試使用後設資料過濾
提高檢索效率的一個非常有效的策略是在資料塊中新增後設資料,然後利用它們來幫助處理結果。日期是一種常見的後設資料標籤,因為它可以讓我們根據時間的先後順序進行篩選[5]。想象一下,假如你正在開發一款允許使用者查詢其電子郵件歷史記錄的應用程式。這種情況下,日期最近的電子郵件很可能更相關,但從嵌入的角度來看,我們並不知道這些郵件是否與使用者的 query 最相似。這就引出了在構建 RAG 時要牢記的一個通用概念: 相似 ≠ 相關。你可以將每封電子郵件的日期附加到其後設資料中,然後在檢索過程中優先考慮日期最近的上下文。LlamaIndex 內建了一款名為 Node Post-Processors 的工具,恰好可以幫助實現這一點。
2.6 使用查詢路由
通常情況下,擁有多個索引(index)是非常有用的。當 query 進來時,就可以將其路由到相應的索引。例如,可以有一個索引處理摘要問題(summarization questions),另一個處理那些直接尋求明確答案的問題(pointed questions),還有一個索引適用於需要考慮時間因素才能得到準確答案的問題。 如果試圖針對所有這些行為最佳化一個索引,最終會影響索引在所有這些行為中的表現。 相反,你可以將 query 路由到適當的索引。另一個使用情況是將一些 query 定向到key-word based index(譯者注:可能為使用關鍵詞或關鍵短語構建的索引),正如第2.2節所討論的那樣。
構建好索引後,只需在文字中定義每個索引的用途。然後在查詢時,LLM 將選擇適當的索引。
2.7 研究重排序
重排序(Reranking)是解決相似性和相關性不一致問題的一種方法。透過重排序,檢索系統會像往常一樣獲取上下文的頂 級節點,然後根據相關性重新排序。Cohere Rereanker[6]通常用於此目的。我經常看到一些 RAG 專家 推薦使用這種策略。 無論在何種情況之下,如果你正在使用 RAG 構建系統,都應該嘗試使用 Rereanking,看看這種方法是否能改善系統。
2.8 考慮使用查詢轉換
前文已經介紹將使用者的 query 放入 base prompt 中來對 RAG 系統進行最佳化,但仍可以進一步修改:
-
重新表述(Rephrasing) :如果 RAG 系統找不到 query 的相關上下文,可以讓 LLM 重新表述 query 並重新提交。在嵌入空間中,對人類來說看似相同的兩個問題並不一定很相似。
-
HyDE:HyDE[7]這種策略,可以接收 query後,先生成假設的回覆,然後將兩者都同時用於嵌入向量(embedding)的查詢。研究顯示這種方法可以顯著提高RAG系統的效能。
-
子查詢(Sub-queries) :對複雜的 query 進行分解,往往能讓 LLM 的效果更好。可以將這一點納入 RAG 系統中,將 query 分解為多個問題。
LLamaIndex 文件涵蓋了這些型別的查詢轉換[8]。
2.9 微調嵌入模型
RAG 的標準檢索機制是基於嵌入向量的相似性,資料被分解並嵌入到索引中。當接收到 query 時,它也轉換為嵌入向量以便與索引中的嵌入向量進行比較。但是,是什麼將文字轉換為嵌入向量呢?通常是一個預訓練模型,比如OpenAI的 text-embedding-ada-002。
問題在於,預訓練模型可能無法很好地捕捉到特定領域中的相似性概念。想象一下,如果你現在需要處理法律檔案,那麼你很可能希望嵌入(embedding)能更多地根據 "智慧財產權 "或 "違約 "等特定領域的術語來判斷相似性,而不是根據 "特此 "和 "協議 "等一般術語。
可以對嵌入模型進行微調來解決這個問題。這樣做可以將檢索效能指標提升5-10%。 微調需要做一些額外的工作,但確實可以顯著提高RAG系統的檢索效能。這個過程應該比您想象的要簡單,因為LlamaIndex可以幫助您生成一個訓練集。如需瞭解更多資訊,您可以檢視 Jerry Liu 撰寫的這篇關於 LlamaIndex 如何微調嵌入模型的文章[9],或者檢視這篇介紹微調過程的文章[10]。
2.10 開始使用 LLM 生態相關開發工具
你可能已經在使用LlamaIndex或LangChain來構建RAG系統了。這兩個框架都擁有比較好用的 debugging 工具,可以讓我們定義回撥函式,檢視使用了哪些上下文,檢查檢索結果來自哪個文件,等等。
如果您發現這些框架內建的工具不夠用,也還有一個日益壯大的工具生態系統可以幫助我們深入瞭解 RAG 系統的內部執行情況。Arize AI有一個內建的工具[11],可以幫助我們探索檢索到的上下文是如何以及為什麼被檢索到的。Rivet[12]是一款提供視覺化介面的工具,可以幫助我們構建複雜的 Agent,法律科技公司 Ironclad 剛剛將其開源。新工具源源不斷地被髮布,都可以值得一試,看看哪些對你的工作流程有幫助。(譯者注:白海科技的大模型平臺IDP LM也可以幫助您零程式碼微調構建領域大模型)
03 Conclusion
構建 RAG 系統的過程可能會令人沮喪,因為讓其執行起來非常容易,但要讓其執行效果良好卻非常困難。我希望上述這些策略可以啟發一些讀者,幫助讀者儘可能彌合這一差距。 這些想法並非一勞永逸的,實踐是一個不斷試驗、嘗試和遇到錯誤的過程。 我在本文中沒有深入探討如何評估系統的效能, 評估過程目前更像是一門藝術而非科學,但建立一種可以被持續評估的系統非常重要。這是唯 一的方法來判斷正在實施的策略是否產生了作用。我之前寫過一篇關於如何評估 RAG 系統的文章[13]。如需瞭解更多資訊,您可以瞭解 LlamaIndex Evals[14]、LangChain Evals[15] 和一個非常有前景的新框架 RAGAS[15]。
Congratulations, you've made it!
Thanks for reading!
END
來自 “ ITPUB部落格 ” ,連結:https://blog.itpub.net/70018536/viewspace-3000739/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 珍惜系統盤的空間10條措施最佳化系統盤(轉)
- 如何最佳化大模型在Java環境下的效能表現大模型Java
- 最佳化J2EE + MySQL 應用系統的效能MySql
- 珍惜空間 10條措施最佳化系統盤(轉)
- Win10系統電腦開啟組策略的方法,Win10系統如何開啟組策略?Win10
- 常用效能最佳化手段及在風控系統中的應用
- 如何實現遊戲陪玩系統原始碼前端效能監控?遊戲原始碼前端
- RAG應用效能最佳化全景圖:從查詢到生成的6個關鍵階段
- RAG知識庫最佳化之Rerank應用
- win10系統最佳化驅動器怎麼用_win10如何最佳化驅動器Win10
- 12條實用 Windows 7系統小技巧Windows
- 使用Cahce實現高效能系統
- 裝置管理系統AI大模型應用RAG案例AI大模型
- HarmonyOS:應用效能最佳化實踐
- 效能最佳化的一般策略及方法
- 大型網站效能最佳化策略的疑問???網站
- Flutter 系統是如何實現ExpansionPanelList的Flutter
- RAG系統架構介紹架構
- 實施語義快取以改進 RAG 系統快取
- 智慧客服系統的坐席分配策略-我們已經實現
- 前端效能最佳化——採用高效的快取策略提供靜態資源前端快取
- 如何最佳化程式的效能
- win10系統下啟用診斷策略服務的方法Win10
- RAG應用開發實戰(01)-RAG應用框架和解析器框架
- win10系統打不開組策略如何解決Win10
- oracle大表效能最佳化Oracle
- 高效能網站效能最佳化與系統架構網站架構
- 生產系統中只讀表的實現思路
- 國民應用QQ如何實現高可用的訂閱推送系統
- 儲存系統實現-跳躍表實現索引檢索索引
- MySQL效能最佳化的最佳20+條經驗MySql
- 如何分析一條sql的效能SQL
- SAP+條碼系統軟體是如何最佳化倉庫庫存管理?
- 教你如何運用python實現學生資訊管理系統Python
- RAG應用
- 用SpringBoot實現策略模式Spring Boot模式
- Win10系統如何啟用網路發現【圖文教程】Win10
- Win10系統modern應用出現閃退如何解決Win10