RAG
RAG(检索增强生成)通过提供对知识来源的访问来减少幻觉,这些知识来源为用户查询提供了额外的上下文,即LLM(如 Claude3.5、 GPT-4o)。它还旨在克服语言模型的上下文限制。
但是如果我们稍微简化一下,它就没有什么特别之处了。想问LLM 巴拉克·奥巴马的生日是什么?为什么不先找到奥巴马的维基百科页面(检索),将其添加到提示中(增强),然后让LLM回答问题(生成)。就这样!我们构建了我们第一个 RAG 系统。
在其核心,RAG 系统包含 2 个组件:一个检索器,用于从外部源文档中检索信息,以及一个生成器,使用检索到的信息生成响应。

RAG 常常与基于语义搜索或嵌入构建索引同时出现。
信息检索已经存在一个世纪了。在那些日子里,我们是如何检索相关文档的?没错,就是我们的好朋友 BM25。简单、快速且有效。基于词的检索解决方案如 BM25 也成功地为许多搜索引擎提供了动力。
虽然 RAG 在减少幻觉方面显示出希望,但它并非没有挑战。传统 RAG 系统中的一个关键问题是,在将文档分割成更小的块进行检索时,可能会丢失上下文。这就是 Anthropic 引入了“上下文检索”这一简单概念,为在 RAG 框架内保持更广泛的上下文提供了一个解决方案。
Contextual Retrieval 上下文检索
传统 RAG 通常将文档分割成更小的块以实现高效检索,但这可能导致上下文丢失。最近,Anthropic 在其论文中引入了“上下文嵌入”的概念,通过在每个嵌入之前添加相关上下文来解决缺乏上下文的问题。
可以使用LLM进行上下文检索。您可以开发一个针对LLM的提示,指示模型根据整体文档生成简洁的、针对特定块的内容,以便为每个块提供上下文信息。

考虑一个关于特定公司季度收入增长的查询。一个相关的片段可能如下:“该公司的收入与前一个季度相比增长了 3%”,它包含了增长百分比,但缺乏关键细节,如公司名称或时间段。这种缺乏上下文可能会阻碍准确检索。
通过将整体文档发送到每个块上的LLM,我们得到如下语境化的块:

这个‘contextualized_chunk’随后被发送到嵌入模型以创建该块的嵌入。
Hybrid search approach 混合搜索方法
尽管这种上下文嵌入已经证明可以改进传统的语义搜索 RAG,但结合 BM25 的混合方法可以产生更好的结果。相同的块特定上下文也可以与 BM25 搜索结合使用,以进一步提高检索性能。
BM25 是一种算法,它解决了 TF-IDF 的一些缺点,这些缺点与词饱和度和文档长度有关。
如果一个文档包含 100 次“计算机”这个术语的出现,它真的比包含 50 次出现的文档相关性强两倍吗?我们希望控制当某个术语可能饱和时 TF 的贡献。BM25 通过引入一个控制饱和曲线形状的参数 k1 来解决此问题。参数 k1 可以被调整,使得当 TF 增加时,在某个点上,BM25 分数将饱和,这意味着 TF 的增加不再对分数有太大贡献。
如果文档非常短,并且只包含一次“计算机”,这可能已经是一个很好的相关性指标。但是,如果文档真的很长,而“计算机”这个术语只出现一次,那么很可能这份文档并不是关于计算机的。我们希望奖励与短文档的术语匹配,并惩罚长文档。
我们可以通过引入另一个参数 b 来平衡短文档和长文档之间的相关性。参数 b 控制惩罚的强度:b 的值越高,对长文档的惩罚就越高。另一方面,小于平均长度的文档会受到奖励并给出更高的分数。语料库的平均长度用作参考点。长文档就是指比语料库平均长度长的文档,而短文档则是指比语料库平均长度短的文档。
虽然 BM25 是一种强大的基于词项的检索方法,但它可能无法捕捉到文档的语义含义,从而错过相关文档。这就是基于嵌入的检索介入的地方。
Embedding-based retrieval (Dense retrieval)基于嵌入的检索(密集检索)
密集检索技术将文本转换为嵌入表示——这听起来很复杂,其实是指我们可以用一大堆数字来表示文本(或图像、音频)。嵌入通常是一个向量,旨在保留原始数据的重要属性。在搜索时,查询被嵌入到相同的向量空间中,通过比较这两个向量之间的距离,可以识别出与查询嵌入最接近的嵌入(块/文档)。

余弦相似度,通过两个向量之间的角度来观察它们有多接近,是密集检索中的一种流行指标。余弦相似度得分越高(意味着角度越小),与查询的语义重叠度越高,因此意义越接近。
例如,“The cat sits on a mat”的嵌入应该与“The dog plays on the grass”有更高的相似度,而不是与“The AI research is super fun”,因为前两个句子共享更多的语义元素。
在实践中,向量搜索通常被实现为最近邻搜索。给定一个查询,目标是找到最相似的 k 个向量。实现这一目标的一种直接方法是 k-最近邻(k-NN)算法:
- 计算查询嵌入与所有存储向量的相似度得分,通常使用余弦相似度。
- 对这些向量根据它们的相似度得分进行排序。
- 选择得分最高的前 k 个向量。
Hybrid search: Contextual BM25 and contextual embeddings混合搜索:上下文 BM25 和上下文嵌入
Anthropic 也采用了一种混合方法,通过使用相互排名将上下文嵌入搜索和上下文 BM25 搜索的检索结果合并,以产生最终的排名得分。

这种混合方法的有效性还取决于在互逆排名过程中分配给语义搜索和 BM25 搜索结果的相对权重。这些相对权重允许您控制每种检索方法对最终排名的影响程度。如果您为语义搜索选择更高的权重,为 BM25 选择较低的权重。在语义搜索(权重更高)中表现良好的块可能在最终结果中排名更高。例如,如果我们把 BM25 的权重设置为 0.2,嵌入权重为 0.8,那么嵌入的物品在排名#20 时的总贡献与 BM25 中排名#5 的物品相同。然而,在 BM25 搜索中也表现良好的块块获得额外的提升。结合上下文嵌入和上下文 BM25 将前 20 个块检索失败率降低了 49%(5.7% → 2.9%)。
RAG evaluation RAG 评估
你的LLM再好也没用,如果你的搜索不行,找不到相关片段。添加更多内容到上下文窗口并不总是能提高结果。过多的无关内容可能导致模型产生幻觉或遗忘信息(阅读“迷失在中途”效应)。这就是为什么评估你的搜索与评估你的LLMs一样重要。
Ragas 是一个帮助你评估你的 RAG 管道的框架。其中两个指标(忠实度和答案相关性)专注于评估生成质量,而接下来的两个指标则评估搜索。
- 上下文召回:在所有与查询相关的文档中,检索到了多少百分比?
这衡量了检索内容中是否包含回答问题所需的所有相关信息。低语境回忆表明需要改进您的搜索算法。
- 上下文精确度:在检索到的所有文档中,有多少百分比与查询相关?
此指标评估检索到的内容中有多少被实际用于生成答案。它将上下文与答案进行比较,以查看答案是否确实来自上下文。它告诉你添加更多上下文是否真正有助于检索答案。所以,如果你得到 95%的准确率,但只有 10%的上下文精确度,那么添加更多上下文可能对提高答案质量没有帮助。目标是提供最精确、最相关的内容片段。
More on RAG evaluation can be found here.
RAG和SFT对比
在更新大型语言模型的知识方面,微调模型和使用RAG这两种方法有着各自的优缺点。微调模型优势在于能够通过有监督学习的方式,通过对任务相关数据的反复迭代调整,使得模型更好地适应特定领域的知识和要求。RAG能够从外部知识库中检索最新、准确的信息,从而提高了答案的质量和时效性。其优势在于可以利用最新的外部信息,从而更好地适应当前事件和知识。
| 微调模型 | RAG | |
|---|---|---|
| 优点 | 针对特定任务调整预训练模型。优点是可针对特定任务优化; | 结合检索系统和生成模型。优点是能利用最新信息,提高答案质量,具有更好的可解释性和适应性: |
| 缺点 | 但缺点是更新成本高,对新信息适应性较差; | 是可能面临检索质量问题和曾加额外计算资源需求; |
| 特性 | RAG技术 | SFT模型微调 |
|---|---|---|
| 知识更新 | 实时更新检索库,适合动态数据,无需频繁重训 | 存储静态信息,更新知识需要重新训练 |
| 外部知识 | 高效利用外部资源,适合各类数据库 | 可对齐外部知识,但对动态数据源不够灵活 |
| 数据处理 | 数据处理需求低 | 需构建高质量数据集,数据限制可能影响性能 |
| 模型定制化 | 专注于信息检索和整合,定制化程度低 | 可定制行为,风格及领域知识 |
| 可解释性 | 答案可追溯,解释性高 | 解释性相对低 |
| 计算资源 | 需要支持检索的计算资源,维护外部数据源 | 需要训练数据集和微调资源 |
| 延迟要求 | 数据检索可能增加延迟 | 微调后的模型反应更快 |
| 减少幻觉 | 基于实际数据,幻觉减少 | 通过特定域训练可减少幻觉,但仍然有限 |
| 道德和隐私 | 处理外部文本数据时需要考虑隐私和道德问题 | 训练数据的敏感内容可能引发隐私问题 |
在RAG技术流程中,涉及多个关键模块,每个模块承担着特定的任务,协同工作以实现准确的知识检索和生成自然语言回答。
| 技术模块 | 描述 |
|---|---|
| 意图理解 | 意图理解模块负责准确把握用户提出的问题,确定用户的意图和主题。处理用户提问的模糊性和不规范性,为后续流程提供清晰的任务目标。 |
| 文档解析 | 文档解析模块用于处理来自不同来源的文档,包括PDF、PPT、Neo4j等格式。该模块负责将文档内容转化为可处理的结构化形式,为知识检索提供合适的输入。 |
| 文档索引 | 文档索引模块将解析后的文档分割成短的Chunk,并构建向量索引。或通过全文索引进行文本检索,使得系统能够更快速地找到与用户问题相关的文档片段。 |
| 向量嵌入 | 向量嵌入模块负责将文档索引中的内容映射为向量表示,以便后续的相似度计算。这有助于模型更好地理解文档之间的关系,提高知识检索的准确性。 |
| 知识检索 | 知识检索模块根据用户提问和向量嵌入计算的相似度检索或文本检索打分。这一步骤需要解决问题和文档之间的语义关联,确保检索的准确性。 |
| 重排序 | 重排序模块在知识检索后对文档库进行重排序,以避免“Lost in the Middle”现象,确保最相关的文档片段在前面。 |
| 大模型回答 | 大模型回答模块利用大型语言模型生成最终的回答。该模块结合检索到的上下文,以生成连贯、准确的文本回答。 |
| 其他功能模块 | 可根据具体应用需求引入其他功能模块,如查询搜索引擎、融合多个回答等。模块化设计使得系统更加灵活,能够根据不同场景选择合适的功能模块组合 |





