<?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/"><channel><title>Retrieval on Tarragon</title><link>https://tarrragon.github.io/blog/tags/retrieval/</link><description>Recent content in Retrieval on Tarragon</description><generator>Hugo -- gohugo.io</generator><language>zh-TW</language><copyright>Tarragon (CC BY 4.0)</copyright><lastBuildDate>Thu, 14 May 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://tarrragon.github.io/blog/tags/retrieval/index.xml" rel="self" type="application/rss+xml"/><item><title>Adaptive Retrieval</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/adaptive-retrieval/</link><pubDate>Thu, 14 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/adaptive-retrieval/</guid><description>&lt;p>Adaptive retrieval 的核心概念是「&lt;strong>先判斷問題是否需要 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/rag/" data-link-title="RAG" data-link-desc="Retrieval-Augmented Generation：動態外掛知識給 LLM、繞開模型參數記憶的靜態限制">RAG&lt;/a> 外部檢索，再決定要不要 retrieve&lt;/strong>」。它避免每個 query 都塞入外部 chunk，降低 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/retrieval-cost/" data-link-title="Retrieval Cost" data-link-desc="RAG 檢索帶來的 latency、token、embedding、reranker、LLM call 與維護成本，用來判斷增強是否划算">retrieval cost&lt;/a>，也減少無關內容干擾模型。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>Adaptive retrieval 位在 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/rag/" data-link-title="RAG" data-link-desc="Retrieval-Augmented Generation：動態外掛知識給 LLM、繞開模型參數記憶的靜態限制">RAG&lt;/a> 的控制流端。它跟 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/query-rewriting/" data-link-title="Query Rewriting" data-link-desc="在 RAG 檢索前改寫使用者查詢，讓 query 更接近文件語言與索引分佈">query rewriting&lt;/a> 不同：rewriting 假設要 retrieve，只改查詢形狀；adaptive retrieval 先決定 retrieve 是否必要。&lt;/p>
&lt;h2 id="可觀察訊號與例子">可觀察訊號與例子&lt;/h2>
&lt;p>「2+2 等於多少」不需要 retrieve；「公司退款政策第 4 條怎麼說」需要 retrieve。若使用者 query 一半是聊天、一半是 factual lookup，adaptive retrieval 可以明顯降低 retrieval cost。&lt;/p>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>判斷器可以是規則、小模型、主模型 self-report 或 confidence signal。風險是模型過度自信而跳過檢索；高風險事實問答應偏向 retrieve 或提供 fallback。&lt;/p></description><content:encoded><![CDATA[<p>Adaptive retrieval 的核心概念是「<strong>先判斷問題是否需要 <a href="/blog/llm/knowledge-cards/rag/" data-link-title="RAG" data-link-desc="Retrieval-Augmented Generation：動態外掛知識給 LLM、繞開模型參數記憶的靜態限制">RAG</a> 外部檢索，再決定要不要 retrieve</strong>」。它避免每個 query 都塞入外部 chunk，降低 <a href="/blog/llm/knowledge-cards/retrieval-cost/" data-link-title="Retrieval Cost" data-link-desc="RAG 檢索帶來的 latency、token、embedding、reranker、LLM call 與維護成本，用來判斷增強是否划算">retrieval cost</a>，也減少無關內容干擾模型。</p>
<h2 id="概念位置">概念位置</h2>
<p>Adaptive retrieval 位在 <a href="/blog/llm/knowledge-cards/rag/" data-link-title="RAG" data-link-desc="Retrieval-Augmented Generation：動態外掛知識給 LLM、繞開模型參數記憶的靜態限制">RAG</a> 的控制流端。它跟 <a href="/blog/llm/knowledge-cards/query-rewriting/" data-link-title="Query Rewriting" data-link-desc="在 RAG 檢索前改寫使用者查詢，讓 query 更接近文件語言與索引分佈">query rewriting</a> 不同：rewriting 假設要 retrieve，只改查詢形狀；adaptive retrieval 先決定 retrieve 是否必要。</p>
<h2 id="可觀察訊號與例子">可觀察訊號與例子</h2>
<p>「2+2 等於多少」不需要 retrieve；「公司退款政策第 4 條怎麼說」需要 retrieve。若使用者 query 一半是聊天、一半是 factual lookup，adaptive retrieval 可以明顯降低 retrieval cost。</p>
<h2 id="設計責任">設計責任</h2>
<p>判斷器可以是規則、小模型、主模型 self-report 或 confidence signal。風險是模型過度自信而跳過檢索；高風險事實問答應偏向 retrieve 或提供 fallback。</p>
]]></content:encoded></item><item><title>Context Packing</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/context-packing/</link><pubDate>Thu, 14 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/context-packing/</guid><description>&lt;p>Context packing 的核心概念是「&lt;strong>retrieve 拿到候選 chunks 後，決定哪些內容、以什麼順序、帶哪些 metadata 塞進 prompt&lt;/strong>」。它是 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/rag/" data-link-title="RAG" data-link-desc="Retrieval-Augmented Generation：動態外掛知識給 LLM、繞開模型參數記憶的靜態限制">RAG&lt;/a> 在 retrieval 與 generation 之間的 context 組裝層，有別於 retrieval 本身。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>Context packing 位在 top-k retrieval 結果與 LLM prompt 之間。它跟 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/retrieval-source/" data-link-title="Retrieval Source" data-link-desc="RAG 從哪個 corpus、index、tool 或外部系統取回內容，決定來源可信度、freshness、權限與引用責任">retrieval source&lt;/a> 相鄰，因為來源 metadata 會影響引用；也跟 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/lost-in-the-middle/" data-link-title="Lost in the Middle" data-link-desc="LLM 對 long context 中段內容的 attention / recall 顯著低於開頭與結尾的現象">lost-in-the-middle&lt;/a> 相鄰，因為 chunk 順序會影響模型注意力。&lt;/p>
&lt;h2 id="可觀察訊號與例子">可觀察訊號與例子&lt;/h2>
&lt;p>常見 packing 決策包含 dedup 重複 chunk、把最相關內容放前後、按 document order 保留段落流、摘要或壓縮過長 chunks、在每段前加 source path 與 score。這些決策會改變答案品質、token cost 與可追溯性。&lt;/p>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>設計 context packing 時要回答：哪些 chunk 真的要進 prompt、順序如何安排、是否保留來源、是否需要 summarization / compression。高追溯場景優先保留 source metadata；長 context 場景要避免把重要 chunk 放在中間；latency 敏感場景要限制 top-k 與 compression call。&lt;/p></description><content:encoded><![CDATA[<p>Context packing 的核心概念是「<strong>retrieve 拿到候選 chunks 後，決定哪些內容、以什麼順序、帶哪些 metadata 塞進 prompt</strong>」。它是 <a href="/blog/llm/knowledge-cards/rag/" data-link-title="RAG" data-link-desc="Retrieval-Augmented Generation：動態外掛知識給 LLM、繞開模型參數記憶的靜態限制">RAG</a> 在 retrieval 與 generation 之間的 context 組裝層，有別於 retrieval 本身。</p>
<h2 id="概念位置">概念位置</h2>
<p>Context packing 位在 top-k retrieval 結果與 LLM prompt 之間。它跟 <a href="/blog/llm/knowledge-cards/retrieval-source/" data-link-title="Retrieval Source" data-link-desc="RAG 從哪個 corpus、index、tool 或外部系統取回內容，決定來源可信度、freshness、權限與引用責任">retrieval source</a> 相鄰，因為來源 metadata 會影響引用；也跟 <a href="/blog/llm/knowledge-cards/lost-in-the-middle/" data-link-title="Lost in the Middle" data-link-desc="LLM 對 long context 中段內容的 attention / recall 顯著低於開頭與結尾的現象">lost-in-the-middle</a> 相鄰，因為 chunk 順序會影響模型注意力。</p>
<h2 id="可觀察訊號與例子">可觀察訊號與例子</h2>
<p>常見 packing 決策包含 dedup 重複 chunk、把最相關內容放前後、按 document order 保留段落流、摘要或壓縮過長 chunks、在每段前加 source path 與 score。這些決策會改變答案品質、token cost 與可追溯性。</p>
<h2 id="設計責任">設計責任</h2>
<p>設計 context packing 時要回答：哪些 chunk 真的要進 prompt、順序如何安排、是否保留來源、是否需要 summarization / compression。高追溯場景優先保留 source metadata；長 context 場景要避免把重要 chunk 放在中間；latency 敏感場景要限制 top-k 與 compression call。</p>
]]></content:encoded></item><item><title>HyDE（Hypothetical Document Embeddings）</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/hyde/</link><pubDate>Thu, 14 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/hyde/</guid><description>&lt;p>HyDE（Hypothetical Document Embeddings、Gao et al. 2022）是 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/rag/" data-link-title="RAG" data-link-desc="Retrieval-Augmented Generation：動態外掛知識給 LLM、繞開模型參數記憶的靜態限制">RAG&lt;/a> retrieval 階段的 query 端增強技術。核心觀察：&lt;strong>query 跟 document 在 embedding 空間的距離往往比 document 跟 document 之間更遠&lt;/strong>——這是典型 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/query-document-gap/" data-link-title="Query-Document Gap" data-link-desc="使用者 query 與文件語言在詞彙、形態、抽象層級或領域分佈上的落差，是 RAG retrieval miss 的常見原因">query-document gap&lt;/a>。HyDE 的做法是先用 LLM 對 query 生成「假設的答案文件」、對假文件做 embedding 拿去 retrieve、而不是直接 embed 原 query。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>HyDE 三步：&lt;/p>





&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-text" data-lang="text">&lt;span class="line">&lt;span class="ln"> 1&lt;/span>&lt;span class="cl">User query
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 2&lt;/span>&lt;span class="cl"> ↓
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 3&lt;/span>&lt;span class="cl">[Step 1] LLM 生成 hypothetical document
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 4&lt;/span>&lt;span class="cl"> (可能 hallucinate、事實正確性不重要)
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 5&lt;/span>&lt;span class="cl"> ↓
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 6&lt;/span>&lt;span class="cl">[Step 2] Embed 假文件
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 7&lt;/span>&lt;span class="cl"> ↓
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 8&lt;/span>&lt;span class="cl">[Step 3] 用假文件 embedding 去 vector DB retrieve 真文件
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 9&lt;/span>&lt;span class="cl"> ↓
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">10&lt;/span>&lt;span class="cl">真實 top-k chunks → 主 LLM 回答&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>為什麼比直接 embed query 好：假文件的 phrasing、長度、結構都更接近真文件的分佈、embedding 距離更可靠。重點是&lt;strong>假文件當 embedding 的代理&lt;/strong>、不是當答案——hallucinate 出錯誤事實 OK、但語意 / 領域要落對。&lt;/p>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>讀 RAG paper 或工具看到「HyDE」「hypothetical document」「query-side augmentation」就是這個機制。實作判讀：&lt;/p>
&lt;ol>
&lt;li>&lt;strong>適用 phrasing 落差顯著的場景&lt;/strong>：問句 vs 陳述、口語 vs 正式、抽象 vs 技術詞彙。HyDE 原論文跨多領域都有提升、不限技術 / 學術。&lt;/li>
&lt;li>&lt;strong>失效在假文件偏離主題&lt;/strong>：LLM hallucinate 到別領域、retrieve 拿到完全不相關的東西。緩解：生成多個假文件取平均 embedding、或用 query + 假文件兩個 embedding 合併 retrieve。&lt;/li>
&lt;li>&lt;strong>Cost&lt;/strong>：每 query 多一個 LLM call（生假文件）、latency 加 500ms-1s，屬於明顯的 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/retrieval-cost/" data-link-title="Retrieval Cost" data-link-desc="RAG 檢索帶來的 latency、token、embedding、reranker、LLM call 與維護成本，用來判斷增強是否划算">retrieval cost&lt;/a>。對 latency 敏感場景考慮 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/query-rewriting/" data-link-title="Query Rewriting" data-link-desc="在 RAG 檢索前改寫使用者查詢，讓 query 更接近文件語言與索引分佈">query rewriting&lt;/a> 等較輕量的替代。&lt;/li>
&lt;li>&lt;strong>跟 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/hybrid-search/" data-link-title="Hybrid Search" data-link-desc="把字面 retrieval（BM25）跟語意 retrieval（embedding）的結果用 RRF 等方法合併、補單一路線的盲點">hybrid search&lt;/a> 互補&lt;/strong>：HyDE 解語意 phrasing 落差、hybrid 解語意 / 字面互補、可以同時用。&lt;/li>
&lt;/ol>
&lt;p>完整 RAG 檢索增強技術 landscape 見 &lt;a href="https://tarrragon.github.io/blog/llm/04-applications/rag-retrieval-enhancements/" data-link-title="4.2 RAG 檢索增強：query rewriting / HyDE / multi-step / context packing" data-link-desc="Query 端增強（rewriting / expansion / HyDE）、multi-step iterative retrieval、retrieve 後的 context packing（dedup / ordering / summarization）、adaptive retrieval：vanilla RAG 不夠時的下一層工具箱">4.2 RAG 檢索增強&lt;/a>。&lt;/p></description><content:encoded><![CDATA[<p>HyDE（Hypothetical Document Embeddings、Gao et al. 2022）是 <a href="/blog/llm/knowledge-cards/rag/" data-link-title="RAG" data-link-desc="Retrieval-Augmented Generation：動態外掛知識給 LLM、繞開模型參數記憶的靜態限制">RAG</a> retrieval 階段的 query 端增強技術。核心觀察：<strong>query 跟 document 在 embedding 空間的距離往往比 document 跟 document 之間更遠</strong>——這是典型 <a href="/blog/llm/knowledge-cards/query-document-gap/" data-link-title="Query-Document Gap" data-link-desc="使用者 query 與文件語言在詞彙、形態、抽象層級或領域分佈上的落差，是 RAG retrieval miss 的常見原因">query-document gap</a>。HyDE 的做法是先用 LLM 對 query 生成「假設的答案文件」、對假文件做 embedding 拿去 retrieve、而不是直接 embed 原 query。</p>
<h2 id="概念位置">概念位置</h2>
<p>HyDE 三步：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="ln"> 1</span><span class="cl">User query
</span></span><span class="line"><span class="ln"> 2</span><span class="cl">   ↓
</span></span><span class="line"><span class="ln"> 3</span><span class="cl">[Step 1] LLM 生成 hypothetical document
</span></span><span class="line"><span class="ln"> 4</span><span class="cl">         (可能 hallucinate、事實正確性不重要)
</span></span><span class="line"><span class="ln"> 5</span><span class="cl">   ↓
</span></span><span class="line"><span class="ln"> 6</span><span class="cl">[Step 2] Embed 假文件
</span></span><span class="line"><span class="ln"> 7</span><span class="cl">   ↓
</span></span><span class="line"><span class="ln"> 8</span><span class="cl">[Step 3] 用假文件 embedding 去 vector DB retrieve 真文件
</span></span><span class="line"><span class="ln"> 9</span><span class="cl">   ↓
</span></span><span class="line"><span class="ln">10</span><span class="cl">真實 top-k chunks → 主 LLM 回答</span></span></code></pre></div><p>為什麼比直接 embed query 好：假文件的 phrasing、長度、結構都更接近真文件的分佈、embedding 距離更可靠。重點是<strong>假文件當 embedding 的代理</strong>、不是當答案——hallucinate 出錯誤事實 OK、但語意 / 領域要落對。</p>
<h2 id="設計責任">設計責任</h2>
<p>讀 RAG paper 或工具看到「HyDE」「hypothetical document」「query-side augmentation」就是這個機制。實作判讀：</p>
<ol>
<li><strong>適用 phrasing 落差顯著的場景</strong>：問句 vs 陳述、口語 vs 正式、抽象 vs 技術詞彙。HyDE 原論文跨多領域都有提升、不限技術 / 學術。</li>
<li><strong>失效在假文件偏離主題</strong>：LLM hallucinate 到別領域、retrieve 拿到完全不相關的東西。緩解：生成多個假文件取平均 embedding、或用 query + 假文件兩個 embedding 合併 retrieve。</li>
<li><strong>Cost</strong>：每 query 多一個 LLM call（生假文件）、latency 加 500ms-1s，屬於明顯的 <a href="/blog/llm/knowledge-cards/retrieval-cost/" data-link-title="Retrieval Cost" data-link-desc="RAG 檢索帶來的 latency、token、embedding、reranker、LLM call 與維護成本，用來判斷增強是否划算">retrieval cost</a>。對 latency 敏感場景考慮 <a href="/blog/llm/knowledge-cards/query-rewriting/" data-link-title="Query Rewriting" data-link-desc="在 RAG 檢索前改寫使用者查詢，讓 query 更接近文件語言與索引分佈">query rewriting</a> 等較輕量的替代。</li>
<li><strong>跟 <a href="/blog/llm/knowledge-cards/hybrid-search/" data-link-title="Hybrid Search" data-link-desc="把字面 retrieval（BM25）跟語意 retrieval（embedding）的結果用 RRF 等方法合併、補單一路線的盲點">hybrid search</a> 互補</strong>：HyDE 解語意 phrasing 落差、hybrid 解語意 / 字面互補、可以同時用。</li>
</ol>
<p>完整 RAG 檢索增強技術 landscape 見 <a href="/blog/llm/04-applications/rag-retrieval-enhancements/" data-link-title="4.2 RAG 檢索增強：query rewriting / HyDE / multi-step / context packing" data-link-desc="Query 端增強（rewriting / expansion / HyDE）、multi-step iterative retrieval、retrieve 後的 context packing（dedup / ordering / summarization）、adaptive retrieval：vanilla RAG 不夠時的下一層工具箱">4.2 RAG 檢索增強</a>。</p>
]]></content:encoded></item><item><title>Multi-Step Retrieval</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/multi-step-retrieval/</link><pubDate>Thu, 14 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/multi-step-retrieval/</guid><description>&lt;p>Multi-step retrieval 的核心概念是「&lt;strong>讓 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/rag/" data-link-title="RAG" data-link-desc="Retrieval-Augmented Generation：動態外掛知識給 LLM、繞開模型參數記憶的靜態限制">RAG&lt;/a> retrieval 變成多輪控制流，而不是一次性取 top-k&lt;/strong>」。模型先讀第一輪檢索結果，判斷資訊是否足夠，再決定下一個 sub-query。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>它是 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/rag/" data-link-title="RAG" data-link-desc="Retrieval-Augmented Generation：動態外掛知識給 LLM、繞開模型參數記憶的靜態限制">RAG&lt;/a> 與 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/agent-loop/" data-link-title="Agent Loop" data-link-desc="LLM agent 自我循環的工作流：LLM 規劃下一步、執行 tool、看結果、再規劃下一步、直到任務完成或停止條件觸發">agent loop&lt;/a> 的交界：控制流比 vanilla RAG 複雜，但目標仍是補齊回答所需 context，而不是任意行動。&lt;/p>
&lt;h2 id="可觀察訊號與例子">可觀察訊號與例子&lt;/h2>
&lt;p>多 hop 問題常需要 multi-step retrieval：先查 A 的屬性，再用該屬性查 B，最後比較。單次 retrieve 可能只抓到其中一邊，導致回答缺關鍵證據。&lt;/p>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>Multi-step retrieval 只有在問題確實需要多 hop、latency budget 允許、且有停止條件時才划算。沒有 stop condition 時容易無限 retrieve；沒有資訊足夠性判斷時容易提高 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/retrieval-cost/" data-link-title="Retrieval Cost" data-link-desc="RAG 檢索帶來的 latency、token、embedding、reranker、LLM call 與維護成本，用來判斷增強是否划算">retrieval cost&lt;/a> 卻沒提升。&lt;/p></description><content:encoded><![CDATA[<p>Multi-step retrieval 的核心概念是「<strong>讓 <a href="/blog/llm/knowledge-cards/rag/" data-link-title="RAG" data-link-desc="Retrieval-Augmented Generation：動態外掛知識給 LLM、繞開模型參數記憶的靜態限制">RAG</a> retrieval 變成多輪控制流，而不是一次性取 top-k</strong>」。模型先讀第一輪檢索結果，判斷資訊是否足夠，再決定下一個 sub-query。</p>
<h2 id="概念位置">概念位置</h2>
<p>它是 <a href="/blog/llm/knowledge-cards/rag/" data-link-title="RAG" data-link-desc="Retrieval-Augmented Generation：動態外掛知識給 LLM、繞開模型參數記憶的靜態限制">RAG</a> 與 <a href="/blog/llm/knowledge-cards/agent-loop/" data-link-title="Agent Loop" data-link-desc="LLM agent 自我循環的工作流：LLM 規劃下一步、執行 tool、看結果、再規劃下一步、直到任務完成或停止條件觸發">agent loop</a> 的交界：控制流比 vanilla RAG 複雜，但目標仍是補齊回答所需 context，而不是任意行動。</p>
<h2 id="可觀察訊號與例子">可觀察訊號與例子</h2>
<p>多 hop 問題常需要 multi-step retrieval：先查 A 的屬性，再用該屬性查 B，最後比較。單次 retrieve 可能只抓到其中一邊，導致回答缺關鍵證據。</p>
<h2 id="設計責任">設計責任</h2>
<p>Multi-step retrieval 只有在問題確實需要多 hop、latency budget 允許、且有停止條件時才划算。沒有 stop condition 時容易無限 retrieve；沒有資訊足夠性判斷時容易提高 <a href="/blog/llm/knowledge-cards/retrieval-cost/" data-link-title="Retrieval Cost" data-link-desc="RAG 檢索帶來的 latency、token、embedding、reranker、LLM call 與維護成本，用來判斷增強是否划算">retrieval cost</a> 卻沒提升。</p>
]]></content:encoded></item><item><title>Query Decomposition</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/query-decomposition/</link><pubDate>Thu, 14 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/query-decomposition/</guid><description>&lt;p>Query decomposition 的核心概念是「&lt;strong>把一個複合問題拆成多個可獨立 retrieve 的子問題&lt;/strong>」。它處理的是單一 query 同時要求比較、列舉、跨 entity 查證或多維度分析時，單次 retrieval 容易只命中其中一部分的問題。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>Query decomposition 位在 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/rag/" data-link-title="RAG" data-link-desc="Retrieval-Augmented Generation：動態外掛知識給 LLM、繞開模型參數記憶的靜態限制">RAG&lt;/a> 的 query 端，跟 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/multi-step-retrieval/" data-link-title="Multi-Step Retrieval" data-link-desc="RAG 中多輪 retrieve → 判斷 → 再 retrieve 的控制流，用來處理 multi-hop 問題">multi-step retrieval&lt;/a> 相鄰但不相同。Decomposition 是先拆好 N 個子 query 平行 retrieve；multi-step retrieval 是 retrieve 後讀結果，再決定下一步要查什麼。&lt;/p>
&lt;h2 id="可觀察訊號與例子">可觀察訊號與例子&lt;/h2>
&lt;p>「比較 A 與 B 在安全性和成本上的差異」可以拆成「A 的安全性」「B 的安全性」「A 的成本」「B 的成本」。每個子 query 都能獨立命中文件，最後再合成比較表。&lt;/p>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>Query decomposition 適合子問題彼此獨立的複合問題。若後一個子 query 需要前一輪結果才能產生，改用 multi-step retrieval；若拆解後子 query 過多，要回到 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/retrieval-cost/" data-link-title="Retrieval Cost" data-link-desc="RAG 檢索帶來的 latency、token、embedding、reranker、LLM call 與維護成本，用來判斷增強是否划算">retrieval cost&lt;/a> 與 latency budget 評估。&lt;/p></description><content:encoded><![CDATA[<p>Query decomposition 的核心概念是「<strong>把一個複合問題拆成多個可獨立 retrieve 的子問題</strong>」。它處理的是單一 query 同時要求比較、列舉、跨 entity 查證或多維度分析時，單次 retrieval 容易只命中其中一部分的問題。</p>
<h2 id="概念位置">概念位置</h2>
<p>Query decomposition 位在 <a href="/blog/llm/knowledge-cards/rag/" data-link-title="RAG" data-link-desc="Retrieval-Augmented Generation：動態外掛知識給 LLM、繞開模型參數記憶的靜態限制">RAG</a> 的 query 端，跟 <a href="/blog/llm/knowledge-cards/multi-step-retrieval/" data-link-title="Multi-Step Retrieval" data-link-desc="RAG 中多輪 retrieve → 判斷 → 再 retrieve 的控制流，用來處理 multi-hop 問題">multi-step retrieval</a> 相鄰但不相同。Decomposition 是先拆好 N 個子 query 平行 retrieve；multi-step retrieval 是 retrieve 後讀結果，再決定下一步要查什麼。</p>
<h2 id="可觀察訊號與例子">可觀察訊號與例子</h2>
<p>「比較 A 與 B 在安全性和成本上的差異」可以拆成「A 的安全性」「B 的安全性」「A 的成本」「B 的成本」。每個子 query 都能獨立命中文件，最後再合成比較表。</p>
<h2 id="設計責任">設計責任</h2>
<p>Query decomposition 適合子問題彼此獨立的複合問題。若後一個子 query 需要前一輪結果才能產生，改用 multi-step retrieval；若拆解後子 query 過多，要回到 <a href="/blog/llm/knowledge-cards/retrieval-cost/" data-link-title="Retrieval Cost" data-link-desc="RAG 檢索帶來的 latency、token、embedding、reranker、LLM call 與維護成本，用來判斷增強是否划算">retrieval cost</a> 與 latency budget 評估。</p>
]]></content:encoded></item><item><title>Query Expansion</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/query-expansion/</link><pubDate>Thu, 14 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/query-expansion/</guid><description>&lt;p>Query expansion 的核心概念是「&lt;strong>把一個使用者 query 擴成多個檢索變體，再把多路 retrieval 結果合併&lt;/strong>」。它處理的是 query 太短、有歧義、或只覆蓋單一表述角度時的 recall 問題，跟 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/query-rewriting/" data-link-title="Query Rewriting" data-link-desc="在 RAG 檢索前改寫使用者查詢，讓 query 更接近文件語言與索引分佈">query rewriting&lt;/a> 的單一路徑改寫不同。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>Query expansion 位在 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/rag/" data-link-title="RAG" data-link-desc="Retrieval-Augmented Generation：動態外掛知識給 LLM、繞開模型參數記憶的靜態限制">RAG&lt;/a> 的 query 端增強層。它會提高 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/retrieval-cost/" data-link-title="Retrieval Cost" data-link-desc="RAG 檢索帶來的 latency、token、embedding、reranker、LLM call 與維護成本，用來判斷增強是否划算">retrieval cost&lt;/a>，因為每個變體都要 retrieve；它也常跟 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/hybrid-search/" data-link-title="Hybrid Search" data-link-desc="把字面 retrieval（BM25）跟語意 retrieval（embedding）的結果用 RRF 等方法合併、補單一路線的盲點">hybrid search&lt;/a> 的 RRF 合併思路相鄰，用排名融合降低單一 query 變體失誤。&lt;/p>
&lt;h2 id="可觀察訊號與例子">可觀察訊號與例子&lt;/h2>
&lt;p>使用者問「python deploy」時，系統可能擴成「Python application deployment」「Docker deploy Python service」「CI/CD for Python backend」。這能增加 coverage，但也可能把不同意圖混在一起。&lt;/p>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>Query expansion 適合短 query、歧義 query、或同一問題有多種常見說法的場景。設計時要限制變體數量，保留 original query，並用 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/retrieval-recall/" data-link-title="Retrieval Recall" data-link-desc="衡量 RAG 檢索是否把應該命中的文件或 chunk 放進 top-k 結果，是 component-level eval 的核心指標">retrieval recall&lt;/a> 驗證是否真的提高命中率；變體太發散時應改用澄清問題或 query rewriting。&lt;/p></description><content:encoded><![CDATA[<p>Query expansion 的核心概念是「<strong>把一個使用者 query 擴成多個檢索變體，再把多路 retrieval 結果合併</strong>」。它處理的是 query 太短、有歧義、或只覆蓋單一表述角度時的 recall 問題，跟 <a href="/blog/llm/knowledge-cards/query-rewriting/" data-link-title="Query Rewriting" data-link-desc="在 RAG 檢索前改寫使用者查詢，讓 query 更接近文件語言與索引分佈">query rewriting</a> 的單一路徑改寫不同。</p>
<h2 id="概念位置">概念位置</h2>
<p>Query expansion 位在 <a href="/blog/llm/knowledge-cards/rag/" data-link-title="RAG" data-link-desc="Retrieval-Augmented Generation：動態外掛知識給 LLM、繞開模型參數記憶的靜態限制">RAG</a> 的 query 端增強層。它會提高 <a href="/blog/llm/knowledge-cards/retrieval-cost/" data-link-title="Retrieval Cost" data-link-desc="RAG 檢索帶來的 latency、token、embedding、reranker、LLM call 與維護成本，用來判斷增強是否划算">retrieval cost</a>，因為每個變體都要 retrieve；它也常跟 <a href="/blog/llm/knowledge-cards/hybrid-search/" data-link-title="Hybrid Search" data-link-desc="把字面 retrieval（BM25）跟語意 retrieval（embedding）的結果用 RRF 等方法合併、補單一路線的盲點">hybrid search</a> 的 RRF 合併思路相鄰，用排名融合降低單一 query 變體失誤。</p>
<h2 id="可觀察訊號與例子">可觀察訊號與例子</h2>
<p>使用者問「python deploy」時，系統可能擴成「Python application deployment」「Docker deploy Python service」「CI/CD for Python backend」。這能增加 coverage，但也可能把不同意圖混在一起。</p>
<h2 id="設計責任">設計責任</h2>
<p>Query expansion 適合短 query、歧義 query、或同一問題有多種常見說法的場景。設計時要限制變體數量，保留 original query，並用 <a href="/blog/llm/knowledge-cards/retrieval-recall/" data-link-title="Retrieval Recall" data-link-desc="衡量 RAG 檢索是否把應該命中的文件或 chunk 放進 top-k 結果，是 component-level eval 的核心指標">retrieval recall</a> 驗證是否真的提高命中率；變體太發散時應改用澄清問題或 query rewriting。</p>
]]></content:encoded></item><item><title>Query Rewriting</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/query-rewriting/</link><pubDate>Thu, 14 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/query-rewriting/</guid><description>&lt;p>Query rewriting 的核心概念是「&lt;strong>在 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/rag/" data-link-title="RAG" data-link-desc="Retrieval-Augmented Generation：動態外掛知識給 LLM、繞開模型參數記憶的靜態限制">RAG&lt;/a> retrieval 前把使用者 query 改寫成更適合搜尋的形狀&lt;/strong>」。使用者常用口語、模糊或情境化說法，文件則使用正式術語；改寫能縮小 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/query-document-gap/" data-link-title="Query-Document Gap" data-link-desc="使用者 query 與文件語言在詞彙、形態、抽象層級或領域分佈上的落差，是 RAG retrieval miss 的常見原因">query-document gap&lt;/a>。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>Query rewriting 位在 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/rag/" data-link-title="RAG" data-link-desc="Retrieval-Augmented Generation：動態外掛知識給 LLM、繞開模型參數記憶的靜態限制">RAG&lt;/a> pipeline 的 query 端，早於 embedding、hybrid search、reranker 與 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/context-packing/" data-link-title="Context Packing" data-link-desc="RAG retrieve 後把 chunks 去重、排序、壓縮、標來源，再塞進 prompt 的組裝決策">context packing&lt;/a>。它跟 HyDE 不同：rewriting 產生更好的查詢句，HyDE 產生假設文件再拿去 embed。&lt;/p>
&lt;h2 id="可觀察訊號與例子">可觀察訊號與例子&lt;/h2>
&lt;p>使用者問「API 為什麼很慢」，rewriting 可能改成「API latency bottleneck, tail latency, database query optimization」。這能讓 retrieval 更容易命中正式文件中的用詞，但會增加 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/retrieval-cost/" data-link-title="Retrieval Cost" data-link-desc="RAG 檢索帶來的 latency、token、embedding、reranker、LLM call 與維護成本，用來判斷增強是否划算">retrieval cost&lt;/a>。&lt;/p>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>改寫要保留原始意圖，避免把「診斷原因」改成「優化方案」這類偏移。實務上要保存 original query，retrieve 後再用原始 query 檢查結果是否對題。&lt;/p></description><content:encoded><![CDATA[<p>Query rewriting 的核心概念是「<strong>在 <a href="/blog/llm/knowledge-cards/rag/" data-link-title="RAG" data-link-desc="Retrieval-Augmented Generation：動態外掛知識給 LLM、繞開模型參數記憶的靜態限制">RAG</a> retrieval 前把使用者 query 改寫成更適合搜尋的形狀</strong>」。使用者常用口語、模糊或情境化說法，文件則使用正式術語；改寫能縮小 <a href="/blog/llm/knowledge-cards/query-document-gap/" data-link-title="Query-Document Gap" data-link-desc="使用者 query 與文件語言在詞彙、形態、抽象層級或領域分佈上的落差，是 RAG retrieval miss 的常見原因">query-document gap</a>。</p>
<h2 id="概念位置">概念位置</h2>
<p>Query rewriting 位在 <a href="/blog/llm/knowledge-cards/rag/" data-link-title="RAG" data-link-desc="Retrieval-Augmented Generation：動態外掛知識給 LLM、繞開模型參數記憶的靜態限制">RAG</a> pipeline 的 query 端，早於 embedding、hybrid search、reranker 與 <a href="/blog/llm/knowledge-cards/context-packing/" data-link-title="Context Packing" data-link-desc="RAG retrieve 後把 chunks 去重、排序、壓縮、標來源，再塞進 prompt 的組裝決策">context packing</a>。它跟 HyDE 不同：rewriting 產生更好的查詢句，HyDE 產生假設文件再拿去 embed。</p>
<h2 id="可觀察訊號與例子">可觀察訊號與例子</h2>
<p>使用者問「API 為什麼很慢」，rewriting 可能改成「API latency bottleneck, tail latency, database query optimization」。這能讓 retrieval 更容易命中正式文件中的用詞，但會增加 <a href="/blog/llm/knowledge-cards/retrieval-cost/" data-link-title="Retrieval Cost" data-link-desc="RAG 檢索帶來的 latency、token、embedding、reranker、LLM call 與維護成本，用來判斷增強是否划算">retrieval cost</a>。</p>
<h2 id="設計責任">設計責任</h2>
<p>改寫要保留原始意圖，避免把「診斷原因」改成「優化方案」這類偏移。實務上要保存 original query，retrieve 後再用原始 query 檢查結果是否對題。</p>
]]></content:encoded></item><item><title>Query-Document Gap</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/query-document-gap/</link><pubDate>Thu, 14 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/query-document-gap/</guid><description>&lt;p>Query-document gap 的核心概念是「&lt;strong>使用者 query 的語言形狀跟被檢索文件的語言形狀不一致&lt;/strong>」。它是 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/rag/" data-link-title="RAG" data-link-desc="Retrieval-Augmented Generation：動態外掛知識給 LLM、繞開模型參數記憶的靜態限制">RAG&lt;/a> retrieval miss 的常見原因：query 可能是口語問句，document 可能是正式陳述、專業術語、程式碼符號或另一種抽象層級。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>Query-document gap 位在 query 端與 embedding / search 端之間。它跟 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/hybrid-search/" data-link-title="Hybrid Search" data-link-desc="把字面 retrieval（BM25）跟語意 retrieval（embedding）的結果用 RRF 等方法合併、補單一路線的盲點">hybrid search&lt;/a> 的字面 vs 語意互補相關，也跟 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/query-rewriting/" data-link-title="Query Rewriting" data-link-desc="在 RAG 檢索前改寫使用者查詢，讓 query 更接近文件語言與索引分佈">query rewriting&lt;/a> 與 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/hyde/" data-link-title="HyDE（Hypothetical Document Embeddings）" data-link-desc="用 LLM 生成假設文件、對假文件做 embedding 去 retrieve、繞過 query-document gap 的 RAG 增強技術">HyDE&lt;/a> 直接相鄰：前者改寫 query，後者生成假設文件來靠近 document 分佈。&lt;/p>
&lt;h2 id="可觀察訊號與例子">可觀察訊號與例子&lt;/h2>
&lt;p>使用者問「API 為什麼很慢」，文件寫的是「tail latency、database query plan、connection pool saturation」。兩者意思相關，但 phrasing、抽象層級與術語不同，embedding 可能命中弱，BM25 可能完全漏掉。&lt;/p>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>處理 query-document gap 時先判斷落差類型：同義詞、口語 vs 正式、問句 vs 陳述、跨語言、domain jargon 或識別碼。輕量修法是 query rewriting；形態落差明顯時可用 HyDE；精確 keyword 與語意都重要時用 hybrid search；仍然 top-k 不準時再加 reranker。&lt;/p></description><content:encoded><![CDATA[<p>Query-document gap 的核心概念是「<strong>使用者 query 的語言形狀跟被檢索文件的語言形狀不一致</strong>」。它是 <a href="/blog/llm/knowledge-cards/rag/" data-link-title="RAG" data-link-desc="Retrieval-Augmented Generation：動態外掛知識給 LLM、繞開模型參數記憶的靜態限制">RAG</a> retrieval miss 的常見原因：query 可能是口語問句，document 可能是正式陳述、專業術語、程式碼符號或另一種抽象層級。</p>
<h2 id="概念位置">概念位置</h2>
<p>Query-document gap 位在 query 端與 embedding / search 端之間。它跟 <a href="/blog/llm/knowledge-cards/hybrid-search/" data-link-title="Hybrid Search" data-link-desc="把字面 retrieval（BM25）跟語意 retrieval（embedding）的結果用 RRF 等方法合併、補單一路線的盲點">hybrid search</a> 的字面 vs 語意互補相關，也跟 <a href="/blog/llm/knowledge-cards/query-rewriting/" data-link-title="Query Rewriting" data-link-desc="在 RAG 檢索前改寫使用者查詢，讓 query 更接近文件語言與索引分佈">query rewriting</a> 與 <a href="/blog/llm/knowledge-cards/hyde/" data-link-title="HyDE（Hypothetical Document Embeddings）" data-link-desc="用 LLM 生成假設文件、對假文件做 embedding 去 retrieve、繞過 query-document gap 的 RAG 增強技術">HyDE</a> 直接相鄰：前者改寫 query，後者生成假設文件來靠近 document 分佈。</p>
<h2 id="可觀察訊號與例子">可觀察訊號與例子</h2>
<p>使用者問「API 為什麼很慢」，文件寫的是「tail latency、database query plan、connection pool saturation」。兩者意思相關，但 phrasing、抽象層級與術語不同，embedding 可能命中弱，BM25 可能完全漏掉。</p>
<h2 id="設計責任">設計責任</h2>
<p>處理 query-document gap 時先判斷落差類型：同義詞、口語 vs 正式、問句 vs 陳述、跨語言、domain jargon 或識別碼。輕量修法是 query rewriting；形態落差明顯時可用 HyDE；精確 keyword 與語意都重要時用 hybrid search；仍然 top-k 不準時再加 reranker。</p>
]]></content:encoded></item><item><title>Retrieval Cost</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/retrieval-cost/</link><pubDate>Thu, 14 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/retrieval-cost/</guid><description>&lt;p>Retrieval cost 的核心概念是「&lt;strong>每一次 retrieve 與其周邊增強會消耗多少 latency、token、compute 與維護成本&lt;/strong>」。它讓 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/rag/" data-link-title="RAG" data-link-desc="Retrieval-Augmented Generation：動態外掛知識給 LLM、繞開模型參數記憶的靜態限制">RAG&lt;/a> 設計從「能不能找更多資料」轉成「多找這些資料是否值得」。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>Retrieval cost 橫跨 query 端、retrieval 端、context 組裝端與控制流端。它跟 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/ttft/" data-link-title="TTFT" data-link-desc="Time To First Token：送出 prompt 到第一個 token 出現的等待時間">TTFT&lt;/a> 有關，但不只是一個延遲數字：query rewriting 多一次 LLM call，query expansion 多次 retrieve，reranker 多一段 cross-encoder 計算，retrieved chunks 進 prompt 會增加 token cost。&lt;/p>
&lt;h2 id="可觀察訊號與例子">可觀察訊號與例子&lt;/h2>
&lt;p>常見訊號是「accuracy 有提升，但 p95 latency 變差」「每個 query 都 retrieve，聊天問題也燒 embedding / vector DB」「multi-step retrieval 連跑三輪，答案只比 single-step 好一點」。這時問題在於收益是否大於成本，而非技術能不能做。&lt;/p>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>判斷 retrieval cost 要把 accuracy、latency、token budget、服務費用與維運複雜度一起看。低風險聊天可用 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/adaptive-retrieval/" data-link-title="Adaptive Retrieval" data-link-desc="RAG 控制流中先判斷是否需要檢索，只在外部知識有價值時才 retrieve">adaptive retrieval&lt;/a> 降低不必要檢索；高價值問答可接受 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/reranker/" data-link-title="Reranker" data-link-desc="對 retrieval top-K 結果用 cross-encoder 重新排序的 RAG 第二階段、品質提升顯著但 latency / cost 增加">reranker&lt;/a> 或 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/multi-step-retrieval/" data-link-title="Multi-Step Retrieval" data-link-desc="RAG 中多輪 retrieve → 判斷 → 再 retrieve 的控制流，用來處理 multi-hop 問題">multi-step retrieval&lt;/a> 的額外成本；即時補完則通常偏向 single-step、cache 或較小 top-k。&lt;/p></description><content:encoded><![CDATA[<p>Retrieval cost 的核心概念是「<strong>每一次 retrieve 與其周邊增強會消耗多少 latency、token、compute 與維護成本</strong>」。它讓 <a href="/blog/llm/knowledge-cards/rag/" data-link-title="RAG" data-link-desc="Retrieval-Augmented Generation：動態外掛知識給 LLM、繞開模型參數記憶的靜態限制">RAG</a> 設計從「能不能找更多資料」轉成「多找這些資料是否值得」。</p>
<h2 id="概念位置">概念位置</h2>
<p>Retrieval cost 橫跨 query 端、retrieval 端、context 組裝端與控制流端。它跟 <a href="/blog/llm/knowledge-cards/ttft/" data-link-title="TTFT" data-link-desc="Time To First Token：送出 prompt 到第一個 token 出現的等待時間">TTFT</a> 有關，但不只是一個延遲數字：query rewriting 多一次 LLM call，query expansion 多次 retrieve，reranker 多一段 cross-encoder 計算，retrieved chunks 進 prompt 會增加 token cost。</p>
<h2 id="可觀察訊號與例子">可觀察訊號與例子</h2>
<p>常見訊號是「accuracy 有提升，但 p95 latency 變差」「每個 query 都 retrieve，聊天問題也燒 embedding / vector DB」「multi-step retrieval 連跑三輪，答案只比 single-step 好一點」。這時問題在於收益是否大於成本，而非技術能不能做。</p>
<h2 id="設計責任">設計責任</h2>
<p>判斷 retrieval cost 要把 accuracy、latency、token budget、服務費用與維運複雜度一起看。低風險聊天可用 <a href="/blog/llm/knowledge-cards/adaptive-retrieval/" data-link-title="Adaptive Retrieval" data-link-desc="RAG 控制流中先判斷是否需要檢索，只在外部知識有價值時才 retrieve">adaptive retrieval</a> 降低不必要檢索；高價值問答可接受 <a href="/blog/llm/knowledge-cards/reranker/" data-link-title="Reranker" data-link-desc="對 retrieval top-K 結果用 cross-encoder 重新排序的 RAG 第二階段、品質提升顯著但 latency / cost 增加">reranker</a> 或 <a href="/blog/llm/knowledge-cards/multi-step-retrieval/" data-link-title="Multi-Step Retrieval" data-link-desc="RAG 中多輪 retrieve → 判斷 → 再 retrieve 的控制流，用來處理 multi-hop 問題">multi-step retrieval</a> 的額外成本；即時補完則通常偏向 single-step、cache 或較小 top-k。</p>
]]></content:encoded></item><item><title>Retrieval Recall</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/retrieval-recall/</link><pubDate>Thu, 14 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/retrieval-recall/</guid><description>&lt;p>Retrieval recall 的核心概念是「&lt;strong>正確文件或 chunk 是否出現在 retrieval top-k 結果中&lt;/strong>」。它把 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/rag/" data-link-title="RAG" data-link-desc="Retrieval-Augmented Generation：動態外掛知識給 LLM、繞開模型參數記憶的靜態限制">RAG&lt;/a> 的 retrieval 階段從主觀感覺改成 component-level eval，讓 generation 失敗與 retrieval miss 能分開判讀。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>Retrieval recall 位在 retrieval component eval 層。它跟 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/reranker/" data-link-title="Reranker" data-link-desc="對 retrieval top-K 結果用 cross-encoder 重新排序的 RAG 第二階段、品質提升顯著但 latency / cost 增加">reranker&lt;/a> 相鄰，因為 reranker 常用來提升 top-k 的排序品質；也跟 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/query-document-gap/" data-link-title="Query-Document Gap" data-link-desc="使用者 query 與文件語言在詞彙、形態、抽象層級或領域分佈上的落差，是 RAG retrieval miss 的常見原因">query-document gap&lt;/a> 相鄰，因為 gap 太大會讓 expected doc 不進 top-k。&lt;/p>
&lt;h2 id="可觀察訊號與例子">可觀察訊號與例子&lt;/h2>
&lt;p>一組 eval query 事先標出 expected chunk。若 expected chunk 出現在 top-5，記為 hit@5；一百題中 82 題命中，hit_rate@5 是 82%。若 retrieval recall 高但答案錯，問題多半在 generation 或 context packing；若 retrieval recall 低，先修 chunking、embedding、hybrid search 或 query 端增強。&lt;/p>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>設計 retrieval recall eval 時要保存 query、expected source、top-k 結果、score 與失敗分類。不要只看 end-to-end answer correctness；否則 retrieval miss 會被 LLM hallucination、judge 偏差或 prompt 問題掩蓋。&lt;/p></description><content:encoded><![CDATA[<p>Retrieval recall 的核心概念是「<strong>正確文件或 chunk 是否出現在 retrieval top-k 結果中</strong>」。它把 <a href="/blog/llm/knowledge-cards/rag/" data-link-title="RAG" data-link-desc="Retrieval-Augmented Generation：動態外掛知識給 LLM、繞開模型參數記憶的靜態限制">RAG</a> 的 retrieval 階段從主觀感覺改成 component-level eval，讓 generation 失敗與 retrieval miss 能分開判讀。</p>
<h2 id="概念位置">概念位置</h2>
<p>Retrieval recall 位在 retrieval component eval 層。它跟 <a href="/blog/llm/knowledge-cards/reranker/" data-link-title="Reranker" data-link-desc="對 retrieval top-K 結果用 cross-encoder 重新排序的 RAG 第二階段、品質提升顯著但 latency / cost 增加">reranker</a> 相鄰，因為 reranker 常用來提升 top-k 的排序品質；也跟 <a href="/blog/llm/knowledge-cards/query-document-gap/" data-link-title="Query-Document Gap" data-link-desc="使用者 query 與文件語言在詞彙、形態、抽象層級或領域分佈上的落差，是 RAG retrieval miss 的常見原因">query-document gap</a> 相鄰，因為 gap 太大會讓 expected doc 不進 top-k。</p>
<h2 id="可觀察訊號與例子">可觀察訊號與例子</h2>
<p>一組 eval query 事先標出 expected chunk。若 expected chunk 出現在 top-5，記為 hit@5；一百題中 82 題命中，hit_rate@5 是 82%。若 retrieval recall 高但答案錯，問題多半在 generation 或 context packing；若 retrieval recall 低，先修 chunking、embedding、hybrid search 或 query 端增強。</p>
<h2 id="設計責任">設計責任</h2>
<p>設計 retrieval recall eval 時要保存 query、expected source、top-k 結果、score 與失敗分類。不要只看 end-to-end answer correctness；否則 retrieval miss 會被 LLM hallucination、judge 偏差或 prompt 問題掩蓋。</p>
]]></content:encoded></item><item><title>Retrieval Source</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/retrieval-source/</link><pubDate>Thu, 14 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/retrieval-source/</guid><description>&lt;p>Retrieval source 的核心概念是「&lt;strong>RAG 或 agent 在 retrieve 時實際查詢的資料來源&lt;/strong>」。它是 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/rag/" data-link-title="RAG" data-link-desc="Retrieval-Augmented Generation：動態外掛知識給 LLM、繞開模型參數記憶的靜態限制">RAG&lt;/a> pipeline 中可被檢索、可被引用、也可能被污染或過期的 corpus、index、database、file system、tool response 或第三方服務——比泛稱的 source 更具體。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>Retrieval source 位在 ingestion、index 與 runtime retrieval 的交界。它跟 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/chunking/" data-link-title="Chunking" data-link-desc="把長文件切成可檢索片段的設計決策：resolution vs context loss 的本質取捨">chunking&lt;/a> 不同：chunking 決定來源如何切片，retrieval source 決定來源本身是否可信、是否新鮮、是否有權限被查、是否能被引用。&lt;/p>
&lt;h2 id="可觀察訊號與例子">可觀察訊號與例子&lt;/h2>
&lt;p>看到「從 codebase retrieve」「從歷史客服案例庫取相似案例」「從 vector DB 查 policy」「把 filesystem search 結果塞進 prompt」就是 retrieval source 問題。不同 source 的責任不同：官方 policy 文件可引用，使用者上傳文件要標記租戶與權限，網頁內容要防 prompt injection，過期 index 要能重建。&lt;/p>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>設計 retrieval source 時要同時回答四件事：資料來源是否可信、資料是否新鮮、查詢者是否有權限、LLM 回答是否能追溯。高風險來源要保留 source metadata、ingestion timestamp、tenant boundary 與引用標籤；否則 retrieval 命中正確內容，也可能把不該看的資料送進 prompt。&lt;/p></description><content:encoded><![CDATA[<p>Retrieval source 的核心概念是「<strong>RAG 或 agent 在 retrieve 時實際查詢的資料來源</strong>」。它是 <a href="/blog/llm/knowledge-cards/rag/" data-link-title="RAG" data-link-desc="Retrieval-Augmented Generation：動態外掛知識給 LLM、繞開模型參數記憶的靜態限制">RAG</a> pipeline 中可被檢索、可被引用、也可能被污染或過期的 corpus、index、database、file system、tool response 或第三方服務——比泛稱的 source 更具體。</p>
<h2 id="概念位置">概念位置</h2>
<p>Retrieval source 位在 ingestion、index 與 runtime retrieval 的交界。它跟 <a href="/blog/llm/knowledge-cards/chunking/" data-link-title="Chunking" data-link-desc="把長文件切成可檢索片段的設計決策：resolution vs context loss 的本質取捨">chunking</a> 不同：chunking 決定來源如何切片，retrieval source 決定來源本身是否可信、是否新鮮、是否有權限被查、是否能被引用。</p>
<h2 id="可觀察訊號與例子">可觀察訊號與例子</h2>
<p>看到「從 codebase retrieve」「從歷史客服案例庫取相似案例」「從 vector DB 查 policy」「把 filesystem search 結果塞進 prompt」就是 retrieval source 問題。不同 source 的責任不同：官方 policy 文件可引用，使用者上傳文件要標記租戶與權限，網頁內容要防 prompt injection，過期 index 要能重建。</p>
<h2 id="設計責任">設計責任</h2>
<p>設計 retrieval source 時要同時回答四件事：資料來源是否可信、資料是否新鮮、查詢者是否有權限、LLM 回答是否能追溯。高風險來源要保留 source metadata、ingestion timestamp、tenant boundary 與引用標籤；否則 retrieval 命中正確內容，也可能把不該看的資料送進 prompt。</p>
]]></content:encoded></item><item><title>Hybrid Search</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/hybrid-search/</link><pubDate>Tue, 12 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/hybrid-search/</guid><description>&lt;p>Hybrid search 的核心概念是「&lt;strong>同時跑字面 retrieval（BM25 / tf-idf）跟語意 retrieval（embedding similarity）、用 Reciprocal Rank Fusion 等方法合併結果&lt;/strong>」。補單一路線的盲點：BM25 抓不到語意相似（同義詞 / 不同表述）、embedding 抓不到精確 keyword（術語 / 識別碼 / 罕見 entity）。是 production RAG 的標配。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>兩條 retrieval 路線的盲點：&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>場景&lt;/th>
 &lt;th>BM25（字面）&lt;/th>
 &lt;th>Embedding（語意）&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>Query / doc 共用 keyword&lt;/td>
 &lt;td>強&lt;/td>
 &lt;td>強&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Query 用同義詞、doc 用另一字&lt;/td>
 &lt;td>找不到&lt;/td>
 &lt;td>命中&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Query 用通俗、doc 用 jargon&lt;/td>
 &lt;td>找不到&lt;/td>
 &lt;td>命中&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>精確 keyword（如 product code、UUID、API 名）&lt;/td>
 &lt;td>命中&lt;/td>
 &lt;td>可能漂掉&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>罕見 entity（人名 / 地名）&lt;/td>
 &lt;td>命中&lt;/td>
 &lt;td>弱（embedding model 不熟）&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Embedding model 不熟的 domain&lt;/td>
 &lt;td>命中&lt;/td>
 &lt;td>表現崩&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>主流合併方法：&lt;/p>
&lt;h3 id="reciprocal-rank-fusionrrf">Reciprocal Rank Fusion（RRF）&lt;/h3>
&lt;p>最常用、簡單：&lt;/p>





&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-text" data-lang="text">&lt;span class="line">&lt;span class="ln"> 1&lt;/span>&lt;span class="cl">對每個 doc：
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 2&lt;/span>&lt;span class="cl"> score = sum_over_retrievers(1 / (k + rank_i))
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 3&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 4&lt;/span>&lt;span class="cl">k 是常數（典型 60）、rank 是該 retriever 給 doc 的排名
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 5&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 6&lt;/span>&lt;span class="cl">example：
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 7&lt;/span>&lt;span class="cl"> doc X 在 BM25 排名 3、在 embedding 排名 1
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 8&lt;/span>&lt;span class="cl"> RRF score = 1/(60+3) + 1/(60+1) = 0.0159 + 0.0164 = 0.0323
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 9&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">10&lt;/span>&lt;span class="cl">按 RRF score 排序、取 top-K&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>優點：不需要 normalize 不同 retriever 的分數、簡單可靠
缺點：不能 fine-tune 兩條路線的權重&lt;/p>
&lt;h3 id="weighted-score-fusion">Weighted score fusion&lt;/h3>
&lt;p>對每條路線的 score 加權平均：&lt;/p>





&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-text" data-lang="text">&lt;span class="line">&lt;span class="ln">1&lt;/span>&lt;span class="cl">score = α × BM25_score_normalized + (1-α) × embedding_score_normalized&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>優點：可以調 α 偏 BM25 或 embedding
缺點：要 normalize 兩個 score scale、調 α 是 hyper-parameter&lt;/p>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>讀 RAG production / retrieval framework 看到「hybrid search」「BM25 + dense」「RRF」就是這 framing。寫 code 場景的判讀：&lt;/p>
&lt;ol>
&lt;li>&lt;strong>何時值得加 hybrid&lt;/strong>：embedding-only retrieval 漏精確 keyword / 識別碼、BM25-only 漏語意相似、混合補完&lt;/li>
&lt;li>&lt;strong>何時不需要&lt;/strong>：純語意任務（embedding 已準）、純 keyword 任務（BM25 已準）、極小語料&lt;/li>
&lt;li>&lt;strong>跟 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/reranker/" data-link-title="Reranker" data-link-desc="對 retrieval top-K 結果用 cross-encoder 重新排序的 RAG 第二階段、品質提升顯著但 latency / cost 增加">reranker&lt;/a> 的組合&lt;/strong>：hybrid retrieve top-50（BM25 top-25 + embedding top-25、RRF 合併）→ reranker rerank → LLM top-5&lt;/li>
&lt;li>&lt;strong>主流實作&lt;/strong>：Elasticsearch / OpenSearch 內建、Weaviate / Qdrant / Pinecone 都支援、Postgres 用 pg_search + pgvector&lt;/li>
&lt;li>&lt;strong>跟 &lt;a href="https://tarrragon.github.io/blog/llm/04-applications/rag-principles/" data-link-title="4.1 RAG 原理：retrieval &amp;#43; augmentation 模式" data-link-desc="為什麼模型需要外掛知識、語意相似 vs 字面相似、chunking 的本質取捨、retrieval 失敗的根本原因">4.1 RAG 章節&lt;/a> 的關係&lt;/strong>：本卡是定義、章節是 retrieval pipeline 設計含 hybrid 段&lt;/li>
&lt;/ol></description><content:encoded><![CDATA[<p>Hybrid search 的核心概念是「<strong>同時跑字面 retrieval（BM25 / tf-idf）跟語意 retrieval（embedding similarity）、用 Reciprocal Rank Fusion 等方法合併結果</strong>」。補單一路線的盲點：BM25 抓不到語意相似（同義詞 / 不同表述）、embedding 抓不到精確 keyword（術語 / 識別碼 / 罕見 entity）。是 production RAG 的標配。</p>
<h2 id="概念位置">概念位置</h2>
<p>兩條 retrieval 路線的盲點：</p>
<table>
  <thead>
      <tr>
          <th>場景</th>
          <th>BM25（字面）</th>
          <th>Embedding（語意）</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Query / doc 共用 keyword</td>
          <td>強</td>
          <td>強</td>
      </tr>
      <tr>
          <td>Query 用同義詞、doc 用另一字</td>
          <td>找不到</td>
          <td>命中</td>
      </tr>
      <tr>
          <td>Query 用通俗、doc 用 jargon</td>
          <td>找不到</td>
          <td>命中</td>
      </tr>
      <tr>
          <td>精確 keyword（如 product code、UUID、API 名）</td>
          <td>命中</td>
          <td>可能漂掉</td>
      </tr>
      <tr>
          <td>罕見 entity（人名 / 地名）</td>
          <td>命中</td>
          <td>弱（embedding model 不熟）</td>
      </tr>
      <tr>
          <td>Embedding model 不熟的 domain</td>
          <td>命中</td>
          <td>表現崩</td>
      </tr>
  </tbody>
</table>
<p>主流合併方法：</p>
<h3 id="reciprocal-rank-fusionrrf">Reciprocal Rank Fusion（RRF）</h3>
<p>最常用、簡單：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="ln"> 1</span><span class="cl">對每個 doc：
</span></span><span class="line"><span class="ln"> 2</span><span class="cl">  score = sum_over_retrievers(1 / (k + rank_i))
</span></span><span class="line"><span class="ln"> 3</span><span class="cl">
</span></span><span class="line"><span class="ln"> 4</span><span class="cl">k 是常數（典型 60）、rank 是該 retriever 給 doc 的排名
</span></span><span class="line"><span class="ln"> 5</span><span class="cl">
</span></span><span class="line"><span class="ln"> 6</span><span class="cl">example：
</span></span><span class="line"><span class="ln"> 7</span><span class="cl">  doc X 在 BM25 排名 3、在 embedding 排名 1
</span></span><span class="line"><span class="ln"> 8</span><span class="cl">  RRF score = 1/(60+3) + 1/(60+1) = 0.0159 + 0.0164 = 0.0323
</span></span><span class="line"><span class="ln"> 9</span><span class="cl">
</span></span><span class="line"><span class="ln">10</span><span class="cl">按 RRF score 排序、取 top-K</span></span></code></pre></div><p>優點：不需要 normalize 不同 retriever 的分數、簡單可靠
缺點：不能 fine-tune 兩條路線的權重</p>
<h3 id="weighted-score-fusion">Weighted score fusion</h3>
<p>對每條路線的 score 加權平均：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="ln">1</span><span class="cl">score = α × BM25_score_normalized + (1-α) × embedding_score_normalized</span></span></code></pre></div><p>優點：可以調 α 偏 BM25 或 embedding
缺點：要 normalize 兩個 score scale、調 α 是 hyper-parameter</p>
<h2 id="設計責任">設計責任</h2>
<p>讀 RAG production / retrieval framework 看到「hybrid search」「BM25 + dense」「RRF」就是這 framing。寫 code 場景的判讀：</p>
<ol>
<li><strong>何時值得加 hybrid</strong>：embedding-only retrieval 漏精確 keyword / 識別碼、BM25-only 漏語意相似、混合補完</li>
<li><strong>何時不需要</strong>：純語意任務（embedding 已準）、純 keyword 任務（BM25 已準）、極小語料</li>
<li><strong>跟 <a href="/blog/llm/knowledge-cards/reranker/" data-link-title="Reranker" data-link-desc="對 retrieval top-K 結果用 cross-encoder 重新排序的 RAG 第二階段、品質提升顯著但 latency / cost 增加">reranker</a> 的組合</strong>：hybrid retrieve top-50（BM25 top-25 + embedding top-25、RRF 合併）→ reranker rerank → LLM top-5</li>
<li><strong>主流實作</strong>：Elasticsearch / OpenSearch 內建、Weaviate / Qdrant / Pinecone 都支援、Postgres 用 pg_search + pgvector</li>
<li><strong>跟 <a href="/blog/llm/04-applications/rag-principles/" data-link-title="4.1 RAG 原理：retrieval &#43; augmentation 模式" data-link-desc="為什麼模型需要外掛知識、語意相似 vs 字面相似、chunking 的本質取捨、retrieval 失敗的根本原因">4.1 RAG 章節</a> 的關係</strong>：本卡是定義、章節是 retrieval pipeline 設計含 hybrid 段</li>
</ol>
]]></content:encoded></item><item><title>Reranker</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/reranker/</link><pubDate>Tue, 12 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/reranker/</guid><description>&lt;p>Reranker 的核心概念是「&lt;strong>對 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/rag/" data-link-title="RAG" data-link-desc="Retrieval-Augmented Generation：動態外掛知識給 LLM、繞開模型參數記憶的靜態限制">retrieval&lt;/a> 第一階段拿到的 top-K（如 50）結果、用 cross-encoder 模型重新評分、排出 top-N（如 5）給 LLM&lt;/strong>」。是 RAG 第二階段、補 bi-encoder（&lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/embedding-model/" data-link-title="Embedding Model" data-link-desc="把文字轉成向量的模型：用於 codebase 索引與語意搜尋">embedding model&lt;/a>）對 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/query-document-gap/" data-link-title="Query-Document Gap" data-link-desc="使用者 query 與文件語言在詞彙、形態、抽象層級或領域分佈上的落差，是 RAG retrieval miss 的常見原因">query-document gap&lt;/a> 的細粒度匹配不足、品質提升明顯（recall@5 通常 +10-30%）但成本 / latency 增加。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>Bi-encoder vs cross-encoder 的差別：&lt;/p>





&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-text" data-lang="text">&lt;span class="line">&lt;span class="ln">1&lt;/span>&lt;span class="cl">Bi-encoder（embedding model、retrieval 第一階段）：
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">2&lt;/span>&lt;span class="cl"> query → embedding A
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">3&lt;/span>&lt;span class="cl"> document → embedding B（pre-compute、存 vector DB）
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">4&lt;/span>&lt;span class="cl"> score = cosine(A, B)
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">5&lt;/span>&lt;span class="cl"> → 快、可 pre-compute、適合海量 retrieval
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">6&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">7&lt;/span>&lt;span class="cl">Cross-encoder（reranker、retrieval 第二階段）：
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">8&lt;/span>&lt;span class="cl"> (query, document) 一起進模型 → 直接輸出 relevance score
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">9&lt;/span>&lt;span class="cl"> → 慢（每對都要 forward pass）、不可 pre-compute、適合 top-K rerank&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>主流 reranker：&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>Reranker&lt;/th>
 &lt;th>類型&lt;/th>
 &lt;th>適合場景&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>Cohere Rerank 3&lt;/td>
 &lt;td>SaaS API&lt;/td>
 &lt;td>Production 高品質、多語&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Jina Reranker v2&lt;/td>
 &lt;td>開源&lt;/td>
 &lt;td>開源、多語&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>BGE Reranker（bge-reranker-v2-m3）&lt;/td>
 &lt;td>開源&lt;/td>
 &lt;td>開源中文友善&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Voyage rerank-2&lt;/td>
 &lt;td>SaaS API&lt;/td>
 &lt;td>跟 voyage embedding 配對&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>ColBERT v2&lt;/td>
 &lt;td>Late interaction&lt;/td>
 &lt;td>介於 bi 跟 cross encoder&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>讀 RAG / production retrieval docs 看到「reranker」「cross-encoder」「rerank stage」就是這 framing。寫 code 場景的判讀：&lt;/p>
&lt;ol>
&lt;li>&lt;strong>何時值得加 reranker&lt;/strong>：retrieval 結果有「相關但不精確」問題、top-K hit rate 高但 top-5 hit rate 低、有 latency / cost budget&lt;/li>
&lt;li>&lt;strong>何時不需要&lt;/strong>：小語料（&amp;lt; 1000 docs、retrieval 已準）、明確 keyword 任務（BM25 已準）、latency 敏感（&amp;lt; 100ms TTFT）&lt;/li>
&lt;li>&lt;strong>Pipeline 設計&lt;/strong>：bi-encoder retrieve top-50 → reranker rerank → 給 LLM top-5；50/5 是常見起點、看實測調&lt;/li>
&lt;li>&lt;strong>跟 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/hybrid-search/" data-link-title="Hybrid Search" data-link-desc="把字面 retrieval（BM25）跟語意 retrieval（embedding）的結果用 RRF 等方法合併、補單一路線的盲點">hybrid search&lt;/a> 結合&lt;/strong>：BM25 + embedding hybrid retrieve top-50 → reranker rerank → LLM、是 production RAG 標配&lt;/li>
&lt;li>&lt;strong>跟 &lt;a href="https://tarrragon.github.io/blog/llm/04-applications/rag-principles/" data-link-title="4.1 RAG 原理：retrieval &amp;#43; augmentation 模式" data-link-desc="為什麼模型需要外掛知識、語意相似 vs 字面相似、chunking 的本質取捨、retrieval 失敗的根本原因">4.1 RAG 章節&lt;/a> 的關係&lt;/strong>：本卡是定義、章節是 retrieval pipeline 設計（含 reranker / hybrid 段）&lt;/li>
&lt;/ol></description><content:encoded><![CDATA[<p>Reranker 的核心概念是「<strong>對 <a href="/blog/llm/knowledge-cards/rag/" data-link-title="RAG" data-link-desc="Retrieval-Augmented Generation：動態外掛知識給 LLM、繞開模型參數記憶的靜態限制">retrieval</a> 第一階段拿到的 top-K（如 50）結果、用 cross-encoder 模型重新評分、排出 top-N（如 5）給 LLM</strong>」。是 RAG 第二階段、補 bi-encoder（<a href="/blog/llm/knowledge-cards/embedding-model/" data-link-title="Embedding Model" data-link-desc="把文字轉成向量的模型：用於 codebase 索引與語意搜尋">embedding model</a>）對 <a href="/blog/llm/knowledge-cards/query-document-gap/" data-link-title="Query-Document Gap" data-link-desc="使用者 query 與文件語言在詞彙、形態、抽象層級或領域分佈上的落差，是 RAG retrieval miss 的常見原因">query-document gap</a> 的細粒度匹配不足、品質提升明顯（recall@5 通常 +10-30%）但成本 / latency 增加。</p>
<h2 id="概念位置">概念位置</h2>
<p>Bi-encoder vs cross-encoder 的差別：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="ln">1</span><span class="cl">Bi-encoder（embedding model、retrieval 第一階段）：
</span></span><span class="line"><span class="ln">2</span><span class="cl">  query → embedding A
</span></span><span class="line"><span class="ln">3</span><span class="cl">  document → embedding B（pre-compute、存 vector DB）
</span></span><span class="line"><span class="ln">4</span><span class="cl">  score = cosine(A, B)
</span></span><span class="line"><span class="ln">5</span><span class="cl">  → 快、可 pre-compute、適合海量 retrieval
</span></span><span class="line"><span class="ln">6</span><span class="cl">
</span></span><span class="line"><span class="ln">7</span><span class="cl">Cross-encoder（reranker、retrieval 第二階段）：
</span></span><span class="line"><span class="ln">8</span><span class="cl">  (query, document) 一起進模型 → 直接輸出 relevance score
</span></span><span class="line"><span class="ln">9</span><span class="cl">  → 慢（每對都要 forward pass）、不可 pre-compute、適合 top-K rerank</span></span></code></pre></div><p>主流 reranker：</p>
<table>
  <thead>
      <tr>
          <th>Reranker</th>
          <th>類型</th>
          <th>適合場景</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Cohere Rerank 3</td>
          <td>SaaS API</td>
          <td>Production 高品質、多語</td>
      </tr>
      <tr>
          <td>Jina Reranker v2</td>
          <td>開源</td>
          <td>開源、多語</td>
      </tr>
      <tr>
          <td>BGE Reranker（bge-reranker-v2-m3）</td>
          <td>開源</td>
          <td>開源中文友善</td>
      </tr>
      <tr>
          <td>Voyage rerank-2</td>
          <td>SaaS API</td>
          <td>跟 voyage embedding 配對</td>
      </tr>
      <tr>
          <td>ColBERT v2</td>
          <td>Late interaction</td>
          <td>介於 bi 跟 cross encoder</td>
      </tr>
  </tbody>
</table>
<h2 id="設計責任">設計責任</h2>
<p>讀 RAG / production retrieval docs 看到「reranker」「cross-encoder」「rerank stage」就是這 framing。寫 code 場景的判讀：</p>
<ol>
<li><strong>何時值得加 reranker</strong>：retrieval 結果有「相關但不精確」問題、top-K hit rate 高但 top-5 hit rate 低、有 latency / cost budget</li>
<li><strong>何時不需要</strong>：小語料（&lt; 1000 docs、retrieval 已準）、明確 keyword 任務（BM25 已準）、latency 敏感（&lt; 100ms TTFT）</li>
<li><strong>Pipeline 設計</strong>：bi-encoder retrieve top-50 → reranker rerank → 給 LLM top-5；50/5 是常見起點、看實測調</li>
<li><strong>跟 <a href="/blog/llm/knowledge-cards/hybrid-search/" data-link-title="Hybrid Search" data-link-desc="把字面 retrieval（BM25）跟語意 retrieval（embedding）的結果用 RRF 等方法合併、補單一路線的盲點">hybrid search</a> 結合</strong>：BM25 + embedding hybrid retrieve top-50 → reranker rerank → LLM、是 production RAG 標配</li>
<li><strong>跟 <a href="/blog/llm/04-applications/rag-principles/" data-link-title="4.1 RAG 原理：retrieval &#43; augmentation 模式" data-link-desc="為什麼模型需要外掛知識、語意相似 vs 字面相似、chunking 的本質取捨、retrieval 失敗的根本原因">4.1 RAG 章節</a> 的關係</strong>：本卡是定義、章節是 retrieval pipeline 設計（含 reranker / hybrid 段）</li>
</ol>
]]></content:encoded></item><item><title>4.2 RAG 檢索增強：query rewriting / HyDE / multi-step / context packing</title><link>https://tarrragon.github.io/blog/llm/04-applications/rag-retrieval-enhancements/</link><pubDate>Thu, 14 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/04-applications/rag-retrieval-enhancements/</guid><description>&lt;p>&lt;a href="https://tarrragon.github.io/blog/llm/04-applications/rag-principles/" data-link-title="4.1 RAG 原理：retrieval &amp;#43; augmentation 模式" data-link-desc="為什麼模型需要外掛知識、語意相似 vs 字面相似、chunking 的本質取捨、retrieval 失敗的根本原因">4.1 RAG 原理&lt;/a> 建立了 vanilla RAG 的骨架——chunk、embed、retrieve、prompt——並列出 hybrid + reranker 的 production 兩段式。本章往上走一層、寫&lt;strong>當 vanilla 兩段式仍不夠時、有哪些增強技術可選&lt;/strong>。&lt;/p>
&lt;p>實務上 vanilla RAG 不夠用的場景比想像多：&lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/query-document-gap/" data-link-title="Query-Document Gap" data-link-desc="使用者 query 與文件語言在詞彙、形態、抽象層級或領域分佈上的落差，是 RAG retrieval miss 的常見原因">query-document gap&lt;/a> 大、單次 retrieve 拿到的片段不足以回答完整問題、retrieve 結果太多塞爆 context、不該 retrieve 的問題被強制 retrieve。每個場景對應不同的增強技術。本章把這些技術寫成可挑選的工具箱、不是「全部都套」的最佳實踐。&lt;/p>
&lt;h2 id="本章目標">本章目標&lt;/h2>
&lt;p>讀完本章後你能：&lt;/p>
&lt;ol>
&lt;li>區分 retrieval pipeline 的四個增強層（query 端 / retrieval 端 / context 組裝端 / 控制流端）。&lt;/li>
&lt;li>對 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/query-document-gap/" data-link-title="Query-Document Gap" data-link-desc="使用者 query 與文件語言在詞彙、形態、抽象層級或領域分佈上的落差，是 RAG retrieval miss 的常見原因">query-document gap&lt;/a> 選對工具（query rewriting / expansion / HyDE）。&lt;/li>
&lt;li>判斷任務需要 multi-step retrieval 還是 single-step 夠用。&lt;/li>
&lt;li>設計 retrieve 後的 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/context-packing/" data-link-title="Context Packing" data-link-desc="RAG retrieve 後把 chunks 去重、排序、壓縮、標來源，再塞進 prompt 的組裝決策">context packing&lt;/a>（dedup、ordering、summarization）。&lt;/li>
&lt;li>設計 adaptive retrieval：什麼時候該 retrieve、什麼時候直接答。&lt;/li>
&lt;/ol>
&lt;h2 id="retrieval-pipeline-的四個增強層">Retrieval Pipeline 的四個增強層&lt;/h2>
&lt;p>Vanilla RAG 是「query → retrieve → prompt」三步。增強分四層、每層解不同問題：&lt;/p>





&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-text" data-lang="text">&lt;span class="line">&lt;span class="ln"> 1&lt;/span>&lt;span class="cl">┌─────────────────────────────────────────────────┐
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 2&lt;/span>&lt;span class="cl">│ User query │
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 3&lt;/span>&lt;span class="cl">└─────────┬───────────────────────────────────────┘
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 4&lt;/span>&lt;span class="cl"> ↓
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 5&lt;/span>&lt;span class="cl"> [1. Query 端增強]
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 6&lt;/span>&lt;span class="cl"> query rewriting / expansion / HyDE / query decomposition
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 7&lt;/span>&lt;span class="cl"> ↓
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 8&lt;/span>&lt;span class="cl"> [2. Retrieval 端增強]
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 9&lt;/span>&lt;span class="cl"> hybrid search + reranker（見 4.1）
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">10&lt;/span>&lt;span class="cl"> multi-step / iterative retrieval
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">11&lt;/span>&lt;span class="cl"> ↓
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">12&lt;/span>&lt;span class="cl"> [3. Context 組裝端]
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">13&lt;/span>&lt;span class="cl"> dedup / ordering / summarization / compression
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">14&lt;/span>&lt;span class="cl"> ↓
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">15&lt;/span>&lt;span class="cl"> [4. 控制流端]
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">16&lt;/span>&lt;span class="cl"> adaptive retrieval（要不要 retrieve）/ self-RAG
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">17&lt;/span>&lt;span class="cl"> ↓
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">18&lt;/span>&lt;span class="cl"> LLM final answer&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>判讀 vanilla 不夠時、先定位失敗在哪一層、再選對應工具。盲目把四層全套上、&lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/retrieval-cost/" data-link-title="Retrieval Cost" data-link-desc="RAG 檢索帶來的 latency、token、embedding、reranker、LLM call 與維護成本，用來判斷增強是否划算">retrieval cost&lt;/a> 跟 latency 翻倍、accuracy 不一定有對應收益。&lt;/p></description><content:encoded><![CDATA[<p><a href="/blog/llm/04-applications/rag-principles/" data-link-title="4.1 RAG 原理：retrieval &#43; augmentation 模式" data-link-desc="為什麼模型需要外掛知識、語意相似 vs 字面相似、chunking 的本質取捨、retrieval 失敗的根本原因">4.1 RAG 原理</a> 建立了 vanilla RAG 的骨架——chunk、embed、retrieve、prompt——並列出 hybrid + reranker 的 production 兩段式。本章往上走一層、寫<strong>當 vanilla 兩段式仍不夠時、有哪些增強技術可選</strong>。</p>
<p>實務上 vanilla RAG 不夠用的場景比想像多：<a href="/blog/llm/knowledge-cards/query-document-gap/" data-link-title="Query-Document Gap" data-link-desc="使用者 query 與文件語言在詞彙、形態、抽象層級或領域分佈上的落差，是 RAG retrieval miss 的常見原因">query-document gap</a> 大、單次 retrieve 拿到的片段不足以回答完整問題、retrieve 結果太多塞爆 context、不該 retrieve 的問題被強制 retrieve。每個場景對應不同的增強技術。本章把這些技術寫成可挑選的工具箱、不是「全部都套」的最佳實踐。</p>
<h2 id="本章目標">本章目標</h2>
<p>讀完本章後你能：</p>
<ol>
<li>區分 retrieval pipeline 的四個增強層（query 端 / retrieval 端 / context 組裝端 / 控制流端）。</li>
<li>對 <a href="/blog/llm/knowledge-cards/query-document-gap/" data-link-title="Query-Document Gap" data-link-desc="使用者 query 與文件語言在詞彙、形態、抽象層級或領域分佈上的落差，是 RAG retrieval miss 的常見原因">query-document gap</a> 選對工具（query rewriting / expansion / HyDE）。</li>
<li>判斷任務需要 multi-step retrieval 還是 single-step 夠用。</li>
<li>設計 retrieve 後的 <a href="/blog/llm/knowledge-cards/context-packing/" data-link-title="Context Packing" data-link-desc="RAG retrieve 後把 chunks 去重、排序、壓縮、標來源，再塞進 prompt 的組裝決策">context packing</a>（dedup、ordering、summarization）。</li>
<li>設計 adaptive retrieval：什麼時候該 retrieve、什麼時候直接答。</li>
</ol>
<h2 id="retrieval-pipeline-的四個增強層">Retrieval Pipeline 的四個增強層</h2>
<p>Vanilla RAG 是「query → retrieve → prompt」三步。增強分四層、每層解不同問題：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="ln"> 1</span><span class="cl">┌─────────────────────────────────────────────────┐
</span></span><span class="line"><span class="ln"> 2</span><span class="cl">│ User query                                      │
</span></span><span class="line"><span class="ln"> 3</span><span class="cl">└─────────┬───────────────────────────────────────┘
</span></span><span class="line"><span class="ln"> 4</span><span class="cl">          ↓
</span></span><span class="line"><span class="ln"> 5</span><span class="cl">   [1. Query 端增強]
</span></span><span class="line"><span class="ln"> 6</span><span class="cl">   query rewriting / expansion / HyDE / query decomposition
</span></span><span class="line"><span class="ln"> 7</span><span class="cl">          ↓
</span></span><span class="line"><span class="ln"> 8</span><span class="cl">   [2. Retrieval 端增強]
</span></span><span class="line"><span class="ln"> 9</span><span class="cl">   hybrid search + reranker（見 4.1）
</span></span><span class="line"><span class="ln">10</span><span class="cl">   multi-step / iterative retrieval
</span></span><span class="line"><span class="ln">11</span><span class="cl">          ↓
</span></span><span class="line"><span class="ln">12</span><span class="cl">   [3. Context 組裝端]
</span></span><span class="line"><span class="ln">13</span><span class="cl">   dedup / ordering / summarization / compression
</span></span><span class="line"><span class="ln">14</span><span class="cl">          ↓
</span></span><span class="line"><span class="ln">15</span><span class="cl">   [4. 控制流端]
</span></span><span class="line"><span class="ln">16</span><span class="cl">   adaptive retrieval（要不要 retrieve）/ self-RAG
</span></span><span class="line"><span class="ln">17</span><span class="cl">          ↓
</span></span><span class="line"><span class="ln">18</span><span class="cl">   LLM final answer</span></span></code></pre></div><p>判讀 vanilla 不夠時、先定位失敗在哪一層、再選對應工具。盲目把四層全套上、<a href="/blog/llm/knowledge-cards/retrieval-cost/" data-link-title="Retrieval Cost" data-link-desc="RAG 檢索帶來的 latency、token、embedding、reranker、LLM call 與維護成本，用來判斷增強是否划算">retrieval cost</a> 跟 latency 翻倍、accuracy 不一定有對應收益。</p>
<h2 id="query-端增強">Query 端增強</h2>
<p>Vanilla RAG 直接用 user query 做 embedding、但 user query 往往不是「最適合 retrieve 的形狀」。Query 端增強就是在 retrieve 前重塑 query。</p>
<h3 id="query-rewriting"><a href="/blog/llm/knowledge-cards/query-rewriting/" data-link-title="Query Rewriting" data-link-desc="在 RAG 檢索前改寫使用者查詢，讓 query 更接近文件語言與索引分佈">Query rewriting</a></h3>
<p>用 LLM 把 user query 改寫成「更接近 document phrasing」的形式。</p>
<ul>
<li><strong>適用</strong>：query 口語、document 正式（如 user：「怎麼讓 API 跑快」、document：「latency optimization techniques」）。</li>
<li><strong>實作</strong>：LLM call、prompt 是「把以下 query 改寫成適合 search 的查詢句、保留語意、改用技術詞彙」。</li>
<li><strong>失效</strong>：rewriting 把意圖改偏（user 問「為什麼慢」、改成「optimization」、答非所問）。緩解：rewriting 提示要求 preserve intent、retrieve 結果回來後讓 LLM 對照原 query 判斷。</li>
<li><strong>Cost</strong>：每 query 多一個 LLM call、latency 加 200–500ms，屬於 <a href="/blog/llm/knowledge-cards/retrieval-cost/" data-link-title="Retrieval Cost" data-link-desc="RAG 檢索帶來的 latency、token、embedding、reranker、LLM call 與維護成本，用來判斷增強是否划算">retrieval cost</a>。</li>
</ul>
<h3 id="query-expansion"><a href="/blog/llm/knowledge-cards/query-expansion/" data-link-title="Query Expansion" data-link-desc="RAG 檢索前把一個 query 擴成多個語意變體，增加 coverage，再合併 retrieval 結果">Query expansion</a></h3>
<p>不改 query、而是<strong>生成多個 query 變體</strong>、一起 retrieve、合併結果。</p>
<ul>
<li><strong>適用</strong>：query 短、有多種可能解讀（「python」可指語言 / shell / 套件）、單一 query 漏 coverage。</li>
<li><strong>實作</strong>：LLM 生成 3–5 個變體（同義改寫、不同角度、不同抽象層級）、每個變體獨立 retrieve、結果用 Reciprocal Rank Fusion 合併（RRF 是 RAG 文獻常見的多 <a href="/blog/llm/knowledge-cards/retrieval-source/" data-link-title="Retrieval Source" data-link-desc="RAG 從哪個 corpus、index、tool 或外部系統取回內容，決定來源可信度、freshness、權限與引用責任">retrieval source</a> 合併演算法、不在本指南範圍展開）。</li>
<li><strong>失效</strong>：變體太發散、混入無關 doc、稀釋了 top-k 的精確度。緩解：限制變體數量（3–5）、合併時對重複出現的 doc 加權。</li>
<li><strong>Cost</strong>：N 倍 <a href="/blog/llm/knowledge-cards/retrieval-cost/" data-link-title="Retrieval Cost" data-link-desc="RAG 檢索帶來的 latency、token、embedding、reranker、LLM call 與維護成本，用來判斷增強是否划算">retrieval cost</a>、但每次 retrieve 是平行、latency 不是 N 倍。</li>
</ul>
<h3 id="hydehypothetical-document-embeddings">HyDE（Hypothetical Document Embeddings）</h3>
<p><a href="/blog/llm/knowledge-cards/hyde/" data-link-title="HyDE（Hypothetical Document Embeddings）" data-link-desc="用 LLM 生成假設文件、對假文件做 embedding 去 retrieve、繞過 query-document gap 的 RAG 增強技術">HyDE</a>（<a href="/blog/llm/04-applications/rag-principles/" data-link-title="4.1 RAG 原理：retrieval &#43; augmentation 模式" data-link-desc="為什麼模型需要外掛知識、語意相似 vs 字面相似、chunking 的本質取捨、retrieval 失敗的根本原因">4.1 RAG 原理</a> 提過、這裡展開）。核心觀察：<strong>query 跟 document 在 embedding 空間的距離、往往比 document 跟 document 之間更遠</strong>——這是 <a href="/blog/llm/knowledge-cards/query-document-gap/" data-link-title="Query-Document Gap" data-link-desc="使用者 query 與文件語言在詞彙、形態、抽象層級或領域分佈上的落差，是 RAG retrieval miss 的常見原因">query-document gap</a> 的典型表現。</p>
<p>機制：</p>
<ol>
<li>用 LLM 對 user query 生成「一份假設的答案文件」（hallucinated document）。</li>
<li>對這份假文件做 embedding、不是對原 query。</li>
<li>用假文件 embedding 去 retrieve 真實 document。</li>
</ol>
<p>為什麼比直接 embed query 好：假文件的 phrasing、長度、結構都更接近 document 分佈、embedding 距離更可靠。<strong>重點是 retrieval、不是回答</strong>——假文件的事實正確性不重要（hallucinate 出錯誤細節 OK）、但語意 / 領域要落在對的範圍、才能拉回對的 document。</p>
<ul>
<li><strong>適用</strong>：<a href="/blog/llm/knowledge-cards/query-document-gap/" data-link-title="Query-Document Gap" data-link-desc="使用者 query 與文件語言在詞彙、形態、抽象層級或領域分佈上的落差，是 RAG retrieval miss 的常見原因">query-document gap</a> 顯著的場景（問句 vs 陳述、口語 vs 正式、抽象 vs 技術詞彙）。HyDE 原論文跨多個領域 benchmark 都有提升、不限技術 / 學術。</li>
<li><strong>失效</strong>：假文件偏離主題（LLM hallucinate 到別的領域）、retrieve 拿到完全不相關的東西。緩解：生成多個假文件取平均 embedding、或用 query + 假文件兩個 embedding 合併 retrieve。</li>
<li><strong>Cost</strong>：每 query 多一個 LLM call（生假文件）、latency 加 500ms–1s。</li>
</ul>
<h3 id="query-decomposition"><a href="/blog/llm/knowledge-cards/query-decomposition/" data-link-title="Query Decomposition" data-link-desc="把複合 query 拆成可獨立檢索的子 query，平行取得證據後再合成答案">Query decomposition</a></h3>
<p>把複雜 query 拆成幾個子 query、各自 retrieve、再合併。</p>
<ul>
<li><strong>適用</strong>：複合問題（「比較 A 跟 B 在 X 跟 Y 的差異」）、單次 retrieve 拿到的 chunk 不完整。</li>
<li><strong>跟 multi-step retrieval 的差異</strong>：decomposition 是「一次拆成 N 個 query 平行 retrieve」、multi-step 是「retrieve → 看結果 → decide 下一個 query」。前者快、後者貼近資料。</li>
<li><strong>失效</strong>：子 query 之間有依賴（後面的 query 要看前面的結果）、平行做不出來、要走 multi-step。</li>
</ul>
<h3 id="何時用哪個">何時用哪個</h3>
<table>
  <thead>
      <tr>
          <th>Query 問題</th>
          <th>對應技術</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>用詞跟 document 落差大</td>
          <td>Query rewriting</td>
      </tr>
      <tr>
          <td>Query 太短 / 有歧義</td>
          <td><a href="/blog/llm/knowledge-cards/query-expansion/" data-link-title="Query Expansion" data-link-desc="RAG 檢索前把一個 query 擴成多個語意變體，增加 coverage，再合併 retrieval 結果">Query expansion</a></td>
      </tr>
      <tr>
          <td>Query-document 形態落差（問句 vs 陳述）</td>
          <td>HyDE</td>
      </tr>
      <tr>
          <td>複合問題、子問題彼此獨立</td>
          <td><a href="/blog/llm/knowledge-cards/query-decomposition/" data-link-title="Query Decomposition" data-link-desc="把複合 query 拆成可獨立檢索的子 query，平行取得證據後再合成答案">Query decomposition</a></td>
      </tr>
      <tr>
          <td>子問題彼此依賴</td>
          <td>Multi-step（下一節）</td>
      </tr>
  </tbody>
</table>
<p>實務上 query rewriting 跟 HyDE 是首選——cost 低、改 prompt 即可、收益穩。Expansion 跟 decomposition 在特定 query 形態才有顯著收益、預設不開。</p>
<h2 id="multi-step--iterative-retrieval"><a href="/blog/llm/knowledge-cards/multi-step-retrieval/" data-link-title="Multi-Step Retrieval" data-link-desc="RAG 中多輪 retrieve → 判斷 → 再 retrieve 的控制流，用來處理 multi-hop 問題">Multi-step / Iterative Retrieval</a></h2>
<p>Single-step retrieve 假設「一次 retrieve 拿到所有需要的 chunk」、但多 hop 問題（要從 doc A 找到 entity X、再從 doc B 找 X 的屬性）這個假設不成立。Multi-step retrieval 是 retrieve → LLM 判斷夠不夠 → 不夠就再 retrieve、靠 LLM 的判斷決定 retrieve 路徑。</p>
<p>機制：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="ln"> 1</span><span class="cl">Initial query
</span></span><span class="line"><span class="ln"> 2</span><span class="cl">   ↓
</span></span><span class="line"><span class="ln"> 3</span><span class="cl">Retrieve round 1 → top-k chunks
</span></span><span class="line"><span class="ln"> 4</span><span class="cl">   ↓
</span></span><span class="line"><span class="ln"> 5</span><span class="cl">LLM：「這些 chunks 夠回答嗎？若不夠、下一個該 retrieve 什麼？」
</span></span><span class="line"><span class="ln"> 6</span><span class="cl">   ↓ (不夠)
</span></span><span class="line"><span class="ln"> 7</span><span class="cl">Generate sub-query 2
</span></span><span class="line"><span class="ln"> 8</span><span class="cl">   ↓
</span></span><span class="line"><span class="ln"> 9</span><span class="cl">Retrieve round 2 → top-k chunks
</span></span><span class="line"><span class="ln">10</span><span class="cl">   ↓
</span></span><span class="line"><span class="ln">11</span><span class="cl">LLM 判斷
</span></span><span class="line"><span class="ln">12</span><span class="cl">   ↓ (夠)
</span></span><span class="line"><span class="ln">13</span><span class="cl">Final answer</span></span></code></pre></div><p>跟 vanilla single-step 的差異：</p>
<ul>
<li><strong>靈活</strong>：retrieve 路徑是 query-dependent、不是固定。</li>
<li><strong>昂貴</strong>：每 round 加一個 LLM call + retrieve、latency 跟 cost 線性疊加。</li>
<li><strong>失敗模式</strong>：LLM 判斷「不夠」的能力差、無限 retrieve；或判斷「夠了」太樂觀、缺資訊還是答。</li>
</ul>
<p>對應 <a href="/blog/llm/04-applications/agent-architecture/" data-link-title="4.4 Agent 架構原理" data-link-desc="Agent loop 結構、失敗模式、什麼任務適合 vs 不適合、跟人類審查的協作模型">4.4 agent 架構</a> 的失敗模式分類：multi-step retrieval 是 agent loop 的特例、context drift / goal drift 一樣會發生。</p>
<h3 id="multi-hop-推理的核心模式">Multi-hop 推理的核心模式</h3>
<p>Multi-hop 問題的典型 pattern：「A 跟 B 有什麼共同點」、需要先 retrieve A 的屬性、再 retrieve B 的屬性、再 compare。Single-step retrieve 不會自動把這兩組 chunk 都抓回來。</p>
<p>Multi-step retrieval 在這類問題上的 accuracy 提升明顯、但 trade-off 是 latency 翻倍以上、cost 翻倍以上。</p>
<h3 id="multi-step-划算的三條件">Multi-step 划算的三條件</h3>
<p>三條件全滿足才走 multi-step、任一不滿足就停在 single-step：</p>
<ul>
<li><strong>問題確實 multi-hop</strong>：需要 retrieve A → 推 X → retrieve B 的形態。Single-hop 問題硬套 multi-step 純增加 cost。</li>
<li><strong>Latency budget 允許</strong>：每 round 加 1-2 秒、即時 chatbot 場景通常不容許、batch 場景才行。</li>
<li><strong>有客觀停止訊號</strong>：可用 deterministic check 判斷「夠了」、不是純靠 LLM 自評。沒有停止訊號容易無限 loop。</li>
</ul>
<h2 id="context-packingretrieve-拿到後怎麼塞進-prompt"><a href="/blog/llm/knowledge-cards/context-packing/" data-link-title="Context Packing" data-link-desc="RAG retrieve 後把 chunks 去重、排序、壓縮、標來源，再塞進 prompt 的組裝決策">Context packing</a>：retrieve 拿到後怎麼塞進 prompt</h2>
<p>Retrieve 拿到 top-k chunks 後、怎麼塞進 prompt 不是「直接 concat」這麼簡單。Context 組裝端的決策影響最終 accuracy 跟 cost。</p>
<h3 id="dedup">Dedup</h3>
<p>不同 chunk 可能涵蓋同樣內容（同段文字被多個版本切到、或不同 doc 引用同一個事實）。直接 concat 浪費 context budget。</p>
<ul>
<li><strong>實作</strong>：semantic dedup（embedding 距離小於 threshold 視為重複）、或字面 dedup（hash 比對）。</li>
<li><strong>失敗</strong>：dedup 太激進、誤殺有用 chunk；dedup 不夠、context 塞重複內容。</li>
</ul>
<h3 id="ordering">Ordering</h3>
<p>塞進 prompt 的 chunk 順序影響 LLM 注意力。LLM 對 context 開頭跟結尾的注意力比中間強（<a href="/blog/llm/knowledge-cards/lost-in-the-middle/" data-link-title="Lost in the Middle" data-link-desc="LLM 對 long context 中段內容的 attention / recall 顯著低於開頭與結尾的現象">lost-in-the-middle</a> 現象、深度討論見 <a href="/blog/llm/04-applications/long-context-engineering/" data-link-title="4.11 Long context engineering" data-link-desc="128K / 1M context 模型怎麼用：claimed vs effective context、lost-in-the-middle、context 設計策略、Long context vs RAG 取捨">4.11 long context engineering</a>）。</p>
<ul>
<li><strong>策略一：relevance ordering</strong>：最相關的 chunk 放最前 / 最後、不重要的放中間。Trade-off：依賴 retrieval 的 ranking 準。</li>
<li><strong>策略二：document order</strong>：按原文順序排（同一 doc 的 chunk 連起來）。Trade-off：保留邏輯流、但相關性散落。</li>
<li><strong>策略三：mixed</strong>：top-3 放最前、top-4 到 top-K 按 document order 放後面。</li>
</ul>
<h3 id="summarization--compression">Summarization / compression</h3>
<p>Retrieve 拿到的 chunk 太多、塞不進 context。兩條路：</p>
<ul>
<li><strong>Summarization</strong>：用 LLM 把 chunks 摘要成更短的版本、再餵主 LLM。</li>
<li><strong>Compression</strong>：用較小模型抽出 chunks 中跟 query 相關的句子、丟掉無關部分。</li>
</ul>
<p>Trade-off：</p>
<table>
  <thead>
      <tr>
          <th>路線</th>
          <th>收益</th>
          <th>代價</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Summarization</td>
          <td>Context 大幅縮、保留意義</td>
          <td>多一個 LLM call、可能漏細節</td>
      </tr>
      <tr>
          <td>Compression</td>
          <td>保留原文片段、可 traceable</td>
          <td>抽錯關鍵句、漏關鍵資訊</td>
      </tr>
      <tr>
          <td>Naïve concat（全塞）</td>
          <td>實作最簡、不漏資訊</td>
          <td>Token cost 高、lost-in-the-middle 風險高</td>
      </tr>
  </tbody>
</table>
<h3 id="source-attribution"><a href="/blog/llm/knowledge-cards/retrieval-source/" data-link-title="Retrieval Source" data-link-desc="RAG 從哪個 corpus、index、tool 或外部系統取回內容，決定來源可信度、freshness、權限與引用責任">Source attribution</a></h3>
<p>Retrieve 拿到的 chunk 進 prompt 時、要不要標來源，是 retrieval source 的追溯責任問題。</p>
<ul>
<li><strong>標</strong>：LLM 可以引用、提升可信度、user 可以 verify。Cost：每 chunk 加幾十 token。</li>
<li><strong>不標</strong>：context 短、但 LLM 沒法引用、user 沒法追溯。</li>
</ul>
<p>實務多半標、特別是法律 / 醫療 / 學術場景。</p>
<h2 id="控制流端要不要-retrieve">控制流端：要不要 retrieve</h2>
<p>Vanilla RAG 對每個 query 都 retrieve、不問該不該。實務上有些 query 不需要外部資料（「現在幾點」「2+2 等於多少」「翻譯這段文字」）、強制 retrieve 反而塞無關 chunk 干擾，也會浪費 <a href="/blog/llm/knowledge-cards/retrieval-cost/" data-link-title="Retrieval Cost" data-link-desc="RAG 檢索帶來的 latency、token、embedding、reranker、LLM call 與維護成本，用來判斷增強是否划算">retrieval cost</a>。</p>
<h3 id="adaptive-retrieval"><a href="/blog/llm/knowledge-cards/adaptive-retrieval/" data-link-title="Adaptive Retrieval" data-link-desc="RAG 控制流中先判斷是否需要檢索，只在外部知識有價值時才 retrieve">Adaptive retrieval</a></h3>
<p>讓 LLM 自己決定 retrieve 與否。</p>
<ul>
<li><strong>路線一：predict-then-retrieve</strong>：先用小模型 / 規則判斷 query 類型（factual / reasoning / chitchat）、factual 才 retrieve。</li>
<li><strong>路線二：self-RAG</strong>：LLM 在生成過程中、輸出特殊 token 「我需要 retrieve」、觸發 retrieve、整合結果繼續生成。需要訓練過或 prompt engineered 的模型支援。</li>
</ul>
<p>判讀 adaptive retrieval 是否有用：</p>
<ul>
<li>Query 分佈：若 80% query 都需要 retrieve、adaptive 收益小、固定 retrieve 就好。</li>
<li>Query 分佈：若 query 一半 chitchat 一半 factual、adaptive 減半 <a href="/blog/llm/knowledge-cards/retrieval-cost/" data-link-title="Retrieval Cost" data-link-desc="RAG 檢索帶來的 latency、token、embedding、reranker、LLM call 與維護成本，用來判斷增強是否划算">retrieval cost</a>、收益大。</li>
</ul>
<h3 id="confidence-based-retrieval">Confidence-based retrieval</h3>
<p>LLM 先嘗試直接答、若 confidence 低（self-report 或 logits 機率）、再 retrieve。</p>
<ul>
<li><strong>適用</strong>：模型對部分 query 有把握、部分沒、想省 <a href="/blog/llm/knowledge-cards/retrieval-cost/" data-link-title="Retrieval Cost" data-link-desc="RAG 檢索帶來的 latency、token、embedding、reranker、LLM call 與維護成本，用來判斷增強是否划算">retrieval cost</a>。</li>
<li><strong>失敗</strong>：模型過度自信、low-confidence 訊號不準、該 retrieve 沒 retrieve。</li>
</ul>
<h2 id="失敗模式增強堆疊出反效果">失敗模式：增強堆疊出反效果</h2>
<p>不同層的增強可以堆、但堆過頭會反效果：</p>
<ul>
<li><strong>Query rewriting + HyDE + expansion 全開</strong>：query 端 noise 過多、retrieve 結果稀釋、accuracy 反降。</li>
<li><strong>Multi-step + reranker + summarization 全開</strong>：每 round latency 累積到使用者不能忍受。</li>
<li><strong>Adaptive + multi-step 混亂</strong>：adaptive 說「不 retrieve」、但 multi-step 又觸發 retrieve、控制流互打。</li>
</ul>
<p>設計反射動作：先確認 vanilla RAG（hybrid + reranker）的失敗在哪一層、針對性加一個增強、看是否有收益、有再加下一個。<strong>不要四層全套</strong>。</p>
<h2 id="跟相鄰章節的邊界">跟相鄰章節的邊界</h2>
<ul>
<li><strong>vs <a href="/blog/llm/04-applications/rag-principles/" data-link-title="4.1 RAG 原理：retrieval &#43; augmentation 模式" data-link-desc="為什麼模型需要外掛知識、語意相似 vs 字面相似、chunking 的本質取捨、retrieval 失敗的根本原因">4.1 RAG 原理</a></strong>：4.1 寫 vanilla 骨架跟 production 兩段式（hybrid + reranker），這章寫進一步增強。</li>
<li><strong>vs <a href="/blog/llm/04-applications/long-context-engineering/" data-link-title="4.11 Long context engineering" data-link-desc="128K / 1M context 模型怎麼用：claimed vs effective context、lost-in-the-middle、context 設計策略、Long context vs RAG 取捨">4.11 long context engineering</a></strong>：long context 是「context 大到能塞」、RAG 是「context 不夠要 retrieve」、兩者是不同 regime 的策略。本章 <a href="/blog/llm/knowledge-cards/context-packing/" data-link-title="Context Packing" data-link-desc="RAG retrieve 後把 chunks 去重、排序、壓縮、標來源，再塞進 prompt 的組裝決策">context packing</a> 段的 lost-in-the-middle 是兩個 regime 的共通議題。</li>
<li><strong>vs <a href="/blog/llm/04-applications/workflow-patterns/" data-link-title="4.7 Workflow 編排模式" data-link-desc="Pipeline / router / parallel / reflection：多 LLM call 組合的四種基本模式與退化條件">4.7 workflow patterns</a></strong>：multi-step retrieval 是 workflow pattern 在 RAG 場景的特例。</li>
</ul>
<h2 id="何時過時--何時不過時">何時過時 / 何時不過時</h2>
<p><strong>不會過時的部分</strong>：</p>
<ul>
<li>四層增強分類（query / retrieval / context 組裝 / 控制流）的座標。</li>
<li>各 query 端技術解的核心問題（用詞落差 / 歧義 / 形態落差 / 複合問題）。</li>
<li>Multi-step retrieval 跟 single-step 的 trade-off 結構。</li>
<li>Context 組裝的三個議題（dedup / ordering / compression）。</li>
<li>「先 vanilla、再針對失敗加增強」的設計反射。</li>
</ul>
<p><strong>會變的部分</strong>：</p>
<ul>
<li>HyDE 等特定方法的最佳實作（隨 embedding 模型演化、效果會變）。</li>
<li>Self-RAG 等需要訓練的方法（隨 base model alignment 訓練成熟、可能變預設能力）。</li>
<li>各家 reranker 跟 embedding 模型的選型（半年一個世代）。</li>
</ul>
<h2 id="下一章">下一章</h2>
<p>下一章：<a href="/blog/llm/04-applications/tool-use-principles/" data-link-title="4.3 Tool use 原理：LLM 跟外部世界互動" data-link-desc="Structured output 是 LLM 跨入工程系統的橋、function calling 取捨、為什麼本地小模型 tool use 表現崩潰">4.3 Tool use 原理</a>、從「LLM 讀外部資料」延伸到「LLM 對外部世界做事」。Vanilla RAG 的骨架見 <a href="/blog/llm/04-applications/rag-principles/" data-link-title="4.1 RAG 原理：retrieval &#43; augmentation 模式" data-link-desc="為什麼模型需要外掛知識、語意相似 vs 字面相似、chunking 的本質取捨、retrieval 失敗的根本原因">4.1</a>、long context 跟 RAG 的取捨見 <a href="/blog/llm/04-applications/long-context-engineering/" data-link-title="4.11 Long context engineering" data-link-desc="128K / 1M context 模型怎麼用：claimed vs effective context、lost-in-the-middle、context 設計策略、Long context vs RAG 取捨">4.11</a>、multi-step 跟 reflection 的失敗模式比對見 <a href="/blog/llm/04-applications/workflow-patterns/" data-link-title="4.7 Workflow 編排模式" data-link-desc="Pipeline / router / parallel / reflection：多 LLM call 組合的四種基本模式與退化條件">4.7</a>。</p>
]]></content:encoded></item></channel></rss>