← 回首頁

混合檢索 BM25/RRF(打分表 + 融合排名)

想在一堆文件裡找答案,就像問兩個個性不同的朋友:一個記性好、你講的字要一模一樣才找得到, 專有名詞和代碼最準,換句話說卻會傻眼;另一個很懂你的意思、能猜到你想問什麼,但常漏掉必須 一字不差的字眼。與其只信一個,不如兩個都問、再把兩份名單合成一份——這就是混合檢索 (hybrid retrieval)的想法。下面你會看到 BM25 怎麼逐詞替關鍵字打分,RRF 又怎麼只看名次、把兩路排名截長補短融成最終順序。

現代 RAG(檢索增強生成)系統很少只用單一路檢索:BM25 抓「關鍵字語意」(詞出現在多少文件裡、在單一文件 裡出現幾次,配合文件長度正規化避免長文件灌水取巧),向量檢索抓「語意相似度」(見 HNSW 等近似最近鄰索引)。兩路排序清單的分數量綱通常不可直接比較(BM25 分數 與向量餘弦相似度不是同一種尺度),因此常用 RRF(Reciprocal Rank Fusion,倒數排名融合)只看各路的 「名次」而非原始分數,依 1/(k+rank) 加總重新排序,讓兩路排序截長補短。本頁 Section 1 示範 BM25 逐詞 逐文件打分表,Section 2 示範 RRF 融合排名與三方排名對照。

為什麼 AI 時代重要

混合檢索(hybrid retrieval)是 RAG 管線的骨幹:純向量檢索容易漏掉「精確關鍵字/專有名詞/代碼」這類 字面比對比語意相似更重要的查詢,純 BM25 又抓不到同義詞與語意相近但字面不同的內容。實務系統 (Elasticsearch、OpenSearch、Weaviate 等)常見作法是 BM25 與向量檢索各自跑出一份排名,再用 RRF 這類 「只看名次、不看原始分數」的融合法合併,兼顧字面精確與語意相似兩種需求。

它是倒排索引與排序融合的延伸

BM25 建立在倒排索引之上(詞 → 含詞文件清單 + 統計量),與雜湊表「先分桶、再依統計量排序候選」同源, 也與 相似度雜湊 MinHash/LSH/SimHash 一樣仰賴「先用固定規則壓縮/分桶、再排序或比對」的手法;RRF 則是「先各自排序、再合併」的排序融合, 概念上與 MinHash 的 banding 候選對(先分桶縮小候選範圍)互補——一個是縮小候選、一個是合併多路候選。

1. BM25(倒排統計 → IDF → 逐詞逐文件打分 → 排名)

統計:對查詢詞逐一計算文件頻率 df(含詞的文件數)與逆文件頻率 IDF;本頁採 BM25+ 慣例變體 IDF = ln((N-df+0.5)/(df+0.5)+1),分式外多加的「+1」讓 IDF 對任意 0≤df≤N 恆正——查詢詞「檢索」 df=3(4 份文件裡有 3 份含詞,超過半數),教科書原始 BM25 公式 ln((N-df+0.5)/(df+0.5)) 在此會算出 負值(≈-0.847),BM25+ 變體則仍為正值(≈0.357),是 Lucene 等實務系統常見的穩定寫法,非教科書 唯一寫法,本頁誠實標示為變體而非原始定義。打分:tf=0 時分數為 0;否則 idf·(tf·(k1+1))/(tf+k1·(1-b+b·(docLen/avgdl))),k1=1.5 控制詞頻飽和速度,b=0.75 控制長度正規化 強度——文件越長於平均長度(avgdl),分母越大、分數越受懲罰。逐詞分數加總為文件總分,依分數高到低 排名(同分取索引小,tie-break)。

固定資料:4 份文件(d0 短、含查詢詞×2;d1 短;d2 長,8 個 token;d3 不含任何查詢詞),3 個查詢詞 「向量」「檢索」「排名」;k1=1.5、b=0.75。
已計算格數(scores):0 階段:stats
列=3 個查詢詞(依序:向量、檢索、排名)、欄=4 份文件(d0-d3);格值=該詞對該文件的 BM25 分數 (toFixed(4)),空白代表尚未輪到的詞×文件組合,tf=0(詞未出現)之格為 0.0000,非空白。藍色外框 (active)與粉紅(pivot)皆標示本步驟正在計算的格。
長文件正規化懲罰實例:詞「檢索」在 d1(長度3)與 d2(長度8,本頁最長文件)都恰好出現 1 次(tf=1),IDF 相同,但 d1 分數≈0.4196,d2 分數≈0.2642——同樣 tf=1,文件長度越超過平均長度 (avgdl=4.5),分母的長度正規化項越大,分數越低,這就是 BM25 抑制「長文件灌水」的機制。

df / IDF 對照表

dfIDF

總分 / 排名表

名次文件總分

已執行操作紀錄(opLog)

(空)

2. RRF(倒數排名融合 + 三方排名對照)

輸入 A 為上方 BM25 節算出的排名;輸入 B 為 VEC_RANKING——固定給定的「向量檢索排名」示意值,並非本頁 計算所得,代表現實系統中由 HNSW 等 ANN 索引另外算出的一路排名,本頁誠實標示其為外部輸入,不假裝 是本頁推導的結果。兩路排名各自轉為 1-based 名次後,逐文件算 RRF 分數 = 1/(k+rankA) + 1/(k+rankB), k=60 是 Cormack et al. (2009) 原始論文與多數實務系統(Elasticsearch、OpenSearch 等)沿用的慣例平滑 常數,本頁沿用而非自行推導,數值越小的名次(越前面)貢獻越大。依 RRF 分數由高到低重新排序即為融合 排名(同分 tie-break 與 BM25 排名共用同一套規則:索引小者優先)。

輸入 A:上方 BM25 排名(本頁算出)。輸入 B:VEC_RANKING=[2,0,3,1](固定給定,外部示意值)。k=60。
已融合文件數(fusions):0 階段:inputs
列=4 份文件(d0-d3)、欄=[BM25 名次, 向量名次, RRF 分數];名次欄於兩輸入排名宣告幀一次性填入 (兩路排名本就是已知輸入,非逐步算出),RRF 分數欄逐文件覆寫。藍色外框(active)與粉紅(pivot) 標示本步驟正在融合的列。
融合排名與兩輸入皆不同的意義:本頁資料下,BM25 排名=[0,1,2,3]、向量排名(外部給定) =[2,0,3,1]、融合排名=[0,2,1,3]——三者互不相同。融合排名把「BM25 第 3 名、向量第 1 名」的 doc2 拉到第 2 名,是兩路排名的折衷結果,而不是照抄任一路,這正是混合檢索勝過單路檢索的核心: 任一路單獨看都不是最終答案,融合後才是。

逐文件 RRF 分數

(尚未計算)

三方排名對照表(BM25 / 向量 / 融合)

名次BM25向量(外部給定)融合

已執行操作紀錄(opLog)

(空)