人工智能小白到高手:RAG通過重排(Reranking)提升信息檢索的質量
RAG(檢索增強生成)是一種很厲害的技術,能幫助企業開發更智能的 AI 應用。
這類 AI 不僅能結合實時數據,還能利用企業自己的數據,生成更自然、更有互動感的對話。
RAG 的核心思路是讓 AI 在回答問題時,不是光靠自己“想”,而是先去查找外部的、可靠的專業知識,把這些信息當作參考,讓回答更準確、更有依據。
但問題在于,AI 找到的資料是否靠譜,直接決定了它給出的答案是否可信。
所以,優化 RAG 的搜索過程非常重要,能有效提升 AI 生成內容的可靠性。
一個提升搜索質量的方法是“重新排序”,可以幫助 AI 先篩選出最相關的內容,再生成更靠譜的答案。
1. RAG 是怎么工作的?
RAG 的流程可以簡單分成兩個步驟:
- 檢索(Retrieval)– AI 先根據問題去數據庫或外部數據源里查找相關的文檔或段落,就像人在搜索引擎里輸入問題找答案一樣。
- 生成(Grounded Generation)– AI 拿到這些相關資料后,再基于它們生成答案,并在回答里附上參考來源,讓信息更可信。
RAG 如何找到最相關的文檔?
RAG 里常用的一種檢索方式叫向量檢索,它的思路是理解用戶問題的真正意思,而不是單純匹配關鍵詞。向量檢索會把問題和文檔轉換成“向量”(一種數學表示),然后在這個向量空間里計算相似度,比如用余弦相似度或者歐幾里得距離,找到最貼近問題的文檔。
不過,這種方式雖然高效,能應對超大規模的數據,但也有個缺點——因為信息被壓縮成固定長度的向量,有些重要細節可能會丟失。這就導致,檢索出來的文檔可能不總是最合適的,影響 AI 最終的回答質量。
重排(Reranking) 通過對初步檢索的結果進行二次排序,確保最相關的內容排名靠前,提升信息檢索的質量。
image-20250328194524197
2. 重排(Reranking)的作用是什么?
通過 RAG,我們對許多文本文件進行語義搜索——這些文件的數量可能從幾萬到幾百萬不等,甚至更多。
為了確保大規模快速搜索,我們通常使用向量搜索。我們將文本轉換為嵌入向量,放入向量空間中,并使用余弦相似度等相似性指標來比較這些向量與查詢向量的接近程度。
簡單來說,最開始的檢索過程通常是為了快,而不是追求完美的準確性。所以,AI 一開始找到的那批文檔可能會比較寬泛,既有高度相關的內容,也可能夾雜一些不太相關的信息。
那能不能不考慮準確性,而通過增加文檔數量,送給LLM,從而提升回答的可靠性呢?
很遺憾不行,LLMs 對我們可以傳遞給他們的文本量有一定限制——我們稱這個限制為上下文窗口。而且填滿上下文的效果,在目前(202503)性能也不是最佳,研究表明,隨著大量的 tokens 被放入上下文窗口,LLM的召回能力(LLM's recall performance )會下降,而且在太長的上下文中,LLMs也不容易遵循指令。
太長的上下文可能會導致模型難以聚焦關鍵信息,特別是在文檔位于中間時,準確率下降最明顯。這可能是因為模型在處理長上下文時,信息容易被稀釋或受到干擾。
image-20250328211333286
解決此問題的方法是通過檢索大量文檔來盡可能多的找到相關文檔,最大化檢索的召回率,然后通過減少進入LLM的文檔數量來提升LLM的響應準確度。
為此,我們會對檢索到的文檔進行重新排序,僅保留與我們的LLM最相關的文檔——這就是我們使用重排序的原因。
image-20250328212513439
通過重新排序(reranking) 后,把這些文檔按相關性重新篩選和排列,減少無關內容的干擾。
如果沒有重新排序,AI 可能得自己在一堆信息里“扒拉”出有用的內容,這不僅降低了回答的準確性和連貫性,還可能讓 AI 產生“幻覺”(也就是編造出和真實情況不符的信息)。
通過重新排序,AI 能更專注于最有用的資料,最終生成的回答也會更加精準和可靠。
還有一種情況是。
在RAG里可能會使用混合檢索來實現了多個檢索技術之間的互補。
混合檢索能夠結合不同檢索技術的優勢獲得更好的召回結果,但在不同檢索模式下的查詢結果需要進行合并和歸一化(將數據轉換為統一的標準范圍或分布,以便更好地進行比較、分析和處理),然后再一起提供給大模型。
這時候也需要對已召回的文檔結果再一次進行語義重排序,優化排序結果。
image-20250328200611481
重排序模型會計算候選文檔列表與用戶問題的語義匹配度,根據語義匹配度重新進行排序,從而改進語義排序的結果。其原理是計算用戶問題與給定的每個候選文檔之間的相關性分數,并返回按相關性從高到低排序的文檔列表。
重排序在混合檢索、單一檢索模式下,都可以有效幫助改進文檔的召回效果。
3. 重排(Reranking) 的基本流程
- 初步檢索:使用向量搜索或其他搜索獲取相關文檔。
- 重排序:按照新計算的相關性分數調整排名,確保最相關的文檔靠前。
相比向量搜索,重排(Reranking) 具有更高的計算成本,但能極大提升檢索質量,尤其適用于高精準度要求的場景,如法律、金融、醫療等專業領域。
4. 用代碼實現一個簡單的基本流程
我們要使用 openai 的嵌入模型生成文檔的嵌入向量,使用cohere的重排模型做兩階段重排。
在documents變量中保存測試使用的文檔列表
import chromadb
from openai import OpenAI
import cohere
# 設置 API Key(替換成你的)
OPENAI_API_KEY = "hk-iwtbie118cf1b4a91e427"
COHERE_API_KEY = "myRKkiGg24uQqXZfe"
co = cohere.ClientV2(COHERE_API_KEY)
# 初始化 ChromaDB(本地存儲)
chroma_client = chromadb.PersistentClient(path="./chroma_db")
collection = chroma_client.get_or_create_collection("my_documents",
metadata={"hnsw:space": "cosine"})
# 文檔數據
documents = [
# 與大語言模型高度相關的文檔
"大語言模型(LLM)是基于Transformer架構的深度學習模型,能夠理解和生成人類語言",
"ChatGPT是OpenAI開發的大語言模型,通過強化學習和人類反饋訓練,具有優秀的對話能力",
"大語言模型通過自監督學習從海量文本中學習語言規律和知識,形成強大的語義理解能力",
"大語言模型的涌現能力使其在沒有專門訓練的情況下也能完成復雜任務,如推理和編程",
"大語言模型的參數規模從數十億到數萬億不等,參數量越大通常性能越強",
# 與AI技術相關但與大語言模型關聯度較低的文檔
"人工智能技術正在各行各業引發革命性變革,提高生產效率和創新能力",
"機器學習是人工智能的核心技術,通過數據訓練算法模型來完成特定任務",
"深度學習是機器學習的一個分支,使用多層神經網絡處理復雜數據和任務",
"人工智能倫理問題日益受到關注,包括隱私保護、算法偏見和責任歸屬等方面",
"人工智能的發展經歷了從規則系統到統計學習再到深度學習的多次范式轉變",
]
doc_ids = [f"doc{i}"for i in range(1, len(documents) + 1)]
生成嵌入向量保存到向量數據庫:
# 獲取 OpenAI 嵌入向量
def get_embedding(text):
print(f"Getting embedding for : {text}")
client = OpenAI(
api_key=OPENAI_API_KEY, # 如果您沒有配置環境變量,請在此處用您的API Key進行替換
base_url="https://api.openai-hk.com/v1", # 百煉服務的base_url
)
response = client.embeddings.create(model="text-embedding-3-small", input=text)
# response = client.embeddings.create(model="text-embedding-ada-002", input=text)
# print(response)
return response.data[0].embedding
# 計算所有文檔的嵌入,并存入 ChromaDB
for doc, doc_id in zip(documents, doc_ids):
embedding = get_embedding(doc)
collection.add(
ids=[doc_id],
documents=[doc],
embeddings=[embedding]
)
print("? 嵌入數據已存入 ChromaDB")
在向量數據庫中通過余弦相似度做一階段檢索:
# 用戶查詢
query_text = "大語言模型的工作原理和技術特點"
query_embedding = get_embedding(query_text)
print(f"用戶問題:{query_text}")
# 從 ChromaDB 搜索最相似的 5 條結果
results = collection.query(
query_embeddings=[query_embedding],
n_results=5,
include=["documents", "distances"]
)
retrieved_docs = results["documents"][0] # 獲取返回的文檔列表
distances = results["distances"][0] # 獲取相似度距離
print("\n?? ChromaDB 搜索結果(未重排):")
for i, (doc, distance) in enumerate(zip(retrieved_docs, distances), 1):
similarity = 1 - distance # 將距離轉換為相似度
print(f"{i}. 相似度: {similarity:.4f} - {doc}")
?
?? ChromaDB 搜索結果(未重排):
- 相似度: 0.7058 - 大語言模型的涌現能力使其在沒有專門訓練的情況下也能完成復雜任務,如推理和編程
- 相似度: 0.7017 - 大語言模型的參數規模從數十億到數萬億不等,參數量越大通常性能越強
- 相似度: 0.6908 - 大語言模型通過自監督學習從海量文本中學習語言規律和知識,形成強大的語義理解能力
- 相似度: 0.6731 - 大語言模型(LLM)是基于Transformer架構的深度學習模型,能夠理解和生成人類語言
- 相似度: 0.5491 - ChatGPT是OpenAI開發的大語言模型,通過強化學習和人類反饋訓練,具有優秀的對話能力
通過重排模型對一階段檢索結果,做二階段重排,可以看到文檔:“大語言模型(LLM)是基于Transformer架構的深度學習模型,能夠理解和生成人類語言”
在通過排序后,與查詢的相似度是最高的,排到了第一位,其他的文檔也有了相似度的變化。
經過重新排序,LLM獲得了更加相關的信息。這自然會顯著提升 RAG 的性能。這意味著RAG在最大化相關信息的同時,盡量減少輸入到我們的LLM中的噪聲。
# 使用 Cohere Reranker 進行重排序
response = co.rerank(query=query_text, documents=retrieved_docs, model="rerank-v3.5")
reranked_results = []
reranked_scores = []
for item in response.results:
original_doc = retrieved_docs[item.index] # 使用索引獲取原始文檔
reranked_results.append(original_doc)
reranked_scores.append(item.relevance_score)
print("\n?? 經過 Reranker 重新排序的最終結果:")
for i, (doc, score) in enumerate(zip(reranked_results, reranked_scores), 1):
print(f"{i}. 相似度: {score:.4f} - {doc}")
經過 Reranker 重新排序的最終結果:
- 相似度: 0.7699 - 大語言模型(LLM)是基于Transformer架構的深度學習模型,能夠理解和生成人類語言
- 相似度: 0.6999 - 大語言模型通過自監督學習從海量文本中學習語言規律和知識,形成強大的語義理解能力
- 相似度: 0.5974 - 大語言模型的涌現能力使其在沒有專門訓練的情況下也能完成復雜任務,如推理和編程
- 相似度: 0.4884 - 大語言模型的參數規模從數十億到數萬億不等,參數量越大通常性能越強
- 相似度: 0.4183 - ChatGPT是OpenAI開發的大語言模型,通過強化學習和人類反饋訓練,具有優秀的對話能力
總結
重新排序(reranking) 通過對第一次檢索結果進行二次排序,顯著提升檢索質量,使最相關的內容排在前面。
相比傳統向量檢索,它能更準確理解查詢意圖,減少無關文檔,提高搜索、推薦系統和 RAG 任務的精準度。
雖然計算成本較高,但在高精度任務中優勢明顯。
本文轉載自??AI取經路??,作者:AI取經路
