RAG高级数据索引技术
作者: 吃果冻不吐果冻皮 来源: 吃果冻不吐果冻皮
本文将重新审视分块技术 以及其他方法,包括查询增强 、层次结构 和知识图谱 。
一、简单RAG架构快速概览
在2023年年初,我的主要关注点集中在Vector DB及其在更广泛的设计领域中的表现上。然而,随着2023年的收尾,这一领域出现了重大进展。在RAG系统的设计中,需要考虑以下一些事情:
* LLM模型领域正在进行的开源和开源之间的斗争,那么在实际使用中最好的模型是什么?
* 应该微调LLM还是直接对数据集进行嵌入?
* 文件处理有了新的突破。之前仅依靠**文档块** ,现在拥有一系列技术,包括**层次结构** 、**句子窗口** 、**自动合并** 等。
* 数据检索技术也突飞猛进。今年年初,只使用了**k-相似性** 技术,现在我们有**递归** 、**混合搜索** 、**重新排序** 、**元数据过滤器** 、**多智能体** 等。
那么,是什么造就了一个好的数据检索系统呢?
两个词:相关性和相似性。
相关性是指检索到的信息与用户的查询相关的相关性或重要性,而相似性在数据检索的上下文中是指用户的查询与可用数据之间的相似性。
similarity = word matching,relevancy = context matching.
矢量数据库有助于识别语义相近的内容(相似性),但识别相关性或检索相关内容更复杂的方法(可以参考:https://www.youtube.com/watch?v=TRjq7t2Ms5I)。
二、高级数据处理实现更好的数据检索
2.1 分块策略
在自然语言处理的背景下,“分块”是将文本分解为可管理、清晰和重要的块的过程。在这种情况下,使用较小的文本片段而不是较大的文档可以使RAG系统更快、更准确地发现相关上下文。
确保选择的分块是合适的,这对分块策略的成功至关重要。这些文本段落的水平和组织对这种策略的效果有很大影响。为了找到和提取捕捉RAG系统所需的基本细节或上下文的文本段落,需要仔细检查内容和上下文。智能分块策略提高了系统遍历和理解自然语言的能力,最终实现了更准确、更有效的信息处理。
在本文中,块大小为1024似乎会产生更好的结果
较大的块可以捕获更多的上下文,但由于它们产生的噪声,处理它们需要更长的时间和更多的钱。虽然较小的片段可能无法完全传达必要的上下文,但它们的噪音确实较小。平衡这两个要求的一种方法是具有重叠部分。组合块的查询可能能够从各种向量中获得足够的相关信息,以产生适当的上下文化答案。
2.2 这种策略有什么不好的地方?****
该策略假设需要访问的每一条信息都可以位于一个文档中,这是其局限性之一。如果相关上下文分布在多个单独的文档上,请使用具有递归方法的多文档代理和子查询等解决方案。
2.3 小到大分块与小到大检索相结合****
这个想法是,选择最佳的块大小有时不是最佳的,因为嵌入/检索大文本块并不总是最好的选择。大的文本块可能包含大量的填充内容,这些填充内容模糊了语义表示并降低了检索性能。 如果我们可以根据更集中、更小的比特进行提取或嵌入,同时为LLM保持足够的上下文以做出适当的响应,该怎么办?将用于合成的文本块与用于检索的文本块分离可能是有益的。较大的文本块提供更多的上下文信息,而较小的文本块提高了检索的准确性。小到大检索背后的概念是在检索过程中使用较小的文本块,然后将检索到的文本所属的较大文本块提供给大语言模型。
在(https://towardsdatascience.com/advanced-rag-01-small-to-big-retrieval-172181b396d4)文章中,作者对分块大小进行了两种方案的简单比较,从小到大似乎效果更好,但缺点是查询时间更长,而且重新嵌入数据的成本也更高。
如果想体验一下从小到大的方案,可以使用LlamaHub包,链接:https://llamahub.ai/l/llama_packs-recursive_retriever-small_to_big?from=all
2.4 文档层次结构****
构建数据结构以增强信息检索的一种有效方法是创建文档层次结构。文档层次结构可以与RAG系统的目录进行比较。通过构建块,RAG系统可以更快地检索和处理相关数据。因为文档层次结构有助于LLM选择包含要提取的最相关数据的部分,所以文档层次结构对RAG的效率至关重要。
在文档层次结构中,节点以父子关系排列,块与节点链接。数据的摘要存储在每个节点上,这有助于快速遍历数据,并帮助RAG系统确定要提取哪些块。
2.5 但是…为什么你需要一个文档层次结构?****
文档层次结构可以与文件目录或目录进行比较。虽然LLM能够从矢量数据库中提取相关的文本片段,但通过使用文档层次结构作为预处理步骤来识别最相关的文本段,可以提高检索速度和可靠性 。除了提高速度、可重复性和检索可靠性外,这种策略还可以减少块提取问题带来的幻觉。构建文档层次结构可能需要特定领域或问题的知识,以确保摘要与当前工作完全相关。
在左侧菜单中,存在多个部分,每个部分都包含自己的一组子部分,而每个子部分又包含其唯一的文档和随后的信息层。在一种基本的分块方法中,矢量查询可能会从不同的部分检索类似的代码片段,这可能会在没有适当排名的情况下导致混乱。
通过实现文档层次结构,RAG系统可以显著增强其在给定部分内为特定问题提供准确答案的能力。这种层次结构能够更细致地理解上下文,防止共享相似代码但存在细微差异的部分之间的潜在混淆。例如,当解决有关SageMaker处理的特定方面的问题时,系统可以准确地识别与该特定部分相关的信息并对其进行优先级排序,避免与SageMaker模型构建无意中混淆,后者可能有共同之处,但需要不同的考虑。这种方法降低了幻觉的风险,并有助于建立一个更可靠和上下文感知的RAG系统。
具体实现,可以参考:https://docs.llamaindex.ai/en/stable/examples/retrievers/auto_merging_retriever.html和https://llamahub.ai/l/llama_packs-auto_merging_retriever?from=llama_packs
2.6 知识图谱
知识图谱是为文档层次结构提供数据基础的好方法,而数据基础对于保持一致性至关重要。从本质上讲,知识图是不同概念和实体之间连接的确定性映射。与矢量数据库中的相似性搜索不同,知识图谱提供了可靠、准确地检索相关规则和概念的能力,大大降低了产生幻觉的可能性。
使用知识图谱来表示文档层次结构的一个明显好处是,它们可以用于将信息检索过程转换为LLM能够理解的指令。例如,当LLM被呈现有特定的查询(例如,X)时,知识图可以通过指示数据必须从某个文档(例如,文档a)中提取,然后被引导将提取的数据与另一个文档(如,文档B)进行比较来引导LLM。这种有条不紊的技术提高了知识检索的准确性,并使LLM能够通过遵循逻辑步骤生成上下文良好的回复,从而提高了RAG系统的整体功效。
知识图谱使用自然语言映射关系,这意味着即使是非技术用户也可以构建和修改规则和关系,以控制他们的企业RAG系统。例如,规则可能会说,要响应有关SageMaker内置算法的查询,应首先查阅适当的SageMaker文档,然后查找其中的特定算法。
(https://neo4j.com/developer-blog/advanced-rag-strategies-neo4j/)这篇文章介绍了使用LlamaIndex是如何来操作知识图谱的。官方文档:https://docs.llamaindex.ai/en/stable/examples/index_structs/knowledge_graph/Neo4jKGIndexDemo.html。如果想寻求简单的实现,请查看此LlamaHub包的实现:https://llamahub.ai/l/llama_packs-neo4j_query_engine?from=llama_packs
除了讨论的基本分块策略之外,再讨论两种更高级的数据检索。
三、两项数据检索技术
3.1 查询增强****
RAG中的一个主要问题是查询的措辞不当,可以通过查询扩充来解决,为查询提供进一步的上下文来解决查询缺乏特定场景的情况,从而确保生成的答案具有最佳相关性。这种方法提高了系统理解和处理更广泛问题的能力,最终提高了RAG框架的性能和用户满意度。
糟糕的问题表述往往是由语言的复杂性造成的。例如,根据上下文的不同,同一个单词可以有两种不同的含义。
即使是像GPT-4这样的高级模型仍然不知道所指的LLM的上下文。这在很大程度上是一个特定于领域的问题。
那么,如果你想使用特定于行业或领域的术语来将LLM上下文化呢?公司缩写词就是一个简单的例子。大多数LLM很难区分这些术语。然而,当涉及到MLA时,MLA(现代语言协会)、MLA(医学实验室助理)或MLA(最大似然估计)是两种不同的东西。我的方法包括预处理查询,并添加特定于公司的上下文以引用相关分段来映射“MLA”。我使用的另一种更昂贵的方法是微调嵌入或微调LLM模型。
PS:查询增强可以参考llamaindex的实现:https://docs.llamaindex.ai/en/latest/optimizing/advanced_retrieval/query_transformations.html#
3.2 子问题规划****
子问题规划代表了生成子问题的过程,这些子问题需要适当地将其上下文化并生成答案,当这些答案组合在一起时,可以完全回答原始问题。添加相关上下文的过程在原理上可以类似于查询扩充。
让我们以个人理财顾问中的一个问题为例:
投资者简介:John,45岁,风险承受能力中等,拥有由个股组成的多元化投资组合。他旨在评估股票投资的表现,并将其与相关基准进行比较。
问题:“作为一名风险承受能力中等的45岁投资者,John如何评估其个人股票投资的表现,并将其与基准进行比较,以确保其与他的长期财务目标相一致?”
子问题:
1.John目标的度量标准选择:
考虑到John的投资目标和风险承受能力,在评估投资组合中个股的表现时,他应该优先考虑哪些具体指标?
2.为John量身定制的基准:
考虑到John的投资状况,他如何确定一个符合其多元化投资组合并反映其财务目标的基准?
3.审查频率与John的策略一致 :
考虑到John繁忙的日程安排和长期的投资前景,什么频率的绩效评估对他来说是实用和有益的?
4.符合John偏好的风险调整后回报:
考虑到John适度的风险承受能力和对稳定、长期增长的渴望,他如何将风险调整后的指标纳入绩效评估?
5.为John的投资组合量身定制的相对绩效分析:
John可以通过什么方式进行相对绩效分析,具体考虑其多元化投资组合中所代表的行业和行业?
6.股息再投资策略与John的目标一致:
考虑到John对长期增长的偏好,他应该如何处理股息的再投资,以优化他的整体投资组合表现?
7.符合John目标的长期关注 :
鉴于John强调长期财务目标,在评估股票表现时,他应该如何平衡短期波动和持续增长?
8.调整和战略与John的财务目标保持一致:
根据绩效评估,John应该考虑哪些具体调整(如果有的话),以确保他的股票投资与他更广泛的财务战略和退休计划保持一致?
PS:现有的子查询引擎能够做到这一点有点牵强。然而,考虑到用于微调LLM的训练数据集的数量。
这种方法因在推理过程中引入人工参与以及不可能为每个可能的问题想象每个可能的子问题而受到批评。考虑到LLM的当前状态,应该避免试图重现每一个潜在的子问题,而是只在LLM即将失败时才采用外部推理规则进行干预。
四、将高级数据处理与高级数据检索相结合
要么得到响应的速度,要么用金钱和时间换取更好的RAG响应。
把它想象成一个乐高游戏,把所有的碎片叠在一起。你在上面放的乐高越多,你的乐高就越好,但过程也就越慢。你必须尝试多种组合,找出最适合你的文档的组合。没有一个适合所有人的建筑师可以使用。
上图说明了如何将多个检索放在查询引擎的顶部以产生更好的结果。除此之外,还可以尝试上面讨论的多种数据处理技术。
知识图谱可以对已知关系的某些关键主题和概念进行一致检索。
例如:除了上面的摘要索引、矢量索引和图形索引外,还可以添加另一个具有文档层次结构的矢量索引,也可以添加一个具有句子窗口或从小到大分块的矢量索引。
当涉及到检索时,可以进行多次检索加上混合搜索,然后使用重新排序来获得与您的查询最匹配的结果。
当涉及到查询引擎时,可以尝试上面讨论的多种查询规划技术,并将它们堆叠在一起。
来自多个查询引擎的多个响应将被发送到LLM以获得最终答案。
五、RAG中未解决的问题
* 数据处理不存在一刀切的问题。当为多个查询引擎索引组合多个数据处理时,成本效率是一个问题。
* 构建或改进矢量数据库在自动检索方面的表现。
* 能把知识图谱和传统的矢量数据库结合起来吗?
* 有什么简单的方法来处理不断变化的文档而不是编程的方法吗?
参考文献:
历史文章:2023年11月大模型文章集锦
更多AI工具,参考Github-AiBard123,国内AiBard123