微软GraphRAG框架源码深度解读
微软开源的GraphRAG是基于知识图谱的检索增强生成系统,通过社区检测将知识图谱分解为模块化社区,利用大模型自下而上生成摘要,再以map-reduce方式汇总为全局答案。索引阶段借助LLM提取实体关系构建图谱,查询阶段支持全局与局部搜索,有效解决传统RAG难以回答高层次概括性问题。
近段时间,微软正式开源了GraphRAG——一个基于知识图谱构建的检索增强生成系统,迅速在技术社区引发了广泛关注。坦白说,我对这个框架关注已久,趁着热度深入研读了源码。本文权当一份学习笔记,记录下对GraphRAG系统架构、核心概念以及主要工作流的理解与总结。
(本次分析的代码对应 commit id 为 a22003c302bf4ffeefec76a09533acaf114ae7bb,更新于2024年7月5日。)
框架概述
在深入代码之前,有必要先厘清GraphRAG试图解决的核心问题。论文一针见血地指出了传统RAG的致命短板:
“然而,RAG在面对针对整个文本语料库的全局性问题时,比如‘这个数据集的核心主题是什么?’,就显得力不从心了。因为这本质上是一个聚焦于查询的总结性任务,而非一个明确的检索任务。”
简单来说,传统RAG难以胜任这种高层次的归纳性问题。GraphRAG给出了明确解法:采用社区检测算法,将整个知识图谱分解为多个模块化的社区,然后让大模型自下而上地为每个社区生成摘要。最后,通过一种“map-reduce”机制,让各社区并行回答查询,最终汇总成一个全局性的答案。
实现方式是什么?

与大多数RAG系统类似,GraphRAG的整个流水线也划分为索引和查询两个阶段。在索引阶段,利用LLM抽取实体、关系和协变量等结构化信息,构建知识图谱;接着运用社区检测技术进行切分,再由LLM生成摘要。到了查询阶段,则针对具体问题,将相关社区的摘要汇总起来,形成全局性的答案。
源码解析
官方文档虽已说明清晰,但要理解实现细节仍需深入源码。项目的整体结构如下:
. ├── cache ├── config ├── emit ├── graph │ ├── embedding │ ├── extractors │ │ ├── claims │ │ ├── community_reports │ │ ├── graph │ │ └── summarize │ ├── utils │ └── visualization ├── input ├── llm ├── progress ├── reporting ├── storage ├── text_splitting ├── utils ├── verbs │ ├── covariates │ │ └── extract_covariates │ │ └── strategies │ │ └── graph_intelligence │ ├── entities │ │ ├── extraction │ │ │ └── strategies │ │ │ └── graph_intelligence │ │ └── summarize │ │ └── strategies │ │ └── graph_intelligence │ ├── graph │ │ ├── clustering │ │ │ └── strategies │ │ ├── embed │ │ │ └── strategies │ │ ├── layout │ │ │ └── methods │ │ ├── merge │ │ └── report │ │ └── strategies │ │ └── graph_intelligence │ ├── overrides │ └── text │ ├── chunk │ │ └── strategies │ ├── embed │ │ └── strategies │ ├── replace │ └── translate │ └── strategies └── workflows └── v1
这里面隐藏了大量值得深挖的细节,接下来将结合具体代码逐步展开。
Workflows
程序运行时,控制台会打印出完整的 workflow 列表,这是理解整个索引流水线的关键入口:
⠹ GraphRAG Indexer ├── Loading Input (InputFileType.text) - 1 files loaded (0 filtered) ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 100% 0:00:00 0:00:00 ├── create_base_text_units ├── create_base_extracted_entities ├── create_summarized_entities ├── create_base_entity_graph ├── create_final_entities ├── create_final_nodes ├── create_final_communities ├── join_text_units_to_entity_ids ├── create_final_relationships ├── join_text_units_to_relationship_ids ├── create_final_community_reports ├── create_final_text_units ├── create_base_documents └── create_final_documents All workflows completed successfully.
Index
索引阶段是整个项目的核心,流程也最为复杂。启动索引的命令十分简洁:
python -m graphrag.index --init --root ./ragtest python -m graphrag.index --root ./ragtest

实际调用的是 `graphrag/index/__main__.py` 的主函数,通过 argparse 解析参数后,会转调 `graphrag/index/cli.py` 里的 `index_cli` 函数。
简单梳理一下调用链路(上图中灰色标记的为核心函数):
cli.py::index_cli()函数首先处理用户输入,比如检查是否需要初始化目录(`--init`),这一逻辑由 `cli.py::index_cli()` 执行,主要看配置文件、prompt 模板、`.env` 文件等是否存在,若不存在则创建。- 真正执行索引的是内部函数 `cli.py::index_cli()._run_workflow_async()`,其中又涉及两个关键函数:`cli.py::_create_default_config()` 和 `run.py::run_pipeline_with_config()`。
限于篇幅,这里只讨论默认配置的运行流程。理解逻辑后,你可自行修改配置。
- 默认配置生成逻辑:`cli.py::_create_default_config()` 先检查根目录及 `settings.yaml`,然后调用 `cli.py::_read_config_parameters()` 读取系统配置,例如 LLM、数据分块、缓存、存储等。接下来的操作十分关键:根据当前参数创建一个 pipeline 配置,具体代码在 `create_pipeline_config.py::create_pipeline_config()`,这是整个项目中逻辑最复杂的模块之一。
- 深入 `create_pipeline_config.py::create_pipeline_config()` 的代码,会发现其核心逻辑如下:
result = PipelineConfig( root_dir=settings.root_dir, input=_get_pipeline_input_config(settings), reporting=_get_reporting_config(settings), storage=_get_storage_config(settings), cache=_get_cache_config(settings), workflows=[ *_document_workflows(settings, embedded_fields), *_text_unit_workflows(settings, covariates_enabled, embedded_fields), *_graph_workflows(settings, embedded_fields), *_community_workflows(settings, covariates_enabled, embedded_fields), *(_covariate_workflows(settings) if covariates_enabled else []), ], )
这段代码的意图十分清晰:根据不同的功能模块生成完整的 workflow 序列。需要注意的是,这里并不考虑 workflow 之间的依赖关系,只是单纯地根据 `workflows/v1` 目录下的模板生成一系列 workflow。
- Pipeline 执行逻辑:`run.py::run_pipeline_with_config()` 先通过 `load_pipeline_config.py::load_pipeline_config()` 加载上一步生成的 pipeline 配置,接着创建目录(如 cache、storage、input、output 等),最后利用 `run.py::run_pipeline()` 依次执行每个 workflow,并返回结果。
`run.py::run_pipeline()` 才是真正的执行者,其核心逻辑包含两部分:
- 加载 workflows:`workflows/load.py::load_workflows()`,除了常规创建工作流外,还会进行拓扑排序。
workflows/load.py::create_workflow():利用现有模板创建不同的工作流。graphlib::topological_sort():根据 workflow 间的依赖关系,计算 DAG 的拓扑排序。- 执行过程中,还会调用 `inject_workflow_data_dependencies()` 进行依赖注入,`write_workflow_stats()` 写入统计信息,`emit_workflow_output` 保存输出。真正的 `workflow.run` 操作会在 `write_workflow_stats()` 之前执行。
Workflow
到目前为止,我们实际上还未触及索引阶段的业务逻辑,只是理清了 GraphRAG 内置的这套 pipeline 编排系统。现在以一个具体的 workflow——index/workflows/v1/create_final_entities.py——为例,看看它究竟是怎样运作的。
- DataShaper:在深入 workflow 之前,有必要先了解 `datashaper`,这是微软开源的一个工作流处理库,内置了许多组件(官方称为 `Verb`)。通俗地讲,datashaper 就像一条流水线,每一步都对输入数据执行一种特定操作,例如裁剪、旋转、缩放。如果还不熟悉,建议先跑一下官方文档里的 demo 程序
examples/single_verb,应该就能明白。从功能上看,它有点像 Prefect。 - 知识图谱构建:对应的 workflow 是
create_final_entities.py。查看源码可以发现,它依赖于workflow:create_base_extracted_entities,并定义了cluster_graph、embed_graph等操作。其中cluster_graph采用了leiden策略,具体代码在index/verbs/graph/clustering/cluster_graph.py中:
from datashaper import TableContainer, VerbCallbacks, VerbInput, progress_iterable, verb @verb(name="cluster_graph") def cluster_graph( input: VerbInput, callbacks: VerbCallbacks, strategy: dict[str, Any], column: str, to: str, level_to: str | None = None, **_kwargs, ) -> TableContainer:
可以看到,这里的 `leiden` 算法实际上来自另一个图算法库 `graspologic`。
- Pipeline:厘清 workflow 的执行逻辑后,再结合上节提到的编排日志或
artifacts/stats.json文件,就能整理出完整的索引流水线。官方文档也给出了非常详细的说明,不过根据源码提取出来的 pipeline 似乎仍存在一些差异,有兴趣的朋友欢迎留言探讨。
Query
查询阶段的 pipeline 相对简单。执行查询的命令如下:
# Global search python -m graphrag.query --root ./ragtest --method global "What are the top themes in this story?" # Local search python -m graphrag.query --root ./ragtest --method local "Who is Scrooge, and what are his main relationships?"
这里有 Global/Local 两种搜索模式。生成函数调用关系图后,整体结构会更加清晰。

graphrag/query/__main__.py 中的主函数会根据参数不同,分别路由至 cli::run_local_search() 或 cli::run_global_search()。
Global Search
cli::run_global_search() 主要调用 factories.py::get_global_search_engine(),返回一个 GlobalSearch 类的实例。该类和 LocalSearch 类似,均基于工厂模式创建。其核心方法是 structured_search/global_search/search.py::GlobalSearch.asearch(),采用了 map-reduce 策略:先让大模型为每个社区的摘要并行生成答案,然后将所有答案汇总,形成最终结果。作者在相关的 prompts 中给出了非常详细的说明。
正因为这种 map-reduce 机制,Global Search 对 token 的消耗量相当大。
Local Search
与全局搜索类似,cli::run_local_search() 主要调用 factories.py::get_local_search_engine(),返回一个 LocalSearch 类的实例。这里的 asearch() 方法相对简洁,直接根据上下文给出回复。这种模式更接近常规的 RAG 语义检索策略,token 消耗也更少。
与 Global Search 不同,Local 模式综合了 nodes、community_reports、text_units、relationships、entities、covariates 等多种源数据。官方文档对此有详细说明,这里就不再赘述。
一些思考
- GraphRAG 最核心的价值,在于它一定程度上解决了聚焦于查询的总结性(QFS)任务。以目前了解的情况来看,这应该是首创。此前思路最接近的项目是 RAPTOR,但后者并非基于知识图谱。QFS 与多跳问答是现阶段 RAG 系统难以解决的痛点,然而在数据分析等领域却有广泛应用。尽管当下 GraphRAG 的使用成本仍然较高,但它至少提供了一种可行的解决路径。
- 相较于一般的知识图谱 RAG 项目,GraphRAG 更令人印象深刻的是它内置的那套完整的工作流编排系统。这在其他 RAG 框架中并不多见,也是值得深挖的方向。基于模板定义好大部分工作流,只提供少部分的配置灵活性,使每一个环节都可控、可追溯,而不是把一切都交给大模型。相比之下,常规的 RAG 部分(如 embedding、retrieval)反而没有太多需要特别讨论的地方,尽管加入了社区检测算法。
- 在知识图谱的处理颗粒度上,GraphRAG 也做得相当细致,例如社区检测的 Leiden 算法、综合多源数据的 Local Search 等。一个有趣的细节是:项目中的实体抽取完全采用大模型实现,并且对三元组的 schema 没有设置任何约束。作者的逻辑是,反正后续要做相似性聚类,每次抽取的差异对最终结果影响不大。这一点在鲁棒性上确实是很大的提升。
- 当然,目前的 GraphRAG 也有不少值得改进之处。例如,它创造了一些让人费解的术语(如 Emit、Claim、Verbs、Reporting),同时还“夹带私货”,用了一些微软自家相对小众的库,增加了理解门槛。此外,模块化方面也有待加强,特别是与 OpenAI 相关的部分,耦合度较高。
综合来看,微软这次推出的 GraphRAG 框架确实干货满满,值得花些时间去仔细研读和思考。
Reference
- Welcome to GraphRAG (microsoft.github.io)
- GraphRAG: LLM-Derived Knowledge Graphs for RAG (youtube.com)
- GraphRAG is now on GitHub | Hacker News (ycombinator.com)
- GraphRAG & Ollama - intelligent Search of local data : r/LocalLLaMA (reddit.com)
- GraphRAG on narrative private data : r/LocalLLaMA (reddit.com)
你是一名 AI 行业编辑,请围绕下面这条热点输出一份资讯解读:
热点:微软GraphRAG框架源码深度解读要求:
1. 先用一句话解释这条热点在讲什么
2. 再总结它为什么重要
3. 说明会影响哪些 AI 产品或内容方向
4. 最后给出 3 个适合资讯站使用的标题
游乐网为非赢利性网站,所展示的游戏/软件/文章内容均来自于互联网或第三方用户上传分享,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系youleyoucom@outlook.com。
相关热点客服需用标准化话术应对投诉,先归类前5类高频问题,再按情绪安抚、事实澄清(按需)、解决方案三层结构设计模板,并在阶跃AI后台配置变量话术且通过模拟测试后启用。客户投诉时情绪往往激烈,客服若临时组织语言容易词不达意、激化矛盾,需要一套能快速调用、语气得体、覆盖高频场景的标准化话术模板。 梳理投诉类型
通义千问系列模型升级至Qwen2,涵盖0 5B至72B共五个尺寸,全部标配分组查询注意力机制,上下文长度最高支持128Ktokens。新增27种语言训练数据,在代码、数学等能力上显著提升,Qwen2-72B超越Llama-3-70B等顶尖开源模型。
腾讯发布混元文生图大模型加速库,生图时间缩短75%,支持ComfyUI界面与HuggingFace三行调用。作为业内首个中文原生DiT架构开源模型,支持中英双语输入,最低11GB显存。
StabilityAI推出StableAudioOpen1 0,专门用于生成鼓点、乐器乐段及环境音效等短音频片段,时长最长47秒。该模型遵循非商业研究社区协议开源,允许用户进行微调,训练数据源自FreeSound及免费音乐档案,确保不含版权材料,可用于研究和创作。
- 日榜
- 周榜
- 月榜
热点快看
