<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>BM25 on Khari Z's LogBook</title><link>https://n571e.github.io/tags/bm25/</link><description>Recent content in BM25 on Khari Z's LogBook</description><generator>Hugo -- gohugo.io</generator><language>zh-cn</language><lastBuildDate>Fri, 15 May 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://n571e.github.io/tags/bm25/index.xml" rel="self" type="application/rss+xml"/><item><title>多路召回学习笔记：BM25、Embedding、SPLADE 和 Reranker 各在解决什么</title><link>https://n571e.github.io/p/multi-recall-retrieval-notes/</link><pubDate>Fri, 15 May 2026 00:00:00 +0000</pubDate><guid>https://n571e.github.io/p/multi-recall-retrieval-notes/</guid><description>&lt;p&gt;最近在补 RAG 和检索系统的基础。刚开始看资料时，最容易混在一起的几个词就是：&lt;code&gt;BM25&lt;/code&gt;、&lt;code&gt;Embedding&lt;/code&gt;、&lt;code&gt;SPLADE&lt;/code&gt;、&lt;code&gt;Reranker&lt;/code&gt;，再加一个听起来很工程的词：多路召回。&lt;/p&gt;&#10;&lt;p&gt;单独看定义不难，难点在于把它们放进同一条检索链路里。复习时重点回答这些问题：&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;哪些方法负责“先找一批候选”？&lt;/li&gt;&#10;&lt;li&gt;哪些方法负责“把候选重新排好”？&lt;/li&gt;&#10;&lt;li&gt;BM25 和 Embedding 明明都能搜，为什么还要一起用？&lt;/li&gt;&#10;&lt;li&gt;Reranker 听起来更准，为什么不直接全库跑？&lt;/li&gt;&#10;&lt;li&gt;SPLADE 到底是关键词检索，还是语义检索？&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;这篇笔记不铺满公式，重点讲清每种方法在检索系统里的位置、优势和边界。&lt;/p&gt;&#10;&lt;hr&gt;&#10;&lt;h2 id="速读版"&gt;&lt;a href="#%e9%80%9f%e8%af%bb%e7%89%88" class="header-anchor"&gt;&lt;/a&gt;速读版&#10;&lt;/h2&gt;&lt;p&gt;先给一个压缩版结论：&lt;/p&gt;&#10;&lt;table&gt;&#10;&#9;&lt;thead&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;方法&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;系统位置&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;主要解决&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;优点&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;短板&lt;/th&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/thead&gt;&#10;&#9;&lt;tbody&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;BM25&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;关键词搜索&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;字面精确命中&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;快、可解释、对术语敏感&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;不懂同义表达&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Embedding&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;语义近邻搜索&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;意思接近但字面不同&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;泛化强，适合自然语言问题&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;细粒度容易混&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;SPLADE&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;神经稀疏搜索&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;语义扩展后的关键词匹配&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;兼顾稀疏结构和语义扩展&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;模型和索引更复杂&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Reranker&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;精排裁判&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;少量候选谁最相关&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;判断细，通常更准&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;慢，不适合全库扫描&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;p&gt;一条典型链路大概是：&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;&#10;&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1&#10;&lt;/span&gt;&lt;span class="lnt"&gt;2&#10;&lt;/span&gt;&lt;span class="lnt"&gt;3&#10;&lt;/span&gt;&lt;span class="lnt"&gt;4&#10;&lt;/span&gt;&lt;span class="lnt"&gt;5&#10;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#10;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;用户 query&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; -&amp;gt; BM25 / Embedding / SPLADE 多路召回&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; -&amp;gt; 候选合并、去重、分数融合&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; -&amp;gt; Reranker 精排&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; -&amp;gt; 返回 top-k 或交给下游生成模型&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&lt;p&gt;多路召回要解决的是：&lt;strong&gt;不要让单一检索方法承担所有召回责任，而是让不同方法互相补盲区。&lt;/strong&gt;&lt;/p&gt;&#10;&lt;hr&gt;&#10;&lt;h2 id="一先分清召回和精排"&gt;&lt;a href="#%e4%b8%80%e5%85%88%e5%88%86%e6%b8%85%e5%8f%ac%e5%9b%9e%e5%92%8c%e7%b2%be%e6%8e%92" class="header-anchor"&gt;&lt;/a&gt;一、先分清召回和精排&#10;&lt;/h2&gt;&lt;p&gt;搜索系统一般不会一开始就让最复杂的模型扫描整个文档库。文档量一大，成本会很高。&lt;/p&gt;&#10;&lt;p&gt;所以它会分成两步：&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;&#10;&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1&#10;&lt;/span&gt;&lt;span class="lnt"&gt;2&#10;&lt;/span&gt;&lt;span class="lnt"&gt;3&#10;&lt;/span&gt;&lt;span class="lnt"&gt;4&#10;&lt;/span&gt;&lt;span class="lnt"&gt;5&#10;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#10;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Recall 召回&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; 从大量文档里快速捞出一批“可能相关”的候选。&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Ranking / Reranking 排序或精排&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; 在候选集合变小之后，再认真比较谁更相关。&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&lt;p&gt;召回阶段的目标是“尽量别漏掉相关候选”；精排阶段的目标是“在候选里排得更准”。&lt;/p&gt;&#10;&lt;p&gt;BM25、Embedding、SPLADE 通常更适合放在召回阶段；Reranker 通常更适合放在精排阶段。&lt;/p&gt;&#10;&lt;hr&gt;&#10;&lt;h2 id="二bm25最经典的关键词检索"&gt;&lt;a href="#%e4%ba%8cbm25%e6%9c%80%e7%bb%8f%e5%85%b8%e7%9a%84%e5%85%b3%e9%94%ae%e8%af%8d%e6%a3%80%e7%b4%a2" class="header-anchor"&gt;&lt;/a&gt;二、BM25：最经典的关键词检索&#10;&lt;/h2&gt;&lt;p&gt;BM25 是传统搜索里很经典的方法。它不理解深层语义，也不做推理，主要看一个问题：&lt;/p&gt;&#10;&#10; &lt;blockquote&gt;&#10; &lt;p&gt;query 里的词，在文档里有没有出现？出现的词有没有区分度？&lt;/p&gt;&#10;&#10; &lt;/blockquote&gt;&#10;&lt;p&gt;比如用户搜：&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;&#10;&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1&#10;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#10;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;酒店住宿报销&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&lt;p&gt;如果一篇文档里出现了“酒店”“住宿”“报销”，它就应该比完全没出现这些词的文档更相关。&lt;/p&gt;&#10;&lt;p&gt;BM25 可以先记成：&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;&#10;&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1&#10;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#10;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;BM25 分数 ≈ 词频 TF × 逆文档频率 IDF × 文档长度修正&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&lt;p&gt;复习时先理解这三个部分，再回到完整公式。&lt;/p&gt;&#10;&lt;h3 id="21-词频命中-query-词说明可能相关"&gt;&lt;a href="#21-%e8%af%8d%e9%a2%91%e5%91%bd%e4%b8%ad-query-%e8%af%8d%e8%af%b4%e6%98%8e%e5%8f%af%e8%83%bd%e7%9b%b8%e5%85%b3" class="header-anchor"&gt;&lt;/a&gt;2.1 词频：命中 query 词，说明可能相关&#10;&lt;/h3&gt;&lt;p&gt;如果 query 里有“住宿”，文档 A 出现了“住宿”，文档 B 没出现，那文档 A 大概率更相关。&lt;/p&gt;&#10;&lt;p&gt;但 BM25 不会让词频无限加分。一个词重复出现很多次，并不代表相关性可以无限升高。所以 BM25 会对词频做饱和处理。&lt;/p&gt;&#10;&lt;h3 id="22-idf越少见的词越有区分度"&gt;&lt;a href="#22-idf%e8%b6%8a%e5%b0%91%e8%a7%81%e7%9a%84%e8%af%8d%e8%b6%8a%e6%9c%89%e5%8c%ba%e5%88%86%e5%ba%a6" class="header-anchor"&gt;&lt;/a&gt;2.2 IDF：越少见的词，越有区分度&#10;&lt;/h3&gt;&lt;p&gt;有些词太常见：&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;&#10;&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1&#10;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#10;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;申请、说明、费用、管理、流程&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&lt;p&gt;它们出现了当然有一点信息，但区分度不强。&lt;/p&gt;&#10;&lt;p&gt;有些词更具体：&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;&#10;&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1&#10;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#10;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;住宿、发票、差旅、押金、手续费&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&lt;p&gt;这些词更能帮助判断文档主题。&lt;/p&gt;&#10;&lt;p&gt;这就是 IDF 的直觉：一个词在全库里越少见，它越能区分文档。&lt;/p&gt;&#10;&lt;h3 id="23-文档长度修正长文档不能天然占便宜"&gt;&lt;a href="#23-%e6%96%87%e6%a1%a3%e9%95%bf%e5%ba%a6%e4%bf%ae%e6%ad%a3%e9%95%bf%e6%96%87%e6%a1%a3%e4%b8%8d%e8%83%bd%e5%a4%a9%e7%84%b6%e5%8d%a0%e4%be%bf%e5%ae%9c" class="header-anchor"&gt;&lt;/a&gt;2.3 文档长度修正：长文档不能天然占便宜&#10;&lt;/h3&gt;&lt;p&gt;长文档词多，命中 query 词的概率天然更高。如果不修正，长文档会占便宜。&lt;/p&gt;&#10;&lt;p&gt;BM25 会考虑文档长度，让“短但精准命中”的文档也有机会排在前面。&lt;/p&gt;&#10;&lt;h3 id="24-bm25-的位置"&gt;&lt;a href="#24-bm25-%e7%9a%84%e4%bd%8d%e7%bd%ae" class="header-anchor"&gt;&lt;/a&gt;2.4 BM25 的位置&#10;&lt;/h3&gt;&lt;p&gt;BM25 特别适合这些场景：&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;搜索专有名词&lt;/li&gt;&#10;&lt;li&gt;搜索编号、代码、实体名&lt;/li&gt;&#10;&lt;li&gt;搜索业务词或固定术语&lt;/li&gt;&#10;&lt;li&gt;需要可解释的检索结果&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;比如：&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;&#10;&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1&#10;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#10;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;增值税专用发票&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&lt;p&gt;如果文档里明确出现这个词，BM25 的表现通常很稳。&lt;/p&gt;&#10;&lt;p&gt;它的短板也很明显：不太懂同义词。&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;&#10;&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1&#10;&lt;/span&gt;&lt;span class="lnt"&gt;2&#10;&lt;/span&gt;&lt;span class="lnt"&gt;3&#10;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#10;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;住酒店&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;住宿费&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;差旅住宿支出&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&lt;p&gt;这些表达意思接近，但字面不完全一样。如果没有共同词，BM25 可能就会漏。&lt;/p&gt;&#10;&lt;p&gt;复习锚点：BM25 适合作为基础召回，尤其适合术语、编号、实体名；短板是同义表达和口语化改写。&lt;/p&gt;&#10;&lt;hr&gt;&#10;&lt;h2 id="三embedding把文本放进语义空间"&gt;&lt;a href="#%e4%b8%89embedding%e6%8a%8a%e6%96%87%e6%9c%ac%e6%94%be%e8%bf%9b%e8%af%ad%e4%b9%89%e7%a9%ba%e9%97%b4" class="header-anchor"&gt;&lt;/a&gt;三、Embedding：把文本放进语义空间&#10;&lt;/h2&gt;&lt;p&gt;Embedding 的思路和 BM25 不同。BM25 看词有没有命中；Embedding 把文本编码成向量。&lt;/p&gt;&#10;&lt;p&gt;语义相近的文本，在向量空间里应该更接近。&lt;/p&gt;&#10;&lt;p&gt;比如：&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;&#10;&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1&#10;&lt;/span&gt;&lt;span class="lnt"&gt;2&#10;&lt;/span&gt;&lt;span class="lnt"&gt;3&#10;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#10;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;员工出差住酒店&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;差旅住宿费用&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;酒店房费报销&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&lt;p&gt;这些句子字面不同，但语义接近。好的 Embedding 模型会尽量把它们编码到相近的位置。&lt;/p&gt;&#10;&lt;p&gt;检索时通常是这样：&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;&#10;&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1&#10;&lt;/span&gt;&lt;span class="lnt"&gt;2&#10;&lt;/span&gt;&lt;span class="lnt"&gt;3&#10;&lt;/span&gt;&lt;span class="lnt"&gt;4&#10;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#10;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;文档库里的文档 -&amp;gt; 提前编码成向量&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;用户 query -&amp;gt; 编码成向量&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;计算 query 向量和文档向量的相似度&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;返回最相似的 top-k 文档&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&lt;p&gt;最常见的相似度是余弦相似度：&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;&#10;&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1&#10;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#10;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;cosine similarity = 两个向量方向的接近程度&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&lt;p&gt;它关心的是方向，而不是文本长度。两个文本语义越接近，向量夹角通常越小，相似度越高。&lt;/p&gt;&#10;&lt;h3 id="31-embedding-解决了-bm25-的一部分盲区"&gt;&lt;a href="#31-embedding-%e8%a7%a3%e5%86%b3%e4%ba%86-bm25-%e7%9a%84%e4%b8%80%e9%83%a8%e5%88%86%e7%9b%b2%e5%8c%ba" class="header-anchor"&gt;&lt;/a&gt;3.1 Embedding 解决了 BM25 的一部分盲区&#10;&lt;/h3&gt;&lt;p&gt;用户的问题往往很口语化：&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;&#10;&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1&#10;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#10;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;出差住酒店怎么报销&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&lt;p&gt;文档标题可能是：&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;&#10;&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1&#10;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#10;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;差旅住宿费用管理办法&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&lt;p&gt;BM25 如果没有命中关键分词，可能不够稳；Embedding 更可能从整体意思上判断它们相关。&lt;/p&gt;&#10;&lt;p&gt;Embedding 适合：&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;同义表达&lt;/li&gt;&#10;&lt;li&gt;口语化 query&lt;/li&gt;&#10;&lt;li&gt;标题和问题表达方式不一致&lt;/li&gt;&#10;&lt;li&gt;需要整体语义理解的场景&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h3 id="32-embedding-也会犯语义太近的错"&gt;&lt;a href="#32-embedding-%e4%b9%9f%e4%bc%9a%e7%8a%af%e8%af%ad%e4%b9%89%e5%a4%aa%e8%bf%91%e7%9a%84%e9%94%99" class="header-anchor"&gt;&lt;/a&gt;3.2 Embedding 也会犯“语义太近”的错&#10;&lt;/h3&gt;&lt;p&gt;Embedding 的问题是，它有时会太模糊。&lt;/p&gt;&#10;&lt;p&gt;比如：&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;&#10;&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1&#10;&lt;/span&gt;&lt;span class="lnt"&gt;2&#10;&lt;/span&gt;&lt;span class="lnt"&gt;3&#10;&lt;/span&gt;&lt;span class="lnt"&gt;4&#10;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#10;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;技术服务费&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;咨询服务费&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;软件服务费&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;会议服务费&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&lt;p&gt;从语义上看都和“服务”有关，向量空间里可能靠得很近。但在实际业务里，它们可能需要被分到不同类别。&lt;/p&gt;&#10;&lt;p&gt;复习锚点：Embedding 擅长找“语义相近”的内容，但在术语边界、细分类别、编号实体上可能不够精确。因此它常和 BM25 搭配使用。&lt;/p&gt;&#10;&lt;hr&gt;&#10;&lt;h2 id="四为什么需要多路召回"&gt;&lt;a href="#%e5%9b%9b%e4%b8%ba%e4%bb%80%e4%b9%88%e9%9c%80%e8%a6%81%e5%a4%9a%e8%b7%af%e5%8f%ac%e5%9b%9e" class="header-anchor"&gt;&lt;/a&gt;四、为什么需要多路召回&#10;&lt;/h2&gt;&lt;p&gt;BM25 和 Embedding 的优缺点互补。BM25 负责词面命中，Embedding 负责语义相近；SPLADE 可以补充神经稀疏召回。多路召回就是同时跑多种召回方法，再合并候选：&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;&#10;&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1&#10;&lt;/span&gt;&lt;span class="lnt"&gt;2&#10;&lt;/span&gt;&lt;span class="lnt"&gt;3&#10;&lt;/span&gt;&lt;span class="lnt"&gt;4&#10;&lt;/span&gt;&lt;span class="lnt"&gt;5&#10;&lt;/span&gt;&lt;span class="lnt"&gt;6&#10;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#10;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;BM25 召回一批&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Embedding 召回一批&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;SPLADE 也可以召回一批&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; -&amp;gt; 合并候选&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; -&amp;gt; 去重&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; -&amp;gt; 融合或重排&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&lt;p&gt;举个简单例子。&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;&#10;&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1&#10;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#10;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;query: 出差住酒店怎么报销&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&lt;p&gt;BM25 可能找到：&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;&#10;&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1&#10;&lt;/span&gt;&lt;span class="lnt"&gt;2&#10;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#10;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;酒店发票填写要求&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;住宿费报销单填写说明&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&lt;p&gt;Embedding 可能找到：&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;&#10;&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1&#10;&lt;/span&gt;&lt;span class="lnt"&gt;2&#10;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#10;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;差旅费用管理办法&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;员工出差报销流程&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&lt;p&gt;两路结果合起来，比单独用一路更稳。&lt;/p&gt;&#10;&lt;h3 id="41-分数不能直接相加"&gt;&lt;a href="#41-%e5%88%86%e6%95%b0%e4%b8%8d%e8%83%bd%e7%9b%b4%e6%8e%a5%e7%9b%b8%e5%8a%a0" class="header-anchor"&gt;&lt;/a&gt;4.1 分数不能直接相加&#10;&lt;/h3&gt;&lt;p&gt;多路召回带来一个麻烦：不同方法的分数不是一个尺度。&lt;/p&gt;&#10;&lt;p&gt;BM25 可能返回：&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;&#10;&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1&#10;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#10;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;12.7, 8.3, 3.1&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&lt;p&gt;Embedding 的余弦相似度可能是：&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;&#10;&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1&#10;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#10;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;0.82, 0.77, 0.65&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&lt;p&gt;这些分数不能直接相加。&lt;/p&gt;&#10;&lt;p&gt;常见处理方法有两类。&lt;/p&gt;&#10;&lt;p&gt;第一类是分数归一化，例如 min-max normalization，把不同来源的分数压到相近区间，再加权融合：&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;&#10;&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1&#10;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#10;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;final_score = 0.5 * norm(BM25) + 0.5 * norm(Embedding)&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&lt;p&gt;第二类是只看排名，比如 Reciprocal Rank Fusion。它不太关心原始分数，而是看一个文档在每一路里排第几：&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;&#10;&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1&#10;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#10;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;RRF(d) = sum(1 / (k + rank_i(d)))&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&lt;p&gt;如果一个文档在多路召回里都排得靠前，它的融合分数就会更高。&lt;/p&gt;&#10;&lt;p&gt;RRF 的复习锚点：&lt;strong&gt;多路召回都排得靠前的文档，融合后应该获得更高优先级。&lt;/strong&gt;&lt;/p&gt;&#10;&lt;hr&gt;&#10;&lt;h2 id="五reranker候选少了以后再认真判断"&gt;&lt;a href="#%e4%ba%94reranker%e5%80%99%e9%80%89%e5%b0%91%e4%ba%86%e4%bb%a5%e5%90%8e%e5%86%8d%e8%ae%a4%e7%9c%9f%e5%88%a4%e6%96%ad" class="header-anchor"&gt;&lt;/a&gt;五、Reranker：候选少了以后，再认真判断&#10;&lt;/h2&gt;&lt;p&gt;如果 BM25、Embedding、SPLADE 负责先找候选，Reranker 负责在候选变少后做细粒度比较。&lt;/p&gt;&#10;&lt;p&gt;Embedding 通常是 bi-encoder：&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;&#10;&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1&#10;&lt;/span&gt;&lt;span class="lnt"&gt;2&#10;&lt;/span&gt;&lt;span class="lnt"&gt;3&#10;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#10;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;query 单独编码&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;doc 单独编码&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;然后算向量相似度&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&lt;p&gt;这种方式快，因为文档向量可以提前算好。&lt;/p&gt;&#10;&lt;p&gt;Reranker 通常接近 cross-encoder 思路：&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;&#10;&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1&#10;&lt;/span&gt;&lt;span class="lnt"&gt;2&#10;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#10;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;把 query 和 doc 放在一起&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;让模型直接判断相关性&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&lt;p&gt;例如：&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;&#10;&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1&#10;&lt;/span&gt;&lt;span class="lnt"&gt;2&#10;&lt;/span&gt;&lt;span class="lnt"&gt;3&#10;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#10;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;query: 出差住酒店怎么报销&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;doc: 差旅住宿费用管理办法&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;score: 0.93&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&lt;p&gt;模型可以同时看到 query 和 doc，细粒度判断它们是否匹配。&lt;/p&gt;&#10;&lt;h3 id="51-为什么-reranker-不直接全库跑"&gt;&lt;a href="#51-%e4%b8%ba%e4%bb%80%e4%b9%88-reranker-%e4%b8%8d%e7%9b%b4%e6%8e%a5%e5%85%a8%e5%ba%93%e8%b7%91" class="header-anchor"&gt;&lt;/a&gt;5.1 为什么 Reranker 不直接全库跑&#10;&lt;/h3&gt;&lt;p&gt;Reranker 通常更准，但也更慢。&lt;/p&gt;&#10;&lt;p&gt;如果文档库有 100 万篇，让 Reranker 对每篇都判断一次：&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;&#10;&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1&#10;&lt;/span&gt;&lt;span class="lnt"&gt;2&#10;&lt;/span&gt;&lt;span class="lnt"&gt;3&#10;&lt;/span&gt;&lt;span class="lnt"&gt;4&#10;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#10;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;query-doc1&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;query-doc2&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;...&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;query-doc1000000&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&lt;p&gt;成本太高。&lt;/p&gt;&#10;&lt;p&gt;所以它一般放在召回之后：&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;&#10;&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1&#10;&lt;/span&gt;&lt;span class="lnt"&gt;2&#10;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#10;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;先用 BM25 / Embedding / SPLADE 召回 top50&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;再用 Reranker 对这 50 个候选重新排序&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&lt;p&gt;复习锚点：召回阶段追求快和覆盖，Reranker 阶段追求细粒度相关性判断。&lt;/p&gt;&#10;&lt;h3 id="52-reranker-适合处理候选之间的细微差别"&gt;&lt;a href="#52-reranker-%e9%80%82%e5%90%88%e5%a4%84%e7%90%86%e5%80%99%e9%80%89%e4%b9%8b%e9%97%b4%e7%9a%84%e7%bb%86%e5%be%ae%e5%b7%ae%e5%88%ab" class="header-anchor"&gt;&lt;/a&gt;5.2 Reranker 适合处理候选之间的细微差别&#10;&lt;/h3&gt;&lt;p&gt;比如 query 是：&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;&#10;&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1&#10;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#10;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;酒店发票抬头填错了怎么办&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&lt;p&gt;召回阶段可能找出：&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;&#10;&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1&#10;&lt;/span&gt;&lt;span class="lnt"&gt;2&#10;&lt;/span&gt;&lt;span class="lnt"&gt;3&#10;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#10;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;酒店发票填写要求&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;发票作废与重开流程&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;差旅住宿费报销规则&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&lt;p&gt;这些都相关，但最该排前面的可能是“发票作废与重开流程”。Reranker 就是在这种时候发挥价值。&lt;/p&gt;&#10;&lt;hr&gt;&#10;&lt;h2 id="六splade神经网络版的关键词检索"&gt;&lt;a href="#%e5%85%adsplade%e7%a5%9e%e7%bb%8f%e7%bd%91%e7%bb%9c%e7%89%88%e7%9a%84%e5%85%b3%e9%94%ae%e8%af%8d%e6%a3%80%e7%b4%a2" class="header-anchor"&gt;&lt;/a&gt;六、SPLADE：神经网络版的关键词检索&#10;&lt;/h2&gt;&lt;p&gt;SPLADE 是这几个方法里最容易混淆的一块，可以先这样理解：&lt;/p&gt;&#10;&#10; &lt;blockquote&gt;&#10; &lt;p&gt;SPLADE 试图把 BM25 的稀疏可解释性，和神经模型的语义扩展能力接起来。&lt;/p&gt;&#10;&#10; &lt;/blockquote&gt;&#10;&lt;p&gt;BM25 在词项空间工作。文档里有哪些词，就在哪些词上有统计权重。&lt;/p&gt;&#10;&lt;p&gt;Embedding 在稠密向量空间工作。每个维度不一定有明确含义，但整体能表达语义。&lt;/p&gt;&#10;&lt;p&gt;SPLADE 也在词表空间里工作。假设模型词表有 30,000 个 token，那么一段文本会被表示成一个 30,000 维向量。&lt;/p&gt;&#10;&lt;p&gt;不同的是，这个向量很稀疏：&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;&#10;&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1&#10;&lt;/span&gt;&lt;span class="lnt"&gt;2&#10;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#10;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;大部分维度是 0&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;少数相关 token 维度有正权重&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&lt;p&gt;比如用户输入：&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;&#10;&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1&#10;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#10;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;住酒店&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&lt;p&gt;SPLADE 可能不只激活“酒店”，还会激活：&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;&#10;&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1&#10;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#10;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;住宿、旅馆、房费、差旅&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&lt;p&gt;这相当于模型自动帮 query 做语义扩展，但结果仍然落在稀疏词项空间里。&lt;/p&gt;&#10;&lt;h3 id="61-splade-的激活直觉"&gt;&lt;a href="#61-splade-%e7%9a%84%e6%bf%80%e6%b4%bb%e7%9b%b4%e8%a7%89" class="header-anchor"&gt;&lt;/a&gt;6.1 SPLADE 的激活直觉&#10;&lt;/h3&gt;&lt;p&gt;很多 SPLADE 实现会对模型输出做类似这样的变换：&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;&#10;&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1&#10;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#10;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;log(1 + ReLU(x))&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&lt;p&gt;拆开看：&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;code&gt;ReLU(x)&lt;/code&gt;：负数清零，只保留正向激活。&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;log(1 + x)&lt;/code&gt;：压缩过大的权重，让数值更稳定。&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;这样得到的是非负稀疏权重。&lt;/p&gt;&#10;&lt;p&gt;检索时可以直接做点积：&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;&#10;&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1&#10;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#10;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;score(query, doc) = sparse_query_vector · sparse_doc_vector&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&lt;p&gt;如果 query 和 doc 在相同或相关 token 上都有权重，分数就会变高。&lt;/p&gt;&#10;&lt;h3 id="62-splade-放在哪个位置"&gt;&lt;a href="#62-splade-%e6%94%be%e5%9c%a8%e5%93%aa%e4%b8%aa%e4%bd%8d%e7%bd%ae" class="header-anchor"&gt;&lt;/a&gt;6.2 SPLADE 放在哪个位置&#10;&lt;/h3&gt;&lt;p&gt;可以把它放在 BM25 和 Embedding 中间理解：&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;&#10;&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1&#10;&lt;/span&gt;&lt;span class="lnt"&gt;2&#10;&lt;/span&gt;&lt;span class="lnt"&gt;3&#10;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#10;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;BM25 ：词面匹配，稀疏，可解释&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Embedding ：语义匹配，稠密，不太可解释&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;SPLADE ：神经稀疏匹配，有语义扩展，也保留词项空间&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&lt;p&gt;SPLADE 吸引人的地方在于，它不像普通 Embedding 那样完全进入黑盒稠密空间，也不像 BM25 那样只依赖原始词面。它可以学习到一些扩展关系。&lt;/p&gt;&#10;&lt;p&gt;它的成本也更高：需要专门模型，向量维度很高，索引和部署比 BM25 更复杂。&lt;/p&gt;&#10;&lt;hr&gt;&#10;&lt;h2 id="七一个完整检索链路可以怎么想"&gt;&lt;a href="#%e4%b8%83%e4%b8%80%e4%b8%aa%e5%ae%8c%e6%95%b4%e6%a3%80%e7%b4%a2%e9%93%be%e8%b7%af%e5%8f%af%e4%bb%a5%e6%80%8e%e4%b9%88%e6%83%b3" class="header-anchor"&gt;&lt;/a&gt;七、一个完整检索链路可以怎么想&#10;&lt;/h2&gt;&lt;p&gt;假设用户问：&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;&#10;&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1&#10;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#10;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;差旅住宿发票丢了还能报销吗&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&lt;p&gt;一条比较完整的检索链路可以这样组织：&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;&#10;&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1&#10;&lt;/span&gt;&lt;span class="lnt"&gt;2&#10;&lt;/span&gt;&lt;span class="lnt"&gt;3&#10;&lt;/span&gt;&lt;span class="lnt"&gt;4&#10;&lt;/span&gt;&lt;span class="lnt"&gt;5&#10;&lt;/span&gt;&lt;span class="lnt"&gt;6&#10;&lt;/span&gt;&lt;span class="lnt"&gt;7&#10;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#10;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;1. BM25 找到包含“差旅”“住宿”“发票”“报销”的文档&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;2. Embedding 找到语义上接近“发票遗失”“报销材料补充”的文档&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;3. SPLADE 如果可用，再补一批神经稀疏召回结果&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;4. 合并候选，去掉重复文档&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;5. 用归一化加权或 RRF 做候选融合&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;6. 用 Reranker 对候选重新排序&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;7. 把 top 文档交给下游问答模型或直接返回&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&lt;p&gt;每一步对应一个具体问题：&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;BM25：有没有明确命中关键词？&lt;/li&gt;&#10;&lt;li&gt;Embedding：语义上像不像？&lt;/li&gt;&#10;&lt;li&gt;SPLADE：能不能做更聪明的词项扩展？&lt;/li&gt;&#10;&lt;li&gt;Reranker：候选里谁最贴合用户问题？&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;hr&gt;&#10;&lt;h2 id="八选型建议"&gt;&lt;a href="#%e5%85%ab%e9%80%89%e5%9e%8b%e5%bb%ba%e8%ae%ae" class="header-anchor"&gt;&lt;/a&gt;八、选型建议&#10;&lt;/h2&gt;&lt;p&gt;如果只是做一个小型知识库，最简单的起点通常是：&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;&#10;&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1&#10;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#10;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Embedding 召回 + Reranker 精排&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&lt;p&gt;如果业务词很强，比如法规条款、财务科目、商品型号、错误代码，可以加上 BM25：&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;&#10;&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1&#10;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#10;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;BM25 + Embedding 多路召回 + Reranker 精排&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&lt;p&gt;如果发现 BM25 词面太死、Embedding 又容易把细分类别混在一起，再考虑 SPLADE：&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;&#10;&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1&#10;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#10;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;BM25 + Embedding + SPLADE 多路召回 + Reranker 精排&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&lt;p&gt;不要一开始就把所有东西都加上。检索系统越堆越复杂，调试成本也越高。更稳的做法是先跑通 baseline，再根据错误样本决定补哪一路。&lt;/p&gt;&#10;&lt;hr&gt;&#10;&lt;h2 id="小结"&gt;&lt;a href="#%e5%b0%8f%e7%bb%93" class="header-anchor"&gt;&lt;/a&gt;小结&#10;&lt;/h2&gt;&lt;p&gt;多路召回不是一个单独算法，而是一种系统设计思路：让不同检索方法从不同角度找候选，再用排序模型做最终筛选。&lt;/p&gt;&#10;&lt;p&gt;BM25 解决精确词面匹配，Embedding 解决语义泛化，SPLADE 尝试在稀疏词项空间里加入神经语义扩展，Reranker 负责最后的细粒度判断。&lt;/p&gt;&#10;&lt;p&gt;以后复习或设计检索链路时，优先问这些问题：&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;&#10;&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1&#10;&lt;/span&gt;&lt;span class="lnt"&gt;2&#10;&lt;/span&gt;&lt;span class="lnt"&gt;3&#10;&lt;/span&gt;&lt;span class="lnt"&gt;4&#10;&lt;/span&gt;&lt;span class="lnt"&gt;5&#10;&lt;/span&gt;&lt;span class="lnt"&gt;6&#10;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#10;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;它用了哪些召回路？&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;每一路分别解决什么盲区？&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;候选是取并集，还是只在某一路结果里重打分？&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;不同分数怎么融合？&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Reranker 放在多少候选之后？&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;最终阈值有没有单独校准？&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&lt;p&gt;这些问题比单独背概念更有用。检索效果通常不是由某个单点算法决定的，而是由整条链路的召回覆盖、候选融合、精排质量和阈值校准共同决定的。&lt;/p&gt;&#10;</description></item></channel></rss>