1. graphrag vs rag
一个典型的rag有三个步骤:
- 🔍 检索:从论文库中找出 GNN 和推荐系统相关的片段
- 📄 增强:构造 prompt 输入
- ✍️ 生成:大模型总结出 3 个主要挑战,如冷启动问题、图结构稀疏性、计算效率瓶颈
微软的graphrag有什么不同呢,常用说法是它用图数据库存储了数据,能跨越多个节点回答问题。我认为这种说法不足以描述graphrag的本质,也经常将对graphrag的理解带入误区。相比于传统的rag,graphrag在使用方面和传统rag并无不同,但是在自身技术构造上,与传统的RAG系统有二个不同点:
- 数据存储使用图数据库,用节点和关系描述真实世界关系
- 构造图数据和检索数据均有LLM参与构造和增强
第一点让rag系统能反映真实世界的关系,第二点是graphrag与传统rag的本质不同,某种程度上,可以理解成这是一个rag智能体。
2. microsoft graphrag
2024年4月,微软发布了论文《From Local to Global: A GraphRAG Approach to
Query-Focused Summarization》,并在今年开源了graphrag。
2.1 graphrag建立索引
graphrag的部件图如下,有4个部件,其中我们最关注的是索引

索引的结构如下:

其中工作流如下:
| 步骤名称 | 目的 | 输出工件 |
|---|---|---|
| create_base_text_units | 将文档分块到文本单元中 | 基本文本单位 |
| create_final_documents | 完成文档元数据 | documents.parquet |
| extract_graph | 基于 LLM 的实体/关系提取 | 原始实体和关系 |
| finalize_graph | 清理和删除重复的图形数据 | entities.parquet, relationships.parquet |
| extract_covariates | 提取声明(可选) | covariates.parquet |
| create_communities | 使用 Leiden 进行社区检测 | communities.parquet |
| create_final_text_units | 使用图形数据增强文本单元 | text_units.parquet |
| create_community_reports | 生成社区摘要 | community_reports.parquet |
| generate_text_embeddings | 创建向量嵌入 | 嵌入 parquet 文件 |
从工作流我们可以看到,它将文档切成文本块,利用大模型抽取实体和关系,建立图,并对图使用算法分为社区,对社区用大模型生成摘要,并创建向量加速检索。
这里就是graphrag和传统rag不同的地方,传统rag就是存储成key和answer,使用向量检索,而graphrag将数据使用大模型构建为图,并分为社区生成摘要,回答复杂性问题。
2.2 graphrag检索
graphrag有四种检索,这里我们以local检索为例,其流程如下:

可以看到local检索就是先聚合查询上下文,再使用大模型结构化生成格式。
其中形成上下文的流程实际就是图检索过程,首先用向量匹配实体,在用图检索实体相关的关系实体聚合成上下文。上下文构造过程如下:

3. graphrag的使用
参考官网,非常简便:
- 建立工程:graphrag init --root /xxx/
- 建立索引:graphrag index --root /xxx/
-- 查询:graphrag query --method local --root /xxx/
几条命令就搞定了建立索引到查询。
另外它是高度可配置的,搞懂怎么配置大模型、输入配置、流程配置,参考graphrag setting.yaml配置官网说明
4. graphrag的问题
从上面整个graphrag的流程我们可以看到,它与传统的rag天然不同,图存储是修改了存储结构,更贴合世界本质,但是rag+AI才是是它与传统rag的本质不同。
rag+AI既是graphrag的优点也是致命缺点,当面对一个比较大的输入的时候,与大模型的交互是非常频繁的,等待时间非常长,使用的token是巨量的,如果使用付费大模型,是非常烧钱的。要将graphrag工程化要走到路还很长,这可能也是微软为何要把graphrag开源的原因。