高级 16 分钟RAG

本地 GraphRAG:基于知识图谱的 RAG(指南 高级)

经典向量 RAG 很擅长回答具体问题,但一旦需要关联多个文档来进行综合归纳,效果就会急剧下降。GraphRAG 通过从您的语料库中构建知识图谱——包含实体、关系和社区——来解决这一问题,然后查询该图谱,而不是仅查询向量数据库。本指南介绍如何使用 Ollama 搭建基于本地 LLM 的 GraphRAG,不调用任何远程 API,并重点说明这种方法究竟在什么情况下真正优于向量检索。

作者: Mohamed Meguedmi·更新于 2026-08-27·已在 Windows、macOS 和 Linux 上测试

#为何选择GraphRAG?

设想一家律师事务所的资料库:200 份合同、500 封邮件、80 份裁判文书。您提出问题:“过去三年,我们的客户合同中提到了哪些主要法律风险,又涉及哪些长期往来的客户?”传统的向量 RAG 会检索 5 个或 10 个“相关”文本块,将它们交给大语言模型,而模型会据此回答……但只能看到部分内容。它会遗漏贯穿不同文档的共同规律。

GraphRAG 不只是返回原始文本片段,而是基于结构进行推理:谁提到了什么、哪些实体反复出现,以及哪些关系将它们连接起来。对于这类针对整个语料库的综合性(“全局”)问题,图结构优于向量检索——这正是 Microsoft Research 在 2024 年的原始论文中展示的结果。

i
本指南面向谁
您已经有一个正常运行的本地向量 RAG(ChromaDB、LlamaIndex、AnythingLLM 等),但在需要综合归纳的问题上遇到了瓶颈。如果不是这种情况,请先从传统 RAG 入手,再尝试这里的方案。

#GraphRAG 与向量RAG:真正的区别

本地 RAG 工具包

你的文档,你的 AI:基于你的 PDF、笔记和邮件的可靠本地 RAG——无需向云端发送任何内容。

  • 在线空间,终身可用
  • PDF + 文件
  • 30 天内退款

这两种方法的目标相同:将外部上下文注入 LLM 的提示中,以减少幻觉现象。但它们获取的内容并不相同。

向量 RAG
将语料库分割为多个块,为每个块计算嵌入向量,并存储到向量数据库中(ChromaDB、Qdrant、FAISS)。在查询时,根据余弦相似度检索最接近的k个块。
GraphRAG
让 LLM 从每个文本块中提取实体和关系,构建图谱,将实体划分为社群,并为每个社群生成摘要。查询时,遍历图谱或汇总社群摘要。
向量检索的优势
建立索引速度快(10 MB 文本只需几分钟),成本低,非常适合有针对性的问题(“Acme 合同中的解约条款是什么?”)。
GraphRAG 的优势
非常适合回答全局性问题(“哪些主题反复出现?”、“哪些实体的连接最多?”),可通过图中的边进行精细追溯,并原生支持多跳查询。
向量检索的弱点
丢失文档间的关联。一个要求结合 3 个语义上相距较远的文档的问题,无法返回正确的文本块。
GraphRAG 的短板
索引构建开销大:每个文本块都需要经过 LLM 处理。对于10 MB的语料库,要预计耗时数小时并占用大量显存,而向量索引只需5分钟就能完成。
→
混合方案往往更有效
实际应用中,最佳的技术方案会结合两者:用图处理全局性问题和导航,用向量检索(或 BM25)处理针对性查询。另请参阅 BM25 + 向量混合检索,了解另一种组合方式。

#内部运行机制

一个完整的GraphRAG流程包含5个步骤,所有步骤均使用LLM(除聚类步骤外)。

  1. 01
    Chunking
    与传统 RAG 一样,语料库被切分为每段 500 至 1500 个 token 的文本片段。片段长度直接影响提取质量:过短,LLM 会漏掉关系;过长,它也会遗漏其中的一些关系。
  2. 02
    实体与关系抽取
    每个 chunk 都会传入 LLM,并配上结构化提示,例如:“提取所有实体(人物、组织、地点、概念)及它们之间的关系。使用 JSON 格式。”这是成本较高的环节——每个 chunk 都需要调用一次 LLM。
  3. 03
    构建图谱
    提取出的实体成为节点,关系成为边。多个 chunk 中出现的相同实体会被合并(实体解析,通常通过嵌入或规范化规则实现)。
  4. 04
    社区检测
    聚类算法(微软使用 Leiden,nano-graphrag 使用更简单的算法)会将连接紧密的节点归为社群。这些社群是“全局”推理的关键。
  5. 05
    社区摘要
    LLM 会基于社区中包含的实体和关系,生成每个社区的文本摘要。这些摘要成为回答全局问题时的检索单元。

查询时,GraphRAG 区分两种模式:局部模式(查找某个特定实体及其邻域)和全局模式(汇总社群摘要)。随后,LLM 将检索到的上下文与问题结合起来,生成最终回答。

#本地部署可用工具

Microsoft GraphRAG
参考实现(github.com/microsoft/graphrag)。功能完整、设计精良,但较为笨重:最初为 Azure OpenAI 设计,将其适配到 Ollama 需要耐心。索引过程消耗大量 token。
nano-graphrag
最小实现(约1000行)原生兼容 Ollama(github.com/gusye1234/nano-graphrag)。这里我们将使用它:代码量减少10倍,思路却相同。
LightRAG
较新的变体,针对查询延迟进行了优化。兼容 Ollama。比 Microsoft GraphRAG 更简单,比 nano-graphrag 更有条理。
LlamaIndex KnowledgeGraphIndex
如果您已经在使用 LlamaIndex,就能直接集成,但这种方法较为基础(没有图社区)。
i
便于学习的选择
本指南使用nano-graphrag,因为所有内容都包含在两个可读、可修改、可调试的Python文件中。一旦掌握概念,切换到生产环境中的Microsoft GraphRAG或LightRAG将变得简单。

#先决条件

Ollama已安装并正常运行
如果尚未安装 Ollama 或它尚不能正常运行,请先按照本站的 Ollama 安装指南操作。
具备扎实推理能力的大型语言模型(14-24B)
实体提取需要较多计算资源。gpt-oss 20B、Mistral Small 24B 或 Qwen 3.5 9B(最低档选择)都表现不错。低于 8B 的模型生成的 JSON 经常格式不正确。
本地嵌入模型
通过 Ollama 使用 nomic-embed-text,或通过 sentence-transformers 使用 bge-m3 / multilingual-e5-large。
至少 16 GB VRAM
12 GB 搭配 8–9B 的 Q4 模型(Qwen 3.5 9B)可以勉强应付,但索引构建会很慢。16 GB 可以容纳 gpt-oss 20B 或 Mistral Small 24B;24 GB(RTX 4090、M-Max)则较为宽裕。
Python 3.10+
nano-graphrag 以及大多数现代 RAG 框架要求 Python 3.10 或更高版本。

#1. 使用 nano-graphrag 索引语料库

首先在 Ollama 中准备好模型。本教程使用 gpt-oss 20B(默认采用 MXFP4 量化,约 14 GB),并使用 nomic-embed-text 作为嵌入模型。

终端
ollama pull gpt-oss:20b
ollama pull nomic-embed-text
ollama serve  # si pas déjà en service

随后在专用的虚拟环境中安装nano-graphrag。

终端
python -m venv .venv
source .venv/bin/activate  # Linux/macOS
pip install nano-graphrag

索引脚本只需二十行左右。通过端口 11434 上兼容 OpenAI 的端点,即可将其连接到 Ollama。

index.py
import asyncio
from nano_graphrag import GraphRAG, QueryParam
from nano_graphrag.llm import ollama_model_if_cache, ollama_embedding

WORKING_DIR = "./graphrag_cache"

async def main():
    rag = GraphRAG(
        working_dir=WORKING_DIR,
        best_model_func=ollama_model_if_cache,
        cheap_model_func=ollama_model_if_cache,
        embedding_func=ollama_embedding,
        best_model_kwargs={"model_name": "gpt-oss:20b"},
        cheap_model_kwargs={"model_name": "gpt-oss:20b"},
    )

    with open("corpus.txt", encoding="utf-8") as f:
        text = f.read()

    await rag.ainsert(text)

if __name__ == "__main__":
    asyncio.run(main())

启动索引过程。根据语料库大小和 GPU 性能,耗时从几分钟(1 MB 文本)到数小时(50 MB)不等。

终端
python index.py
!
请耐心等待:这一过程本来就慢
在 RTX 4090 上使用 gpt-oss 20B 处理 5 MB 的语料库,预计需要约 2 小时。nano-graphrag 默认逐个处理文本块。这是正常的——耗时的是使用 LLM 进行提取,而不是计算嵌入向量。

最终,graphrag_cache/ 目录中将包含序列化后的图结构、嵌入向量以及社区的摘要。

#2. 查询图谱

索引完成后,查询速度很快(每次查询几秒),因为 LLM 只读取图谱中检索到的上下文,而不再读取整个语料库。

query.py
import asyncio
from nano_graphrag import GraphRAG, QueryParam
from nano_graphrag.llm import ollama_model_if_cache, ollama_embedding

async def main():
    rag = GraphRAG(
        working_dir="./graphrag_cache",
        best_model_func=ollama_model_if_cache,
        cheap_model_func=ollama_model_if_cache,
        embedding_func=ollama_embedding,
        best_model_kwargs={"model_name": "gpt-oss:20b"},
        cheap_model_kwargs={"model_name": "gpt-oss:20b"},
    )

    # Mode global : synthèse à partir des résumés de communautés
    print(await rag.aquery(
        "Quels sont les thèmes principaux du corpus ?",
        param=QueryParam(mode="global")
    ))

    # Mode local : recherche centrée sur des entités
    print(await rag.aquery(
        "Quelle est la position de l'entreprise X sur le sujet Y ?",
        param=QueryParam(mode="local")
    ))

asyncio.run(main())
→
选择合适的模式
以“主要的……有哪些”“有哪些趋势……”“做一个总结……”开头的问题 → 全局模式。针对某个具体实体的问题 → 局部模式。如果不确定,就试试两种模式:回答往往截然不同。

#本地算力成本:需要有怎样的预期

这是大家第一次遇到时都会感到惊讶的部分。用 GraphRAG 为 5 MB 文本建立索引,所需计算量约为同一语料库上向量 RAG 的 50 至 200 倍。下面给出一些具体参考值,以数量级表示。

语料库1 MB(约300页)
gpt-oss 20B(MXFP4)在RTX 4090上索引约25分钟,在RTX 3060 12GB(部分卸载)上约3小时,在Mac M3 Max 64GB上约40分钟
语料库 5 MB(约1500页)
RTX 4090:约 2 小时。M4 Pro 48 GB:约 3 小时。超过这一数据量时,应做好让任务运行一整夜的准备。
显存峰值
gpt-oss 20B 模型(MXFP4)持续占用约 14 GB。nomic 嵌入模型还会额外占用约 1 GB。显存不足 16 GB 时,预计需要将部分模型卸载到系统内存,由 CPU 执行这部分计算。
每次请求的成本
局部模式需要几秒,全局模式(聚合多个社群的信息)需要5至30秒。与建立索引相比,这点开销很轻。
增量重索引
nano-graphrag 当前尚无法正确更新现有图谱。新增10%的新文档 = 需重新进行部分或完整索引。Microsoft GraphRAG 在此方面表现更佳。
!
LLM模型过小的陷阱
想用 Granite 4.2 3B 或 Qwen 3.5 2B 来提高速度?JSON 提取结果会前后不一致,实体命名会出错,图谱也会无法使用。这正是只求快速索引、却生成了无法利用的图谱这一错误。请至少选用 80 亿参数的模型,理想选择是 gpt-oss 20B 或 Mistral Small 24B。

#GraphRAG 在哪些情况下真正胜过向量检索

GraphRAG并不是向量RAG的通用替代方案。在某些用例中,它远胜于向量RAG;在另一些用例中,它则明显逊色。

基于语料库的摘要
“我们关于主题 X 的 200 封邮件中,讨论的 5 个主要主题是什么?”→ GraphRAG 明显胜出。向量检索只能返回 5–10 封邮件,而图检索会汇总图中的社群。
多跳问题
« 哪些供应商同时与Acme和Beta Corp合作?» → GraphRAG通过遍历边来解决。向量检索需找到正确的片段,并依赖LLM完成连接操作。
探索关系
“与 Atlas 项目相关的提及中,哪些人被提到的次数最多?”→ GraphRAG 原生适合处理这类查询(中心性、邻域)。向量检索没有关系这一概念。
定向事实问答
「Acme 的 2024 年 3 月 12 日合同中规定的提前通知期有多长?」→ 向量 RAG 更胜一筹:速度更快、准确性更高、索引成本更低。
变化频繁的语料库
如果每天不断添加文档,GraphRAG的重新索引成本将变得不可接受。建议继续使用向量检索或向量检索+BM25。
语料库 < 500 KB
无需使用图谱:如果您有 32k token 或更大的上下文容量,LLM 就可以在上下文中读取全部内容。只有当语料库大到无法放入上下文时,使用 GraphRAG 才有必要。
→
实际操作原则
如果您的用户主要提出“查找这条具体信息”之类的问题,请继续使用向量检索。如果价值主要在于对稳定语料库进行综合归纳、探索模式或跨文本分析,那么 GraphRAG 的索引成本就是值得的。

#深入了解

GraphRAG 是一个发展活跃的领域:各种实现和基准测试都在快速演进。以下是一些继续探索的方向。

本地 RAG:简介
如果您对基于向量的 RAG 的某些概念仍不清楚,入门指南能帮助您打好基础,再将 GraphRAG 投入生产环境。
分块策略
实体提取的质量直接取决于文本块的大小和内容连贯性。本指南深入探讨相关最佳实践。
BM25 + 向量混合搜索
要将 GraphRAG 与传统检索结合使用,可以先了解混合检索:两者都采用了融合多种信号的思路。
为本地 AI 选择 GPU
GraphRAG 的索引过程资源消耗较大。如果您当前使用 8-12 GB 显存的 GPU,升级到 16-24 GB 显存将显著改变运行速度。
这份指南对您有帮助吗?

有反馈、发现了错误,或想补充说明?请告诉我们,让这份指南对每个人都更有帮助。