第 08 篇|RAG 为什么还要“重新排序”?我开始研究 Rerank
系列:《从 0 打造我的本地 AI 知识库:Obsidian + Ollama + Milvus + RAG + MCP + Agent》
上一篇:《RAG 为什么总是“搜不到”?我终于搞懂了 Chunk 才是关键》
本篇关键词: Rerank、Vector Search、Candidate、Top-K、Relevance、Cross-Encoder
01|我的向量搜索已经能用了,但我又发现了一个问题
前面我已经把自己的 Obsidian 知识库拆成 Chunk,然后:
Markdown
↓
Chunk
↓
Embedding
↓
Vector
↓
Milvus
用户搜索的时候:
用户问题
↓
Embedding
↓
Milvus
↓
Vector Search
↓
找到相似 Chunk
看起来已经没问题了。
但是实际使用一段时间后,我发现:
“搜到了”不代表“排在最前面的就是最相关的”。
例如我的知识库里面有:
Chunk A
MySQL MVCC 是多版本并发控制机制。
Chunk B
Undo Log 用于保存数据库记录的历史版本。
Chunk C
Read View 用于判断事务能够看到哪些版本。
Chunk D
事务隔离级别决定事务之间的可见性。
Chunk E
MVCC 可以减少部分读写之间的锁竞争。
用户问:
Read View 是干什么的?
向量搜索可能返回:
1. Chunk A
2. Chunk B
3. Chunk D
4. Chunk C
5. Chunk E
注意:
Chunk C 明明最直接回答了问题,却没有排在第一。
这时候我开始思考:
有没有一种方法,可以先把“可能相关的内容”找出来,再对这些结果重新判断一次?
于是我遇到了:
Rerank
02|Rerank 到底是什么?
Rerank:
Rerank【重排序】
字面意思就是:
重新排序。
但这个解释还不够。
放到 RAG 里面,更准确地说:
Rerank 是在初步检索得到一批候选文档之后,再对“用户 Query【查询】”和“候选文档”之间的相关性进行更细粒度判断,并重新排序。
所以它不是替代 Vector Search。
而是:
Vector Search
↓
候选结果
↓
Rerank
↓
重新排序
整个思路发生了变化:
以前:
Query
↓
Vector Search
↓
Top-K
↓
LLM
现在:
Query
↓
Vector Search
↓
Top-K 候选
↓
Rerank
↓
Top-N
↓
LLM
这里的核心思想只有一句:
先快速找一批候选,再从候选里面精细挑选。
03|为什么不能让 Rerank 直接搜索整个知识库?
这是我刚开始容易产生的疑问。
既然 Rerank 能判断相关性:
那为什么不让 Rerank 直接在整个知识库里找?
比如我的知识库有:
100 万个 Chunk
难道:
Query
↓
Rerank
↓
100 万个 Chunk
全部比较?
理论上可以想象这种方案,但实际系统通常不会这么做,因为计算成本会非常高。
更常见的架构是:
100 万 Chunk
↓
Vector Search
↓
Top 20 / Top 50 / Top 100
↓
Rerank
↓
Top 5 / Top 10
所以:
Vector Search 负责从大规模候选中快速找到一批可能相关的内容。
然后:
Rerank 负责在这批候选里面进一步判断相关性并重新排序。
04|这就是“两阶段检索”
Two-Stage Retrieval:
Two-Stage Retrieval【两阶段检索】
我的 RAG 现在可以理解成两个阶段。
第一阶段:Candidate Retrieval
Candidate Retrieval:
Candidate Retrieval【候选召回】
例如:
知识库
100,000 个 Chunk
↓
Vector Search
↓
Top 20
这一阶段的目标是:
尽量不要漏掉可能相关的内容。
第二阶段:Reranking
然后:
Top 20
↓
Rerank
↓
Top 5
这一阶段的目标是:
把真正相关的内容尽可能排到前面。
所以:
全量知识库
↓
快速检索
↓
候选集合
↓
精细排序
↓
最终上下文
这就是我现在理解的:
两阶段检索架构。
05|这里必须把 Recall 和 Precision 搞清楚
前面学习 RAG 的时候,我很容易把:
Recall
Precision
Vector Search
Rerank
几个概念混在一起。
实际上它们不是同一层面的东西。
Recall
Recall:
Recall【召回率】
它关注的是:
真正相关的内容,有多少被检索出来了?
例如知识库中实际上有:
10 个相关 Chunk
Vector Search 找到了:
8 个
那么从这个简化例子看:
Recall = 8 / 10 = 80%
Precision
Precision:
Precision【精确率】
它关注的是:
检索出来的内容里面,有多少是真正相关的?
例如:
Vector Search 找到了 20 个 Chunk
其中真正相关的有 8 个
那么:
Precision = 8 / 20 = 40%
这里先不纠结具体评估实现。
只需要记住:
Recall
关注:有没有漏掉相关内容?
Precision
关注:找到的里面有多少是真的相关?
06|所以 Vector Search 和 Rerank 不能简单画等号
一个容易出现的错误说法是:
Vector Search 负责 Recall,Rerank 负责 Precision。
这句话作为非常粗略的工程直觉可以帮助理解,但如果严格来说并不准确。
更准确的表达应该是:
Vector Search 通常承担大规模候选检索的任务,需要尽量保证相关内容进入候选集合。
而:
Rerank 对已经进入候选集合的内容进行更细粒度的相关性判断和排序,从而改善候选结果的排序质量。
所以:
Recall
Precision
是:
Evaluation Metrics【评估指标】
而:
Vector Search
Rerank
是:
Retrieval Components【检索组件】
它们不是一个维度。
07|Rerank 到底比向量搜索“多做了什么”?
这个问题才是理解 Rerank 的关键。
Vector Search 的核心是:
Query Vector
↓
Candidate Vector
↓
计算相似度
↓
排序
例如:
Query
“Read View 是干什么的?”
↓ Embedding
Query Vector
然后和:
Chunk A Vector
Chunk B Vector
Chunk C Vector
...
计算相似度。
例如使用:
Cosine Similarity【余弦相似度】
最终得到:
Chunk A → 0.82
Chunk B → 0.80
Chunk C → 0.79
Chunk D → 0.77
然后按照分数排序。
08|Rerank 的思路不一样
Rerank 通常不是简单地:
Vector
↕
Vector
而是直接关注:
Query
+
Document / Chunk
之间的相关性。
例如:
Query:
Read View 是干什么的?
Candidate:
Read View 用于判断事务能够看到哪些版本。
Rerank 模型会针对:
Query + Chunk
进行相关性判断。
可以简单理解成:
它不只是问“这两个向量像不像”,而是进一步判断“这个 Chunk 到底是不是在回答这个 Query”。
当然,具体模型的内部实现会有所不同,不能把所有 Reranker 都简单等同于某一种模型结构。
09|Cross-Encoder 是什么?
很多 Rerank 模型会使用:
Cross-Encoder【交叉编码器】
可以先用一个非常简化的方式理解。
传统 Embedding 检索:
Query
↓
Embedding
↓
Query Vector
Chunk
↓
Embedding
↓
Chunk Vector
Query Vector
↕
Chunk Vector
然后计算向量相似度。
而 Cross-Encoder 更像:
Query
+
Chunk
↓
Reranker
↓
Relevance Score
相关性分数
也就是说:
Query 和 Chunk 会被一起输入模型,让模型直接判断两者之间的相关性。
因此它可以进行更加细粒度的 Query–Document Relevance Modeling:
Query–Document Relevance Modeling【查询与文档相关性建模】
10|为什么不全部使用 Cross-Encoder?
因为:
它通常计算成本更高。
假设:
知识库
100 万 Chunk
如果每个 Chunk 都和 Query 做一次复杂的联合计算:
Query + Chunk 1
Query + Chunk 2
Query + Chunk 3
...
Query + Chunk 1,000,000
成本会非常高。
所以更常见的方式:
100 万 Chunk
↓
Vector Search
↓
Top 50
↓
Rerank
↓
Top 5
这样 Rerank 只需要处理 50 个候选。
这就是一个非常经典的工程思想:
便宜的方法负责缩小搜索范围,昂贵的方法负责精细判断。
11|一个完整例子
假设我的知识库里面有 10,000 个 Chunk。
用户问:
MySQL Read View 到底有什么作用?
第一阶段:
10,000 Chunk
↓
Embedding
↓
Milvus Vector Search
↓
Top 20
得到:
Candidate 1
Candidate 2
Candidate 3
...
Candidate 20
这 20 个并不意味着:
“已经确定是最相关的 20 个。”
更准确地说:
它们是第一阶段认为值得进一步考虑的候选。
然后:
Top 20
↓
Rerank
↓
重新计算相关性
↓
重新排序
可能变成:
1. Read View 的作用
2. Read View 的创建时机
3. MVCC 的可见性判断
4. Undo Log
5. 事务隔离级别
...
最后只取:
Top 5
作为 LLM 的 Context。
12|为什么 Rerank 对 RAG 有价值?
因为 LLM 最终看到的上下文是有限的。
假设:
Vector Search
↓
Top 20
如果把 20 个 Chunk 全部塞给大模型:
Chunk 1
Chunk 2
...
Chunk 20
可能产生:
- 上下文过长
- 无关信息增加
- Token 消耗增加
- 相关内容被淹没
如果:
Top 20
↓
Rerank
↓
Top 5
那么可以只把更相关的内容交给 LLM。
于是:
知识库
↓
Vector Search
↓
Top 20
↓
Rerank
↓
Top 5
↓
Context
↓
LLM
这里 Rerank 的价值就非常明显了。
13|但是有一个非常重要的限制
这可能是今天最重要的一句话:
Rerank 无法找回第一阶段根本没有召回的内容。
例如:
知识库
10000 Chunk
真正答案
Chunk 9000
第一阶段:
Vector Search
↓
Top 20
结果:
Chunk 1
Chunk 5
Chunk 20
...
Chunk 800
但是:
Chunk 9000
根本没有进入候选集合。
那么:
Top 20
↓
Rerank
Rerank 只能排序:
这 20 个
它不会突然把:
Chunk 9000
变出来。
所以:
Rerank 的前提,是第一阶段已经把真正相关内容召回到候选集合中。
这也是为什么:
Candidate Retrieval
仍然非常重要。
14|所以我现在重新理解“召回”
以前我可能会说:
“Rerank 可以提高 RAG 的召回率。”
这个说法太粗了。
现在我更愿意这样说:
如果第一阶段候选召回本身存在漏检,那么 Rerank 无法补救;Rerank 的主要价值是在已有候选集合中改善相关性排序。
如果第一阶段:
Top 20
里面已经包含正确答案,但是它排在:
第 15 名
那么 Rerank 就可能把它重新排到:
第 1 名
这才是 Rerank 最典型的价值。
15|Rerank 不是“加上就一定更准”
这一点也必须写进我的知识库。
不能简单说:
“Vector Search 不准,所以加 Rerank 就一定准。”
实际效果会受到很多因素影响:
Embedding 模型
Chunk 策略
Query
候选数量
Reranker 模型
领域数据
文档质量
共同影响。
尤其是:
第一阶段没有召回正确答案
那么 Rerank 就没有办法解决。
所以更准确的说法是:
Rerank 是一种检索优化手段,在候选集合质量合适的情况下,可以通过更细粒度的相关性建模改善结果排序。
16|我的 RAG 架构再次升级
之前:
Query
↓
Embedding
↓
Milvus
↓
Vector Search
↓
Context
↓
LLM
现在:
Query
↓
Query Embedding
查询向量化
↓
Milvus Vector Search
向量检索
↓
Candidate Top-K
候选结果
↓
Rerank
重新排序
↓
Top-N
最终结果
↓
Context
上下文
↓
LLM
大模型
↓
Answer
回答
17|联系描述:这条链路到底是怎么工作的?
这一部分我以后会一直保留,因为真正理解 RAG,不能只记箭头。
第一阶段:快速寻找候选
用户提出 Query。
系统首先将 Query 转换成向量,然后使用 Milvus 对知识库中的向量进行相似度检索。
由于知识库可能有大量 Chunk,不适合对所有内容进行复杂的相关性判断,所以第一阶段主要负责:
快速缩小搜索范围。
例如:
100,000 Chunk
↓
Vector Search
↓
Top 20
此时的 20 个结果是:
值得进一步检查的候选。
第二阶段:精细判断
接下来 Rerank 接管这 20 个候选。
它重新结合:
Query
+
Candidate Chunk
判断它们之间的相关性,并重新排序。
于是:
Top 20
↓
Rerank
↓
Top 5
第三阶段:交给大模型
最终排名靠前的 Chunk 被组织成 Context:
Top 5
↓
Context
↓
LLM
大模型再基于这些检索结果生成最终答案。
所以完整链路可以用一句话讲:
先利用向量检索从大规模知识库中快速找到候选,再利用 Rerank 对候选进行更细粒度的相关性排序,最后把排序靠前的内容作为上下文交给大模型生成答案。
这就是我现在对 RAG 两阶段检索的完整理解。
18|那我的本地知识库现在需要 Rerank 吗?
我的答案是:
现在可以研究,但不一定马上接入。
因为我现在做的是个人 Obsidian 知识库。
如果:
知识库规模还比较小
而且:
Vector Search
已经能够满足大部分查询,那么没有必要为了“看起来高级”强行加入 Rerank。
我的学习顺序更适合:
Vector Search
↓
先把基础检索跑通
↓
观察真实问题
↓
发现排序问题
↓
加入 Rerank
↓
对比效果
这样才是真正的工程实践。
19|我准备怎么验证 Rerank?
下一步我不会直接相信:
“Rerank 一定更好。”
而是自己做一个小实验。
准备一些测试问题:
Q1:MySQL MVCC 是什么?
Q2:Read View 有什么作用?
Q3:Undo Log 保存什么?
Q4:HashMap 为什么扩容?
Q5:G1 的 Remembered Set 是什么?
然后分别测试:
实验 A
Query
↓
Vector Search
↓
Top 5
记录结果。
实验 B
Query
↓
Vector Search
↓
Top 20
↓
Rerank
↓
Top 5
再记录结果。
然后比较:
正确答案是否进入候选?
正确答案最终排名?
Top 1 是否正确?
Top 5 是否包含答案?
这样我才能知道:
Rerank 在我自己的知识库里到底有没有实际价值。
20|这一篇真正让我搞懂的不是“Rerank”
而是一个更重要的系统设计思想:
不同阶段应该承担不同的任务。
Vector Search
↓
快速、规模化地寻找候选
Rerank
↓
对候选进行更细粒度的相关性判断
LLM
↓
理解上下文并生成答案
也就是:
大范围
↓
快速筛选
↓
小范围
↓
精细排序
↓
更小范围
↓
生成答案
这其实就是很多 AI 系统里面非常重要的:
Coarse-to-Fine【由粗到细】
思想。
21|本篇总结
到这里,我的 RAG 检索链路已经从:
Vector Search
升级成:
Vector Search
+
Rerank
我现在需要记住 7 件事情。
① Rerank 是什么?
Rerank = 重排序
对第一阶段检索出来的候选结果进行更细粒度的相关性判断和重新排序。
② 为什么需要它?
因为:
向量搜索找到的候选中,最相关的内容不一定排在最前面。
③ 为什么不能直接 Rerank 全库?
因为计算成本通常更高。
所以采用:
全库
↓
Vector Search
↓
Top-K
↓
Rerank
↓
Top-N
④ Recall 和 Precision 是什么?
Recall
→ 相关内容有没有被找出来
Precision
→ 找出来的内容有多少是真相关
它们是评估指标,不是 Vector Search / Rerank 的同义词。
⑤ Rerank 能不能找回漏掉的答案?
不能。
没有进入候选集合的内容,Rerank 无法重新发现。
⑥ Rerank 是不是一定提高准确率?
不能这样绝对表述。
它的效果取决于:
候选质量
+
Embedding
+
Chunk
+
Reranker
+
Query
+
知识库
⑦ 我的 RAG 现在是什么结构?
用户 Query
↓
Query Embedding
↓
Milvus Vector Search
↓
Top-K Candidates
↓
Rerank
↓
Top-N
↓
Context
↓
LLM
↓
Answer
22|下一篇:我又发现一个更麻烦的问题
现在我的 RAG 已经能够:
切 Chunk
↓
Embedding
↓
Vector Search
↓
Rerank
↓
LLM
但是我继续使用自己的 Obsidian 后,又发现一个非常现实的问题:
假设知识库里面有:
MySQL
Redis
Java
Spring
AI
用户问:
MySQL 的 MVCC 是什么?
如果只是根据向量相似度搜索,系统可能找到:
MySQL MVCC
Redis 数据一致性
Java 并发
数据库事务
AI Agent
这些内容语义上可能都有一定关系。
但我其实已经知道:
我要的是 MySQL 相关知识。
于是我开始思考:
能不能除了“语义相似”,再利用知识库本身的结构和标签来缩小搜索范围?
例如:
category = MySQL
或者:
technology = MySQL
type = interview
这就进入下一步:
第 09 篇|为什么 RAG 不只靠相似度?我开始给知识库加 Metadata Filter
这一篇会把:
Metadata【元数据】、Filter【过滤】、Vector Search【向量检索】
真正结合起来,也会让我的 Obsidian 知识库开始从“能搜索”走向“可控制的检索系统”。s

浙公网安备 33010602011771号