RAG的压缩和高级总结。
在第一部分中,我们将重点介绍模块化RAG的概念和组成部分,包括6种模块类型,14个模块和40多个运算符。
在过去的一年里,检索增强生成(RAG)作为实现LLM应用的方法的概念引起了相当大的关注。我们撰写了一份关于RAG的综合调查报告,深入探讨了从天真的RAG到先进的RAG和模块化RAG的转变。然而,该调查主要通过增强的视角(例如增强源/阶段/过程)来审视RAG技术。
本文将重点介绍模块化RAG范式。我们进一步定义了一个三层的模块化RAG范式,包括模块类型、模块和操作符。在这个范式下,我们详细阐述了当前RAG系统中的核心技术,包括6种主要的模块类型、14个模块和40多个操作符,旨在提供对RAG的全面理解。
通过组织不同的运营商,我们可以得出各种RAG流程,这是我们在本文中要阐明的一个概念。根据广泛的研究,我们已经提炼和总结了典型的模式、几个具体的实施案例和最佳行业案例。(由于空间限制,这部分将在第二部分中讨论。)
本文的目标是提供对RAG发展现状的更深入理解,并为未来的进展铺平道路。
模块化RAG提供了许多机会,方便定义新的运算符、模块和配置新的流程。
RAG的进展带来了更多样化和灵活的过程,如下关键方面所示:
模块化RAG的定义
以上,我们可以看到RAG的快速发展已经超越了链式高级RAG范式,展示了模块化的特点。为了解决当前的组织和抽象不足,我们提出了一种模块化的RAG方法,无缝地集成了天真RAG和高级RAG的开发范式。
模块化RAG呈现出一种高度可扩展的范式,将RAG系统划分为模块类型、模块和运算符的三层结构。每个模块类型代表RAG系统中的核心流程,包含多个功能模块。每个功能模块又包含多个具体的运算符。
整个RAG系统成为多个模块和相应操作符的排列组合,形成我们所称的RAG流程。
在Flow中,可以在每个模块类型中选择不同的功能模块,并且在每个功能模块中可以选择一个或多个运算符。
与之前的范式的关系
模块化的RAG以多层次的模块形式组织RAG系统。高级RAG是RAG的一种模块化形式,而天真的RAG是高级RAG的一个特例。这三种范式之间的关系是继承和发展的关系。
模块化RAG的机会
模块化RAG的好处是显而易见的,为现有的与RAG相关的工作提供了新鲜而全面的视角。通过模块化组织,相关技术和方法得到了清晰的总结。
模块化RAG的框架
在本章中,我们将深入探讨三层结构,并为RAG构建一个技术路线图。由于空间限制,我们将避免深入讨论技术细节;然而,我们将提供全面的参考资料供进一步阅读。
索引化是将文本分解为可管理的块的过程,在组织系统中是一个关键步骤,面临着三个主要挑战:
较大的块可以捕捉更多的上下文,但也会产生更多的噪音,需要更长的处理时间和更高的成本。而较小的块可能无法完全传达必要的上下文,但它们的噪音较少。
使用重叠的块是平衡这些需求的一种简单方法。通过使用滑动窗口,语义转换得到增强。
然而,存在一些限制,包括对上下文大小的控制不精确,截断单词或句子的风险,以及缺乏语义考虑。
关键思想是将用于检索的块与用于合成的块分开。使用较小的块可以提高检索的准确性,而较大的块可以提供更多的上下文信息。
具体而言,一种方法可以是检索较小的块,然后引用父ID来返回较大的块。或者,可以检索单个句子,并返回该句子周围的文本窗口。
详细信息和LlamaIndex实施。
towardsdatascience.com
这类似于小到大的概念,首先生成较大块的摘要,然后在摘要上进行检索。随后,可以对较大块进行二次检索。
块可以通过元数据信息进行丰富,例如页码、文件名、作者、时间戳、摘要或块可以回答的问题。随后,可以根据这些元数据进行检索过滤,限制搜索范围。请参阅LlamaIndex中的实现。
提升信息检索效果的一种有效方法是为文档建立层次结构。通过构建块状结构,RAG系统可以加快相关数据的检索和处理。
在文档的层次结构中,节点以父子关系排列,与它们链接的是块。每个节点存储数据摘要,帮助快速遍历数据,并协助RAG系统确定要提取的块。
这种方法还可以减轻由块提取问题引起的错觉。
构建结构化索引的方法主要包括:
检查Arcus在大规模下的分层索引。
在构建文档的层次结构中利用知识图谱(KGs)有助于保持一致性。它勾勒了不同概念和实体之间的连接,显著减少了产生错觉的可能性。
另一个优势是将信息检索过程转化为LLM能够理解的指令,从而提高知识检索的准确性,并使LLM能够生成上下文连贯的回答,从而提高RAG系统的整体效率。
检查Neo4j的实现和LllmaIndex Neo4j查询引擎。
使用知识图谱来组织多个文档,您可以参考这篇研究论文《KGP:用于多文档问答的知识图谱提示》。
medium.com
Naive RAG的主要挑战之一是直接依赖用户的原始查询作为检索的基础。准确清晰地提出问题是困难的,不明智的查询会导致检索效果不佳。
这个阶段的主要挑战包括:
将单个查询扩展为多个查询可以丰富查询的内容,提供进一步的上下文以解决特定细微差别的缺失,从而确保生成的答案的最佳相关性。
通过使用LLMs来扩展查询,可以通过及时工程来并行执行这些查询。查询的扩展不是随机的,而是经过精心设计的。这个设计的两个关键标准是查询的多样性和覆盖范围。
使用多个查询的一个挑战是可能会削弱用户最初的意图。为了减轻这个问题,我们可以指示模型在提示工程中给予原始查询更大的权重。
子问题规划的过程代表了在组合时生成必要的子问题,以对原始问题进行情境化和完全回答。这个添加相关背景的过程,原则上类似于查询扩展。
具体来说,可以使用从最少到最多提示的方法将复杂问题分解为一系列更简单的子问题。
docs.llamaindex.ai
另一种查询扩展的方法是使用Meta AI提出的验证链(CoVe)。扩展的查询经过LLM的验证,以达到减少幻觉的效果。经过验证的扩展查询通常具有更高的可靠性。
使用转换后的查询来检索和生成,而不是使用用户的原始查询。
原始查询在LLM检索中并不总是最优的,特别是在现实场景中。因此,我们可以提示LLM重新编写查询。除了使用LLM进行查询重写外,还可以利用专门的较小语言模型,如RRR(重写-检索-阅读)。
淘宝推广系统中的查询重写方法的实施,即BEQUE:用于检索增强的大型语言模型的查询重写,显著提高了长尾查询的召回效果,导致了GMV的增长。
在回答查询时,LLM构建假设文档(假设的答案),而不是直接在向量数据库中搜索查询及其计算向量。
它专注于将相似性嵌入到答案之间,而不是寻求问题或查询的嵌入相似性。此外,它还包括反向HyDE,专注于从查询到查询的检索。
HyDE和Reverse HyDE的核心思想是建立查询和答案之间的联系。
https://medium.aiplanet.com/
使用Google DeepMind提出的Step-back Prompting方法,将原始查询抽象化以生成一个高级概念问题(后退问题)。
在RAG系统中,回退问题和原始查询都用于检索,并且两者的结果都被用作语言模型答案生成的基础。
cobusgreyling.medium.com
根据不同的查询,将路由到不同的RAG管道,适用于一个多功能的RAG系统,旨在适应各种情况。
第一步是从查询中提取关键词(实体),然后根据关键词和块内的元数据进行过滤,以缩小搜索范围。
另一种路由方法涉及利用查询的语义信息。具体方法见语义路由器。当然,还可以采用混合路由方法,结合语义和基于元数据的方法,以增强查询路由。
检查语义路由器存储库。
https://cobusgreyling.medium.com/
将用户的查询转换为另一种查询语言,以访问其他数据源。常见的方法包括:
在许多场景中,结构化查询语言(例如SQL、Cypher)通常与语义信息和元数据一起使用,以构建更复杂的查询。有关具体细节,请参阅Langchain博客。
博客.langchain.dev
检索过程在RAG中起着至关重要的作用。利用强大的PLMs能够有效地表示查询和文本在潜在空间中,从而促进问题和文档之间的语义相似性建立,以支持检索。
需要考虑三个主要因素:
自从ChatGPT发布以来,嵌入模型的开发疯狂进行。Hugging Face的MTEB排行榜评估了几乎所有可用的嵌入模型在8个任务上的表现——聚类、分类、双语文本匹配、配对分类、重新排序、检索、语义文本相似度(STS)和摘要,涵盖了58个数据集。此外,C-MTEB专注于评估中文嵌入模型的能力,涵盖了6个任务和35个数据集。
在构建RAG应用程序时,没有一个适用于所有情况的答案来回答“使用哪种嵌入模型”。然而,您可能会注意到特定的嵌入模型更适合特定的用例。
检查MTEB/C-MTEB排行榜。
Hugging Face
稀疏编码模型可能被认为是一种有些过时的技术,通常基于词频统计等统计方法,但由于其较高的编码效率和稳定性,它们仍然具有一定的地位。常见的系数编码模型包括BM25和TF-IDF。
神经网络密集编码模型包括几种类型:
两种嵌入方法捕捉到不同的相关特征,并且可以通过利用互补的相关信息相互受益。例如,稀疏检索模型可以用于为训练密集检索模型提供初始搜索结果。
此外,PLM可以用于学习术语权重,以增强稀疏检索。
具体来说,它还表明稀疏检索模型可以增强密集检索模型的零-shot检索能力,并帮助密集检索器处理包含稀有实体的查询,从而提高鲁棒性。
IVAN ILIN:高级RAG技术:图解概述的图片
在上下文可能与预训练模型在嵌入空间中认为相似的情况下分歧较大的情况下,特别是在高度专业化的领域,如医疗保健、法律和其他充斥着专有术语的领域,调整嵌入模型可以解决这个问题。
虽然这种调整需要额外的努力,但它可以大大提高检索效率和领域对齐。
您可以根据领域特定的数据构建自己的微调数据集,使用LlamaIndex可以迅速完成这项任务。
与直接从数据集构建微调数据集不同,LSR利用语言模型生成的结果作为监督信号,在RAG过程中对嵌入模型进行微调。
受到RLHF(从人类反馈中进行强化学习)的启发,利用基于语言模型的反馈来通过强化学习加强检索器。
有时候,对整个检索器进行微调可能会很昂贵,特别是当处理基于API的检索器时,因为这些检索器无法直接进行微调。
在这种情况下,我们可以通过添加适配器模块并进行微调来减轻这种情况。添加适配器的另一个好处是能够更好地与特定的下游任务对齐。
检索整个文档块并直接将其输入LLM的上下文环境并不是一个最佳选择。对文档进行后处理可以帮助LLM更好地利用上下文信息。
主要挑战包括:
重新对检索到的文档块进行重新排序,不改变其内容或长度,以增强对于LLM更关键的文档块的可见性。具体来说:
根据特定规则,计算指标以重新排列块。常见的指标包括:
MMR的理念是减少冗余并增加结果的多样性,它用于文本摘要。MMR根据查询相关性和信息新颖性的综合标准,在最终关键词列表中选择短语。
检查HayStack中的rerank实现
towardsdatascience.com
利用语言模型重新排序文档块,选项包括:
在RAG过程中的一个常见误解是认为尽可能检索到更多相关文件并将它们连接起来形成一个冗长的检索提示是有益的。
然而,过多的上下文可能会引入更多的噪音,降低LLM对关键信息的感知,并导致“迷失在中间”等问题。解决这个问题的常见方法是压缩和选择检索到的内容。
通过利用对齐和训练的小型语言模型,如GPT-2 Small或LLaMA-7B,实现了对提示中不重要的标记的检测和删除,将其转化为对人类难以理解但LLMs能够理解的形式。这种方法提供了一种直接实用的提示压缩方法,无需对LLMs进行额外的训练,同时平衡了语言的完整性和压缩比。
检查LLMLingua项目。
https://wyydsb.xin/
Recomp引入了两种类型的压缩器:一种是从检索到的文档中选择相关句子的抽取式压缩器,另一种是通过合并多个文档中的信息生成简洁摘要的抽象式压缩器。
两个压缩器都经过训练,以提高语言模型在最终任务上的性能,当生成的摘要被添加到语言模型的输入时,同时确保摘要的简洁性。
在检索到的文档与输入无关或未提供额外信息给语言模型时,压缩器可以返回一个空字符串,从而实现选择性增强。
通过识别和删除输入上下文中的冗余内容,可以简化输入,从而提高语言模型的推理效率。选择性上下文类似于“停用词去除”策略。在实践中,选择性上下文根据基础语言模型计算的自信息评估词汇单位的信息内容。
通过保留具有更高自信息量的内容,该方法为语言模型处理提供了更简洁高效的文本表示,而不会影响其在各种应用中的性能。
然而,它忽视了压缩内容与目标语言模型和用于提示压缩的小语言模型之间的相互依赖关系。
标记是一种相对直观和简单的方法。具体来说,首先对文档进行标记,然后根据查询的元数据进行过滤。
python.langchain.com
另一种直接而有效的方法是在生成最终答案之前,让LLM评估检索到的内容。这使得LLM能够通过LLM批判性评估来过滤掉相关性较差的文档。例如,在Chatlaw中,LLM被要求对相关的法律条款进行自我建议,以评估其相关性。
利用LLM根据用户的查询和检索到的上下文信息生成答案。
根据情况,选择LLM可以分为以下两种类型:
基于云API利用第三方LLMs,通过调用它们的API,如OpenAI的ChatGPT、GPT-4和Anthropic Claude等。好处:
缺点:
本地部署的开源或自主开发的LLMs,如Llama系列、GLM等。优缺点与基于云API的模型相反。
本地部署的模型提供更大的灵活性和更好的隐私保护,但需要更高的计算资源。
除了直接使用LLM之外,根据场景和数据特征进行有针对性的微调可以获得更好的结果。这也是使用本地设置的最大优势之一。常见的微调方法包括以下几种:
当LLMs在特定领域缺乏数据时,可以通过微调向LLM提供额外的知识。Huggingface的微调数据也可以作为初始步骤使用。
微调的另一个好处是能够调整模型的输入和输出。例如,它可以使LLM适应特定的数据格式,并按照指示以特定的风格生成回应。
通过强化学习将LLM的输出与人类或检索器的偏好进行对齐是一种潜在的方法。例如,手动注释最终生成的答案,然后通过强化学习提供反馈。
除了与人类偏好保持一致外,还可以与经过精调的模型和检索器的偏好保持一致。
当情况阻止访问强大的专有模型或更大参数的开源模型时,一种简单而有效的方法是提炼更强大的模型(例如GPT-4)。
优化生成器和检索器以使它们的偏好一致。一个典型的方法,比如RA-DIT,使用KL散度来对齐检索器和生成器之间的评分函数。
Orchestration是指用于控制RAG过程的模块。RAG不再遵循固定的流程,它涉及在关键点上做出决策,并根据结果动态选择下一步。
这也是模块化RAG与Naive RAG相比的关键特点之一。
法官模块评估RAG过程中的关键点,确定是否需要检索外部文档存储库,回答的满意程度以及进一步探索的必要性。通常在递归、迭代和自适应检索中使用。
具体而言,主要包括以下两个运营商:
下一步的行动是根据预先定义的规则确定的。通常,生成的答案会被评分,然后根据评分是否达到预先定义的阈值来决定是否继续或停止。常见的阈值包括令牌的置信水平。
LLM自主确定下一步行动。主要有两种方法实现这一目标。第一种方法是通过提示LLM根据对话历史进行反思或做出判断,就像ReACT框架中所看到的那样。
这里的好处是不需要对模型进行微调。然而,判断的输出格式取决于LLM对指令的遵守程度。一个基于提示的案例是FLARE。
第二种方法涉及生成特定的令牌以触发特定的动作,这种方法可以追溯到Toolformer,并应用于RAG,例如Self-RAG。
这个概念源自RAG Fusion。如前面关于查询扩展的部分所提到的,当前的RAG过程不再是一个单一的流程。它经常需要通过多个分支来扩展检索范围或多样性。因此,在扩展到多个分支之后,依赖于融合模块来合并多个答案。
融合方法基于从多个分支生成的不同令牌的加权值,从而综合选择最终输出。主要采用加权平均法。请参见REPLUG。
RRF是一种将多个搜索结果列表的排名结合起来生成一个统一排名的技术。
与滑铁卢大学(加拿大)和谷歌合作开发的RRF产生的结果比在任何单个分支下重新排序块更有效。
https://towardsdatascience.com
https://pub.towardsai.net