RAG 检索三板斧原理
1. RAG 检索三板斧原理
在 RAG 知识库中,如果要想取得不错的结果,重点之一就是要在海量的知识库中,检索出来最相关的、完整的信息,目前的检索方式有三种:密集向量检索、稀疏向量检索、关键词检索
首先需要说明一点,向量数据库的检索,和常见的对象数据库逻辑不一样
向量数据库重点在于 “概率”,相同的关键词,在不同的参数或方式下,查询出来的结果是不同的,查询出来的数量也是可控制的
但对象数据库是确定性的,不论是等于还是 like,在数据和关键词不变的情况下,查询的结果总是确定的
这是理解上述三种检索方式的思维前提,我们需要先跳出查询结果是确定性的这个思维定式
接下来我们详细了解下,这三种检索方式的原理以及优缺点,以便在业务中选择最合适的检索方式
开始前,我们先介绍两种算法:TF-IDF 和 BM25,这两种算法跟关键词检索和稀疏向量检索密切相关
2. TF-IDF 和 BM25
2.1. TF-IDF 是什么
TF-IDF 的全称是 Term Frequency-Inverse Document Frequency,即词频 - 逆文档频率。
主要用来评估一个词语对于一个文件集或语料库中的其中一份文件的重要程度。一个词语在某篇文章中出现的频率高(TF 高),并且在其他文章很少出现(IDF 高),则认为该词语有很好的区分能力,对这篇文章更重要
- TF (词频):一个词在一篇文档中出现的频率。
- IDF (逆文档频率):一个词在整个文档集合中的普遍重要性。出现越广泛的词(如 “的”、“是”),其重要性越低;出现越罕见的词,其重要性越高。
TF-IDF 的值就是 TF 与 IDF 的乘积。
2.1.1. TF (Term Frequency) - 词频
词频表示一个词在文档中出现的次数。但为了消除不同文档长度带来的偏差,会对词频进行标准化。常见的标准化方法是使用相对词频。
公式 1:相对词频
TF(t, d) = (词t在文档d中出现的次数) / (文档d中所有词的总数)
例如:一篇文档总共有 100 个词,其中 “苹果” 出现了 5 次,那么 “苹果” 的 TF 值就是 5 / 100 = 0.05。
2.1.2. IDF (Inverse Document Frequency) - 逆文档频率
逆文档频率的核心逻辑是,如果一个词在很多文档出现,那么这个词可能不重要,比如 “的”、“是” 等,无法用于区分文章。反之,如果一个词只在少数几篇文章出现,那么说明这个词对这几篇文章的筛选很重要,可以用于区分文章
IDF(t, D) = log( (语料库中文档的总数N) / (包含词t的文档数 + 1) )
- N:语料库中文档的总数。
- 包含词 t 的文档数:也叫 “文档频率”(DF)。如果一个词越常见,这个值就越大。
- +1:平滑项(Laplace Smoothing),防止分母为 0(即防止某个词不在任何文档中出现的情况)。有时也用 +1 或 +0.5 等其他平滑方式。
“逆” 体现在哪里?
- 常见词(如 “的”)的 DF 很高,N/DF 的值接近 1,取对数后接近 0,从而降低了该词的权重。
- 罕见词的 DF 很低,N/DF 的值很大,取对数后得到一个较大的正数,从而提升了该词的权重。
log 的作用是压缩尺度,使 IDF 的值不会因为 N 和 DF 的差距过大而爆炸式增长。
2.1.3. TF-IDF
最终,一个词 t 对于文档 d 在语料库 D 中的 TF-IDF 值计算如下:
TF-IDF(t, d, D) = TF(t, d) * IDF(t, D)
- TF-IDF 值与一个词在文档中的出现次数成正比。一个词在某篇文档中出现的次数越多,TF-IDF 值越大,说明这个词可以用来查询这个文档
- TF-IDF 值与包含该词的文档数成反比。一个词在整个语料库内出现的文档数越多,TF-IDF 值越小,说明这词太常见了,在几乎所有文档都有,无法用来查询某个文档
因此,在你输入一句话时,TF-IDF 可以针对其中的某些词,查询出这个词出现的此处较多的文档,但是会避免使用场景词语比如 “的”、“是” 等查询文档,因为这些词在所有文档出现的次数都很多
2.2. BM25
BM25 是 TF-IDF 的改进版,核心还是使用词频和逆文档频率计算文档的相关性。通过引入一系列参数和算法优化,由于算法有点复杂,暂时不做深入研究,理解原理即可。BM25 的计算公式如下
Score(D, Q) = Σ(i=1 to n) IDF(q_i) * [ (TF(q_i, D) * (k1 + 1)) / (TF(q_i, D) + k1 * (1 - b + b * |D| / avgdl)) ]
BM25 相对 TF-IDF 做了一些改进
- 控制词频的无限增大
在 TF-IDF 中,词频是不受限制的,比如 “的” 在某个文档中出现了 1000 次,他的 TF 值会很高,这显然是不合理的。因此 BM25 引入了饱和函数限制 TF 值的无限增大
- 控制文档长度对算法的影响
TF-IDF 只对文档内的词频进行了归一化处理(除以总词数),但没有考虑不同文档之间的长度差异。一篇长文档自然比短文档包含更多的词,因此任何一个词在长文档中出现的概率本身就更高,但这并不一定意味着长文档与查询更相关。
- 逆文档频率的调整
BM25 使用的 IDF 公式也与标准 IDF 略有不同,但其核心思想一致:惩罚常见词,提升罕见词的权重。
BM25 的这些改进,使得算法对于某篇文档的匹配度评分时,更少的受到文档本身的长度、某些常见词的高频出现的影响,通过更科学的函数控制这些因素对于评分的影响,使得 BM25 在信息检索领域的实际应用中,其效果几乎总是优于传统的 TF-IDF
现在让我们进入正题,首先看一下关键词检索
3. 关键词检索
通过对上述两个算法的介绍,我们不难猜出,关键词检索,绝不仅仅是像对象数据库中的 “like” 那样简单的获取包含这个关键词的所有数据
而是根据一系列算法,如 TF-IDF 或 BM25,对重要的词优先检索,对不重要的词,降低对检索的影响,从而得出整个语料库中,满足检索关键词的,评分最高的文档
4. 密集向量检索
说到密集向量检索,我们又不得不再次提到向量化
向量化是指将非结构化的数据,如文本,转换为结构化的向量,是由一系列数字组成的高维数组。
如 “我喜欢吃苹果。” 这句话,经过向量算法,可能被转化为 [0.8, 0.2, 0.1](实际中维度通常是几百或上千)
密集向量检索,实际上是计算关键词与被匹配文档的余弦相似度,从而得出 “最像” 的文本
假设我们有三部电影:
- 《星际穿越》:简介:“一群探险家穿越虫洞,进行太空冒险的故事。”
- 《盗梦空间》:简介:“一群特工进入他人梦境,窃取秘密的故事。”
- 《玩具总动员》:简介:“一个男孩的玩具们活了过来并一起冒险的故事。”
我们使用一个文本嵌入模型将所有简介转换为向量(假设为 3 维)并存入向量数据库:
- 《星际穿越》向量:[0.9, 0.1, 0.2] // 高维代表 “太空”、“科幻”
- 《盗梦空间》向量:[0.8, 0.2, 0.1] // 高维代表 “梦境”、“科幻”
- 《玩具总动员》向量:[0.1, 0.8, 0.9] // 低维代表 “科幻”,高维代表 “玩具”、“动画”
现在,用户输入查询:“给我找一些关于在想象世界里冒险的科幻电影。”
- 向量化查询:将用户的查询语句也通过同一个模型转换为向量。假设得到查询向量:[0.85, 0.15, 0.1]。这个向量捕捉了 “科幻”、“冒险”、“想象世界” 等核心语义。
- 相似度计算:系统计算查询向量与数据库中所有电影向量的余弦相似度(一种衡量向量方向相似性的指标,值越接近 1 越相似)。
- 返回结果:系统按照相似度从高到低返回最相关的电影。即使用户的查询中没有出现 “太空”、“梦境”、“虫洞” 等任何电影简介里的具体关键词,系统依然能通过向量的语义理解返回最相关的结果:《星际穿越》和《盗梦空间》。
密集向量检索解决了关键词检索中,相似语句的匹配度问题,如 “香蕉”、“苹果” 这两个在关键词匹配时不可能被匹配到一起的词,在向量检索中,可能因为这两个词的 “水果” 属性被匹配
换言之,密集向量检索可以基于语义检索,而关键词检索只能基于词语本身检索
5. 稀疏向量检索
稀疏向量检索,可以理解为关键词检索的更优化算法,核心逻辑是将文本表示为一个很长的向量,这个向量的维度对应于整个词汇表(比如英语中的所有单词),可能是数万或者数百万维度,但向量中绝大多数位置的值都是 0,只有少数几个对应着文档中实际出现过的词的位置不为零。
因此,它被称为 “稀疏” 向量。
稀疏向量中,每一个有值的向量都代表一个词,因此可以很好的验证检索的生效关键词
相对来讲,密集向量的多数维度都有值,而且维数相对较低(几百或者几千)
稀疏向量通常使用 TF-IDF 或 BM25 计算关键词,然后将关键词的 TF-IDF 值加入到这个稀疏向量中这个关键词对应的位置
现在我们有三篇文档:
- D1: “苹果是一种水果。” → 包含词:苹果,水果
- D2: “苹果公司生产手机。” → 包含词:苹果,公司,手机
- D3: “香蕉和苹果都是水果。” → 包含词:香蕉,苹果,水果
我们使用一种简单的二进制表示法(如果词出现则为 1,否则为 0)。它们的稀疏向量如下(维度顺序为:[苹果, 手机, 水果, 香蕉, 公司]):
- D1: [1, 0, 1, 0, 0]
- D2: [1, 1, 0, 0, 1]
- D3: [1, 0, 1, 1, 0]
可以看到,每个向量大部分都是 0。
在实际应用中,我们不会用简单的 1 和 0,而是使用 TF-IDF 值,它更能体现一个词对文档的重要性。
用户输入查询:“水果”。
- 向量化查询:查询 Q “水果” 的向量为:[0, 0, 1, 0, 0]。
- 计算相似度:通常使用点积或余弦相似度来计算查询向量与每个文档向量的相似度。
- 返回结果:根据相似度排序,返回排名靠前的文档
关键词检索和稀疏向量检索几乎类似,稀疏向量检索是关键词检索的数学化实现。
但是在一些匹配度要求极高的情况下,如法律,医疗等,依然需要使用关键词检索
6. 对比
目前在 RAG 中,通常采用混合检索策略,同时使用稀疏检索和密集检索,然后将两者的结果进行融合和重新排序。
- 稀疏检索可以快速地从海量文档中筛选出一个候选集
- 密集检索可以理解语义的情况下,检索出更多稀疏检索无法检索到的内容
混合检索方式既能利用关键词检索的快速和稳定,又能发挥语义理解的智能和精准
以上就是对于 RAG 中几种检索方式的介绍,在实际的业务中,还需要根据自己的语料库和需求情况,选择合适的方式及混合比例进行检索,力求达到满足业务的检索结果
在检索结束后,为了保证信息不被遗漏,我们可能会检索大量的结果,此时直接将所有结果输入大语言模型,仍会因信息过载而影响生成质量与效率。
因此,我们还需对召回结果进行精细化筛选与重排(ReRank),为后续的大模型生成提供更优质、更聚焦的上下文信息,在达到效果的前提下高效的完成任务。