- Published on
RAG 進階檢索(一):Multi-Query 與四大 Query 改寫策略
Table of Contents
你花了兩週把公司的知識庫做成 RAG 系統,Embedding 也選了最新的 text-embedding-3-small,向量資料庫也架好了。測試的時候,你問了一句:「如何提升 API 效能?」
系統很認真地回答你了。但你仔細一看,它給的三篇參考文件全部都是「API 效能概論」、「API 效能測試工具」、「API 效能監控」——清一色都是泛泛而談的概論文章。
你明明知道知識庫裡有一篇超實用的「Redis 快取實戰指南」,還有一篇「N+1 Query 效能調校」,但它們完全沒被撈出來。
為什麼?因為「快取」和「N+1 Query」這些詞,跟你的原始查詢「API 效能」在向量空間裡的距離,就是比那些直接寫著「API 效能」的概論文章遠了那麼一點點。
這就是單一查詢的致命傷:你只用了一個角度去搜尋,自然只能撈到那個角度的文件。
核心觀念:Query 端的優化
在 RAG 的世界裡,大部分人把精力花在「怎麼切 Chunk」、「怎麼選 Embedding 模型」、「怎麼做 Rerank」——這些都是在優化 Document 端(文件那一側)。
但很少人注意到,Query 端(查詢那一側)其實也有巨大的優化空間。
想像一下:你去圖書館找資料,如果你只跟館員說「我要找效能相關的書」,他大概會給你幾本教科書。但如果你說「我要找快取策略、資料庫調校、還有 CDN 加速的書」,他能幫你找到的資料就完全不同了。
Multi-Query 和 Query 改寫策略,就是在幫你把一句模糊的問題,變成多句精準的搜尋指令。
Multi-Query 擴展:一個問題,多個角度
Multi-Query 的概念非常直覺:既然一個查詢只能覆蓋一個角度,那我就用 LLM 幫我生成多個不同角度的查詢,分別去搜尋,最後再把結果合併起來。
運作流程
- 使用者輸入原始查詢:「如何提升 API 效能?」
- LLM 生成 3~5 個查詢變體:
- Q1:「API 延遲優化方法」
- Q2:「後端效能調校技巧」
- Q3:「REST API 快取策略」
- 每個查詢分別去向量資料庫檢索,各自拿回 Top K 結果
- 用 RRF(Reciprocal Rank Fusion,倒數排名融合) 把所有結果合併、去重、重新排序
圖說:Multi-Query 的核心就是「用不同角度的網去撈魚」,最後再用 RRF 把最好的魚挑出來。
為什麼用 RRF 而不是直接合併?
你可能會想:「把三次搜尋的結果直接合在一起不就好了?」
問題在於,不同查詢回來的相似度分數沒有可比性。Q1 的 Top 1 分數是 0.92,Q2 的 Top 1 分數是 0.85,這不代表 Q1 的結果比較好——可能只是 Q1 的查詢剛好跟某篇文件的用詞高度重疊而已。
RRF 的聰明之處在於:它只看排名,不看分數。一篇文件如果在 Q1 排第 2、在 Q2 排第 1、在 Q3 排第 5,那它的 RRF 分數就是:
RRF = 1/(60+2) + 1/(60+1) + 1/(60+5) = 0.0161 + 0.0164 + 0.0154 = 0.0479
(其中 k=60 是常用的平滑常數)
這樣一來,在多個查詢中都表現不錯的文件,會被自然地推到最前面。
實作提示:生成查詢變體的 Prompt
MULTI_QUERY_PROMPT = """
你是一個搜尋查詢優化助手。
請根據以下使用者問題,生成 3 個不同角度的搜尋查詢。
每個查詢應該用不同的詞彙和角度來表達同一個資訊需求。
使用者問題:{question}
請直接輸出 3 個查詢,每行一個:
"""
這個 Prompt 的關鍵是要求「不同角度」和「不同詞彙」。如果 LLM 只是把原始問題換個說法(例如「怎麼讓 API 更快」),那跟原始查詢的向量距離太近,等於白做工。
四大 Query 改寫策略
Multi-Query 只是 Query 端優化的其中一種。根據不同的場景,還有三種策略各有所長。
圖說:四種策略解決的問題不同——Multi-Query 提升召回率、HyDE 縮小語意鴻溝、Step-back 補充背景、Sub-question 拆解複雜問題。
策略一:Multi-Query(多角度改寫)
上面已經詳細介紹過了。核心價值是提升 Recall(召回率),用不同角度的查詢去覆蓋更多相關文件。
適合場景:使用者的問題比較模糊或涵蓋多個面向時。
策略二:HyDE(Hypothetical Document Embeddings,假設性文件嵌入)
HyDE 的思路非常有趣:與其直接拿使用者的短查詢去搜尋,不如先讓 LLM 生成一篇假的答案文件,然後拿這篇假答案的 Embedding 去搜尋。
為什麼這樣做有效?因為使用者的查詢通常很短(「K8s Pod 一直 CrashLoop 怎麼辦」),而知識庫裡的文件通常是長篇的技術文章。短查詢和長文件在向量空間裡的分佈本來就不同——這叫做 Query-Document 語意鴻溝。
HyDE 的做法是:讓 LLM 先生成一段「看起來像是知識庫文件」的假答案(即使內容不完全正確也沒關係),然後用這段假答案的向量去搜尋。因為假答案的「文體」和「長度」跟真正的文件更接近,所以在向量空間裡的距離會更近。
# HyDE 的核心流程
hypothetical_answer = llm.generate(f"請回答以下問題(即使不確定也請嘗試):{query}")
hyde_embedding = embed(hypothetical_answer) # 用假答案的 Embedding 去搜尋
results = vector_db.search(hyde_embedding, top_k=10)
HyDE 的風險:幻覺會帶偏搜尋方向
如果 LLM 生成的假答案嚴重偏離事實(例如把 CrashLoop 的原因歸咎於網路問題,但實際上是 OOM),那搜尋結果就會被帶到錯誤的方向。所以 HyDE 比較適合 LLM 對該領域有基本認知的場景,不適合極度冷門或專業的領域。
策略三:Step-back Prompting(退一步提問)
有些問題太具體了,直接搜尋反而找不到好的結果。
例如:「為什麼 gpt-4o 的回答速度比 gpt-4 快?」
如果你直接拿這句話去搜尋,可能只會找到一些 gpt-4o 的發布新聞。但真正能回答這個問題的文件,可能是一篇講「LLM 推理加速技術(Speculative Decoding、KV Cache 優化)」的技術深度文章——而這篇文章裡可能根本沒提到 gpt-4o 這個詞。
Step-back Prompting 的做法是:先讓 LLM 把具體問題抽象化,生成一個更高層次的查詢,然後同時用原始查詢和抽象查詢去搜尋。
原始查詢:「為什麼 gpt-4o 比 gpt-4 快?」
Step-back:「LLM 推理加速的底層技術有哪些?」
這樣就能同時撈到「gpt-4o 相關新聞」和「推理加速技術原理」兩類文件,讓 LLM 有足夠的背景知識來回答。
策略四:Sub-question Decomposition(子問題分解)
當使用者問了一個複合型問題時,單一查詢幾乎不可能同時覆蓋所有面向。
例如:「比較 React 和 Vue 在效能、學習曲線和生態系方面的差異」
這個問題至少包含三個獨立的資訊需求。Sub-question Decomposition 會讓 LLM 把它拆成:
- Q1:「React 的效能特點與 Virtual DOM 機制」
- Q2:「Vue 的效能特點與響應式系統」
- Q3:「React 和 Vue 的生態系與社群比較」
每個子問題各自檢索,最後把所有結果合併,讓 LLM 能夠全面地回答。
決策指南:什麼時候用哪種策略?
這四種策略不是互斥的,但在不同場景下各有最佳選擇:
| 場景 | 推薦策略 | 原因 |
|---|---|---|
| 模糊的開放式問題 | Multi-Query | 需要多角度覆蓋 |
| 短查詢 + 長文件知識庫 | HyDE | 縮小 Query-Document 語意鴻溝 |
| 需要背景知識的深度問題 | Step-back | 先抓原理再抓細節 |
| 複合型比較問題 | Sub-question | 拆解後各自精準命中 |
| 企業級高精度需求 | Multi-Query + Sub-question | 組合使用,最大化召回率 |
成本與延遲的現實考量
每種策略都需要額外呼叫 LLM 來生成查詢變體,這意味著:
- 延遲增加:Multi-Query 需要等 LLM 生成變體(約 0.5
1 秒),然後做 35 次檢索(可以平行化) - 成本增加:每次 Query 改寫都是一次 LLM API 呼叫,多次檢索也會增加向量資料庫的查詢成本
- 複雜度增加:需要額外的 Prompt 工程和結果融合邏輯
所以在實戰中,不是每個查詢都需要開啟 Query 擴展。常見的做法是:
- 簡單的精確查詢(例如搜尋料號、人名):直接走 Keyword Search,不需要任何改寫
- 一般的知識問答:用 Multi-Query 就夠了
- 複雜的分析型問題:用 Sub-question Decomposition
- 冷門領域的短查詢:考慮 HyDE
跟 Azure AI Search 的關係
如果你有在用 Azure AI Search(可以參考我的 Azure AI Search 系列文章),你可能會問:「Azure 的 Hybrid Search 已經同時做了 BM25 + Vector,我還需要 Multi-Query 嗎?」
答案是:看情況。
Azure 的 Hybrid Search 解決的是「同一個查詢,用兩種演算法去搜」的問題。而 Multi-Query 解決的是「同一個意圖,用多個不同查詢去搜」的問題。兩者是不同維度的優化,可以疊加使用。
但如果你的場景比較單純(例如企業內部 FAQ),Azure 的 Hybrid + Semantic Ranker 組合已經非常強大,不一定需要額外加 Multi-Query。Query 擴展策略更適合用在查詢意圖模糊、知識庫龐大且多元的場景。
小結
這篇我們聚焦在 RAG 的 Query 端優化,介紹了四種改寫策略:
- Multi-Query:用多個角度的查詢提升召回率
- HyDE:用假答案縮小 Query-Document 的語意鴻溝
- Step-back:退一步提問,補充背景脈絡
- Sub-question:拆解複雜問題,各個擊破
但把更多文件撈回來只是第一步。撈回來的文件品質參差不齊、可能有大量重複——這時候就需要 Rerank(重排序) 和 MMR(多樣性去重) 來做最後的精煉。
下一篇,我們會深入探討 Bi-Encoder vs Cross-Encoder 的根本差異,以及如何打造一條完整的 RAG Scoring Pipeline。