1 引言
在之前的向量化篇章中,已经有了解到向量的结构。 向量有模长与方向,通常用于标识语义信息。
-
模长 模长可能反映嵌入向量(embedding)的“强度”或“信息量”。例如,在某些嵌入模型中,模长可能与输入文本的长度、复杂度或特征强度相关。 模长一般会归一化来统一尺度、聚焦方向。因为不同文档或查询的嵌入向量可能有不同的模长,归一化可以消除这种差异,聚焦于语义方向。 归一化减少了因模长差异导致的检索偏差,减少了噪声。
-
方向 方向决定语义相似性,方向越接近,语义越相似。 模长对相似性计算无影响,RAG的检索完全依赖方向(即语义相似性)。
本篇我们继续了解一下相似度的计算,以及给予相似度计算的检索。
2 Query
在RAG系统中,用户输入的查询被称为Query,我们需要使用与之前处理文档时完全相同的Embedding模型,将这个Query也转换为一个向量。
只有使用同一个Embedding模型,才能保证用户的“问题向量”和数据库中存储的“知识向量”位于同一个“语义空间”中。
2.1 执行搜索
在之前的篇章中,我们已经了解到常见的Embedding模型都会采取归一化,然后使用点积(效果等于“余弦相似度”)来计算相似度。 但在高质量的RAG系统中,这样的纯向量检索是不够的。 其往往采用“混合检索”。
2.1.1 向量检索的缺陷
向量搜索虽然强大,但它有一个致命弱点:对于那些没有太多语义、但本身就非常重要的关键词,它可能会“理解过度”而导致匹配失败。
举个例子:
- 用户问题: "请问LangChain4j在处理GPT-4o模型时有什么注意事项?"
- 向量搜索可能的结果: 它可能会找到一篇讲“如何在Java里使用最新的大语言模型”的文档,因为“语义”非常接近。但它可能会忽略掉另一篇专门讲“LangChain4j的GPT-4o补丁说明”的文档,因为从整体语义上看,这篇文档可能不如前一篇那么“宽泛匹配”。
- 关键词搜索的结果: 它会精确地找到所有包含 "LangChain4j" 和 "GPT-4o" 这两个关键词的文档。
2.1.2 混合检索(Hybrid Search) 弥补缺陷
混合检索结合了两种根本不同的搜索技术:
- 向量搜索 (Vector Search): 点积、余弦相似度、欧氏距离。它擅长理解 语义和意图。例如,用户问“AI导师”,它能找到包含“人工智能教练”的文档。
- 关键词搜索 (Keyword Search): 这是传统的搜索引擎技术,最经典的算法是 BM25。它擅长匹配 特定的、精确的词语,尤其是专有名词、产品型号、错误代码等。
当知识库中包含大量对 精确关键词 高度敏感的信息时,强烈建议使用混合检索。例如:
- 产品名称、型号 (如 "iPhone 15 Pro")
- 技术术语、库名 (如 "LangChain4j", "Pandas")
- 人名、地名
- 错误代码、特定ID
2.1.2.1 混合检索的融合算法
混合检索同时执行向量搜索和关键词搜索,然后将两边的结果进行智能的“融合”,得到一个最终的排序列表。 最常用的融合算法叫做 倒数排序融合 (Reciprocal Rank Fusion, RRF)。它不关心原始分数是多少,只关心一个文档在每个列表中的“排名”,这使得它能很好地结合两种不同维度的搜索结果。
RRF通过一个简单的公式来为每个文档计算一个新的、可比较的“融合分数”: Score(d) = Σ (1 / (k + rank(d)))
- Score(d): 我们要为文档 d 计算的最终融合分数。
- Σ (西格玛): 这是一个求和符号。意味着一个文档如果在两个搜索结果列表中都出现了,我们会把它的两个得分加起来。
- rank(d): 这是文档 d 在 某一个 搜索结果列表中的排名(第1名,第2名,...)。这是RRF最核心的输入。
- k: 这是一个常量,通常设置为60。它的作用是一个“平滑”或“阻尼”因子,用来减少排名靠后的文档对总分的巨大影响,确保排名靠前的文档获得更显著的优势。
2.2 控制返回结果
向量数据库可以配置返回结果的相似度阈值。 但是一般通过Top-K参数来控制。Top-K:会根据余弦相似度得分,从高到低进行排序,然后返回给你 最靠前的K个 知识块。这个“K”是一个你可以自己设定的参数。
Q:为什么要返回K个? 返回多个相关的知识块,可以让后续的LLM拥有更丰富、更全面的上下文信息,从而生成一个更综合、更准确的答案。 比如,一个知识块解释了RAG,另一个解释了微调,第三个对比了二者,把这三个都提供给LLM,它就能给出一个非常完美的答案。
2.2.1 K值选择的权衡
Q:这个K设置成多少比较合适?
A: 又是一个典型Trade-off。K过大则可能噪声大,K过小则可能不够精确,我们需要在全面性和信噪比之前权衡。其他还要考虑的因素有成本、响应速度(性能)
-
过小的K值 上下文不足,结果不够精确。 但是Token消耗更小,LLM处理的更快,可以用于快速定位问题是出在检索还是生成阶段。
-
过大的K值 噪声大,信息矛盾风险大,且成本高、响应慢。
2.2.2 K值决策参考
调整K值可以从以下几个角度来决策:
- 问题的类型:
- 对于简单的 事实问答(“什么是RAG?”),小K值 通常足够且高效。
- 对于复杂的 综合分析或比较(“请详细阐述RAG和微调在成本、效果和适用场景上的全部区别”),大K值 更有可能提供全面的信息。
- 知识库的质量:
- 如果您的知识库非常干净、切分得很好、噪声很低,可以适当 增大K值。
- 如果知识库比较杂乱,充满了重复或过时的信息,使用 小K值 更安全,可以避免引入过多噪声。
- LLM的能力:
- 像GPT-4或Claude 3 Opus这样拥有超长上下文窗口和强大理解能力的模型,对 大K值 的处理能力更强。
- 对于一些小模型或老模型,小K值 更容易让它们聚焦。
2.2.3 重排序Re-ranking优化Top-K
一种常见的返回结果优化策略是“两阶段检索”:
- 召回 (Recall): 先用向量数据库快速召回一个较大的K值(比如K=20),确保“宁可错杀,不可放过”,保证信息的全面性。
- 精排 (Re-rank): 然后,使用一个更轻量、更精准的模型或算法(称为“重排序器”),对这20个文档进行二次打分和排序,挑出其中最相关的3-5个。
- 生成 (Generation): 最后,只把这精选出的3-5个文档送给LLM。
这种方法兼顾了全面性和精准性,是构建高质量RAG系统的常用技巧。
2.2.3.1 精排技术
这项技术的核心是使用一种与初次检索不同的、通常更强大但也更慢的模型。最主流的技术是 交叉编码器 (Cross-Encoder)。
精排模型 (Cross-Encoder / 交叉编码器)****:
- 工作方式: 它同时查看Query和某一个候选文档。它将两者拼接在一起,作为一个整体输入到模型中,然后模型会输出一个单一的分数(通常是0到1之间),代表“相关性得分”。
- 流程:
- Input = [Query, Document] -> Cross-Encoder Model -> Relevance Score (e.g., 0.98)
- 优点: 准确度极高。因为它允许模型内部的注意力机制(Attention Mechanism)在问题和文档的每个词之间进行充分的、细致的交互和比对。它能捕捉到双编码器无法发现的细微关联。
- 缺点: 速度极慢。因为你不能提前处理。对于召回的每个文档,你都必须和问题一起完整地跑一遍模型。这就是为什么它不能用于海量文档的初筛,而只能用于对少量候选文档(比如Top 20)进行精排。
具体的精排技术/模型举例:
- Cohere Rerank: 这是一个非常流行的商业化精排API,效果很好。
- Hugging Face上的开源模型: 社区里有大量开源的交叉编码器模型,例如 bge-reranker-large 或 ms-marco-MiniLM 系列,您可以下载并在自己的代码中直接使用。
- LLM as a Judge: 一种更前沿的方法是,直接调用一个强大的LLM(比如GPT-4),给它问题和候选文档,然后让它根据一系列标准(如相关性、准确性)给出一个分数。这种方法非常灵活,但成本和延迟也最高。
精排技术的核心,就是用一个 计算成本更高但判断力更强 的交叉编码器,来弥补初次向量检索可能存在的“理解不够深入”的问题。