RAG学习之-Rerank 技术详解:从入门到面试

Rerank 技术详解:从入门到面试

一站式掌握 RAG 中的重排序技术 ------ 从 12 岁能懂的故事,到面试官想听的答案


目录

  1. 核心概念:什么是 Rerank(#一核心概念什么是 rerank)
  2. 技术原理:Bi-Encoder vs Cross-Encoder(#二技术原理 bi-encoder-vs-cross-encoder)
  3. 为什么需要 Rerank(#三为什么需要 rerank)
  4. 常用 Rerank 模型选型(#四常用 rerank 模型选型)
  5. 代码实现:两阶段检索
  6. 面试回答模板
  7. 知识总结

一、核心概念:什么是 Rerank

1.1 12 岁就能听懂的故事 🍎

问题: 你让两个人帮你挑苹果,有什么区别?

第一个人:快手阿姨(检索)

  • 30 秒抓了 10 个苹果给你
  • 方法:看颜色(红的拿)、看大小(大的拿)、看位置(手边的拿)
  • 结果:快是快,但有些苹果看着红其实有伤

第二个人:品果大师(Rerank)

  • 接过这 10 个苹果,开始仔细检查
  • 方法:摸一摸(软硬)、闻一闻(香味)、掂一掂(水分)、看一看(斑点)
  • 结果:告诉你"这 10 个里真正最好吃的 3 个是这几个"
快手阿姨(检索) 品果大师(Rerank)
速度 30 秒 10 个 🚀 5 分钟 1 个 🐢
准确度 看外表 ⭐⭐⭐ 看内在 ⭐⭐⭐⭐⭐
能大批量吗 可以 太慢,只能挑少量

核心思想:

Rerank = 先快速找一堆候选答案,再花时间仔细排序,把最好的放在最前面

1.2 生活中的例子

场景 检索 Rerank
淘宝买东西 搜索"运动鞋"出来 1000 件 按销量/好评重新排序,展示前 20 个
抖音推荐 先找一批相关视频 根据你的喜好重新排序
高考志愿 把所有大学列出来 按分数/专业/地点排序,选前几个

1.3 概念定位

复制代码
Rerank(重排序技术)
    │
    └── 通常用 Cross-Encoder(模型架构)来实现
问题 答案
Rerank 是什么? 一种重排序技术思想
Rerank 用什么模型? Cross-Encoder
Bi-Encoder 用于什么? 第一阶段检索(召回)

二、技术原理:Bi-Encoder vs Cross-Encoder

2.1 本质定义

Bi-Encoder 和 Cross-Encoder 是基于 Transformer Encoder 的两种应用架构

它们不是 Transformer 原生的设计,而是后人基于 Transformer 的用法总结。

2.2 结构对比

Bi-Encoder(双编码器)
复制代码
输入 A → 编码器 E → 向量 a ↘
                        相似度计算 → 得分
输入 B → 编码器 E → 向量 b ↗

特点:两个输入独立编码,无法交互
Cross-Encoder(交叉编码器)
复制代码
输入 A + 输入 B → 编码器 E → Self-Attention 交互 → 分数

特点:两个输入一起编码,充分交互

2.3 Self-Attention 交互差异

Bi-Encoder(无交互)
复制代码
句子 A: [我] [喜欢] [苹果]     句子 B: [苹果] [公司] [发布] [手机]
         │     │      │                   │      │      │      │
         └─────┴──────┘                   └──────┴──────┴──────┘
           Self-Attention                    Self-Attention
           (只在 A 内部)                    (只在 B 内部)

❌ A 的"苹果"看不到 B 的"苹果"
Cross-Encoder(充分交互)
复制代码
输入:[我] [喜欢] [苹果] [苹果] [公司] [发布] [手机]
       │     │      │      │      │      │      │
       └─────┴──────┴──────┴──────┴──────┴──────┘
                    全局 Self-Attention
                  
✅ A 的"苹果"能看到 B 的"苹果",判断是不是同一个意思

2.4 形象比喻

Bi-Encoder Cross-Encoder
比喻 相亲看照片 相亲真人见面
做法 分别给问题和文档拍照,然后对比照片 把问题和文档放在一起仔细读
速度 快 ✅ 慢 ❌
准确度 一般 高 ✅
预计算 可以 不可以

2.5 代码对比

Bi-Encoder
python 复制代码
from sentence_transformers import SentenceTransformer

model = SentenceTransformer('all-MiniLM-L6-v2')

# 分别编码
embedding_a = model.encode("问题")
embedding_b = model.encode("文档")

# 计算相似度
score = cosine_similarity(embedding_a, embedding_b)

特征 :encode() 单独调用,向量事后计算相似度

Cross-Encoder
python 复制代码
from sentence_transformers import CrossEncoder

model = CrossEncoder('cross-encoder/ms-marco-MiniLM-L-6-v2')

# 一起输入
score = model.predict([["问题", "文档"]])

特征 :predict() 输入是成对的,直接输出分数

2.6 对比总结表

特性 Bi-Encoder Cross-Encoder
输入方式 问题、文档分开编码 问题 + 文档拼在一起编码
输出 两个向量 一个相似度分数
预计算 ✅ 可以提前算文档向量 ❌ 不能预计算
检索速度 🚀 快(毫秒级) 🐢 慢(秒级)
准确度 ⭐⭐⭐ 一般 ⭐⭐⭐⭐⭐ 很高
适用场景 大规模检索 精排序 Rerank
计算复杂度 O(n) O(n²)

三、为什么需要 Rerank

3.1 核心问题:向量检索有先天缺陷

缺陷 1:向量检索是"粗匹配"
复制代码
用户问:"Python 怎么读取文件?"

向量检索返回:
├── ✅ "Python 文件操作方法大全"  ← 很相关
├── ❌ "Python 入门教程"          ← 标题有 Python,但内容不相关
├── ❌ "如何管理你的文件"         ← 有"文件",但讲的是整理文件
└── ✅ "Python open() 函数详解"   ← 很相关,但排在第 8 位

问题 :向量检索只看"整体相似度",不懂真正的相关性

缺陷 2:词汇不匹配
复制代码
文档里写:"使用 open() 函数打开文件"
用户问:"Python 怎么读取文件?"

→ 没有共同关键词!向量相似度可能很低

但如果有一个模型能理解语义:

  • "open()" = "读取文件"
  • 它就知道这是高度相关的
缺陷 3:长文本吃亏
复制代码
文档 A:整篇都在讲"Python 文件操作"(1000 字)
文档 B:第一段讲"Python 文件操作",后面 90% 讲别的(2000 字)

向量检索可能觉得 B 更相似,因为总内容更多
但 A 才是真正相关的!

3.2 实际数据对比(BEIR 基准)

方法 Recall@10 MRR NDCG@5
向量检索(Bi-Encoder) 0.45 0.40 0.50
+ Rerank(Cross-Encoder) 0.65 0.58 0.68
提升 +44% +45% +36%

3.3 两阶段检索架构

复制代码
Stage 1: 向量检索(快)
├── 从 10 万文档中快速筛选 20 个候选
├── 耗时:10-20ms
└── 成本低

Stage 2: Rerank(慢但精)
├── 仔细判断 20 个候选的相关性
├── 耗时:50-200ms(20 个文档)
└── 成本较高

最终:给你看 Top-5 最相关的

3.4 适用场景

✅ 适合用 Rerank 的场景
场景 原因
专业领域问答(医疗、法律) 需要高精度,不能出错
代码检索 变量名不同但功能相同的代码需要被找到
长文档检索 避免"整体相似但内容不相关"
多语言检索 不同语言表达相同意思
歧义查询 "苹果"是水果还是公司?
❌ 可以不用 Rerank 的场景
场景 原因
简单事实查询 "珠穆朗玛峰多高"直接检索就够了
延迟敏感 Rerank 增加 100-500ms 延迟
预算有限 Rerank 增加计算成本

四、常用 Rerank 模型选型

4.1 模型清单总览

模型 发布者 语言 特点 适用场景
BGE-Reranker-base 智源 中英 中文最强,平衡速度和精度 中文知识库、生产环境
BGE-Reranker-large 智源 中英 精度最高,稍慢 专业领域、质量优先
Cohere Rerank Cohere 多语 API 服务,免部署 不想自己部署
Jina Reranker Jina 多语 支持长文本 长文档检索
ms-marco-MiniLM Microsoft 英文 轻量快速 快速原型、英文场景
bge-reranker-v2 智源 中英 最新版,支持混合检索 复杂检索场景

4.2 模型选择指南

场景 推荐模型
中文知识库 BGE-Reranker-base
英文场景 ms-marco-MiniLM 或 BGE
长文档(>1000 字) Jina Reranker
延迟敏感 ms-marco-MiniLM
质量优先 BGE-Reranker-large
不想部署 Cohere Rerank
资源有限(CPU) bge-reranker-v2-minilm

一句话记忆:

"中文用 BGE,英文用 Marco,长文本用 Jina,不想部署用 Cohere。"

4.3 性能对比(中文场景)

模型 Recall@10 MRR 延迟 (20 文档) 模型大小
BGE-Reranker-large 0.68 0.61 250ms 1.3GB
BGE-Reranker-base 0.65 0.58 150ms 440MB
ms-marco-MiniLM 0.58 0.52 80ms 80MB
Cohere Rerank 0.64 0.57 300ms(API) -
无 Rerank(基线) 0.45 0.40 - -

五、代码实现:两阶段检索

5.1 完整实现

python 复制代码
from sentence_transformers import SentenceTransformer, CrossEncoder
import numpy as np

class TwoStageRetriever:
    """两阶段检索器:检索 + 重排序"""
  
    def __init__(
        self,
        embed_model_name: str = 'all-MiniLM-L6-v2',
        rerank_model_name: str = 'BAAI/bge-reranker-base',
        top_k_retrieve: int = 20,
        top_k_rerank: int = 5
    ):
        # Stage 1: Bi-Encoder 用于快速检索
        self.embedder = SentenceTransformer(embed_model_name)
      
        # Stage 2: Cross-Encoder 用于精排序
        self.reranker = CrossEncoder(rerank_model_name)
      
        self.top_k_retrieve = top_k_retrieve
        self.top_k_rerank = top_k_rerank
        self.documents = []
        self.doc_embeddings = None
  
    def index(self, documents: list[str]):
        """索引文档"""
        self.documents = documents
        # 预先计算所有文档的向量
        self.doc_embeddings = self.embedder.encode(documents)
        # 归一化
        self.doc_embeddings = self.doc_embeddings / np.linalg.norm(
            self.doc_embeddings, axis=1, keepdims=True
        )
  
    def retrieve(self, query: str) -> list[tuple[str, float]]:
        """两阶段检索"""
        # === Stage 1: 向量检索(快)===
        query_embedding = self.embedder.encode([query])
        query_embedding = query_embedding / np.linalg.norm(query_embedding)
      
        # 计算余弦相似度
        similarities = np.dot(self.doc_embeddings, query_embedding.T).flatten()
      
        # 取 Top-20 候选
        candidate_indices = np.argsort(similarities)[::-1][:self.top_k_retrieve]
        candidate_docs = [self.documents[i] for i in candidate_indices]
      
        # === Stage 2: Rerank(慢但精)===
        pairs = [[query, doc] for doc in candidate_docs]
        rerank_scores = self.reranker.predict(pairs)
      
        # 重新排序
        ranked_results = sorted(
            zip(candidate_docs, rerank_scores),
            key=lambda x: x[1], reverse=True
        )
      
        # 返回 Top-5
        return ranked_results[:self.top_k_rerank]


# 使用示例
if __name__ == "__main__":
    retriever = TwoStageRetriever()
  
    docs = [
        "Python 中 open() 函数用于打开文件",
        "Python 入门教程:第一个 Hello World 程序",
        "如何管理电脑上的文件和文件夹",
        "Python 文件操作:read() write() close() 方法详解",
    ]
    retriever.index(docs)
  
    query = "Python 怎么读取文件?"
    results = retriever.retrieve(query)
  
    print(f"查询:{query}\n")
    for i, (doc, score) in enumerate(results, 1):
        print(f"[{i}] (得分:{score:.4f}) {doc}")

5.2 关键代码解析

python 复制代码
# Stage 1: Bi-Encoder 检索
query_embedding = self.embedder.encode([query])  # 编码查询
similarities = np.dot(self.doc_embeddings, query_embedding.T)  # 矩阵乘法算相似度
candidate_indices = np.argsort(similarities)[::-1][:20]  # 取 Top-20

# Stage 2: Cross-Encoder Rerank
pairs = [[query, doc] for doc in candidate_docs]  # 构建 (查询,文档) 对
rerank_scores = self.reranker.predict(pairs)  # Cross-Encoder 打分
ranked_results = sorted(zip(candidate_docs, rerank_scores), key=lambda x: x[1], reverse=True)

六、面试回答模板

6.1 30 秒简短版

"Rerank 的核心思想是:先广撒网,再精挑选。

第一阶段用向量检索快速召回 Top-20 候选文档,

第二阶段用 Cross-Encoder Rerank 精排序,最终返回 Top-5 给 LLM。

用少量的时间代价,换取检索质量的大幅提升。"

6.2 2 分钟完整版

第一步:说问题

"我发现纯向量检索有几个问题:

  1. 只看向量相似度,不懂真正的相关性
  2. 词汇不匹配时效果差(用户说'读文件',文档写'open()')
  3. 长文档容易吃亏"
第二步:说方案

"我引入了 Rerank 机制,采用两阶段架构:

Stage 1 检索:用 Bi-Encoder 从 10 万文档中快速召回 Top-20,耗时 10-20ms。

Stage 2 Rerank:用 Cross-Encoder 对这 20 个文档逐一打分,重新排序后取 Top-5,耗时 100-200ms。

Cross-Encoder 能把问题和文档拼在一起编码,通过 Self-Attention 捕捉细粒度语义交互,所以更精准。"

第三步:说结果

"效果提升很明显:

  • Recall@10 从 0.45 提升到 0.65(+44%)
  • MRR 从 0.40 提升到 0.58(+45%)
  • 延迟增加约 100-200ms,在可接受范围内"

6.3 被追问技术细节

问题 参考回答
Bi-Encoder 和 Cross-Encoder 有什么区别? "Bi-Encoder 分别编码,快但粗糙;Cross-Encoder 拼接编码,慢但精准。比喻:相亲看照片 vs 真人见面。"
为什么不只用 Rerank? "Cross-Encoder 不能预计算,10 万文档要算 5000 秒。所以先用 Bi-Encoder 快筛 20 个,再 Rerank 这 20 个,兼顾速度和精度。"
用的什么 Rerank 模型? "BGE-Reranker-base,中文场景效果最好,速度和精度平衡。"
Rerank 增加多少延迟? "每个文档约 5-10ms,20 个文档约 100-200ms。相比 LLM 生成的 1-2 秒,可以接受。"

6.4 加分项:说出 Trade-off

"Rerank 不是银弹,需要权衡:

  • 延迟敏感场景(实时对话)→ 可以不用 Rerank
  • 质量优先场景(专业问答)→ Rerank 是必须的
  • 我的项目是知识库问答,对准确率要求高,所以选择了 Rerank"

6.5 杀手锏:说出踩过的坑

"我一开始直接用 Cross-Encoder 对所有文档排序,结果延迟爆炸(5 秒+)。

后来改成两阶段:

  1. 向量检索从 10 万 → 20
  2. Rerank 从 20 → 5

延迟降到 200ms,效果还更好了。

这个教训让我理解到:好的架构不是堆模型,而是让每个模型在自己擅长的位置发挥作用。"

6.6 万能模板(背下来)

复制代码
核心思想:先粗筛,再精排

为什么:又快又准难兼得

怎么做:Bi-Encoder 快筛 20 个 → Cross-Encoder 精排 5 个

效果:Recall@10 提升 44%,延迟增加 100-200ms

比喻:快手阿姨抓苹果 → 品果大师选最好的

6.7 面试关键词清单

关键词 含义
Bi-Encoder 双编码器,向量检索用的
Cross-Encoder 交叉编码器,Rerank 用的
两阶段检索 Recall + Rerank
Recall@K 召回率指标
MRR / NDCG 排序质量指标
Self-Attention Cross-Encoder 的核心机制
预计算 Bi-Encoder 可以提前算文档向量
Trade-off 速度 vs 精度的权衡

七、知识总结

7.1 核心要点

知识点 核心内容
Rerank 是什么 先粗筛,再精排
为什么需要 向量检索有缺陷,需要更精准排序
用什么模型 Cross-Encoder
Bi-Encoder 用途 第一阶段快速检索
效果提升 Recall@10 提升 40%+
延迟代价 100-200ms
常用模型 BGE-Reranker-base(中文首选)

7.2 记忆口诀

Bi 检索,Cross 重排
先粗筛,再精排
中文就用 BGE,不想部署 Cohere
两阶段是标准做法,用时间换精度

7.3 一句话金句

"Rerank 就是用时间换精度,先广撒网再精挑选,是工业界提升检索效果的标准做法。"


文档整理日期:2026-04-14
基于 RAG 学习项目整理

相关推荐
Navicat中国12 分钟前
Navicat 18 内置 AI 助手让数据库开发从繁琐操作迈向智能协作
大数据·人工智能·数据库开发
4SAPI33 分钟前
多模型请求路由怎么设计?成本、速度和能力如何平衡
人工智能·python·gateway·php
魔乐社区44 分钟前
翼芯・智算测试与适配优化专区,让国产算力“选得准、跑得通、用得好“
人工智能·开源·大模型
XCDoris3 小时前
郴州logo设计机构
大数据·人工智能·python
Goboy3 小时前
一个人带三个Agent,我用全新TRAE从0到1搭了个资讯周刊站
人工智能·trae
俊哥V3 小时前
每日 AI 研究简报 · 2026-10-19
人工智能·ai
AI_AGENT_DEV_AI3 小时前
AI英语教培智能体的开发
人工智能
物联网软硬件开发-轨物科技3 小时前
【技术白皮书】光伏清检一体化机器人系统解决方案技术白皮书
大数据·运维·网络·人工智能·机器人
海宇数据3 小时前
零信任架构实战:基于海宇网上踪迹欺诈行为识别构建自动化信贷资信评估网关
运维·人工智能·架构·自动化
冬奇Lab4 小时前
开源项目第242期:HyperFrames —— 写 HTML 就能渲染视频,专为 AI Agent 设计的确定性视频框架
人工智能·开源·音视频开发