GraphRAG 与基线 RAG
RAG
检索增强生成 (RAG) 是一种使用真实世界信息改进 LLM 输出的技术。这种技术是大多数基于 LLM 的工具的重要组成部分,大多数 RAG 方法使用向量相似性作为搜索技术,我们称之为基线 RAG。
RAG 技术在帮助 LLM 推理私有数据集方面显示出前景——LLM 没有接受过训练且以前从未见过的数据,例如企业的专有研究、商业文档或通信。基线 RAG 是为了帮助解决此问题而创建的,但我们观察到基线 RAG 性能非常差的情况。
RAG不适合大型、全面、不同、新的
例如:
1、基线 RAG 难以将这些点连接起来。当回答一个问题需要通过其共享属性遍历不同的信息片段以提供新的综合见解时,就会发生这种情况。
2、当被要求在大型数据集合甚至单一的大型文档中全面理解汇总的语义概念时,基线 RAG 的表现很差。
为了解决这个问题,技术界正在努力开发扩展和增强RAG的方法-GraphRAG
GraphRAG
Microsoft Research 的新方法 GraphRAG 使用 LLM 基于输入语料库创建知识图谱。此图形以及社区摘要和图形机器学习输出用于增强查询时的提示。GraphRAG 在回答上述两类问题方面显示出实质性的改进,展示了优于以前应用于私有数据集的其他方法的智能或掌握能力。
索引
作用
- 从原始文本中提取实体、关系和声明
- 在实体中执行社区检测
- 生成多个粒度级别的社区摘要和报告
- 将实体嵌入到图形向量空间中
- 将文本块嵌入到文本向量空间中
工作流
由于数据索引任务的复杂性,我们需要能够将数据管道表示为一系列多个相互依赖的工作流。 在 GraphRAG 索引管道中,每个工作流都可以定义对其他工作流的依赖关系,从而有效地形成工作流的有向无环图 (DAG),然后用于调度处理。
Dataframe 消息格式
工作流之间以及工作流步骤之间的主要通信单元是 的实例。 尽管可能会产生副作用,但我们的目标是在数据处理方法中以数据为中心和以表为中心。 这使我们能够轻松地对数据进行推理,并利用基于数据帧的生态系统的力量。 我们的底层 DataFrame 技术可能会随着时间的推移而改变,但我们的主要目标是支持 DataShaper 工作流架构,同时保持单机易用性和开发人员人体工程学。
LLM 缓存
GraphRAG 库在设计时考虑了 LLM 交互,使用 LLM API 时的一个常见挫折是由于网络延迟、节流等导致的各种错误、错误。 由于存在这些可能的错误情况,我们在 LLM 交互周围添加了一个缓存层。 当使用相同的输入集(提示和调整参数)发出完成请求时,如果存在,我们将返回缓存结果。 这使我们的索引器能够更灵活地应对网络问题,以幂等方式执行操作,并提供更高效的最终用户体验。
GraphRAG 知识模型
知识模型是符合我们的数据模型定义的数据输出的规范。您可以在 GraphRAG 存储库内的 python/graphrag/graphrag/model 文件夹中找到这些定义。提供了以下实体类型。此处的字段表示默认情况下嵌入文本的字段。
- Document- 将文档输入到系统中。它们要么表示 CSV 中的单个行,要么表示单个.txt文件。
- TextUnit-要分析的一大块文本。这些块的大小、它们的重叠以及它们是否遵循任何数据边界可以在下面进行配置。一个常见的用例是设置为,以便文档和TextUnits 之间存在一对多关系,而不是多对多关系。CHUNK_BY_COLUMNSid
- Entity- 从 TextUnit中提取的实体。这些表示您提供的人员、地点、事件或其他实体模型。
- Relationship- 两个实体之间的关系。这些是由协变量生成的。
- Covariate- 提取的索赔信息,其中包含有关实体的声明,这些声明可能有时间限制。
- Community Report-一旦生成了实体,我们就会对它们执行分层社区检测,并为此层次结构中的每个社区生成报告。
- Node- 此表包含已嵌入和聚类的实体和文档的呈现图形视图的布局信息。
默认配置工作流
阶段 1:撰写 TextUnits
默认配置工作流的第一阶段是将输入文档转换为 TextUnits。TextUnit 是用于图形提取技术的文本块。它们还被提取的知识项用作源引用,以便使概念的面包屑和来源能够回到其原始源 tex。
块大小(以令牌为单位)是用户可配置的。默认情况下,这设置为 300 个令牌,尽管我们在使用单个“拾穗”步骤处理 1200 个令牌块方面有积极的经验。(“拾穗”步骤是后续提取)。较大的块会导致低保真度的输出和意义不大的参考文本;但是,使用较大的块可能会导致更快的处理时间。
group-by 配置也是用户可配置的。默认情况下,我们将块与文档边界对齐,这意味着 Documents 和 TextUnit 之间存在严格的一对多关系。在极少数情况下,这可以变成多对多的关系。当文档很短并且我们需要其中几个文档来组成一个有意义的分析单元(例如推文或聊天记录)时,这很有用
这些文本单元中的每一个都嵌入了文本,并传递到管道的下一阶段。
第 2 阶段:图形提取
在此阶段,我们分析每个文本单元并提取图形基元:Entities、Relationships 和 Claims。 实体和关系在我们的entity_extract动词中同时提取,声明在我们的claim_extract动词中提取。然后,将结果合并并传递到管道的后续阶段。
实体和关系提取
在图形提取的第一步中,我们处理每个文本单元,以便使用 LLM 从原始文本中提取实体和关系。此步骤的输出是一个 subgraph-per-TextUnit,其中包含具有名称、类型和描述的实体列表,以及与源、目标和描述的关系列表。
这些子图被合并在一起 - 任何具有相同名称和类型的实体都通过创建其描述数组来合并。同样,与同一源和目标的任何关系都是通过创建其描述的数组来合并的。
实体和关系摘要
现在我们有了一个实体和关系的图,每个实体和关系都有一个描述列表,我们可以将这些列表汇总为每个实体和关系的单个描述。这是通过要求 LLM 提供一个简短的摘要来完成的,该摘要捕获了每个描述中的所有不同信息。这使我们所有的实体和关系都有一个简洁的描述。
实体解析(默认情况下未启用)
图形提取的最后一步是解析表示相同真实世界实体但名称不同的任何实体。由于这是通过LLM完成的,而且我们不想丢失信息,因此我们希望对此采取保守的、非破坏性的方法。
然而,我们目前实施的实体决议是破坏性的。它将为 LLM 提供一系列实体,并要求它确定应该合并哪些实体。然后,这些实体将合并为一个实体,并且它们的关系会更新。
我们目前正在探索其他实体解析技术。在不久的将来,实体解析将通过在实体变体之间创建边缘来执行,该边缘指示索引引擎已解析实体。这将允许最终用户撤销索引端分辨率,并使用类似的过程添加他们自己的非破坏性分辨率。
索赔提取和排放
最后,作为一个独立的工作流,我们从源 TextUnits 中提取声明。这些声明代表了积极的事实陈述,具有评估的状态和时间限制。它们作为称为协变量的主要工件发出。
第 3 阶段:图形增强
现在我们有了一个可用的实体和关系图,我们想了解他们的社区结构,并用其他信息来增强图。这分两步完成:社区检测和图形嵌入。这些为我们提供了显式(社区)和隐式(嵌入)方法来理解我们图的拓扑结构。
社区检测
在此步骤中,我们使用分层莱顿算法生成实体社区的层次结构。这种方法将递归社区聚类应用于我们的图,直到我们达到社区规模阈值。这将使我们能够理解图的社区结构,并提供一种在不同粒度级别上导航和汇总图的方法。
图形嵌入
在此步骤中,我们使用 Node2Vec 算法生成图形的向量表示。这将使我们能够理解图的隐式结构,并提供一个额外的向量空间,用于在查询阶段搜索相关概念。
图表排放
一旦我们的图形增强步骤完成,最终的 Entities 和 Relationships 表在其文本字段嵌入文本字段后就会发出。
第 4 阶段:社区总结
在这一点上,我们有一个实体和关系的功能图,一个实体的社区层次结构,以及node2vec嵌入。
现在,我们希望以社区数据为基础,并为每个社区生成报告。这使我们在图形粒度的几个点上对图形有了高层次的理解。例如,如果社区 A 是顶级社区,我们将获得有关整个图表的报告。如果社区级别较低,我们将收到有关本地集群的报告。
生成社区报告
在此步骤中,我们使用 LLM 生成每个社区的摘要。这将使我们能够理解每个社区中包含的不同信息,并从高层次或低层次的角度提供对图形的有范围的理解。这些报告包含执行概述,并参考了社区子结构中的关键实体、关系和索赔。
汇总社区报告
在此步骤中,然后通过 LLM 对每个社区报告进行汇总,以供速记使用。
社区嵌入
在此步骤中,我们通过生成社区报告的文本嵌入、社区报告摘要和社区报告的标题来生成社区的矢量表示。
社区表排放
此时,将执行一些簿记工作,并发出 Communities 和 CommunityReports 表。
第 5 阶段:文档处理
在工作流的此阶段,我们将为知识模型创建“文档”表。
使用列进行增强(仅限 CSV)
如果工作流对 CSV 数据进行操作,您可以配置工作流以向文档输出添加其他字段。这些字段应存在于传入的 CSV 表中。有关配置此功能的详细信息,请参阅配置文档。
链接到 TextUnits
在此步骤中,我们将每个文档链接到在第一阶段创建的文本单元。这使我们能够了解哪些文档与哪些文本单元相关,反之亦然。
文档嵌入
在此步骤中,我们使用文档切片的平均嵌入来生成文档的向量表示。我们重新对文档进行分块,而不重叠分块,然后为每个分块生成一个嵌入。我们创建这些块的平均值,按令牌计数加权,并将其用作文档嵌入。这将使我们能够理解文档之间的隐含关系,并将帮助我们生成文档的网络表示。
文件表排放
此时,我们可以将 Documents 表发出到知识模型中。
第 6 阶段:网络可视化
在工作流的这个阶段,我们将执行一些步骤来支持现有图形中高维向量空间的网络可视化。在这一点上,有两个逻辑图在起作用:实体关系图和文档图。
对于每个逻辑图,我们执行 UMAP 降维以生成图形的 2D 表示。这将使我们能够在 2D 空间中可视化图形,并理解图形中节点之间的关系。然后,UMAP 嵌入将作为节点表发出。此表的行包括一个鉴别器,该鉴别器指示节点是文档还是实体,以及 UMAP 坐标。
索引器 CLI
GraphRAG 索引器 CLI 允许无代码使用 GraphRAG 索引器。
CLI 参数
–verbose- 在运行期间添加额外的日志记录信息。
–root - 数据根目录。这应该包含一个包含输入数据的目录,以及一个包含环境变量的文件。下面将介绍这些内容。input.env
–init- 这将使用 bootstrap 配置和提示覆盖在指定位置初始化数据项目目录。root
–resume - 如果指定,管道将尝试恢复之前的运行。上一次运行的 parquet 文件将作为输入加载到系统中,并且将跳过生成这些文件的工作流。输入值应为带时间戳的输出文件夹,例如“20240105-143721”。
–config <config_file.yml>- 这将选择退出默认配置模式并执行自定义配置。如果使用此选项,则下面的环境变量均不适用。
–reporter - 这将指定要使用的进度报告器。缺省值为 。有效值为 、 和 。richrichprintnone
–emit - 这指定了管道应发出的表输出格式。缺省值为 。有效值为 、 和 、 、 逗号分隔。parquetparquetcsvjson
–nocache- 这将禁用缓存机制。这对于调试和开发很有用,但不应在生产中使用。
查询
在查询时,这些结构用于在回答问题时为 LLM 上下文窗口提供材料。主要的查询模式有:
通过利用社区摘要对语料库的整体问题进行全局搜索。
本地搜索,通过扇形扩展到其邻居和相关概念来对特定实体进行推理。
本地搜索
基于实体的推理
本地搜索方法将来自知识图谱的结构化数据与来自输入文档的非结构化数据相结合,以在查询时使用相关实体信息增强 LLM 上下文。它非常适合回答需要理解输入文档中提到的特定实体的问题(例如,“洋甘菊的治疗特性是什么?)
给定一个用户查询和对话历史记录(可选),本地搜索方法会从知识图谱中识别出一组在语义上与用户输入相关的实体。这些实体充当知识图谱的访问点,从而能够提取更多相关详细信息,例如连接的实体、关系、实体协变量和社区报告。
此外,它还从与已识别实体关联的原始输入文档中提取相关文本块。
然后,对这些候选数据源进行优先级排序和筛选,以适应预定义大小的单个上下文窗口,该窗口用于生成对用户查询的响应。
全局搜索
全数据集推理
Baseline RAG 在处理需要跨数据集聚合信息以组成答案的查询时遇到困难。诸如“数据中的前 5 个主题是什么?”之类的查询性能非常糟糕,因为基线 RAG 依赖于数据集中语义相似的文本内容的向量搜索。查询中没有任何内容可以将其定向到正确的信息。
但是,使用 GraphRAG,我们可以回答此类问题,因为 LLM 生成的知识图谱的结构告诉我们整个数据集的结构(以及主题)。这使得私有数据集可以被组织成有意义的语义集群,这些语义集群是预先汇总的。使用我们的全局搜索方法,LLM 在响应用户查询时使用这些聚类来总结这些主题。
给定用户查询和可选的对话历史记录,全局搜索方法使用来自图形社区层次结构指定级别的 LLM 生成的社区报告集合作为上下文数据,以 map-reduce 方式生成响应。在此步骤中,社区报告被分割成预定义大小的文本块。
然后,每个文本块用于生成一个中间响应,其中包含一个点列表,每个点都附有一个数字评级,指示该点的重要性。
在该步骤中,从中间响应中筛选出的一组最重要的点被聚合并用作生成最终响应的上下文。mapreduce
全球搜索响应的质量可能会受到为获取社区报告而选择的社区层次结构级别的严重影响。较低层次结构级别的报告及其详细的报告往往会产生更彻底的回应,但由于报告的数量众多,也可能增加生成最终回应所需的时间和 LLM 资源。
提示调优
在数据开箱即用的情况下使用 GraphRAG 可能无法产生最佳结果。 我们强烈建议您按照我们文档中的提示调整指南来微调您的提示。