🗒️微软GraphRAG原理介绍(附带部分源码)
00 分钟
2024-7-13
2024-7-17
type
status
date
summary
slug
tags
category
password
URL
icon
我们前几天写了一篇文章,简单跑了一下GraphRAG看了下效果,没看过这篇文章的可以看下https://www.luxinfeng.top/article/动手实操微软开源的GraphRAG。今天我们介绍一下GraphRAG的实现原理,关于实验对比的内容,我会在下一篇文章中给出。
 
GraphRAG的工作流程可以分为两部分,第一部分是构建过程;第二部分是查询过程。我们也是按照这两部分来介绍原理。

GraphRAG数据构建过程

基于微软在论文中提到的实现思路,GraphRAG构建图数据的执行流程如下:
  1. Source Documents → Text Chunks:将源文档分割成文本块。
  1. Text Chunks → Element Instances:使用大模型从每个文本块中提取图节点和边的实例。
  1. Element Instances → Element Summaries:使用大模型为每个图元素生成摘要。
  1. Element Summaries → Graph Communities:使用社区检测算法将图划分为社区。
  1. Graph Communities → Community Summaries:使用大模型为每个社区生成摘要。
  1. Community Summaries → Community Answers → Global Answer:使用社区摘要生成局部答案,然后汇总这些局部答案以生成全局答案。
最终生成的图数据是以graphml语法的字符串存储在.parquet文件中。从执行流程中也可以看出,很多地方都用到了大模型处理,因此如果文本内容很大的话,消耗的大模型Token数也会很多。
在工程中,构建检索的入口代码为graphrag.index.cli.index_cli()。在实际运行过程中,会根据配置文件读取工作流编排,如果传参中的配置为空,则会调用graphrag.index.create_pipeline_config.create_pipeline_config()方法创建工作流编排,不同工作流编排的具体组成在graphrag/index/workflows/v1这个文件夹下。
notion image
如果想查看实体提取和总结相关的prompt内容,可以在执行—init指令后,在对应根目录下的prompts目录下看到对应的prompt文件内容,我这里也把我上次Demo演示过程中使用的Prompt都展示出来吧。
 
 
 

GraphRAG查询过程

在查询时,GraphRAG支持global和local这两种查询方式,这两种方式的实现逻辑不同,我下面分别介绍下。

global查询模式

在global查询模式下的数据来源是create_final_nodes.parquetcreate_final_entities.parquetcreate_final_community_reports.parquet ,相关代码展示如下:
还是拿我之前的Demo为例,我们看下这几个文件中都存放了哪些信息。
create_final_nodes.parquet
这个文件中主要存放了各种知识图谱中各类节点的信息。
notion image
create_final_entities.parquet
这个文件中主要存放了各种知识图谱中各类实体的信息。
notion image
create_final_community_reports.parquet
这个文件中存放了通过社区算法聚合而来的各个社区信息描述和标题。
notion image
获取到数据内容后,global模式的查询流程如下:
1.从create_final_community_reports.parquet文件中获取选中的community_report数据,选取规则的源代码片段如下,代码路径为graphrag.query.context_builder.community_context.build_community_context:
  1. 基于选中的community_reports列表批量请求大模型(这里由于community_reports内容较多,会耗费较多的大模型Token),让大模型基于每个community_report回答用户的问题,具体的prompt模板如下:
  1. 把第二步获取到的大模型返回的结果列表整合成一个完整的答案,当然,这个整合过程也是通过大模型完成的,具体的prompt如下:
  1. 将整合后的结果直接返回给用户。

local查询模式

local查询模式下,与global模式相比,多了几个数据来源create_final_text_units.parquetcreate_final_relationships.parquet
这两个文件中的具体内容展示如下:
create_final_text_units.parquet
这个文件中存储了源文件被分割后的文本片段。
notion image
create_final_relationships.parquet
这里存储着节点之间的关系数据。
notion image
获取到原始数据后,local模式的查询逻辑如下:
  1. 基于用户的问题通过语义相似度计算相似度高的实体Entity,相关代码逻辑如下,代码路径为graphrag.query.context_builder.entity_extraction.map_query_to_entities:
  1. 基于选中的Entity获取对应的Community内容,调用方法如下,方法路径为graphrag.query.structured_search.local_search.mixed_context.LocalSearchMixedContext._build_community_context
  1. 基于聊天上下文和community_content构建prompt内容,prompt模板的内容如下:
  1. 调用大模型并将结果返回给用户。
 
以上就是这篇博客的全部内容,在下一篇中,我打算使用网易开源的Qanything这个开源RAG框架和微软的GraphRAG的实际效果做个对比,大家有什么想法欢迎随时沟通交流。
 
 
上一篇
ThreadLocal里的变量一定是线程独享的吗?
下一篇
动手实操微软开源的GraphRAG