1.传统的RAG的缺陷:

1.1跨文档的多跳推理

什么叫多跳推理(Multi-hop Reasoning)

一个形象化地解释就是:需要从A关联到B,再从B关联到C,然后由A推到C地问题 或者还有一种比较具体的表现:链式推理

1.2全局性问题

举例: 这本小说的主题思想是什么? Query-Focused Summarization问题,本质上不是检索任务,而是归纳任务

1.3.切块带来的语义断裂

  • 语言切断
  • 实体关系丢失
  • 检索噪声:这个有个比较有意思的点:[苹果的营收]检索到一堆水果

1.4 根本原因:

传统的RAG只理解语义,但是忽略了关系

1.5 解决方法:

引入知识图谱,这也就是GraphRAG的核心思路

2.什么是GraphRAG?为什么会有GraphRAG?

基于知识图谱做RAG的方法,基于微软发布的开源项目 定义:GraphRAG就是用LLM把文档读成一张知识图谱,然后基于这张图谱来做检索和回答

传统RAG和GraphRAG的核心差异

知识的存储形式:

传统RAG:离散的文本块 GraphRAG:以图的形式存储,文档中的实体和他们的关系被显式提取出来,形成一张结构化的关系网络

图的优点:

  1. 多跳推理可行
  2. 全局性 将整个知识图谱通过社区检测算法划分为若干个社区(图中关系密切的节点),然后再用LLM为各个社区生成一份摘要
  3. 实体和关系显式化,切断语义迎刃而解

3.GraphRAG的工作流程

分为两大阶段:索引阶段和查询阶段

索引阶段

1.文档切块(Text Chunking):

毕竟上下文窗口有限

2.实体与关系提取

将文本块发送给LLM,让他提取出其中的实体(Entity)和关系(Relationship)

专用的prompt,大致格式:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
你是一个实体关系抽取助手。请从下面的文本中:
1. 识别所有的实体,每个实体给出:
   - entity_name:实体名(大写)
   - entity_type:类型(比如 [人物, 组织, 地点, 事件])
   - entity_description:实体的综合描述

2. 识别所有实体之间的关系,每对关系给出:
   - source_entity:源实体
   - target_entity:目标实体
   - relationship_description:关系的描述
   - relationship_strength:关系强度(1-10 的数字)

文本内容:
{input_text}

请按以下格式输出:
("entity"|实体名|类型|描述)
("relationship"|源|目标|描述|强度)

此处有一个缺陷:重复和歧义 同一个实体可能有不同的身份,不如刘备,玄德都是同一个人,都是LLM提取时不会合并

3.生成实体/关系摘要

把同一个实体在所有文本块里的描述汇总起来,让 LLM 合成一段更完整的实体描述,关系也是如此

4.社区检测

社区检测算法:Leiden算法,是一种层次化社区检测办法 他会把图谱划分为多个层级的社区 这种层次化的划分,时Graph能够处理不同粒度全局问题的基础:不同程度的问题,使用对应层级的社区

5.生成社区摘要

为每个社区单独生成一份摘要报告

最终产物: 实体节点-关系边-层次化社区-社区报告

在这个过程中,token的成本非常大

查询阶段:两种搜索方法各司其职

模式一:Local Search(本地搜索)

适用场景:询问某个具体实体

工作流程:

  1. 定位入口实体:先用问题的向量,在所有实体节点的向量索引里做相似度搜索,找到最相关的几个实体。比如问诸葛亮,就先定位到「诸葛亮」这个节点
  2. 顺藤摸瓜扩展:从入口实体出发,沿着图的边扩展,找到相关的邻居实体、关系、原始文本块、所属社区报告
  3. 组装上下文:把找到的这些信息整合成一段上下文(Context)
  4. 交给 LLM 生成答案

模式二:Global Search(全局搜索)

适用场景:全局性,宏观性

工作流程:Map-Reduce策略

  • Map 阶段:把某个层级(比如 Level 1)的所有社区报告都拿出来,分成好多批,对每一批都让 LLM 生成一个「中间答案」,并给每个观点打一个「重要性评分」
  • Reduce 阶段:把所有中间答案里的观点汇总,按评分排序,保留最重要的那些,最后让 LLM 合并成一个完整的最终答案:

本质:将某个问题拆分成多个社区内部的子问题并行解答,再汇总 很烧钱

img

img

img

我觉得这个图做的真心不错

4.Graph的缺陷

1.索引成本

过程中多次调用LLM,token成本非常高

2.实体消歧

LLM做实体抽取,对于现实的统一实体的不同名称会抽取为几个独立的实体

导致问题:图谱被近重复节点塞满;关系碎片化;错误指数级放大

3.查询延迟

特别是Global Search 虽然后续提出了动态社区选择的这样的优化,都是延迟依然比ANN低一个数量级

4.增量更新很麻烦

业界应对增量问题的几种思路(有点懒得看)

这个问题这么难,业界有没有办法?有,但每种办法都是有代价的妥协。下面几种主流思路,你可以根据自己的业务场景挑。

思路一:简单粗暴,定期全量重建

最土但最省心的办法:每天、每周、或者每月定时把所有文档重新跑一遍 GraphRAG 索引。

优点:实现简单,一致性好,图谱永远是新鲜的。

缺点:贵。非常贵。假设你有 1000 万 token 的语料,每天重建一次,一年就是 300 多次全量索引,光 LLM 调用费可能就要几万美元。而且重建过程中服务还要切换到「旧索引」上,运维复杂度也不低。

适合什么场景?文档更新频率低 + 数据量不大 + 对实时性不敏感的场景,比如公司年度法规库、历史档案库。

思路二:增量索引(Incremental Indexing)

微软 GraphRAG 的后续版本(以及 Fast GraphRAG 这类改良方案)都支持了增量索引,只处理新增的文档,把新抽出的实体和关系追加到已有图上。

imgimg

核心流程是这样的:先对新文档做一次实体和关系抽取(注意,只处理新的,老文档完全不碰),然后把抽出来的新实体和图里的老实体做消歧合并(这一步也叫 upsert,实现上一般会用字符串编辑距离加上向量相似度组合判断),合并完之后把新关系追加到图上。这时候关键的一步来了:系统要判断哪些社区受到了这次更新的影响(通常是通过图算法识别受影响的子图),然后只对这些受影响的社区重新做一次检测和摘要,没受影响的部分保持原样不动。

优点:不用全量重建,成本低很多。Fast GraphRAG 这种方案跑 430 个文档的增量,用本地 14B 模型大概 8.5 小时就能搞定。

缺点:精度会有损失。因为社区划分本质是一个全局优化问题,你只重做局部社区,全局的社区划分就不一定是最优的。时间长了,图谱的质量会慢慢「漂移」,需要阶段性做一次全量重建来「校准」。

思路三:混合策略,小增量 + 周期性全量

这是目前生产环境最常见的做法,就是把前面两个思路结合起来用。日常有新文档进来,就跑一次增量索引,又快又便宜;但每隔一段时间(比如每个月一次),再做一次全量重建,把之前累积漂移掉的精度拉回来。

这种方式的优点就是成本和质量的平衡最好,缺点嘛,就是你得同时维护两套流程。

思路四:时间分区(Temporal Partitioning)

如果你的数据有明显的时间属性(比如新闻、月度报告、季度财报),还有一种做法是按时间段分开建图:2025 Q1 一张图,Q2 一张图,Q3 又是一张图。

查询的时候,要么指定时间段查对应的图,要么跨图联邦查询再聚合。

优点:每张图相对小、更新隔离性好、老数据不受新数据影响。

缺点:跨时间段的查询要专门做联邦策略,图和图之间的实体也需要做全局对齐。

思路五:延迟实体合并 + 最终一致性

有些团队的做法更激进:索引时不做消歧,只把所有实体直接加进去,哪怕同一个 IBM 有四个节点也无所谓。然后查询时再做合并,或者异步离线跑消歧任务。

优点:索引极快,增量几乎零成本。

缺点:查询时可能要做更多的聚合和去重,查询延迟会变高。而且在没来得及异步合并之前,查询结果可能会漏召回。

5.什么是 LightRAG?为什么会有 LightRAG?

在保留图结构带来的关系理解能力的前提下,把成本,速度,增量三件事做到了极致

LightRAG的三个核心创新

一.图增强的文本索引**(Graph-Enhanced Text Indexing)**

保留实体节点+关系边,省略社区检测和社区摘要

二.双层检索范式

对于全局问题的解法: 不用提前做全局聚合,而是在查询时把查询本身拆成两层关键词,分别做检索

底层关键词关注具体的实体和细节 高层关键词关心抽象的主题和概念

对于两种关键词

  • 用低级关键词去向量库里面检索实体
  • 用高级关键词去向量库找相关的关系

优点:每次查询只调取一次LLM做关键词抽取,然后几次向量检索,降低了成本和查询延迟

三.增量更新算法

LightRAG 的增量更新,本质上就是「追加」两个字。新文档来了,跑一下实体和关系抽取,然后把抽出来的新实体、新关系直接 upsert 到图和向量库里就行了。如果新实体和老实体有重合(比如都叫 IBM),那就合并节点的描述;要是完全是新实体,那就加个新节点。整个过程完全不需要重新做社区检测、不需要重新生成摘要、更不需要全量重建索引 (抽取实体和关系,然后去重,追加新节点和建立新关系)

LightRAG的代价是什么? 主要牺牲了一定的全局深度洞察 LightRAG的本质还是基于查询去拼凑全局视角

6.LightRAG的工作原理

同样的分为索引阶段和查询阶段

索引阶段:轻量化的图构建

  1. 文档切块(chunking)
  2. 实体和关系提取 此处有一个小巧思:关系关键词:描述的是这条关系所代表的主题或概念
  3. 键对值生成+去重 对于每个实体和关系,生成一个键对值:方便关键词检索时复杂的Embedding和chunk遍历 去重:同名实体和重复关系合并 但是LightRAG的去重比较朴素,主要基于名称朴素,不会处理同人不同名的情况,例如AI和Artificial Intelligence,但是little problem,在查询时所有相似实体都会被查询然后多路召回合并

最终的存储结构 两种形式: 知识图谱 向量数据库:实体描述的向量,关系描述的向量,关系关键词的向量

查询阶段:双层检索

  1. 关键词抽取:调用LLM抽取处低层关键词和高层关键词
1
2
3
4
5
6
7
查询:"国际贸易如何影响全球经济稳定?"

LLM 输出:
{
  "high_level_keywords": ["国际贸易", "全球经济稳定", "经济影响"],
  "low_level_keywords": ["贸易协定", "关税", "货币汇率", "进口", "出口"]
}

WOC有点夸张

img

​ 2.双层检索

Low-level 检索:用低层关键词去向量库里搜实体节点。比如用「贸易协定」「关税」这些关键词,找到相关的实体节点(可能是某个具体的贸易协定、某种税种等)。然后从这些入口实体出发,在图上扩展到它们的一跳邻居,收集相关的关系和描述。

High-level 检索:用高层关键词去向量库里搜关系边。比如用「国际贸易」「经济影响」这些关键词,找到相关的关系边(可能是「贸易协定 → 影响 → 国家经济」这类关系)。然后从这些关系出发,聚合它们涉及的实体和更高层的语义。

​ 3.上下文组装(Context Building) ​ 把 Low-level 检索到的实体 + 邻居 + 相关文本块,和 High-level 检索到的关系 + 涉及实体 + 相关文本块拼在一起,组装成一段完整的上下文。

​ 这里有个细节:LightRAG 会控制上下文的总 token 数(比如默认 4000 token),优先保留相关性最高的内容,避免上下文超过 LLM 窗口。

​ 4.LLM生成答案

四种查询模式:灵活应对不同场景

除了上面描述的「双层检索」默认模式(也叫 Hybrid 模式),LightRAG 实际上提供了四种查询模式,满足不同场景需求:

模式用什么检索适用场景
Naive(朴素)纯向量检索文本块(就是传统 RAG)简单事实问答,不需要关系推理
Local(本地)只用 Low-level 检索(找具体实体)具体实体类问题,比如「这个 API 怎么用」
Global(全局)只用 High-level 检索(找关系主题)抽象概念、主题归纳类问题
Hybrid(混合)Low-level + High-level 同时用复杂综合问题,默认推荐

多数场景用 Hybrid 就够了,它是 LightRAG 推荐的默认模式。

增量更新

流程:

  1. 切块
  2. 抽取实体和关系(针对新文档
  3. 增量更新:已有实体节点->追加描述或合并 全新的实习:增加一个新的节点,再处理逻辑关系
  4. 将新的实习和关系描述做向量化

一个小细节:LightRAG的增量更新对语义冲突不敏感,对于冲突的关系会同时保留,需要自己在上层加逻辑处理(如果有需要)

总结 LightRAG 的完整工作原理

imgimg

索引阶段:

imgimg

查询阶段(Hybrid 模式):

imgimg

增量阶段:

img

这图做的真不错吧!!!!