一句话理解:GraphRAG 把文档里的"实体"和"关系"整理成知识图谱;提问时,系统沿着关系链做多跳推理,再结合原始文本证据生成答案。
一、GraphRAG 要解决什么问题?
普通 RAG 的流程:
text
用户问题 → 向量检索若干文本块 → LLM 生成答案
它擅长找到语义相近的文本,但遇到需要跨越多段事实的"关系问题"时,可能找不全推理链。
例如文档中有:
text
John Smith 是 TechCorp 的 CEO。
Sarah Johnson 是 John Smith 的行政助理。
Sarah Johnson 在 Executive Department 工作。
Mike Brown 和 Lisa Chen 也在 Executive Department 工作。
用户提问:
text
谁和 CEO 的助理在同一个部门?
要得到答案,系统必须连续完成:
text
CEO
↓
John Smith
↓
Sarah Johnson(CEO 的助理)
↓
Executive Department(Sarah 所在部门)
↓
Mike Brown、Lisa Chen(同部门其他成员)
这就是多跳推理。普通 RAG 若只召回了"谁在 Executive Department 工作"的文本,可能无法将它和"CEO 的助理"连接起来。
GraphRAG 将关系保存为可遍历的图,使系统可以明确地沿路径查找。
二、三个基本概念
1. 实体:节点
实体是图中的节点,通常是人、公司、部门、产品、项目、地点、技术或概念。
text
John Smith → Person
Sarah Johnson → Person
TechCorp → Organization
Executive Department → Department
2. 关系:边
关系是节点之间带类型、可带方向的连线。
text
Sarah Johnson ── ASSISTANT_TO ──→ John Smith
Sarah Johnson ── WORKS_IN ──────→ Executive Department
John Smith ────── CEO_OF ───────→ TechCorp
关系也可以保存属性,例如关系开始时间、可信度、信息来源和原始文档位置。
3. 路径:多跳推理链
多个节点和关系组成一条路径:
text
John Smith
← ASSISTANT_TO ─ Sarah Johnson
─ WORKS_IN → Executive Department
← WORKS_IN ─ Mike Brown
GraphRAG 不只是寻找相似文本,也能按节点、关系类型和方向沿路径查找答案。
三、GraphRAG 的四步流程
第 1 步:从文档抽取实体和关系
原始文本:
text
张三在星云科技工作,星云科技开发了智能助手。
抽取结果:
text
实体:
张三:Person
星云科技:Organization
智能助手:Product
关系:
张三 ── WORKS_FOR ──→ 星云科技
星云科技 ── DEVELOPS ──→ 智能助手
生产中通常让 LLM 或信息抽取模型完成这一步。同时需要处理实体消歧和去重,例如"苹果"是水果还是 Apple 公司。
第 2 步:构建知识图谱
将实体写成节点,关系写成边:
text
Person ── works_at ──→ Company ── makes ──→ Product
每条关系最好都绑定来源信息,例如原始文件、Chunk、页码、抽取时间和置信度。这样最终回答才能回到原文核验。
第 3 步:图遍历
收到问题后,系统识别问题中的实体和关系意图,再沿图中的边查找。
text
问题:谁与 John 顾问的公司竞争?
John ── ADVISES ──→ TechCorp
TechCorp ── COMPETES_WITH ──→ DataInc
答案:DataInc
这里的两跳路径是:
text
John → TechCorp → DataInc
第 4 步:混合检索并生成答案
GraphRAG 不应只使用图,也不应丢掉原文。实用流程是:
text
用户问题
↓
图检索:找到实体、关系路径和相连节点
+
文本检索:向量检索 / BM25 找原文、数字、时间和限定条件
↓
合并关系链与原文证据
↓
LLM 生成最终答案并说明来源
| 能力 | 图检索 | 文本检索 |
|---|---|---|
| 查谁和谁有关 | 强 | 一般 |
| 多跳关系推理 | 强 | 不稳定 |
| 找原始段落、数字、时间和例外 | 较弱 | 强 |
| 提供可引用的文本证据 | 需关联来源 | 强 |
四、关键代码:用 NetworkX 手工构建一个小图
NetworkX 是 Python 的内存图计算库,适合学习、算法验证和小规模原型。
python
import networkx as nx
# 创建有向图:箭头表示关系方向。
G = nx.DiGraph()
# 添加实体节点及其属性。
G.add_node("John Smith", type="Person", role="CEO")
G.add_node("Sarah Johnson", type="Person", role="Executive Assistant")
G.add_node("Mike Brown", type="Person", role="CFO")
G.add_node("Executive Department", type="Department", floor="5th")
G.add_node("TechCorp", type="Organization")
# 添加实体之间的关系边。
G.add_edge("John Smith", "TechCorp", relation="CEO_OF")
G.add_edge("Sarah Johnson", "John Smith", relation="ASSISTANT_TO")
G.add_edge("Sarah Johnson", "Executive Department", relation="WORKS_IN")
G.add_edge("Mike Brown", "Executive Department", relation="WORKS_IN")
G.add_edge("John Smith", "Executive Department", relation="WORKS_IN")
这段代码将事实变成可遍历的结构:
text
Sarah Johnson ── ASSISTANT_TO ──→ John Smith
Sarah Johnson ── WORKS_IN ──────→ Executive Department
Mike Brown ────── WORKS_IN ──────→ Executive Department
五、关键代码:手动执行多跳遍历
以下逻辑回答"找 CEO 助理的同部门同事":
python
# 第 1 跳:找到职位为 CEO 的节点。
ceo = next(
node
for node, attrs in G.nodes(data=True)
if attrs.get("role") == "CEO"
)
# 第 2 跳:找到指向 CEO 的 ASSISTANT_TO 边,其起点就是助理。
assistant = next(
source
for source, target, attrs in G.edges(data=True)
if target == ceo and attrs["relation"] == "ASSISTANT_TO"
)
# 第 3 跳:找到助理所在部门。
department = next(
target
for source, target, attrs in G.edges(data=True)
if source == assistant and attrs["relation"] == "WORKS_IN"
)
# 第 4 跳:找也在该部门、但不是助理本人的其他人。
coworkers = [
source
for source, target, attrs in G.edges(data=True)
if target == department
and attrs["relation"] == "WORKS_IN"
and source != assistant
]
print(coworkers)
这个例子的本质是:依据节点属性、关系类型和关系方向,一跳一跳地缩小答案范围。
六、关键代码:用 LLM 抽取实体和关系
真实项目不会手工为每篇文档写节点和边。可以先让 LLM 按固定格式抽取:
python
from langchain_openai import ChatOpenAI
from langchain_core.prompts import ChatPromptTemplate
llm = ChatOpenAI(model="gpt-4o-mini", temperature=0)
prompt = ChatPromptTemplate.from_messages(
[
(
"system",
"""从文本中抽取知识图谱元素。
请输出:
1. 实体:人物、组织、地点、产品、概念等。
2. 关系:实体之间明确存在的关系。
格式:
ENTITIES:
- [类型] 名称: 描述
RELATIONSHIPS:
- 起点 --[关系类型]--> 终点
不要编造文本中没有出现的关系。""",
),
("human", "待处理文本:\n{text}"),
]
)
chain = prompt | llm
result = chain.invoke(
{"text": "张三在星云科技工作,星云科技开发了智能助手。"}
)
print(result.content)
生产中更推荐让模型输出结构化 JSON,并在写图前完成:
- 实体规范化:统一"张三""张先生"等不同写法;
- 实体消歧:区分同名的人、公司或产品;
- 关系去重:防止反复抽到相同关系;
- 质量控制:记录置信度,并抽样人工核验;
- 来源追溯:每个节点和关系都关联回原文 Chunk。
七、NetworkX 与 Neo4j
| 工具 | 适合做什么 | 数据保存位置 |
|---|---|---|
| NetworkX | 学习、图算法验证、小规模原型 | Python 内存;程序停止后消失。 |
| Neo4j | 生产级图存储、多跳查询、并发访问 | 持久化图数据库。 |
Neo4j 使用 Cypher 查询语言。查询"与 Sarah 同部门的其他人"可以写成:
cypher
MATCH (sarah:Person {name: "Sarah Johnson"})
-[:WORKS_IN]->(dept:Department)
<-[:WORKS_IN]-(coworker:Person)
WHERE coworker <> sarah
RETURN coworker.name, dept.name
阅读方式:
text
找到 Sarah
→ 找到她所在部门
→ 找到也属于这个部门的其他人
→ 返回同事和部门名称
八、两种典型查询方式
Local Search:回答具体实体关系问题
适合:
text
某项目由谁负责?
谁和 CEO 的助理同部门?
某技术被哪些产品使用?
流程:
text
识别问题实体
↓
找到对应图节点及邻居
↓
按关系类型与方向遍历
↓
关联原始文本块
↓
生成答案
Global Search:理解整个语料库
适合:
text
这些报告反复出现的主要风险是什么?
整个知识库有哪些共性趋势?
所有项目最重要的技术主题有哪些?
它通常先将关系密集的实体聚成社区,为每个社区生成摘要,再聚合摘要得到全局答案。
Microsoft GraphRAG 的 Local Search 会组合知识图谱信息和原始文本块;Global Search 会聚合社区摘要,适合全局性问题。 Microsoft GraphRAG 查询概览
九、四种常见实现路线
| 路线 | 核心特点 | 适合场景 |
|---|---|---|
| Microsoft GraphRAG | 图抽取、社区发现、全局与局部查询能力较完整 | 大规模文档、全局主题总结、多跳问题。 |
| LangGraph + Neo4j | 自定义 Agent 流程与图数据库查询 | 已有 Neo4j、业务关系复杂、需强定制。 |
| LlamaIndex Knowledge Graph Index | 框架封装多,上手快 | 学习、原型、已使用 LlamaIndex 的项目。 |
| Vector + Graph 混合架构 | 语义文本检索与图遍历结合 | 大多数既查关系又查细节的业务问答。 |
Neo4j 官方提供 GraphRAG Python 工具包,可用于知识图谱构建、向量检索和图检索。 Neo4j GraphRAG for Python
十、什么时候该用 GraphRAG?
适合:
- 文档中存在大量明确关系:组织架构、供应链、论文引用、项目依赖;
- 用户经常问"谁和谁有关""通过几层关系能找到什么";
- 问题需要多跳推理;
- 需要从大规模文档中提炼全局主题、风险或趋势。
不太适合:
- 只查一个简单事实;
- 文档很少、关系简单,普通向量 RAG 已能准确回答;
- 文档需要实时入库并立即可问;
- 无法承担 LLM 抽取、索引和维护图谱的成本。
"文档少于 100 篇就不适合"不是硬规则。真正要判断的是:问题是否依赖关系链,以及普通 RAG 是否已经足够准确。
十一、落地时容易忽略的事情
- 关系质量决定上限:实体或关系抽错,图遍历再准确也会得到错误结果。
- 每条关系要可追溯:保留原始文件、Chunk、页码、抽取时间和置信度。
- 图不能替代原文:图负责关系,原文负责数字、条件、时间和引用。
- 限制图遍历范围:跳数和邻居太多会带来噪声、延迟和成本。
- 约束 LLM 生成的 Cypher:仅允许访问规定的标签、关系和只读查询,避免无效或危险语句。
- 做端到端评估:同时评估关系抽取正确率、图查询正确率、答案正确率、引用正确率、延迟和成本。
十二、最后总结
GraphRAG 的核心价值,是把散落在不同文本块中的关系变成可遍历、可解释的路径:图负责找关系和多跳推理,文本检索负责补充事实细节,LLM 负责整合证据并生成答案。
最实用的架构通常不是用 GraphRAG 替代普通 RAG,而是:
text
向量 / BM25 找文本证据
+
知识图谱找实体关系与多跳路径
↓
合并后交给 LLM 生成答案