GraphRAG 核心原理:如何构建图与如何检索

6 阅读21分钟

项目原地址: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)来"阅读"每个文本块,然后告诉模型:"请找出这段文字中提到的人和事物,以及它们之间的关系"。

具体过程:

  1. 对于每个文本块,LLM 会分析并提取:

    • 实体列表:每个实体有名称、类型(是人、是公司、是产品等)、描述(这个实体是什么)
    • 关系列表:每个关系有起点实体、终点实体、关系描述(它们之间是什么关系)
  2. 举个例子:

    假设文本块内容是:"乔布斯和沃兹尼亚克在1976年共同创立了苹果公司。"

    LLM 会提取出:

    • 实体1:名称="乔布斯",类型="人物",描述="苹果公司的联合创始人之一"
    • 实体2:名称="沃兹尼亚克",类型="人物",描述="苹果公司的联合创始人之一"
    • 实体3:名称="苹果公司",类型="组织",描述="一家科技公司"
    • 关系1:起点="乔布斯",终点="苹果公司",描述="共同创立"
    • 关系2:起点="沃兹尼亚克",终点="苹果公司",描述="共同创立"
  3. 每个文本块都会生成这样一个小图谱,我们称之为"子图谱"。

第三步:合并相同的实体和关系(图谱汇总)

为什么要合并?

  • 同一个实体(比如"苹果公司")可能会在多个文本块中出现。每个文本块都会给它一个描述,但这些描述可能略有不同。我们需要把这些描述合并起来,形成一个统一的、更完整的描述。

怎么合并?

  1. 合并实体:如果两个实体有相同的名称和类型,就把它们合并成一个,并把所有描述收集在一起。

    • 比如"苹果公司"在文本块1中的描述是"一家科技公司",在文本块2中的描述是"总部位于库比蒂诺的公司",在文本块3中的描述是"生产iPhone的公司"。
    • 合并后,我们会收集所有这些描述:[描述1, 描述2, 描述3]
  2. 合并关系:如果两个关系有相同的起点和终点实体,也合并它们,收集所有描述。

  3. 生成统一摘要:收集完所有描述后,LLM 会再次工作,把这些描述总结成一个简洁、统一的描述。

    • 比如对于"苹果公司",LLM 可能会生成这样的统一描述:"苹果公司是一家总部位于库比蒂诺的科技公司,以生产iPhone等消费电子产品而闻名,由乔布斯和沃兹尼亚克在1976年共同创立。"

结果:

经过这一步,我们得到了一个"干净"的知识图谱,其中:

  • 每个实体只有一个统一的描述
  • 每个关系也只有一个统一的描述
  • 所有信息都来自原始文档,但经过了整理和汇总

第四步:发现"社区"(社区检测)

什么是社区?

  • 在知识图谱中,有些实体之间联系很紧密,形成了一个"小团体",这就是"社区"。
  • 比如"苹果公司"、"乔布斯"、"iPhone"、"库比蒂诺"这些实体可能形成一个社区,因为它们都围绕"苹果公司"这个主题。

为什么要发现社区?

  • 社区帮助我们理解文档的整体结构。就像把照片按主题分类(比如"家庭聚会"、"旅行"、"工作"),社区把相关的实体分组。
  • 更重要的是,社区是分层次的。就像文件夹可以嵌套一样,社区也可以有"大社区"和"小社区"。

怎么发现社区?

GraphRAG 使用"分层 Leiden 算法"来发现社区:

  1. 第一层:把所有实体分成几个大社区。比如可能分成"科技公司"、"人物"、"产品"等大社区。
  2. 第二层:在每个大社区内部,再分成更小的社区。比如"科技公司"社区内部,可能分成"苹果相关"、"微软相关"等。
  3. 继续分层:可以继续分下去,直到每个社区足够小。

结果:

我们得到了一个"层次化的社区结构":

  • 顶层:几个大社区(比如"科技公司"、"人物")
  • 中层:每个大社区内部的小社区(比如"苹果相关"、"微软相关")
  • 底层:更小的社区(比如"苹果产品"、"苹果人物")

第五步:为每个社区写"摘要报告"(社区报告生成)

为什么要生成报告?

  • 社区里有很多实体和关系,但我们需要一个"总结"来快速了解这个社区是关于什么的。
  • 这些报告就像每个照片分类的"标题"和"说明",帮助我们快速了解内容。

怎么生成报告?

  1. 对于每个社区,LLM 会查看这个社区里所有的实体、关系和声明。

  2. LLM 会生成一份"社区报告",内容包括:

    • 执行摘要:这个社区是关于什么的,主要主题是什么
    • 关键实体:这个社区里有哪些重要的实体
    • 关键关系:这些实体之间有什么重要关系
    • 重要信息:这个社区包含哪些重要的事实或声明
  3. 举个例子:

    对于"苹果相关"社区,报告可能是:

    执行摘要:这个社区主要围绕苹果公司及其相关人物、产品和地点。
    
    关键实体:
    - 苹果公司:一家总部位于库比蒂诺的科技公司
    - 乔布斯:苹果公司的联合创始人
    - iPhone:苹果公司的主要产品
    
    关键关系:
    - 乔布斯共同创立了苹果公司
    - 苹果公司生产iPhone
    - 苹果公司总部位于库比蒂诺
    
  4. 生成简化版报告:每个完整报告还会被进一步简化成一个更短的版本,用于快速检索。

结果:

  • 每个社区都有了一份可读的报告
  • 这些报告在不同层次上提供了对数据集的语义理解
  • 顶层社区的报告提供"全局视角"(整个数据集的主题)
  • 底层社区的报告提供"局部细节"(特定主题的详细信息)

第六步:生成"向量表示"(向量嵌入)

什么是向量表示?

  • 计算机不能直接理解文字,需要把文字转换成数字(向量)。
  • 向量有一个神奇的特性:意思相近的文字,它们的向量也很相似。这样我们就可以通过比较向量来找到意思相近的内容。

为什么要生成向量?

  • 当我们查询时,需要快速找到"和问题相关的"实体、文本块或社区报告。
  • 通过向量相似度搜索,我们可以快速找到相关内容。

怎么生成向量?

  1. 为实体描述生成向量:把每个实体的统一描述转换成向量
  2. 为文本块生成向量:把每个文本块的原始文字转换成向量
  3. 为社区报告生成向量:把每个社区报告的内容转换成向量

结果:

  • 所有需要检索的内容都有了向量表示
  • 这些向量存储在向量数据库中,可以快速进行相似度搜索

构建图谱的完整流程总结

让我们用一个完整的例子来总结整个过程:

输入:100 篇关于科技公司的文档

处理流程:

  1. 文本分块:100 篇文档 → 500 个文本块(每篇文档平均切成 5 块)

  2. 提取实体和关系:500 个文本块 → 每个文本块提取出平均 10 个实体和 15 个关系 → 总共约 5000 个实体实例和 7500 个关系实例

  3. 合并汇总:5000 个实体实例 → 合并成约 1000 个唯一实体(因为同一个实体在多个文本块中出现);7500 个关系实例 → 合并成约 2000 个唯一关系

  4. 社区检测:1000 个实体 → 分成 3 层社区结构:

    • 顶层:5 个大社区("科技公司"、"人物"、"产品"等)
    • 中层:每个大社区内部有 3-5 个小社区
    • 底层:更小的社区
  5. 生成报告:每个社区 → 生成一份社区报告 → 总共约 50 份报告(不同层次)

  6. 生成向量:1000 个实体描述、500 个文本块、50 份社区报告 → 全部转换成向量并存储

输出:

  • 一个结构化的知识图谱(实体、关系、社区)
  • 多层次的社区报告
  • 所有内容的向量表示

第二部分:GraphRAG 如何检索答案

现在我们已经有了知识图谱,就像有了一张详细的地图。当用户问问题时,GraphRAG 需要在这张地图上找到答案。GraphRAG 提供了三种不同的"查找方式",就像有三种不同的导航模式:近距离导航、远距离导航、和智能导航。

重要说明:这三种检索模式需要用户手动指定,而不是由大模型自动判断。用户需要根据问题的类型,选择最合适的检索方法。比如:

  • 问具体实体的问题 → 选择 Local Search
  • 问数据集整体主题的问题 → 选择 Global Search
  • 问需要全局+细节的复杂问题 → 选择 DRIFT Search

接下来我们详细解释每种方法的工作原理,帮助用户做出正确的选择。

方法一:Local Search(局部搜索)- 近距离导航

适用场景:当你问的是关于"某个具体事物"的问题时,比如"苹果公司的创始人是谁?"

工作原理:就像你在一个城市里找一家具体的商店,你会先找到商店所在的区域,然后在这个区域里仔细查找。

详细步骤:

  1. 理解问题,找到入口点

    • 用户问:"苹果公司的创始人是谁?"
    • GraphRAG 首先把这个问题转换成向量,然后在知识图谱中搜索,找到和这个问题"意思最相近"的实体。
    • 比如找到了"苹果公司"这个实体,这就是我们的"入口点"。
  2. 从入口点出发,收集相关信息

    就像从商店出发,查看周围的街道和建筑一样,GraphRAG 会从"苹果公司"这个实体出发,收集所有相关信息:

    • 直接相关的文本块:包含"苹果公司"的原始文本块
    • 相关的实体:和"苹果公司"有关系的其他实体(比如"乔布斯"、"沃兹尼亚克")
    • 相关的关系:连接"苹果公司"和其他实体的关系(比如"共同创立")
    • 相关的社区报告:包含"苹果公司"的社区报告
    • 相关的声明:关于"苹果公司"的事实声明
  3. 评分和排序

    • 收集到的信息可能很多,但不是所有信息都和问题相关。
    • GraphRAG 会给每条信息打分,判断它和问题的相关程度。
    • 比如"乔布斯共同创立苹果公司"这个关系,和"创始人"问题高度相关,得分就高。
    • "苹果公司生产iPhone"这个关系,和"创始人"问题不太相关,得分就低。
  4. 选择最重要的信息

    • 根据评分,选择最相关的信息,但要注意不能超过 LLM 的处理能力(通常有 token 限制)。
    • 就像你只能带有限的东西去旅行,GraphRAG 只能选择最重要的信息。
  5. 生成答案

    • 把选出的信息(实体、关系、文本块等)整理成一个"上下文",交给 LLM。
    • LLM 基于这些上下文信息,生成一个完整的答案。
    • 比如:"苹果公司的创始人是史蒂夫·乔布斯和史蒂夫·沃兹尼亚克,他们于1976年共同创立了这家公司。"

Local Search 的优势:

  • 答案很详细,因为使用了具体的实体和关系信息
  • 答案可以追溯到原始文档,用户可以验证
  • 适合回答关于特定实体的问题

Local Search 的局限:

  • 如果问题需要理解整个数据集的主题,Local Search 可能不够用
  • 如果问题涉及多个不相关的实体,可能收集不到足够的信息

方法二:Global Search(全局搜索)- 远距离导航

适用场景:当你问的是关于"整个数据集"的问题时,比如"这些文档中提到了哪些主要的科技公司?"

工作原理:就像你想了解整个城市的主要区域分布,你需要查看城市地图的概览,而不是只看某个具体街道。

详细步骤:

  1. 选择社区层次

    • 根据问题的性质,选择一个合适的社区层次。
    • 如果问题很宏观(比如"主要主题是什么"),选择顶层社区。
    • 如果问题需要更多细节,选择中层或底层社区。
  2. Map 阶段:并行处理社区报告

    • 把选定的所有社区报告分成多个批次。
    • 对于每个批次的每个社区报告,LLM 会:
      • 阅读社区报告的内容
      • 结合用户的问题,生成一个"中间答案"
      • 这个中间答案包含多个要点,每个要点都有一个"重要性评分"

    举个例子:

    • 用户问:"这些文档中提到了哪些主要的科技公司?"

    • 对于"苹果相关"社区的报告,LLM 可能生成:

      要点1:苹果公司是一家重要的科技公司(重要性:9/10)
      要点2:苹果公司由乔布斯和沃兹尼亚克创立(重要性:7/10)
      要点3:苹果公司生产iPhone(重要性:6/10)
      
    • 对于"微软相关"社区的报告,LLM 可能生成:

      要点1:微软是一家重要的科技公司(重要性:9/10)
      要点2:微软由比尔·盖茨创立(重要性:7/10)
      
  3. Reduce 阶段:聚合和筛选

    • 收集所有中间答案的所有要点
    • 根据重要性评分,筛选出最重要的要点
    • 把筛选后的要点整理成最终的上下文
    • 再次调用 LLM,基于这些要点生成最终答案
  4. 生成最终答案

    • LLM 基于聚合后的要点,生成一个完整的、综合性的答案。
    • 比如:"这些文档中提到了几家主要的科技公司:苹果公司(由乔布斯和沃兹尼亚克创立,以iPhone等产品闻名)、微软公司(由比尔·盖茨创立)..."

Global Search 的优势:

  • 可以回答需要理解整个数据集的问题
  • 通过 Map-Reduce 模式,可以处理大量数据
  • 答案提供全局视角

Global Search 的局限:

  • 计算成本较高(需要处理很多社区报告)
  • 答案可能不够详细(因为使用的是摘要报告,而不是原始细节)

方法三:DRIFT Search(动态推理搜索)- 智能导航

适用场景:当你问的问题比较复杂,需要既了解全局又深入细节时,比如"苹果公司是如何发展起来的?"

工作原理:就像一个有经验的导游,会先给你一个概览,然后根据你的兴趣点,深入探索相关细节。

详细步骤:

  1. Primer 阶段:生成初始答案和后续问题

    • 用户问:"苹果公司是如何发展起来的?"

    • GraphRAG 首先找到和问题最相关的几个社区报告(比如"苹果相关"社区的报告)

    • LLM 基于这些报告,生成一个"初步答案"和几个"后续问题"

    • 初步答案可能是:"苹果公司由乔布斯和沃兹尼亚克在1976年创立,最初生产个人电脑..."

    • 后续问题可能是:

      • "苹果公司的早期产品有哪些?"
      • "乔布斯在苹果公司的发展中扮演了什么角色?"
      • "苹果公司是如何从电脑公司转型为消费电子公司的?"
  2. Follow-Up 阶段:深入探索

    • 对于每个后续问题,GraphRAG 使用 Local Search 的方法,深入查找相关信息。
    • 比如对于"苹果公司的早期产品有哪些?",会找到相关的实体("Apple I"、"Apple II"、"Macintosh")和相关文本块。
    • 对于每个后续问题,都会生成一个"中间答案"和可能的"更深入的问题"。
  3. 构建答案层次结构

    • 所有的问题和答案会形成一个"树状结构":

      主问题:苹果公司是如何发展起来的?
      ├─ 初步答案:...
      ├─ 后续问题1:早期产品有哪些?
      │  ├─ 答案:Apple I, Apple II, Macintosh...
      │  └─ 更深入问题:Macintosh是如何改变行业的?
      │     └─ 答案:...
      ├─ 后续问题2:乔布斯的角色?
      │  └─ 答案:...
      └─ 后续问题3:转型过程?
         └─ 答案:...
      
  4. 评估和筛选

    • 对于每个节点(问题和答案),系统会评估它的"置信度"(这个答案有多可靠)和"相关性"(和主问题有多相关)。
    • 如果置信度或相关性太低,可能不会继续深入探索。
  5. 生成最终答案

    • 把所有相关的答案整合起来,按照重要性排序,生成最终答案。
    • 最终答案既包含全局视角(来自社区报告),也包含具体细节(来自 Local Search)。

DRIFT Search 的优势:

  • 结合了 Global Search 的全局视角和 Local Search 的详细程度
  • 通过动态生成后续问题,可以深入探索复杂主题
  • 答案既全面又详细

DRIFT Search 的局限:

  • 计算成本介于 Local 和 Global 之间
  • 需要更多的 LLM 调用(因为要生成多个问题和答案)

三种检索方法的对比

特性Local SearchGlobal SearchDRIFT Search
适用问题关于特定实体的问题关于整个数据集的问题需要全局+细节的复杂问题
答案特点详细、具体宏观、综合全面、深入
计算成本中等
使用数据实体、关系、原始文本块社区报告社区报告 + 实体关系
答案可追溯性高(可追溯到原文)中(可追溯到报告)高(可追溯到原文和报告)
选择方式用户手动指定 --method local用户手动指定 --method global用户手动指定 --method drift

如何选择检索方法?

用户需要根据问题的特点手动选择检索方法:

  • 选择 Local Search:当问题涉及具体的实体、人物、地点、组织等,需要详细的、可追溯的答案时。

    • 示例问题:"苹果公司的创始人是谁?"、"iPhone 的主要特点是什么?"
  • 选择 Global Search:当问题需要理解整个数据集的主题、趋势、整体情况时。

    • 示例问题:"这些文档中提到了哪些主要的科技公司?"、"数据集的主要主题是什么?"
  • 选择 DRIFT Search:当问题比较复杂,既需要全局视角又需要深入细节时。

    • 示例问题:"苹果公司是如何发展起来的?"、"这些科技公司之间有什么相似之处?"

重要说明:GraphRAG 不会自动判断应该使用哪种检索方法,用户必须在查询时通过 --method 参数明确指定。如果选择不当,可能会影响答案的质量或计算成本。

检索过程的完整示例

让我们用一个完整的例子来理解检索过程:

用户问题:"这些文档中,苹果公司和微软公司有什么相似之处?"

GraphRAG 的处理:

  1. 用户选择检索方法:用户根据问题特点,手动选择使用 DRIFT Search(通过 --method drift 参数指定)。这是一个需要理解两个实体并比较的问题,既需要全局视角又需要深入细节,所以选择 DRIFT Search 是合适的。

  2. Primer 阶段

    • 找到"苹果相关"和"微软相关"的社区报告

    • 生成初步答案:"苹果公司和微软公司都是重要的科技公司..."

    • 生成后续问题:

      • "两家公司的创始人有什么相似之处?"
      • "两家公司的主要产品有什么相似之处?"
      • "两家公司的发展历程有什么相似之处?"
  3. Follow-Up 阶段

    • 对于每个后续问题,使用 Local Search 查找详细信息

    • 比如"创始人相似之处":

      • 找到"乔布斯"和"比尔·盖茨"的实体信息
      • 找到相关的文本块和关系
      • 生成答案:"两者都是技术天才,都在年轻时创立了公司..."
  4. 整合答案

    • 把所有答案整合,生成最终答案:

      苹果公司和微软公司有以下相似之处:
      
      1. 创始人相似:两者都由技术天才在年轻时创立...
      
      2. 产品相似:两者都从个人电脑起步,后来扩展到其他领域...
      
      3. 发展历程相似:两者都经历了从创业公司到行业巨头的转变...
      
  5. 返回结果

    • 返回最终答案
    • 同时返回使用的上下文数据(实体、关系、文本块、报告),用户可以验证答案的来源

总结

GraphRAG 的核心思想可以用两句话概括:

  1. 构建图谱:把散乱的文档整理成结构化的知识地图,通过提取实体和关系、发现社区、生成报告,让计算机能够"理解"文档的内容和结构。

  2. 检索答案:在知识地图上查找答案,根据问题的类型选择合适的检索方法,既可以利用全局视角回答宏观问题,也可以深入细节回答具体问题。

这种设计的优势在于:

  • 结构化:知识图谱提供了结构化的数据,比纯文本更容易查询和分析
  • 多层次:社区结构提供了从宏观到微观的多层次理解
  • 灵活性:多种检索方法可以适应不同类型的问题
  • 可追溯:答案可以追溯到原始文档,提高了可信度

通过这种方式,GraphRAG 能够回答传统检索方法难以处理的复杂问题,比如需要跨文档聚合信息的问题,或者需要理解数据集整体主题的问题。