检索在系统中的地位
检索是RAG(检索增强生成)系统的核心环节,直接决定了答案质量的上限------如果检索不到相关文档,后续生成再强也无法给出准确回答。
检索阶段分析
一个完整的检索流程通常包括以下步骤:
1、查询理解:识别用户意图与查询类型(事实型、推理型、模糊提问等)。
2、查询改写:优化原始查询的表达,提升召回效果。
3、稀疏检索:基于关键词的精确匹配召回。
4、稠密检索:基于语义的向量相似度召回。
5、结果融合:合并多路检索结果。
6、重排序:用更精细的模型对候选文档精排。
7、Top‑k 选择:截取最终送入生成模型的文档片段。
稀疏检索
1、什么是稀疏检索
将查询和文档转化为高维稀疏向量,维度通常为整个词汇表大小。只有当查询或文档涉及特定词语时,对应维度才为非零值,大部分维度为零,故称"稀疏向量"。通过计算两个稀疏向量在相同维度上的匹配程度(如内积、词项匹配得分)来判定相关性。
举例:词汇表为 苹果, 手机, 牛奶, 鸡蛋。文档"苹果手机很好用"对应向量为 1,1,0,0;查询"苹果牛奶"对应向量为 1,0,1,0。
2、代表算法
1、TF‑IDF
TF (词频):查询词在文档中出现越多次,文档越相关。
IDF(逆文档频率):查询词在越多的文档中出现,其区分度越低,权重越小;反之,稀有词权重高。
公式:


2、BM25
BM25 对 TF‑IDF 做了以下核心优化:
词频饱和:引入参数 k1,使词频贡献呈饱和曲线,避免某词出现50次和100次得分差异过大。当 tf≫k1 时,贡献趋于上限 k1+1k1+1。
文档长度归一化:引入参数 b,根据文档长度与平均长度的比值动态调整归一化强度。短文档的词频贡献被放大,长文档被惩罚,更为公平。
常见 BM25 公式:


3、稀疏检索的缺陷
同义词困境:"轿车"与"汽车"字面不匹配。
语义缺失:无法区分"苹果"是水果还是公司。
分词依赖:中文分词错误会严重影响效果。
4、SPLADE
SPLADE(Sparse Lexical and Document Expansion)是一种学习型稀疏检索模型,利用 BERT 的上下文理解能力进行隐式查询/文档扩展,同时维持稀疏向量的倒排索引高效性。
关键优化:
1、隐式扩展 :由于使用了 BERT 上下文编码,模型能理解同义词和上下文。 会自动为语义相关的词(如"汽车"、"小轿车"、"车辆")赋予一定的非零权重,即使原文里根本没出现这些词。
2、端到端可学习权重 :所有权重都由神经网络根据上下文动态计算,并且模型是在大规模检索数据上用**对比损失函数(如 Margin MSE 或 InfoNCE)**端到端训练出来的。它会直接学习"哪些词对判断相关/不相关最重要",而不是依赖僵硬的统计。
3、精确稀疏性控制 :通过 FLOPS 直接惩罚模型激活的非零项数量。这让模型在训练中学会"谨慎用词",只为最关键的几个词分配权重。最终生成的向量虽然维度极高,但平均只有几十个非零项,和 BM25 的索引项数量在同一量级,保证了使用倒排索引的检索速度,推理成本远低于稠密模型。
4、保留可解释性与域外泛化:仍然基于词汇匹配,跨领域零样本表现稳健,且能清晰回溯是哪些词贡献了得分。
| 算法 | 核心思想 | 优点 | 缺点 |
|---|---|---|---|
| TF‑IDF | 词频 × 逆文档频率 | 简单,可解释,基础基线 | 无词频饱和、无长度归一化、无法处理同义词 |
| BM25 | 带饱和与长度惩罚的词频‑逆文档频率 | 对长文档公平,词频饱和合理,参数可调 | 仍为词袋模型,语义匹配能力弱 |
| SPLADE | 学习型稀疏表示,自动扩展并学习权重 | 语义扩展 + 高效倒排索引,可解释,域外泛化好 | 需要训练数据,推理成本略高于 BM25 |
稠密检索
稠密检索使用低维连续向量(通常 768 维),每一维都非零,通过向量间余弦相似度或内积衡量语义相关性。
1、双塔架构
查询编码器与文档编码器相互独立(参数可共享)。文档向量可离线计算并存入向量数据库,查询时仅需对查询进行编码,再通过近似最近邻(ANN)搜索快速召回。
例:使用 BERT 分别编码"如何做红烧肉"和大量菜谱文档,然后计算向量相似度。
2、训练方法
对比学习(InfoNCE 损失):在一个批次内,拉近查询与正相关文档的距离,推远与其他文档(批次内负样本)的距离。
难负样本挖掘:使用 BM25 或其他方法召回排名靠前但实际不相关的文档作为难负样本,逼迫模型学习精细语义边界。
知识蒸馏 :知识蒸馏的目标,就是把一个强大但慢的"教师模型" 的能力,迁移到一个轻量级快速的"学生模型" 上。 用 Cross‑Encoder 作为教师模型,它会把"查询"和"文档"拼接起来,一同送入模型做深度交互,输出一个高精度的相关性分数。 用教师模型为查询‑文档进行精细化打分,再让学生双塔模型进行训练,除了正负样本,还要求它的向量相似度去拟合教师模型给出的分数分布。
指令微调 :在查询前添加任务指令例如,将"深度学习的教程"改为 "寻找适合初学者的教学文档: 深度学习"。训练出的模型(如 E5 、BGE 系列)具备强大的任务泛化能力。使用时,只需给查询加上合适的指令,同一个模型就能在完全不同的场景下工作。
| 特性 | 稀疏检索 | 稠密检索 |
|---|---|---|
| 向量特点 | 高维、大部分为0 | 低维、连续、各维非零 |
| 匹配方式 | 词项匹配(倒排索引) | 向量相似度(ANN) |
| 优势 | 精确匹配强,训练数据依赖低,可解释 | 语义泛化强,处理同义词与模糊查询 |
| 劣势 | 词汇不匹配,缺乏语义理解 | 精确匹配不稳定,新域需微调,可解释性差 |
| 代表方法 | BM25, SPLADE | DPR, BGE, E5 |
混合检索
单一检索方法均存在短板:稀疏检索无法理解语义,稠密检索在精确匹配(编号、专有名词)上不稳定。混合检索通过多路召回加结果融合,实现优势互补。
应用场景对比
| 场景 | 稀疏检索 (BM25) | 稠密检索 | 混合检索解法 |
|---|---|---|---|
| 精确匹配(订单号、人名) | 极好 | 不稳定 | 稀疏路保底 |
| 语义泛化(同义词、模糊表达) | 差 | 好 | 稠密路增强 |
| 长尾/罕见查询 | 机械匹配可能失败 | 训练不足表现一般 | 两路互补 |
| 领域迁移 | 强,无需训练 | 弱,效果易降 | 稀疏路提供冷启动基线 |
1、核心流程
1、多路并行召回:稀疏路(BM25 或 SPLADE)返回 Top‑K₁,稠密路返回 Top‑K₂。
2、分数归一化 :BM25 的分数是词频统计值(可能大于100),而稠密检索的余弦相似度在 -1, 1 之间。直接加权求和是无意义的,必须先归一化到同一尺度。
3、结果融合:将两路文档合并去重,然后用统一的分数排序,输出最终结果
2、三种融合策略
1、分数融合:先各自对分数做归一化,再线性加权求和。

需要根据业务场景调参。若精确查询多,α 调大;若语义化查询多,则减小。
常见归一化方法:

2、倒数排名融合(RRF) :为了避免归一化的麻烦,RRF 是一种非常流行且鲁棒的融合算法。它只关心文档的排名位置,而非绝对分数。

k 是一个常数(通常取60),用于平滑排名差异。
3、学习排序(LTR)融合 :将融合视为一个机器学习排序问题。训练一个模型,输入是每篇文档在各通路中的分数、排名、文档特征等,输出一个最终的相关性分数。
| 融合方法 | 核心思想 | 优点 | 缺点 |
|---|---|---|---|
| 分数融合 | 归一化后线性加权 | 简单直接,可调权重 | 需归一化和参数搜索 |
| RRF | 基于排名求和 | 无需归一化,鲁棒稳定,超参数少 | 未利用分数差异 |
| 学习排序融合 | 用模型学习融合函数 | 效果上限高,能利用多种特征 | 需训练数据与特征工程,系统复杂度高 |
重排序
检索通常是多轮漏斗筛选:首轮用轻量级双塔模型召回大量候选,重排序阶段用更强但更慢的模型对少量候选精排,提升精度。常用的重排序模型架构有交叉编码器
交叉编码器(Cross‑Encoder)
将查询和文档拼接后送入 Transformer 模型进行深度交互,输出一个细粒度相关性分数。相比双塔架构,交叉编码器能捕捉查询与文档间的词级交互,精度更高,但计算开销大,不能单独用于海量候选召回。
对比:双塔 = 独立编码后点积,速度快但交互弱;交叉编码器 = 联合编码,精度高但速度慢。实际使用时,先用双塔召回 100 条,再用交叉编码器重排,取 Top‑10。
查询改写
原始查询常带有口语化、歧义、信息量不足等问题,直接检索会导致召回质量下降。查询改写通过扩充、抽象、假设或变体生成等方式,从根本上提高检索系统的召回率和精度。
1. 查询扩展
查询扩展是在词汇级别为原始查询增补相关术语,解决"用户描述词"与"文档用词"不匹配的问题。
常见方法
1、同义词词典/知识图谱扩展 :通过人工维护的同义词表、WordNet 或领域知识图谱,添加等义或近义词汇。
例:查询"笔记本散热不好" → 扩展后"笔记本 散热 不好 降温 风扇 清理 过热"。
2、伪相关反馈(PRF):先执行初次检索,取 Top‑K(如 K=10)文档,提取其中高频词(过滤停用词),加入原查询。通常只取 5--10 个扩展词,避免主题漂移。
3、LLM 生成扩展词 :用大模型生成与查询相关的关键词。Prompt 需明确要求"输出搜索关键词,而非回答",并限制词语数量,减少噪声。
Prompt 示例:
扩展词数量:过多会引入不相关内容,通常控制在 5--10 个。
权重控制:若检索引擎支持,可对扩展词降权,原查询词保持最高权重。
噪声过滤:扩展后可通过重排序阶段对结果二次筛选,弱化扩展噪声的影响。
2. HyDE(假设文档嵌入)
HyDE 的核心思想是"生成假设文档 → 用该文档向量检索",利用文档与文档的语义相似度高于查询与文档的相似度这一特性,尤其适用于查询简短、文档描写详实的场景。
实现步骤
1、将原始查询输入 LLM,要求其"写一篇相关文档"(即使内容虚构),语言风格需贴近知识库文档。
2、将生成的假设文档通过同一稠密编码器转换为向量。
3、用该向量在文档库中做 ANN 搜索,召回最相似的 Top‑K 篇真实文档。
例子 :查询:"如何快速缓解头痛"
假设文档:"快速缓解头痛的方法包括:在安静环境中平躺休息,轻轻按摩太阳穴,用冷毛巾敷额头,必要时可服用布洛芬或对乙酰氨基酚。"
该假设文档虽不保证完全正确,但其中的"按摩太阳穴""冷敷""布洛芬"等词会紧密贴合真正的医学文档。
增强策略
1、多角度生成:要求 LLM 从不同视角生成多篇假设文档(如"物理疗法""药物疗法"),分别编码后取平均向量,可提升鲁棒性。
2、风格对齐:在 prompt 中提供一两篇知识库真实文档的片段作为风格示例,引导 LLM 贴近实际文档的写作口吻。
注意事项
1、HyDE 依赖额外的 LLM 推理,延迟较高,适合对实时性要求不苛刻的场景。
2、假设文档的正确性不重要,重要的是其用词和结构是否接近真实文档。
3、如果LLM不了解查询主题可能会生成误导检索方向的假设文档。
3. Step‑back Prompting(后退式提示)
当用户问题过于具体(如某个冷门事件、特定年份的细节)时,直接检索可能因文档覆盖不全而失败。Step‑back Prompting 通过生成一个更抽象的"后退问题",先检索高层背景知识,再从中推理具体答案。
例:原查询:"2024年诺贝尔物理学奖得主的研究方向"
后退查询:"诺贝尔物理学奖历届得主及成就"
检索结果会包含历年获奖者和领域的信息,生成模型可从中定位到 2024 年得主并提取其研究方向。
4. Multi‑Query Retrieval(多查询检索)
Multi‑Query 将单个查询生成多个变体(不同角度、不同措辞或子问题拆分),每个变体独立检索,合并后获得更全面的候选文档集。
生成策略
1、同义改写 :用不同表达方式描述同一需求。
例:"如何减肥" → 变体:"健康减重方法""快速瘦身技巧""科学减脂饮食"。
2、子问题拆解 :复杂问题分解为几个独立且具体的子问题,分别检索。
例:"深度学习入门需要什么数学基础"拆解为"深度学习入门""数学基础 线性代数""概率论 机器学习 前提"。
结果合并
1、并集去重 + 分数排序:取所有变体召回文档的并集,去除重复后按原始分数(或归一化分数)统一排序。
2、投票制:按文档被多少个变体命中次数排序,命中越多越靠前,对噪声查询变体的干扰不敏感。
3、RRF 融合:对各路变体的检索结果使用倒数排名融合,也无需归一化分数。
与查询扩展的组合
二者可叠加使用:先通过 Multi‑Query 生成多个查询变体(查询级拆分),再对每个变体实施词汇级查询扩展,实现"从广到细"的全面覆盖。
| 技术 | 作用层面 | 方法简述 | 适用场景 |
|---|---|---|---|
| 查询扩展 | 词汇级 | 添加同义词、相关词 | 原查询用词与文档不匹配时 |
| HyDE | 文档级 | 生成假设文档用于检索 | 查询简短,需要丰富语义,延迟不敏感 |
| Step‑back 提示 | 抽象层级 | 生成更上层的问题 | 具体查询需要背景知识支撑 |
| Multi‑Query | 查询级 | 生成多个查询变体并行检索 | 意图复杂、可从多角度回答的查询 |