進階收官
Contextual Retrieval:更好的 RAG
RAG 的核心假設是「檢索到正確的 Chunk 就能給出正確的答案」。但實踐中發現了一個根本性問題:切 Chunk 的過程本身就會丟失關鍵信息。Contextual Retrieval 正是為了解決這個問題。
傳統 RAG 的核心問題
傳統 RAG 的工作流程是:把文檔切成小塊(Chunk),對每個 Chunk 做向量化,用戶提問時檢索最相似的 Chunk,然後把 Chunk 餵給 LLM 生成答案。這個流程有一個致命缺陷:
Chunk 脱離上下文後變得模糊不清
文檔被切成 Chunk 後,每個 Chunk 失去了它在原文中的位置信息。一段在原文中意義清晰的文本,單獨拿出來可能完全無法理解。
典型案例
"The company's Q2 revenue increased by 3% over the previous quarter."
哪個公司?哪一年?Q1 的基準是多少?這個增長率在行業中算好還是差?所有這些關鍵上下文,都在切 Chunk 時丟失了。向量檢索可能找到了這個 Chunk,但它本身攜帶的信息嚴重不足。
完整文檔
切成 Chunks
上下文丟失
檢索模糊
Contextual Retrieval 的核心思路
在 Embedding 前,用 LLM 給每個 Chunk 加上上下文前綴
思路非常直觀:在對 Chunk 做向量化之前,先用 LLM 閲讀整篇文檔,然後為每個 Chunk 生成一段簡短的上下文描述作為前綴。這樣每個 Chunk 在被檢索時都自帶了必要的語境信息。
BEFORE -- 裸 Chunk
"The company's Q2 revenue
increased by 3% over the
previous quarter."
誰?什麼時候?無從得知。
AFTER -- 帶上下文的 Chunk
"This chunk is from the company's
2024 Annual Report, specifically
the Financial Performance section.
The company's Q2 revenue
increased by 3% over the
previous quarter."
LLM 生成的前綴自動補充了來源、時間、章節。
三層遞進優化
LAYER 01
Contextual Embeddings
給每個 Chunk 加上下文前綴後再做向量化。前綴包含文檔標題、章節位置、關鍵實體等信息。向量檢索時,Chunk 自帶語境,語義匹配更精準。
LAYER 02
Contextual BM25
傳統的 BM25 關鍵詞檢索也加上上下文前綴。前綴中的關鍵詞(如公司名、年份)讓 BM25 能匹配到原本因缺少語境而無法命中的 Chunk。向量檢索 + BM25 雙路召回,互補盲區。
LAYER 03
Reranking
檢索後,用 Reranker 模型對候選 Chunk 重新排序。Reranker 能更精確地判斷 Chunk 與查詢的相關性,把最相關的結果排到前面。三層疊加效果最佳。
效果數據
檢索失敗率降低幅度
67% 的檢索失敗率降低意味着什麼?假設之前每 100 次檢索有 30 次找不到正確的 Chunk(失敗率 30%),優化後失敗率降到約 10%,三分之二的檢索錯誤被消除了。對於依賴 RAG 的生產系統來説,這是質的飛躍。
成本權衡
沒有免費的午餐
預處理成本增加:每個 Chunk 都需要一次額外的 LLM 調用來生成上下文前綴。對於大規模文檔庫,這個預處理成本不可忽視。
Prompt Caching 可以降低成本:同一篇文檔的不同 Chunk 共享相同的文檔級上下文。利用 Prompt Caching,可以避免重複發送整篇文檔內容。
適合高準確率場景:如果你的 RAG 系統對準確率要求極高(如法律文檔檢索、醫療知識問答、金融合規查詢),額外的預處理成本是值得的。對於容錯率高的場景(如閒聊推薦),可能不划算。
RAG 不是切 Chunk 加向量檢索就夠了,每個 Chunk 要自帶上下文。Contextual Retrieval 的核心洞察:檢索的質素瓶頸在 Chunk 本身的信息完整性,換更強的向量模型幫助有限。給 Chunk 補上丟失的語境,檢索失敗率可以降低三分之二。