<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Information Retrieval on KbWen Blog</title>
    <link>https://www.kbwen.com/tags/information-retrieval/</link>
    <description>Articles and notes on AI systems, machine learning, Python, data engineering, and software development.</description>
    <generator>Hugo</generator>
    <language>zh-tw</language>
    <image>
      <url>https://www.kbwen.com/images/og-default.png</url>
      <title>KbWen Blog</title>
      <link>https://www.kbwen.com/</link>
    </image>
    
    <lastBuildDate>Tue, 27 Oct 2026 14:40:00 +0800</lastBuildDate><atom:link href="https://www.kbwen.com/tags/information-retrieval/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>RAG 混合檢索的 Reciprocal Rank Fusion</title>
      <link>https://www.kbwen.com/rag-reciprocal-rank-fusion-zh/</link>
      <pubDate>Tue, 27 Oct 2026 14:40:00 +0800</pubDate><dc:creator>KbWen</dc:creator>
      <guid>https://www.kbwen.com/rag-reciprocal-rank-fusion-zh/</guid>
      <description>從官方範例看看文字搜尋和向量搜尋的結果，如何用 RRF 合併排序。</description>
      <content:encoded><![CDATA[<blockquote>
<p>計算 RRF 時，保留各份搜尋結果的名次，將每份文件的 <code>1 / (常數 + 名次)</code> 加總後再排序；原本的檢索分數不直接相加。</p>
</blockquote>
<p><a href="https://www.elastic.co/docs/reference/elasticsearch/rest-apis/reciprocal-rank-fusion">Elastic 的 Reciprocal Rank Fusion（RRF）範例</a>有五份文件，文字搜尋與向量搜尋各自回傳一份排名。RAG 的混合檢索會用 RRF 合併這樣的搜尋結果，下面用文件 ID 對照兩份名次：</p>
<table>
  <thead>
      <tr>
          <th>文件 ID</th>
          <th style="text-align: right">文字搜尋名次</th>
          <th style="text-align: right">向量搜尋名次</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>4</td>
          <td style="text-align: right">1</td>
          <td style="text-align: right">沒出現</td>
      </tr>
      <tr>
          <td>3</td>
          <td style="text-align: right">2</td>
          <td style="text-align: right">1</td>
      </tr>
      <tr>
          <td>2</td>
          <td style="text-align: right">3</td>
          <td style="text-align: right">2</td>
      </tr>
      <tr>
          <td>1</td>
          <td style="text-align: right">4</td>
          <td style="text-align: right">3</td>
      </tr>
      <tr>
          <td>5</td>
          <td style="text-align: right">沒出現</td>
          <td style="text-align: right">4</td>
      </tr>
  </tbody>
</table>
<p>文件 4 在文字搜尋排第一，向量搜尋卻沒有它。範例裡，文件 4 沒有向量欄位，因此只出現在文字結果中。文件 2 則是兩邊都找到，文字排第三、向量排第二。兩份清單是分開排序的，文字的第三名只表示前面有兩份文件；向量的第二名也只描述向量結果中的順序。先保留這兩份名次，RRF 會用名次產生新的分數。</p>
<p>表格裡的「沒出現」也需要留著。文件 4 的向量名次不能填成第五名，或是直接接在已經找到的文件後面。向量搜尋並沒有回傳它，從那份結果就拿不到它的位置。合併時能使用的資料，是表格中已經有名次的那些欄位。</p>
<h2 id="名次的加總">名次的加總</h2>
<p>RRF 對每份文件計算：</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">RRF(d) = Σ [1 / (c + rank_L(d))], L: d ∈ L
</span></span></code></pre></div><p><code>L</code> 是其中一份搜尋結果，名次從 1 起算；文件有出現在那份結果裡，才加上該項分數。這裡用 <code>c</code> 表示 RRF 的常數，Elastic API 的參數名稱是 <code>rank_constant</code>。官方範例把它設為 1，目前產品預設值則是 60。</p>
<p>套回文件 4，文字第一名提供的分數是 <code>1 / (1 + 1) = 0.5</code>。向量結果沒有文件 4，也就沒有第二筆分數，所以合併分數仍是 0.5。缺少向量不會讓文件從混合結果中消失，它還有文字搜尋找到的名次。</p>
<p>文件 2 的文字名次雖然較後面，卻有兩筆分數可以加總。文字第三名得到 <code>1 / (1 + 3)</code>，向量第二名得到 <code>1 / (1 + 2)</code>，加起來約 0.5833，比文件 4 的 0.5 高。因此文件 2 在合併後排到文件 4 前面。同份文件出現在兩邊，計算時會把兩筆分數都加進去，不需要選其中較高的那筆，也不會因為內容重複就只留第一次找到的名次。</p>
<p>不過，光是兩邊都有找到，並沒有保證一定排在前面。名次較後面的項目，代入公式後分母較大，對加總的貢獻就較小。文件 2 在這個例子裡得到的分數，來自表上的第三名與第二名；若名次改變，就得照改變後的位置重新計算。原始檢索分數沒有放進公式，只要各份清單內的順序不變，這次加總就不變。</p>
<p>再看文件 3，文字第二名加上向量第一名，得到約 0.8333。範例最後只回傳三份文件，順序是 3、2、4。</p>
<h2 id="候選範圍">候選範圍</h2>
<p>這個計算要先拿到各份搜尋結果。Elastic 用 <code>rank_window_size</code> 決定每份結果有多少候選參加 RRF，再用 <code>size</code> 決定最後回傳多少份文件。前者限制輸入清單，後者裁切合併後的清單。</p>
<p>如果各份候選結果只保留前兩名，文件 2 就只剩向量第二名，文字第三名被截掉了。計算時少了文字搜尋提供的那筆分數，合併結果也會改變。只調整最後回傳的文件數，不會補回已經截掉的名次。對照搜尋結果時，可以先看看文件在哪些輸入清單裡，再核對加總是否符合那些名次。</p>
<p>本文的數字來自 Elastic 的小範例，適合拿來核對 RRF 的計算；換成自己的文件後，哪些結果對提問有幫助，還是得搭配實際的問題與搜尋結果來看。</p>
]]></content:encoded>
    </item>
    
  </channel>
</rss>
