项目原地址:github.com/microsoft/g…
概述
GraphRAG 是一个基于知识图谱的智能问答系统。它的核心思想是:先把文档转换成一张"知识地图"(知识图谱),然后在这张地图上查找答案。本文档用通俗易懂的方式,详细解释 GraphRAG 是如何构建这张知识地图的,以及如何在这张地图上查找答案的。
第一部分:GraphRAG 如何构建知识图谱
想象一下,你有一堆散乱的文档,就像一堆没有整理的照片。GraphRAG 要做的事情,就是把这些照片整理成一本相册,并且给每张照片贴上标签,说明照片里有什么人、这些人之间是什么关系。这个过程就是"构建知识图谱"。
第一步:把文档切成小块(文本分块)
为什么要切块?
- 就像你不能一口吃掉整个苹果,需要切成小块一样,大语言模型(LLM)也不能一次性处理整篇很长的文档。所以我们需要把文档切成合适大小的"文本块"。
怎么切?
- 默认情况下,每个文本块大约是 300 个词(token)。这个大小可以调整。
- 切块时,通常会保留一些重叠,比如前一个块的末尾和后一个块的开头有部分重复。这样做是为了避免在切块边界处丢失重要信息。
举个例子:
假设你有一篇关于"苹果公司"的文档,有 1000 个词。GraphRAG 会把它切成大约 3-4 个文本块:
- 文本块 1:词 1-300(可能包含"苹果公司成立于1976年...")
- 文本块 2:词 280-580(有重叠,包含"乔布斯和沃兹尼亚克共同创立...")
- 文本块 3:词 560-860
- 文本块 4:词 840-1000
每个文本块都会记录它来自哪篇原始文档,这样以后可以追溯到原文。
第二步:从文本块中提取"实体"和"关系"(图谱提取)
什么是实体和关系?
- 实体:就是文档中提到的人、地方、组织、事件等。比如"苹果公司"、"乔布斯"、"iPhone"都是实体。
- 关系:就是实体之间的联系。比如"乔布斯"和"苹果公司"之间的关系是"创始人"。
怎么提取? GraphRAG 使用大语言模型(LLM)来"阅读"每个文本块,然后告诉模型:"请找出这段文字中提到的人和事物,以及它们之间的关系"。
具体过程:
-
对于每个文本块,LLM 会分析并提取:
- 实体列表:每个实体有名称、类型(是人、是公司、是产品等)、描述(这个实体是什么)
- 关系列表:每个关系有起点实体、终点实体、关系描述(它们之间是什么关系)
-
举个例子:
假设文本块内容是:"乔布斯和沃兹尼亚克在1976年共同创立了苹果公司。"
LLM 会提取出:
- 实体1:名称="乔布斯",类型="人物",描述="苹果公司的联合创始人之一"
- 实体2:名称="沃兹尼亚克",类型="人物",描述="苹果公司的联合创始人之一"
- 实体3:名称="苹果公司",类型="组织",描述="一家科技公司"
- 关系1:起点="乔布斯",终点="苹果公司",描述="共同创立"
- 关系2:起点="沃兹尼亚克",终点="苹果公司",描述="共同创立"
-
每个文本块都会生成这样一个小图谱,我们称之为"子图谱"。
第三步:合并相同的实体和关系(图谱汇总)
为什么要合并?
- 同一个实体(比如"苹果公司")可能会在多个文本块中出现。每个文本块都会给它一个描述,但这些描述可能略有不同。我们需要把这些描述合并起来,形成一个统一的、更完整的描述。
怎么合并?
-
合并实体:如果两个实体有相同的名称和类型,就把它们合并成一个,并把所有描述收集在一起。
- 比如"苹果公司"在文本块1中的描述是"一家科技公司",在文本块2中的描述是"总部位于库比蒂诺的公司",在文本块3中的描述是"生产iPhone的公司"。
- 合并后,我们会收集所有这些描述:[描述1, 描述2, 描述3]
-
合并关系:如果两个关系有相同的起点和终点实体,也合并它们,收集所有描述。
-
生成统一摘要:收集完所有描述后,LLM 会再次工作,把这些描述总结成一个简洁、统一的描述。
- 比如对于"苹果公司",LLM 可能会生成这样的统一描述:"苹果公司是一家总部位于库比蒂诺的科技公司,以生产iPhone等消费电子产品而闻名,由乔布斯和沃兹尼亚克在1976年共同创立。"
结果:
经过这一步,我们得到了一个"干净"的知识图谱,其中:
- 每个实体只有一个统一的描述
- 每个关系也只有一个统一的描述
- 所有信息都来自原始文档,但经过了整理和汇总
第四步:发现"社区"(社区检测)
什么是社区?
- 在知识图谱中,有些实体之间联系很紧密,形成了一个"小团体",这就是"社区"。
- 比如"苹果公司"、"乔布斯"、"iPhone"、"库比蒂诺"这些实体可能形成一个社区,因为它们都围绕"苹果公司"这个主题。
为什么要发现社区?
- 社区帮助我们理解文档的整体结构。就像把照片按主题分类(比如"家庭聚会"、"旅行"、"工作"),社区把相关的实体分组。
- 更重要的是,社区是分层次的。就像文件夹可以嵌套一样,社区也可以有"大社区"和"小社区"。
怎么发现社区?
GraphRAG 使用"分层 Leiden 算法"来发现社区:
- 第一层:把所有实体分成几个大社区。比如可能分成"科技公司"、"人物"、"产品"等大社区。
- 第二层:在每个大社区内部,再分成更小的社区。比如"科技公司"社区内部,可能分成"苹果相关"、"微软相关"等。
- 继续分层:可以继续分下去,直到每个社区足够小。
结果:
我们得到了一个"层次化的社区结构":
- 顶层:几个大社区(比如"科技公司"、"人物")
- 中层:每个大社区内部的小社区(比如"苹果相关"、"微软相关")
- 底层:更小的社区(比如"苹果产品"、"苹果人物")
第五步:为每个社区写"摘要报告"(社区报告生成)
为什么要生成报告?
- 社区里有很多实体和关系,但我们需要一个"总结"来快速了解这个社区是关于什么的。
- 这些报告就像每个照片分类的"标题"和"说明",帮助我们快速了解内容。
怎么生成报告?
-
对于每个社区,LLM 会查看这个社区里所有的实体、关系和声明。
-
LLM 会生成一份"社区报告",内容包括:
- 执行摘要:这个社区是关于什么的,主要主题是什么
- 关键实体:这个社区里有哪些重要的实体
- 关键关系:这些实体之间有什么重要关系
- 重要信息:这个社区包含哪些重要的事实或声明
-
举个例子:
对于"苹果相关"社区,报告可能是:
执行摘要:这个社区主要围绕苹果公司及其相关人物、产品和地点。 关键实体: - 苹果公司:一家总部位于库比蒂诺的科技公司 - 乔布斯:苹果公司的联合创始人 - iPhone:苹果公司的主要产品 关键关系: - 乔布斯共同创立了苹果公司 - 苹果公司生产iPhone - 苹果公司总部位于库比蒂诺 -
生成简化版报告:每个完整报告还会被进一步简化成一个更短的版本,用于快速检索。
结果:
- 每个社区都有了一份可读的报告
- 这些报告在不同层次上提供了对数据集的语义理解
- 顶层社区的报告提供"全局视角"(整个数据集的主题)
- 底层社区的报告提供"局部细节"(特定主题的详细信息)
第六步:生成"向量表示"(向量嵌入)
什么是向量表示?
- 计算机不能直接理解文字,需要把文字转换成数字(向量)。
- 向量有一个神奇的特性:意思相近的文字,它们的向量也很相似。这样我们就可以通过比较向量来找到意思相近的内容。
为什么要生成向量?
- 当我们查询时,需要快速找到"和问题相关的"实体、文本块或社区报告。
- 通过向量相似度搜索,我们可以快速找到相关内容。
怎么生成向量?
- 为实体描述生成向量:把每个实体的统一描述转换成向量
- 为文本块生成向量:把每个文本块的原始文字转换成向量
- 为社区报告生成向量:把每个社区报告的内容转换成向量
结果:
- 所有需要检索的内容都有了向量表示
- 这些向量存储在向量数据库中,可以快速进行相似度搜索
构建图谱的完整流程总结
让我们用一个完整的例子来总结整个过程:
输入:100 篇关于科技公司的文档
处理流程:
-
文本分块:100 篇文档 → 500 个文本块(每篇文档平均切成 5 块)
-
提取实体和关系:500 个文本块 → 每个文本块提取出平均 10 个实体和 15 个关系 → 总共约 5000 个实体实例和 7500 个关系实例
-
合并汇总:5000 个实体实例 → 合并成约 1000 个唯一实体(因为同一个实体在多个文本块中出现);7500 个关系实例 → 合并成约 2000 个唯一关系
-
社区检测:1000 个实体 → 分成 3 层社区结构:
- 顶层:5 个大社区("科技公司"、"人物"、"产品"等)
- 中层:每个大社区内部有 3-5 个小社区
- 底层:更小的社区
-
生成报告:每个社区 → 生成一份社区报告 → 总共约 50 份报告(不同层次)
-
生成向量:1000 个实体描述、500 个文本块、50 份社区报告 → 全部转换成向量并存储
输出:
- 一个结构化的知识图谱(实体、关系、社区)
- 多层次的社区报告
- 所有内容的向量表示
第二部分:GraphRAG 如何检索答案
现在我们已经有了知识图谱,就像有了一张详细的地图。当用户问问题时,GraphRAG 需要在这张地图上找到答案。GraphRAG 提供了三种不同的"查找方式",就像有三种不同的导航模式:近距离导航、远距离导航、和智能导航。
重要说明:这三种检索模式需要用户手动指定,而不是由大模型自动判断。用户需要根据问题的类型,选择最合适的检索方法。比如:
- 问具体实体的问题 → 选择 Local Search
- 问数据集整体主题的问题 → 选择 Global Search
- 问需要全局+细节的复杂问题 → 选择 DRIFT Search
接下来我们详细解释每种方法的工作原理,帮助用户做出正确的选择。
方法一:Local Search(局部搜索)- 近距离导航
适用场景:当你问的是关于"某个具体事物"的问题时,比如"苹果公司的创始人是谁?"
工作原理:就像你在一个城市里找一家具体的商店,你会先找到商店所在的区域,然后在这个区域里仔细查找。
详细步骤:
-
理解问题,找到入口点
- 用户问:"苹果公司的创始人是谁?"
- GraphRAG 首先把这个问题转换成向量,然后在知识图谱中搜索,找到和这个问题"意思最相近"的实体。
- 比如找到了"苹果公司"这个实体,这就是我们的"入口点"。
-
从入口点出发,收集相关信息
就像从商店出发,查看周围的街道和建筑一样,GraphRAG 会从"苹果公司"这个实体出发,收集所有相关信息:
- 直接相关的文本块:包含"苹果公司"的原始文本块
- 相关的实体:和"苹果公司"有关系的其他实体(比如"乔布斯"、"沃兹尼亚克")
- 相关的关系:连接"苹果公司"和其他实体的关系(比如"共同创立")
- 相关的社区报告:包含"苹果公司"的社区报告
- 相关的声明:关于"苹果公司"的事实声明
-
评分和排序
- 收集到的信息可能很多,但不是所有信息都和问题相关。
- GraphRAG 会给每条信息打分,判断它和问题的相关程度。
- 比如"乔布斯共同创立苹果公司"这个关系,和"创始人"问题高度相关,得分就高。
- "苹果公司生产iPhone"这个关系,和"创始人"问题不太相关,得分就低。
-
选择最重要的信息
- 根据评分,选择最相关的信息,但要注意不能超过 LLM 的处理能力(通常有 token 限制)。
- 就像你只能带有限的东西去旅行,GraphRAG 只能选择最重要的信息。
-
生成答案
- 把选出的信息(实体、关系、文本块等)整理成一个"上下文",交给 LLM。
- LLM 基于这些上下文信息,生成一个完整的答案。
- 比如:"苹果公司的创始人是史蒂夫·乔布斯和史蒂夫·沃兹尼亚克,他们于1976年共同创立了这家公司。"
Local Search 的优势:
- 答案很详细,因为使用了具体的实体和关系信息
- 答案可以追溯到原始文档,用户可以验证
- 适合回答关于特定实体的问题
Local Search 的局限:
- 如果问题需要理解整个数据集的主题,Local Search 可能不够用
- 如果问题涉及多个不相关的实体,可能收集不到足够的信息
方法二:Global Search(全局搜索)- 远距离导航
适用场景:当你问的是关于"整个数据集"的问题时,比如"这些文档中提到了哪些主要的科技公司?"
工作原理:就像你想了解整个城市的主要区域分布,你需要查看城市地图的概览,而不是只看某个具体街道。
详细步骤:
-
选择社区层次
- 根据问题的性质,选择一个合适的社区层次。
- 如果问题很宏观(比如"主要主题是什么"),选择顶层社区。
- 如果问题需要更多细节,选择中层或底层社区。
-
Map 阶段:并行处理社区报告
- 把选定的所有社区报告分成多个批次。
- 对于每个批次的每个社区报告,LLM 会:
- 阅读社区报告的内容
- 结合用户的问题,生成一个"中间答案"
- 这个中间答案包含多个要点,每个要点都有一个"重要性评分"
举个例子:
-
用户问:"这些文档中提到了哪些主要的科技公司?"
-
对于"苹果相关"社区的报告,LLM 可能生成:
要点1:苹果公司是一家重要的科技公司(重要性:9/10) 要点2:苹果公司由乔布斯和沃兹尼亚克创立(重要性:7/10) 要点3:苹果公司生产iPhone(重要性:6/10) -
对于"微软相关"社区的报告,LLM 可能生成:
要点1:微软是一家重要的科技公司(重要性:9/10) 要点2:微软由比尔·盖茨创立(重要性:7/10)
-
Reduce 阶段:聚合和筛选
- 收集所有中间答案的所有要点
- 根据重要性评分,筛选出最重要的要点
- 把筛选后的要点整理成最终的上下文
- 再次调用 LLM,基于这些要点生成最终答案
-
生成最终答案
- LLM 基于聚合后的要点,生成一个完整的、综合性的答案。
- 比如:"这些文档中提到了几家主要的科技公司:苹果公司(由乔布斯和沃兹尼亚克创立,以iPhone等产品闻名)、微软公司(由比尔·盖茨创立)..."
Global Search 的优势:
- 可以回答需要理解整个数据集的问题
- 通过 Map-Reduce 模式,可以处理大量数据
- 答案提供全局视角
Global Search 的局限:
- 计算成本较高(需要处理很多社区报告)
- 答案可能不够详细(因为使用的是摘要报告,而不是原始细节)
方法三:DRIFT Search(动态推理搜索)- 智能导航
适用场景:当你问的问题比较复杂,需要既了解全局又深入细节时,比如"苹果公司是如何发展起来的?"
工作原理:就像一个有经验的导游,会先给你一个概览,然后根据你的兴趣点,深入探索相关细节。
详细步骤:
-
Primer 阶段:生成初始答案和后续问题
-
用户问:"苹果公司是如何发展起来的?"
-
GraphRAG 首先找到和问题最相关的几个社区报告(比如"苹果相关"社区的报告)
-
LLM 基于这些报告,生成一个"初步答案"和几个"后续问题"
-
初步答案可能是:"苹果公司由乔布斯和沃兹尼亚克在1976年创立,最初生产个人电脑..."
-
后续问题可能是:
- "苹果公司的早期产品有哪些?"
- "乔布斯在苹果公司的发展中扮演了什么角色?"
- "苹果公司是如何从电脑公司转型为消费电子公司的?"
-
-
Follow-Up 阶段:深入探索
- 对于每个后续问题,GraphRAG 使用 Local Search 的方法,深入查找相关信息。
- 比如对于"苹果公司的早期产品有哪些?",会找到相关的实体("Apple I"、"Apple II"、"Macintosh")和相关文本块。
- 对于每个后续问题,都会生成一个"中间答案"和可能的"更深入的问题"。
-
构建答案层次结构
-
所有的问题和答案会形成一个"树状结构":
主问题:苹果公司是如何发展起来的? ├─ 初步答案:... ├─ 后续问题1:早期产品有哪些? │ ├─ 答案:Apple I, Apple II, Macintosh... │ └─ 更深入问题:Macintosh是如何改变行业的? │ └─ 答案:... ├─ 后续问题2:乔布斯的角色? │ └─ 答案:... └─ 后续问题3:转型过程? └─ 答案:...
-
-
评估和筛选
- 对于每个节点(问题和答案),系统会评估它的"置信度"(这个答案有多可靠)和"相关性"(和主问题有多相关)。
- 如果置信度或相关性太低,可能不会继续深入探索。
-
生成最终答案
- 把所有相关的答案整合起来,按照重要性排序,生成最终答案。
- 最终答案既包含全局视角(来自社区报告),也包含具体细节(来自 Local Search)。
DRIFT Search 的优势:
- 结合了 Global Search 的全局视角和 Local Search 的详细程度
- 通过动态生成后续问题,可以深入探索复杂主题
- 答案既全面又详细
DRIFT Search 的局限:
- 计算成本介于 Local 和 Global 之间
- 需要更多的 LLM 调用(因为要生成多个问题和答案)
三种检索方法的对比
| 特性 | Local Search | Global Search | DRIFT Search |
|---|---|---|---|
| 适用问题 | 关于特定实体的问题 | 关于整个数据集的问题 | 需要全局+细节的复杂问题 |
| 答案特点 | 详细、具体 | 宏观、综合 | 全面、深入 |
| 计算成本 | 低 | 高 | 中等 |
| 使用数据 | 实体、关系、原始文本块 | 社区报告 | 社区报告 + 实体关系 |
| 答案可追溯性 | 高(可追溯到原文) | 中(可追溯到报告) | 高(可追溯到原文和报告) |
| 选择方式 | 用户手动指定 --method local | 用户手动指定 --method global | 用户手动指定 --method drift |
如何选择检索方法?
用户需要根据问题的特点手动选择检索方法:
-
选择 Local Search:当问题涉及具体的实体、人物、地点、组织等,需要详细的、可追溯的答案时。
- 示例问题:"苹果公司的创始人是谁?"、"iPhone 的主要特点是什么?"
-
选择 Global Search:当问题需要理解整个数据集的主题、趋势、整体情况时。
- 示例问题:"这些文档中提到了哪些主要的科技公司?"、"数据集的主要主题是什么?"
-
选择 DRIFT Search:当问题比较复杂,既需要全局视角又需要深入细节时。
- 示例问题:"苹果公司是如何发展起来的?"、"这些科技公司之间有什么相似之处?"
重要说明:GraphRAG 不会自动判断应该使用哪种检索方法,用户必须在查询时通过 --method 参数明确指定。如果选择不当,可能会影响答案的质量或计算成本。
检索过程的完整示例
让我们用一个完整的例子来理解检索过程:
用户问题:"这些文档中,苹果公司和微软公司有什么相似之处?"
GraphRAG 的处理:
-
用户选择检索方法:用户根据问题特点,手动选择使用 DRIFT Search(通过
--method drift参数指定)。这是一个需要理解两个实体并比较的问题,既需要全局视角又需要深入细节,所以选择 DRIFT Search 是合适的。 -
Primer 阶段:
-
找到"苹果相关"和"微软相关"的社区报告
-
生成初步答案:"苹果公司和微软公司都是重要的科技公司..."
-
生成后续问题:
- "两家公司的创始人有什么相似之处?"
- "两家公司的主要产品有什么相似之处?"
- "两家公司的发展历程有什么相似之处?"
-
-
Follow-Up 阶段:
-
对于每个后续问题,使用 Local Search 查找详细信息
-
比如"创始人相似之处":
- 找到"乔布斯"和"比尔·盖茨"的实体信息
- 找到相关的文本块和关系
- 生成答案:"两者都是技术天才,都在年轻时创立了公司..."
-
-
整合答案:
-
把所有答案整合,生成最终答案:
苹果公司和微软公司有以下相似之处: 1. 创始人相似:两者都由技术天才在年轻时创立... 2. 产品相似:两者都从个人电脑起步,后来扩展到其他领域... 3. 发展历程相似:两者都经历了从创业公司到行业巨头的转变...
-
-
返回结果:
- 返回最终答案
- 同时返回使用的上下文数据(实体、关系、文本块、报告),用户可以验证答案的来源
总结
GraphRAG 的核心思想可以用两句话概括:
-
构建图谱:把散乱的文档整理成结构化的知识地图,通过提取实体和关系、发现社区、生成报告,让计算机能够"理解"文档的内容和结构。
-
检索答案:在知识地图上查找答案,根据问题的类型选择合适的检索方法,既可以利用全局视角回答宏观问题,也可以深入细节回答具体问题。
这种设计的优势在于:
- 结构化:知识图谱提供了结构化的数据,比纯文本更容易查询和分析
- 多层次:社区结构提供了从宏观到微观的多层次理解
- 灵活性:多种检索方法可以适应不同类型的问题
- 可追溯:答案可以追溯到原始文档,提高了可信度
通过这种方式,GraphRAG 能够回答传统检索方法难以处理的复杂问题,比如需要跨文档聚合信息的问题,或者需要理解数据集整体主题的问题。