GraphRAG 完全指南
微信 ezpoda免费咨询:AI编程 | AI模型微调| AI私有化部署
AI工具导航 | Tripo 3D | Meshy AI | ElevenLabs | KlingAI | ArtSpace | Phot.AI | InVideo
传统RAG改变了我们构建AI应用的方式。通过在生成答案前检索相关文档,它让LLM能够访问私有的、最新的知识。但存在一个根本性问题: vanilla RAG将数据视为孤立的文本块。它能找到语义上相似的内容,但会忽略关联的内容。
进入GraphRAG — 一种将知识图谱融入检索流程的范式,使LLM能够跨关系进行推理、遍历多跳连接,并在结构化、可解释的上下文中产生答案。
在本文中,我将带你了解什么是GraphRAG、为什么它重要、如何运作,以及如何构建一个完整的系统。我们将涵盖架构、代码、基础设施,以及投入生产前需要了解的权衡取舍。
1、什么是GraphRAG?
GraphRAG(图检索增强生成)将知识图谱与大语言模型结合,创建了一个不仅理解数据内容,而且理解信息之间关系的检索系统。
在标准RAG流程中,你将文档分块、将它们嵌入为向量,并根据余弦相似度检索最相似的top-k块。这对于直接的事实查询效果很好——"我们的退款政策是什么?"但当答案需要综合多个文档的信息或推理实体间的关系时,它就失效了。
考虑这样一个问题:"哪些参与了Project Alpha的团队成员也贡献了任何Q3计划?" 向量搜索可能会分别检索到提及Project Alpha的块和提及Q3的块,但它无法将人、项目和时间线联系起来。GraphRAG通过将实体(人、项目、日期)和它们的关系(worked_on、contributed_to、reported_to)编码在图结构中来解决这个问题,该图结构可以在查询时被遍历。
2、GraphRAG如何运作:两阶段管道
GraphRAG在两个基本阶段运行:索引(构建图)和查询(从中检索)。
阶段1:索引
索引阶段将原始的非结构化文本转换为结构化的知识图谱。以下是逐步发生的过程:
文本分块。 文档被分割成可管理的文本单元——段落、句子或固定大小的窗口。这些块成为提取实体和关系的原子单位。
实体和关系提取。 LLM读取每个块并识别其中的实体(人、组织、地点、概念)以及它们之间的关系。例如,从句子*"Dr. Smith leads the oncology department at Boston General"*中,系统提取实体(Dr. Smith、oncology department、Boston General)和关系(leads、part_of)。
知识图谱构建。 提取的实体成为图数据库中的节点,关系成为边。重复实体被解析(图谱解析),并为图谱添加属性,如描述、来源引用和嵌入向量。
社区检测和总结。 Microsoft的GraphRAG实现更进一步,使用层次聚类(Leiden算法)来检测紧密相关的实体社区。每个社区都有一个LLM生成的总结,使系统能够回答跨越整个语料库的广泛、主题性问题。
向量索引。 实体描述、关系描述和社区总结被嵌入为向量,创建了一个支持图遍历和语义搜索的混合检索层。
阶段2:查询
在查询时,GraphRAG提供两种检索策略:
本地搜索最适合具体的、以实体为中心的问题。系统在查询中识别相关实体,扩展到它们的图邻域(k跳内的连接节点),检索相关的文本块,并为LLM组装一个丰富的上下文窗口。
全局搜索处理需要跨整个数据集进行推理的广泛、主题性问题。它利用社区总结——索引期间生成的层次聚类——来提供高层答案,而无需遍历整个图。
在实践中,许多生产系统使用混合方法:快速向量搜索缩小候选文档范围,图遍历用结构关系丰富上下文,LLM从这种组合上下文中生成最终答案。
3、GraphRAG vs. 传统RAG:图何时胜出?
并非每个用例都需要GraphRAG。以下是一个实用的决策框架:
在以下情况使用传统RAG: 你的查询是直接的事实查找("退货政策是什么?"),你的数据没有丰富的实体间关系,或者延迟和成本约束紧张。
在以下情况使用GraphRAG: 查询需要多跳推理("我们网络中的哪些供应商也为我们的竞争对手服务?"),你需要可解释的检索路径(合规、法律、医疗),你的数据本质上是关系型的(组织结构、科学文献、金融网络),或者你需要跨大型语料库回答主题性问题("今年客户反馈的主要主题是什么?")。
来自GraphRAG-Bench项目(2025年)的研究证实,GraphRAG在复杂推理和上下文总结任务上始终优于vanilla RAG,而对于简单的事实检索,性能差距会缩小,因为单独的向量搜索已经足够。
4、实现:构建GraphRAG系统
让我们使用Python、Neo4j和LangChain从头构建一个GraphRAG管道。我将展示每个组件的可用代码。
4.1 前提条件和基础设施
你需要以下基础设施:
图数据库 — Neo4j。 GraphRAG最广泛采用的图数据库。它同时支持属性图查询(Cypher)和原生向量索引,非常适合混合检索。
# Run Neo4j via Docker
docker run \
--name neo4j-graphrag \
-p 7474:7474 -p 7687:7687 \
-d \
-v $PWD/neo4j/data:/data \
-v $PWD/neo4j/plugins:/plugins \
--env NEO4J_AUTH=neo4j/your-password \
neo4j:latest
LLM Provider。 OpenAI、Anthropic或通过Ollama的本地模型,用于提取和生成。
Python依赖:
pip install langchain langchain-community langchain-neo4j langchain-openai
pip install neo4j neo4j-graphrag-python
pip install tiktoken python-dotenv
步骤1:连接Neo4j并配置环境
import os
from dotenv import load_dotenv
from langchain_neo4j import Neo4jGraph
load_dotenv()
os.environ["OPENAI_API_KEY"] = "sk-..."
os.environ["NEO4J_URI"] = "bolt://localhost:7687"
os.environ["NEO4J_USERNAME"] = "neo4j"
os.environ["NEO4J_PASSWORD"] = "your-password"
# Establish graph connection
graph = Neo4jGraph(
url=os.environ["NEO4J_URI"],
username=os.environ["NEO4J_USERNAME"],
password=os.environ["NEO4J_PASSWORD"],
)
print("Connected to Neo4j successfully.")
步骤2:摄取和分块文档
from langchain.text_splitter import TokenTextSplitter
from langchain_community.document_loaders import WikipediaLoader
# Load documents (using Wikipedia as an example source)
raw_documents = WikipediaLoader(query="Artificial Intelligence").load()
# Chunk with overlap for context preservation
text_splitter = TokenTextSplitter(
chunk_size=512,
chunk_overlap=64,
)
documents = text_splitter.split_documents(raw_documents)
print(f"Split into {len(documents)} chunks.")
步骤3:使用基于LLM的提取构建知识图谱
这是GraphRAG的核心——使用LLM从非结构化文本中提取结构化实体和关系。
from langchain_openai import ChatOpenAI
from langchain_experimental.graph_transformers import LLMGraphTransformer
# Initialize the LLM for extraction
llm = ChatOpenAI(model="gpt-4o", temperature=0)
# Create the graph transformer
llm_transformer = LLMGraphTransformer(llm=llm)
# Extract graph documents (entities + relationships)
graph_documents = llm_transformer.convert_to_graph_documents(documents)
# Inspect what was extracted
for doc in graph_documents[:2]:
print(f"Nodes: {doc.nodes}")
print(f"Relationships: {doc.relationships}")
print("---")
# Store in Neo4j
graph.add_graph_documents(
graph_documents,
baseEntityLabel=True, # adds a generic __Entity__ label
include_source=True, # links graph nodes back to source chunks
)
LLMGraphTransformer提示LLM在每个块中识别实体及其关系。你可以通过指定允许的节点类型和关系类型来自定义提取:
llm_transformer = LLMGraphTransformer(
llm=llm,
allowed_nodes=["Person", "Organization", "Technology", "Concept"],
allowed_relationships=[
"FOUNDED_BY", "WORKS_AT", "DEVELOPED",
"RELATED_TO", "USED_IN", "PART_OF",
],
)
步骤4:添加向量索引以实现混合检索
from langchain_neo4j import Neo4jVector
from langchain_openai import OpenAIEmbeddings
# Create a hybrid (vector + keyword) index over the stored chunks
vector_index = Neo4jVector.from_existing_graph(
OpenAIEmbeddings(),
search_type="hybrid",
node_label="Document",
text_node_properties=["text"],
embedding_node_property="embedding",
)
# Test it
results = vector_index.similarity_search(
"What are the major approaches to artificial intelligence?"
)
for r in results[:3]:
print(r.page_content[:200])
print("---")
步骤5:构建图检索器
这就是GraphRAG的不同之处——通过图遍历检索上下文,而不仅仅是向量相似度:
from langchain_neo4j import GraphCypherQAChain
# The Cypher QA chain lets the LLM generate graph queries dynamically
cypher_chain = GraphCypherQAChain.from_llm(
llm=ChatOpenAI(model="gpt-4o", temperature=0),
graph=graph,
verbose=True,
allow_dangerous_requests=True, # required for dynamic Cypher
)
# Ask a relationship-based question
response = cypher_chain.invoke({
"query": "What technologies are related to machine learning?"
})
print(response["result"])
为了更好地控制,构建一个结合向量搜索和邻域遍历的自定义图检索器:
from neo4j_graphrag.retrievers import VectorRetriever
from neo4j_graphrag.llm import OpenAILLM
from neo4j_graphrag.generation import GraphRAG
from neo4j_graphrag.embeddings import OpenAIEmbeddings
from neo4j import GraphDatabase
# Direct Neo4j driver connection
driver = GraphDatabase.driver(
"bolt://localhost:7687",
auth=("neo4j", "your-password"),
)
# Set up retriever with neighborhood expansion
embedder = OpenAIEmbeddings(model="text-embedding-3-large")
retriever = VectorRetriever(
driver=driver,
index_name="vector-index-name",
embedder=embedder,
# Cypher to expand retrieved nodes into their graph neighborhood
retrieval_query="""
MATCH (node)-[r]->(neighbor)
RETURN node.text AS text,
score,
collect(type(r) + ' -> ' + neighbor.name) AS relationships
""",
)
# Wire up the full GraphRAG pipeline
llm = OpenAILLM(model_name="gpt-4o")
rag = GraphRAG(retriever=retriever, llm=llm)
# Query
response = rag.search(
query_text="How is deep learning used in natural language processing?",
retriever_config={"top_k": 5},
)
print(response.answer)
步骤6:使用Microsoft的GraphRAG库(替代方法)
Microsoft的开源GraphRAG库提供了一个内置社区检测和层次总结的完整管道:
pip install graphrag
# Initialize a GraphRAG project
# graphrag init --root ./my_graphrag_project
# Place your documents in ./my_graphrag_project/input/
# Then run indexing:
# graphrag index --root ./my_graphrag_project
# Query with global search (for thematic questions)
# graphrag query --root ./my_graphrag_project \
# --method global \
# --query "What are the main themes in this dataset?"
# Query with local search (for specific questions)
# graphrag query --root ./my_graphrag_project \
# --method local \
# --query "Tell me about entity X"
注意:Microsoft的实现在索引期间可能很昂贵,因为它为实体提取和社区总结进行了许多LLM调用。从小数据集开始并监控你的API成本。
5、GraphRAG生产基础设施
从原型到生产需要深思熟虑的基础设施选择:
图数据库。 Neo4j(社区版或企业版)是标准选择。对于云部署,Neo4j Aura提供了托管服务。替代方案包括Amazon Neptune、TigerGraph或NebulaGraph,尽管Neo4j拥有最强的GraphRAG生态系统。
向量存储。 Neo4j的原生向量索引适用于集成部署。对于大规模系统,你可以将其与专用向量数据库(如Milvus、Pinecone或Weaviate)配对用于初始检索层。
LLM基础设施。 你需要在两个阶段访问LLM:索引期间的实体提取(批量,可以使用较便宜的模型)和查询期间的答案生成(实时,受益于更强的模型)。考虑使用GPT-4o-mini或Claude Haiku进行提取,使用GPT-4o或Claude Sonnet进行生成以管理成本。
编排。 LangChain、LangGraph或LlamaIndex用于链接检索和生成步骤。LangGraph对于具有图和向量检索之间条件路由的复杂工作流程特别有用。
计算。 索引阶段是计算密集型的,受益于异步处理。为大型语料库计划可夜间运行的批量索引作业。查询时的检索通常很快(亚秒级图查询,加上LLM延迟)。
监控。 跟踪图大小(节点/边计数)、查询延迟、检索精度和LLM令牌使用情况。LangSmith或Phoenix(Arize AI)等工具可以帮助实现可观测性。
最小的生产架构如下:
┌─────────────────────────────────────────────────┐
│ Ingestion Pipeline │
│ Documents → Chunking → LLM Extraction → Neo4j │
│ ↓ │
│ Vector Indexing │
└─────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────┐
│ Query Pipeline │
│ User Query │
│ ├── Vector Search (candidate retrieval) │
│ ├── Graph Traversal (relationship expansion) │
│ └── Context Assembly │
│ ↓ │
│ LLM Generation → Response │
└─────────────────────────────────────────────────┘
6、GraphRAG的优势
多跳推理。 图遍历自然地处理需要跨多个文档和实体连接信息的问题,这是向量相似度搜索根本无法做到的。
可解释性。 每个答案都可以追溯到图谱——你可以向用户准确展示哪些实体、关系和源文档贡献了响应。这对于医疗、金融和法律等合规性重的领域至关重要。
减少幻觉。 通过将LLM的上下文建立在结构化的、事实性的关系上,而不是松散相似的文本块,GraphRAG显著减少了幻觉反应的表面面积。
全局推理。 通过社区总结,GraphRAG可以回答主题性的、语料库级别的问题("我们所有客户反馈的主要趋势是什么?"),这在传统RAG中需要处理比上下文窗口允许的更多的令牌。
增量更新。 知识图谱可以增量更新——添加新的实体和关系而无需重新索引整个文档语料库。
7、局限性和权衡
索引成本。 通过LLM进行实体提取代价高昂。处理大型语料库会消耗大量API令牌。Microsoft明确警告索引可能很昂贵,并建议从小规模开始。
复杂性。 与vanilla RAG相比,GraphRAG增加了显著的架构复杂性。你现在需要管理图数据库、向量索引、实体解析和更复杂的检索逻辑。
实体解析质量。 同一实体可能被用不同的名称提取("Dr. John Smith"、"J. Smith"、"John")。糟糕的实体解析导致图谱碎片化。生产系统需要强大的去重策略。
并非总是必要。 对于简单文档的简单问答,GraphRAG的增加复杂性可能不值得其性能提升。始终为你的特定用例对vanilla RAG进行基准测试。
8、新兴变体和未来展望
GraphRAG生态系统正在快速发展。值得关注的关键变体包括LightRAG和FastGraphRAG,它们针对速度和成本优化了索引管道。Microsoft的LazyGraphRAG将昂贵的图构建推迟到查询时间,显著降低了前期成本。HippoRAG使用个性化PageRank进行更智能的图遍历。2025年初的研究表明,图操作符的选择(如何遍历和排名节点)比图结构本身更重要——结合拓扑遍历和统计排名的方法(如个性化PageRank)始终优于其他方法。
趋势很明显:检索的未来不仅仅是找到相似的文本——而是理解知识本身的结构。
9、结束语
GraphRAG代表了我们将LLM与私有数据连接的有意义演进。通过将实体及其关系编码在图结构中,它实现了多跳推理、可解释检索和主题理解,而这是单纯的向量搜索无法提供的。与vanilla RAG相比,实现更复杂,但对于复杂、关系丰富的领域,质量提升是显著的。
从关系重要的清晰用例开始。使用Neo4j和LangChain构建原型。与vanilla RAG进行基准测试。然后从那里扩展。
原文链接: GraphRAG: The Complete Guide to Graph-Powered Retrieval-Augmented Generation
汇智网翻译整理,转载请标明出处