化“腐朽”為“神奇”:5 種 RAG 優化技術應對千奇百怪的 Query 原創 精華
編者按:您是否曾經遇到這樣的情況:明明構建了一個功能強大的 RAG 系統,但用戶卻頻繁抱怨“找不到想要的信息”或“返回的結果不夠準確”?這是許多 RAG 應用開發者面臨的共同挑戰。
這個問題不僅會導致用戶體驗下降,更可能直接影響 RAG 系統的使用率和實際價值。如果未能得到妥善解決,之前的辛苦工作恐將付之東流,甚至影響整個項目的成功。
這篇文章并非紙上談兵,而是源自作者在實際項目中的第一手經驗。文章詳細介紹了 5 種 Query Translation 技術:
a) Step-back prompting:將具體問題轉化為更寬泛的問題,以便獲取更多上下文信息。
b) HyDE (Hypothetical Document Embedding):利用 LLMs 生成文檔,然后基于這個文檔檢索相關信息。
c) Multi-query:使用 LLMs 根據原始 query 生成多個版本的 query ,以改進基于距離的相似度搜索。
d) RAG-Fusion:與 Multi-query 類似,使用 Reciprocal Rank Fusion 算法對檢索結果進行重新排序。
e) Decomposition:將復雜問題分解為多個子問題,分別檢索答案后再整合。
這些技術各有優勢,在實際應用中可能需要根據實際情況結合使用才能達到最佳效果。
作者 ?? | Thuwarakesh Murallie
編譯 ?? | 岳揚

Photo by travelnow.or.crylater[1] on Unsplash[2]
若認為用戶會每次都向 LLMs 提出完美的問題,那您就大錯特錯了。與其直接執行用戶的 query ,為何不選擇優化用戶的 query 呢?這就是所謂的 query translation 技術。
我們開發了一款應用,用戶可以通過它查詢我們公司歷史上制作過的所有文檔,其中包括PPT、項目提案、進度報告、交付文檔和其他各類文檔等。這一成果非常了不起,因為過去的許多此類嘗試都失敗了。多虧了 RAGs,這一次的效果非常好。
在項目演示階段,我們都對這款應用表現出了極大的熱情。最初,我們只針對一小部分員工進行了推廣。然而,我們觀察到的現象并未讓我們感到非常興奮。
原本以為這款應用會徹底改變大家的工作方式,但大多數用戶只是嘗試使用了幾次便不再使用了,仿佛這款應用只是孩子們的玩具項目一樣。
日志數據顯示這款應用表現良好,但我們還是與實際使用過該應用的用戶進行了交流,以便能夠確定問題所在。通過他們的反饋,我們開始思考如何通過 query translation 技術來消除 user inputs 中的歧義。
讓我們來看一個具體的例子。
有位用戶對我們提供給客戶“XYZ”的關于收購與時尚業務相關的企業的建議感興趣。他輸入的問題是:“合作伙伴 XYZ 進行了哪些與時尚業務相關的收購?(What are the fashion-related acquisitions made by XYZ partners?)”該應用程序檢索了相關用于交付的 PPT 文件,給出了一份包含十幾家公司的清單。但這份清單與用戶的期望大相徑庭,合作伙伴 XYZ 實際上已經收購了(比如)7家時裝品牌,而清單中只列出了4家。這位用戶同時也是一名測試人員(tester),他對實際收購的數量了如指掌。
難怪大家會放棄使用這款工具。幸運的是,因為采取了向全體用戶逐步推出的策略,我們還有機會挽回失去的信任。
為了解決這一問題,我們對這款應用程序采取了一系列的改進措施。其中一項重要更新就是 query translations 技術。
本文旨在概述我們使用的不同 query translation 技術,而不進行深入的技術解析。例如,這些技術可以與 few-shot prompting(譯者注:提供幾個示例輸入和輸出。) 和 chain of thoughts(譯者注:鼓勵模型在生成最終答案之前,先產生一系列的中間推理步驟。) 等提示詞技術相結合,以優化結果。但這些技術細節將留待后續文章[3]中詳細討論。
接下來,我們將逐一研究這些技術。在此之前,先來看一個簡單的 RAG 示例。
01 Basic RAG Example
RAG(Retrieval-Augmented Generation)應用都至少會有一個數據庫,通常是一個向量數據庫(vector store)和一個語言模型(language model)。RAG 的核心概念其實很簡單:在大語言模型(LLM)利用其已有知識回答用戶問題之前,它會先在數據庫中搜索相關的上下文信息,以此來生成更加精確的答案。
下圖展示了一個最基礎的 RAG 應用示例。

Basic RAG application Workflow — Image by the author.
在基礎的 RAG(檢索增強生成)應用中,與大語言模型(LLMs)的交互僅發生一次,可以是 OpenAI 的 GPT 模型[4]、Cohere 模型[5],也可以是您自行部署在本地的模型。
下面給出的代碼展示了如何實現上圖的 RAG 基礎工作流。我們將以此代碼為基礎,進一步探討本文中提到的其他技術。

在上述代碼中,我們通過一個網頁加載器(web-based loader)來獲取 Django 的官方文檔頁面,并將其內容存入 Chroma 向量數據庫中。我們可以將這一過程應用于網頁文檔、本地文本文檔、PDF文檔等不同類型的數據資源。
在此例中,我們沒有采用高級的檢索技術,而是直接將檢索器整合到了最終的RAG(檢索增強生成)流程中。后續我們將使用檢索器鏈(retriever chain)來代替單一的檢索器。 文章后續內容將著重講解如何構建檢索器鏈。
02 Step-back prompting
該技術用于確保生成的答案與上下文背景信息保持一致,不發生沖突。
Step-back prompting 與基本的 RAG 流程非常相似,但在處理用戶提出的問題時,不是直接針對用戶提出的初始問題進行查詢,而是用一個更寬泛的問題從數據庫中檢索相關文檔。
與具體問題相比,更寬泛的問題能捕捉到更多的上下文信息。 因此,大語言模型(LLMs)能夠基于這些信息為用戶提供更多有用的信息,且不會與整體上下文信息相抵觸。
當最初的 query 過于具體和詳細,但又缺乏全局視角時,這種方法往往非常有用。

Step-back prompting workflow — image by the author.
Step-back prompting 的流程是:語言模型先擴展用戶輸入的 query ,然后從向量數據庫中檢索相關文檔,以此提供必要的上下文,并回答用戶最初提出的問題。
下面是 step-back prompting 的代碼實現。請注意,我們在這里采用了不同的處理方式,與前文的基本 RAG 流程中直接傳遞檢索器的方法不同。

Step-back prompting 對于那些需要依賴更廣泛的上下文背景信息的應用場景極為有用。 通過這種方式,LLMs 能夠為相關問題提供前后一致的答案。
03 HyDE (Hypothetical Document Embedding)
給出的答案不僅僅是直接回答問題,而是包含了與問題相關的背景信息或其他相關內容,使得答案更加全面和有深度。還會提供與答案內容相關的可靠信息來源,比如學術文獻、研究報告、官方網站等,以便于驗證信息的準確性和可靠性。
HyDE(Hybrid Document Embedding)是一種近來流行且廣受歡迎的文檔檢索技術。其核心思想是利用大語言模型(LLMs)的已學習的先驗知識(prior knowledge)編寫文檔,然后使用這個文檔從向量數據庫中檢索或提取相關的上下文信息。
HyDE 特別適用于用戶使用通俗的語言描述問題,而向量數據庫中的信息卻極為專業的情況。 此外,由于 LLMs 生成的文本信息中包含了較多的關鍵詞或關鍵短語,使得檢索到的相關信息更加精準。
例如,對于“提高 Django 性能的10種方法(10 ways to improve Django's performance)”這樣的 query ,HyDE 能夠提供一個涵蓋成本考慮(cost implications)、緩存策略(caching)、數據壓縮(compression)等全方位的答案。

HyDE document retrieval process — image by the author.
下列代碼片段是上圖的代碼實現。這次,我僅提供了使用 HyDE 構建檢索器鏈(retrieval chain)的代碼片段。

04 Multi-query
該技術通過改進基于距離的相似度搜索(the distance base similarly search),從而能夠檢索到更多與用戶提出的問題相關的文檔,從而提高檢索結果的相關性和準確性。
Multi-query 技術有助于解決在基于距離的相似度搜索中可能遇到的問題。大多數向量數據庫在檢索向量化文檔(vectorized documents)時使用余弦相似度(cosine similarity)作為度量標準。只要文檔之間的相似度足夠高,這種方法一般都能表現良好。 然而,當相似度太低,以至于無法通過基于距離的相似度度量來有效地識別它們之間的關聯時,檢索過程就可能無法達到預期效果。
在 multi-query 方法中,我們要求大語言模型(LLMs)為同一 query 轉換多個版本的 query 。例如, “How to speed up Django apps” 這樣的 query 會被轉換為另一個版本的 query —— “How to improve Django-based web apps' performance?”。這些 query 合在一起共同作用,從向量數據庫中檢索出更多相關的文檔。
在將這些文檔傳遞給 RAG-LLM 生成最終回答之前,我們需要對檢索到的文檔進行去重處理。 因為多個 query 可能會檢索到相同的文檔。如果傳遞所有文檔,可能會包含重復項,超出 LLM 的 tokens 閾值,從而影響最終的回答質量。

Multi-query retrieval workflow — image by the author.
下面這個代碼片段實現了一個額外的功能,可用于去除文檔中的重復項。其余部分與其他方法保持一致。

05 RAG-Fusion
在信息檢索和生成答案的過程中,優先考慮和利用與用戶提出的問題更相關的文檔是非常重要的,因為這些文檔提供的信息更有助于生成準確和有用的答案。
RAG fusion 和 multi-query 在文檔檢索方面有諸多相似之處。我們在這里再次要求大語言模型(LLM)生成初始 query 的多個不同版本。然后,我們用這些不同版本 query 分別檢索相應的文檔,并將它們合并。
然而,在合并和去重文檔的同時,我們也會根據文檔的相關度對它們進行排序。下面是 RAG-fusion 工作流程的示意圖。

RAG-fusion workflow — image by the author.
我們不再只進行去重操作,而是使用排序系統(ranking system)對文檔進行排序。Reciprocal fusion ranking(RRF)是一種非常巧妙的文檔排序算法。
如果多個版本的 query 檢索到的同一文檔是最相關的,那么 RRF 算法就會把該文檔排在前面。 如果某個文檔只在其中一個版本的 query 中出現,且相關度較低,那么 RRF 將把該文檔排在較低的位置。 這樣,我們就能獲得更相關的信息并對其進行優先排序。

06 Decomposition
在處理復雜問題時,大語言模型(LLM)能夠將問題拆分成多個部分,然后逐步構建出答案。
有些情況下,直接給出答案并不是最佳策略。解決復雜任務的高效方法是將問題分解成多個部分,然后逐個部分地回答。
這也不僅僅是 LLMs 獨有的技巧,對嗎?
是的,我們在分解 query 的過程中試圖將初始問題拆分成多個子問題。回答這些子問題的過程中將獲得解決初始問題的線索。

Query decomposition in RAG — image by the author.
如圖所示,我們為每個子問題檢索相關文檔并分別回答。然后,我們將這些問答對(question-and-answer pairs)傳遞給 RAG-LLM 。然后,LLM 擁有了更多、更詳細的信息來解決復雜問題。

07 Final thoughts
這款應用程序從演示版本到部署于生產環境,中間經過了許多優化流程。其中不可避免的一步就是使用 query translation 技術。
我們所解決的問題在復雜程度上也各不相同。必須得考慮用戶發送不完美的 query 才是常態。檢索過程的缺陷也需要得到解決。 這些都是需要考慮的問題。
要選出哪一種 query translation 技術最佳,并沒有唯一正確的方法。在實際應用中,我們可能需要結合多種技術才能獲得理想的輸出結果。
Thanks for reading!
Hope you have enjoyed and learned new things from this blog!
Thuwarakesh Murallie
Data Science Journalist & Independent Consultant
??https://www.linkedin.com/in/thuwarakesh/??
END
??文中鏈接??
[1]??https://unsplash.com/@travelnow_or_crylater?utm_source=medium&utm_medium=referral??
[2]??https://unsplash.com/?utm_source=medium&utm_medium=referral??
[3]??https://towardsdatascience.com/advanced-retrieval-techniques-for-better-rags-c53e1b03c183??
[4]??https://platform.openai.com/docs/models??
本文經原作者授權,由 Baihai IDP 編譯。如需轉載譯文,請聯系獲取授權。
原文鏈接:

















