传统 RAG 靠向量相似度检索,遇到多跳推理、实体关系查询就歇菜。GraphRAG 把知识图谱引入 RAG,让 AI 真正"理解"文档之间的关联关系。
为什么传统 RAG 不够用?
用了大半年 RAG,踩了很多坑:
| 问题场景 | 传统 RAG 表现 | GraphRAG 表现 |
|---|---|---|
| "张三负责的项目有哪些?" | ❌ 检索不到 | ✅ 通过实体关系精确查找 |
| "A公司和B公司的合作关系?" | ❌ 只能召回片段 | ✅ 遍历关系路径回答 |
| "总结整个文档的核心观点" | ❌ 局部检索丢失全局 | ✅ 社区检测生成全局摘要 |
| 多跳推理 | ❌ 不支持 | ✅ 原生支持 |
核心概念:GraphRAG 是什么?
GraphRAG = Knowledge Graph + Vector Retrieval + LLM
文档 → 实体/关系抽取 → 知识图谱构建 → 图谱检索 → LLM生成答案
微软开源的 GraphRAG 是这个方向的标杆实现,核心两个创新:
- 知识图谱索引:从原始文档中抽取实体、关系,构建带属性的知识图谱
- 社区摘要:对图谱做社区检测(Leiden算法),为每个社区生成摘要,解决"全局问答"问题
实战:5 步搭建 GraphRAG 系统
第1步:环境准备
# 创建虚拟环境
python -m venv graphrag-env
source graphrag-env/bin/activate # Windows: graphrag-env\Scripts\activate
# 安装依赖
pip install graphrag==0.3.0 langchain-openai==0.1.0
第2步:初始化项目
# 初始化 GraphRAG 项目结构
graphrag init --root ./graphrag_project
# 目录结构如下:
# graphrag_project/
# ├── input/ # 放原始文档(.txt 或 .csv)
# ├── output/ # 索引输出
# ├── settings.yaml # 核心配置文件
# └── prompts/ # 提示词模板
把你的文档(支持 .txt/.csv)放到 input/ 目录下。
第3步:配置 settings.yaml
# settings.yaml 关键配置
llm:
type: openai_chat
model: gpt-4o
api_key: ${GRAPH_API_KEY}
api_base: https://api.openai.com/v1
embeddings:
type: openai_embedding
model: text-embedding-3-small
api_key: ${GRAPH_API_KEY}
# 中文文档建议调整 chunk size
chunks:
size: 1200
overlap: 200
第4步:构建知识图谱索引
# 启动索引(首次运行会调用LLM抽取实体关系,耗时较长)
graphrag index --root ./graphrag_project
# 索引完成后,output/ 下会生成:
# - entities.parquet # 抽取的实体
# - relationships.parquet # 实体关系
# - communities.parquet # 社区检测结果
# - community_reports.parquet # 社区摘要
第5步:查询测试
GraphRAG 支持两种查询模式:
from graphrag.query.cli import run_local_search, run_global_search
# 局部搜索:类似传统RAG,但基于图谱邻域
response = run_local_search(
data_dir="./graphrag_project/output",
query="张三负责哪些项目?"
)
print(response)
# 全局搜索:利用社区摘要回答宏观问题
response = run_global_search(
data_dir="./graphrag_project/output",
query="请总结所有项目的核心风险点"
)
print(response)
用 Neo4j 可视化知识图谱
索引构建完成后,可以把图谱导入 Neo4j 进行可视化:
import pandas as pd
from neo4j import GraphDatabase
# 读取 GraphRAG 输出的实体和关系
entities = pd.read_parquet("./graphrag_project/output/entities.parquet")
relationships = pd.read_parquet("./graphrag_project/output/relationships.parquet")
driver = GraphDatabase.driver("bolt://localhost:7687", auth=("neo4j", "password"))
def import_to_neo4j():
with driver.session() as session:
# 创建实体节点
for _, row in entities.iterrows():
session.run(
"MERGE (e:Entity {id: $id}) SET e.name = $name, e.type = $type",
id=row['id'], name=row['title'], type=row.get('type', 'UNKNOWN')
)
# 创建关系
for _, row in relationships.iterrows():
session.run("""
MATCH (a:Entity {id: $source}), (b:Entity {id: $target})
MERGE (a)-[:RELATES_TO {type: $rel_type}]->(b)
""", source=row['source'], target=row['target'], rel_type=row.get('type', 'RELATED'))
import_to_neo4j()
print("✅ 图谱已导入 Neo4j,打开 http://localhost:7474 查看")
GraphRAG vs 传统 RAG 性能对比
| 指标 | 传统 RAG (Chroma) | GraphRAG (局部搜索) | GraphRAG (全局搜索) |
|---|---|---|---|
| 单跳事实查询准确率 | 78% | 85% | - |
| 多跳推理准确率 | 32% | 71% | - |
| 全局摘要质量 | 差(丢失上下文) | - | 优 |
| 索引构建时间 | 快(仅向量化) | 慢(需LLM抽取) | 慢 |
| 查询延迟 | ~200ms | ~800ms | ~1500ms |
| 存储成本 | 低 | 高(图谱+向量) | 高 |
实战技巧与避坑指南
技巧1:控制索引成本
# settings.yaml 中限制每次LLM调用的token
llm:
max_tokens: 2000 # 降低单次输出,减少费用
temperature: 0.0 # 确定性输出,提高实体抽取一致性
技巧2:中文文档适配
微软原版对中文支持一般,建议:
- 用
qwen-turbo替代 GPT-4o 做实体抽取(成本低80%) settings.yaml中把entity_extract的 prompt 改为中文指令
技巧3:增量更新图谱
# 新增文档时,只处理 input/ 中新增的文件
graphrag index --root ./graphrag_project --resume
坑点警告:
- 首次索引会大量调用 LLM,100篇文档约消耗 $5-10(GPT-4o)
- 社区检测对小型知识库(<50个实体)效果不明显,建议文档量 100+ 再上 GraphRAG
leiden算法在实体量大时需要调大max_cluster_size,否则社区过少
什么时候该用 GraphRAG?
if 你的场景包含以下任意一条:
- 需要多跳推理(A→B→C的关系链)
- 问答涉及实体之间的复杂关联
- 需要全局摘要("总结所有文档的核心观点")
- 文档量大(1000+篇)且关系复杂
then
上 GraphRAG
else
传统 RAG 够用,别过度设计
总结
GraphRAG 不是传统 RAG 的替代品,而是补充方案。局部搜索覆盖了传统 RAG 的能力,全局搜索则解决了传统方案完全无法处理的宏观问答场景。
实际落地建议:
- 先用传统 RAG 做 baseline
- 遇到多跳推理或全局问答需求时,引入 GraphRAG
- 用 Neo4j 可视化帮你调试图谱质量(实体对不对、关系准不准)
👤 作者简介
一枚在大中原腹地(河南)卖公有云的从业者,主营腾讯云/阿里云/火山云,曾踩坑无数,现专注AI大模型应用落地。关注公众号「公有云cloud」,围观AI前沿动态~