GraphRAG实战:用知识图谱构建智能检索Agent

什么是GraphRAG
检索增强生成(RAG)已经成为大模型应用的标配技术。其核心逻辑很简单:当Agent(智能体)无法仅凭模型权重回答用户问题时,它会从外部数据库检索相关信息,再基于这些「有据可查」的上下文生成答案,从而让回答有事实依据(grounded)。
而GraphRAG(图谱检索增强生成)与传统RAG的关键区别在于——它检索的不是普通的文档片段,而是一张知识图谱。知识图谱(Knowledge Graph)最早由Google在2012年提出,用于增强搜索引擎的语义理解能力。其本质是一种语义网络,采用RDF三元组或属性图模型来表示现实世界中的实体及其关系。在属性图模型中,节点可以携带标签和属性,边则表示有向的类型化关系。知识图谱由实体(节点)和关系(边)构成,能够刻画复杂的连接结构。例如:一个人生活在某个地点,这个人创建了名为Linux的内核,Linux发布于某一年份……这些概念都可以在图中相互关联。与传统关系型数据库相比,图数据库在处理多层关联查询时具有显著的性能优势,因为它避免了大量的JOIN操作,而是通过指针直接遍历相邻节点。Agent既可以「遍历」这张图,也可以借助嵌入(embedding)方法定位特定节点。

何时用GraphRAG,何时用传统RAG
选择哪种技术,取决于你的数据和查询特征,这一点非常关键。
适合GraphRAG的场景
当你的数据「关系密集」,实体多、连接多,且查询本身也依赖关系时,GraphRAG就能发挥威力。最典型的就是多跳推理(multi-hop reasoning):不是简单地问「谁住在某地」,而是「我认识的人所使用的那个操作系统,它的创建者住在哪里?」这类需要沿着多层关系链条推导的问题。多跳推理是自然语言处理和知识推理领域的核心难题之一——传统的单跳检索只需找到与查询最相关的单个文档片段,而多跳推理要求系统能够跨越多个中间实体,沿着关系链逐步推导出最终答案。在学术界,HotpotQA和MuSiQue等基准数据集专门用于评估模型的多跳推理能力。GraphRAG通过图结构天然地支持这种链式推理,因为图的遍历操作本身就是沿着边从一个节点跳转到另一个节点的过程。
此外,GraphRAG在可解释性与审计方面也有天然优势——由于图结构清晰,你可以精确追踪推理经过的路径。这在合规审计、企业问答、研究助手(关联论文、专利、代码库)以及客户支持(把客户关联到工单、订阅、历史Bug、排障资源)等场景中尤其有价值。
适合传统RAG的场景
如果你只需要做简单检索——查找文档中最相似的片段、做语义搜索、查询零散的事实,那么传统的向量RAG就足够了。向量RAG的核心机制是将文档切片后通过embedding模型转换为高维向量,存储在向量数据库(如Pinecone、Weaviate、Milvus)中,检索时通过余弦相似度或欧氏距离找到最相关的片段。这种方法擅长语义匹配但对结构化关系的捕捉较弱。此外,当数据量不大、关系稀疏,或者数据频繁变动时,维护一张知识图谱的成本会变得很高(因为需要持续进行实体抽取、关系对齐和图谱更新),此时传统RAG更为经济。
值得注意的是,向量RAG与GraphRAG并非互斥。混合架构(Hybrid RAG)正成为业界趋势:系统同时维护向量索引和知识图谱,根据查询类型动态选择检索路径,或将两种检索结果融合后再交给LLM生成答案。Microsoft Research在2024年发表的GraphRAG论文中就探索了这种融合方案,通过社区检测算法对图谱进行层次化摘要,再结合向量检索实现全局性问答。
一句话总结:相似度/语义搜索用向量RAG,关系密集型任务用GraphRAG。
环境准备
本文的实现基于 Neo4j —— 一款图数据库,以及官方提供的 neo4j-graphrag Python包。这个库的工作原理是:接收一个自然语言Prompt,借助AI将其转换成 Cypher 查询(Cypher 是 Neo4j 的查询语言),执行后返回结果,Agent 再据此生成答案。
Cypher是Neo4j开发的声明式图查询语言,使用ASCII Art风格的语法来描述图模式。例如 (a)-[:KNOWS]->(b) 表示节点a通过KNOWS关系连接到节点b。这种直观的语法设计使得图查询的编写和阅读都更加自然,也为Text2Cypher(自然语言转Cypher)提供了良好的基础——大语言模型只需理解图谱Schema,就能生成语法正确且语义准确的查询语句。Cypher的设计灵感来源于SQL和SPARQL,但更加注重模式匹配的表达力。它的MATCH子句用于声明要查找的图模式,WHERE子句用于过滤条件,RETURN子句用于指定返回结果——这种声明式范式意味着用户只需描述「想要什么」,而无需指定「如何获取」,查询优化由数据库引擎自动完成。
首先需要一个 Neo4j 数据库。你可以通过 Neo4j Desktop 本地安装、用包管理器安装,或使用在线托管实例。本文采用 Docker 方案,编写一个 docker-compose.yaml:
services:
neo4j:
image: neo4j:latest
ports:
- "7474:7474" # Web UI
- "7687:7687" # Bolt 协议
environment:
- NEO4J_AUTH=neo4j/password123
其中 7474 是 Web 界面端口,7687 是 Neo4j 专用的 Bolt(TCP)协议端口。Bolt是Neo4j自主设计的二进制通信协议,专为高效的数据库客户端-服务器通信而优化。相比HTTP/REST接口,Bolt协议具有更低的延迟和更高的吞吐量,支持连接池、事务管理和流式结果传输,同时支持TLS加密,是生产环境中推荐的连接方式。Bolt协议采用PackStream序列化格式,能够高效地传输图数据结构(节点、关系、路径等原生类型),避免了JSON序列化/反序列化的开销。执行 docker compose up 即可启动。

接着还需要一个 LLM 提供商的 API Key(本文使用 OpenAI),将其写入 .env 文件:
OPENAI_API_KEY=your_key_here
最后安装依赖包:
uv add "langchain[openai]" neo4j neo4j-graphrag python-dotenv
(不使用 uv 的话,用 pip install 同样可以。uv 是由 Astral 团队开发的新一代 Python 包管理器,以 Rust 编写,速度比 pip 快 10-100 倍,正在成为 Python 生态中的热门工具。它同时提供了虚拟环境管理、依赖解析和锁文件功能,可以视为pip、pip-tools、virtualenv和pyenv的统一替代方案。)
构建知识图谱
在正式编码前,先加载环境变量并导入所需模块:
from dotenv import load_dotenv
from langchain.agents import create_agent
from langchain.tools import tool
from neo4j import GraphDatabase
from neo4j_graphrag.llm import OpenAILLM
from neo4j_graphrag.retrievers import Text2CypherRetriever
load_dotenv()
这里选用最简单的 Text2CypherRetriever——它接收Prompt,用AI生成Cypher查询并返回结果。其工作流程是:将用户的自然语言问题与图谱Schema一起发送给LLM,LLM理解图结构后生成对应的Cypher查询语句,然后在Neo4j中执行该查询并将结果返回。在内部实现中,检索器会构造一个包含Schema信息、示例查询和用户问题的Prompt模板,引导LLM输出格式正确的Cypher语句。如果生成的查询执行失败,一些高级实现还支持自动重试和错误修正机制。库中还提供支持嵌入的(基于向量相似度检索图中节点)、混合型的(结合向量检索与图遍历)等更复杂的检索器可供选择。
接着建立数据库连接,并用 Cypher 的 MERGE 命令写入数据。MERGE 的语义是「存在则匹配,不存在则创建」,这确保了重复执行不会产生冗余数据(幂等性),在图谱构建和维护中非常实用:
driver = GraphDatabase.driver(
"bolt://localhost:7687",
auth=("neo4j", "password123")
)
driver.execute_query('''
MERGE (f:Person {name: "Florian", country: "Austria"})
MERGE (c:YTChannel {name: "NeuralNine"})
MERGE (os:OS {name: "Linux"})
MERGE (l:Person {name: "Linus Torvalds", country: "Finland"})
MERGE (f)-[:OWNS]->(c)
MERGE (f)-[:USES]->(os)
MERGE (l)-[:CREATED]->(os)
''')
这样就构建出了一张完整的知识图谱:Florian 住在奥地利,拥有名为 NeuralNine 的 YouTube 频道,使用 Linux 操作系统;而 Linux 由住在芬兰的 Linus Torvalds 创建。这些信息以节点和边的形式结构化地存储在图数据库中。在上述Cypher语句中,圆括号()定义节点,冒号后跟标签(如:Person),花括号内是属性;方括号[]定义关系,箭头->表示关系方向。这种图结构的优势在于:当我们需要回答涉及多个实体的关联问题时,只需沿着边进行遍历,而不需要像关系型数据库那样执行复杂的多表JOIN操作。

定义Schema与检索器
为了让检索器理解图谱结构,需要提供一段 Schema 描述作为上下文提示。这段Schema本质上是给LLM的「图谱说明书」——它告诉模型有哪些类型的节点、每种节点有什么属性、节点之间可以存在什么关系。有了这些信息,LLM才能生成合法的Cypher查询,而不会「凭空捏造」不存在的标签或关系类型。这个设计体现了「约束引导生成」的思想——通过提供明确的结构约束,大幅降低LLM产生幻觉(hallucination)的概率:
schema = '''
Node labels:
- Person (name, country)
- YTChannel (name)
- OS (name)
Relationships:
- (Person)-[:OWNS]->(YTChannel)
- (Person)-[:CREATED]->(OS)
- (Person)-[:USES]->(OS)
'''
retriever = Text2CypherRetriever(
driver=driver,
llm=OpenAILLM(model_name="gpt-4o-mini"),
neo4j_schema=schema
)
在真实项目中,Schema 会描述更庞大的实体和关系体系(可能包含数十甚至上百种节点类型和关系类型),这里只是一个极简的浓缩版本。在大型图谱中,Schema管理本身也是一个工程挑战——需要考虑版本控制、Schema演进以及与数据库实际结构的同步问题。一些团队会使用自动化工具从数据库中提取当前Schema(Neo4j提供了db.schema.visualization()等内省查询),然后与代码中定义的Schema进行一致性校验。此外,当Schema过于庞大时,还需要考虑Schema压缩或分片策略,避免超出LLM的上下文窗口限制。
将检索器封装为Agent工具
有了检索器,我们把它包装成 LangChain Agent 可以调用的工具。LangChain的Tool机制允许Agent在推理过程中自主决定何时调用外部工具——Agent会根据用户问题判断是否需要查询知识图谱,如果需要则调用工具获取信息,再基于返回结果生成最终答案。这种「推理-行动」(ReAct)模式是当前AI Agent的主流架构,它源自Yao等人2022年的研究论文,将思维链(Chain-of-Thought)推理与外部工具调用交替进行,使Agent能够在每一步都根据观察结果调整下一步行动:
@tool
def query_kg(question: str) -> str:
"""Query the knowledge graph for information.
Pass entire user questions. Returns graph rows."""
results = retriever.search(question)
return "\n".join(item.content for item in results.items) or "no content"
agent = create_agent(
model="gpt-4o-mini",
tools=[query_kg],
system_prompt="You are a helpful assistant with access to a knowledge graph, query it whenever you need to."
)
这里的@tool装饰器将普通Python函数转换为Agent可调用的工具,函数的docstring会被用作工具描述——Agent正是通过阅读这段描述来决定何时以及如何调用该工具的。因此,docstring的质量直接影响Agent的工具选择准确率。
最后发起一个需要多跳推理的复杂查询:
if __name__ == "__main__":
query = "What country is the creator of the operating system used by the person who runs NeuralNine from?"
response = agent.invoke({"messages": [("user", query)]})
print(response["messages"][-1].content)

运行后,Agent 正确回答:运行 NeuralNine 的人(Florian)使用的操作系统(Linux)的创建者是 Linus Torvalds,他来自芬兰。
观察推理过程与模型能力的差异
通过流式输出(agent.stream(..., stream_mode="values")),可以看到 Agent 拆解问题的完整链条:谁运营 NeuralNine → Florian → 他用什么系统 → Linux → 谁创建了 Linux → Linus Torvalds → 他来自哪个国家 → 芬兰。这种可追踪的推理路径,正是 GraphRAG 在可解释性上的优势体现。相比之下,传统向量RAG返回的是「最相似的文档片段」,用户很难理解答案是如何从原始数据推导而来的。在需要审计和合规的场景中(如金融、医疗、法律领域),这种推理路径的可追溯性不仅是「锦上添花」,更是监管要求——决策者需要清楚地知道每一个结论是基于哪些事实、经过什么逻辑推导得出的。
更值得注意的是,模型能力会显著影响执行效率。当使用更强的模型(如GPT-4o相比GPT-4o-mini)并注入更丰富的数据后,面对「NeuralNine 教授的编程语言,其发明者的出生国的首都是什么」这样的多跳问题,模型能够**一次性(one-shot)**生成正确的 Cypher 查询,无需分步拆解——沿着「Python → 发明者 Guido van Rossum → 出生国荷兰 → 首都阿姆斯特丹」的关系链直接得出答案。这种能力差异体现了LLM在理解复杂图结构和生成多跳Cypher查询方面的推理深度:更强的模型能够在单次推理中「看到」更长的关系链,而较弱的模型则需要将问题分解为多个子查询逐步执行。从工程角度看,one-shot查询不仅减少了LLM调用次数(降低成本和延迟),还避免了多步推理中可能出现的错误累积问题——每多一次中间查询,就多一次LLM产生错误的机会。
总结
GraphRAG 为处理关系密集型知识提供了一条强有力的路径。它的核心价值不在于替代传统向量检索,而在于补足后者在多跳推理和可解释性上的短板。借助 Neo4j 与 neo4j-graphrag,开发者只需定义好图谱结构和 Schema,就能让 Agent 通过自然语言完成复杂的图谱查询。在企业问答、合规审计、研究助手和客户支持等场景中,这套方案的潜力尤其值得关注。
展望未来,GraphRAG的发展方向包括:自动化图谱构建(从非结构化文本中自动抽取实体和关系,目前LlamaIndex和LangChain都提供了基于LLM的自动图谱构建管道)、动态Schema推断(让系统自动发现和适应图谱结构的变化)、以及与向量检索的深度融合(在同一次查询中同时利用语义相似度和图结构信息)。此外,图神经网络(GNN)与LLM的结合也是一个活跃的研究方向——通过GNN对图谱进行预编码,将结构信息注入LLM的推理过程中,有望进一步提升多跳推理的准确性和效率。随着LLM推理能力的持续提升,GraphRAG在处理更复杂、更长链条的知识推理任务上将展现出越来越大的优势。
核心要点
- GraphRAG的本质:将知识图谱作为检索源,利用图结构天然支持多跳推理和关系推导
- 适用场景选择:关系密集、需要多跳推理用GraphRAG;语义搜索、简单事实查询用向量RAG
- 技术栈组合:Neo4j(图数据库)+ Cypher(图查询语言)+ LLM(自然语言转Cypher)构成完整的Text2Cypher管道
- 可解释性优势:图结构使推理路径完全可追踪,满足审计和合规需求
- 模型能力影响:更强的LLM能够一次性生成多跳Cypher查询,降低延迟和错误累积
- 混合架构趋势:向量RAG与GraphRAG并非互斥,融合使用可兼顾语义匹配和结构化推理
相关推荐

EmbeddedSass for .NET:告别Node.js依赖的Sass编译方案
EmbeddedSass for .NET基于官方Embedded Sass协议,让.NET开发者无需Node.js即可原生编译Sass/SCSS。本文解析其技术原理、应用场景及与ASP.NET生态的集成方式。

旧金山到新加坡时差:硅谷科技人的跨太平洋日常
旧金山与新加坡之间存在15-16小时时差,频繁往返两地已成为科技从业者的常态。本文解析SF到SG时差挑战、两大科技中心的连接趋势,以及AI行业全球化布局背后的人才与资本流动。

Anthropic官方Claude Code插件目录发布:精选高质量扩展生态
Anthropic发布官方Claude Code插件目录claude-plugins-official,提供经过审核的高质量插件精选集。了解官方目录的定位、核心价值及对AI编程工具生态的深远影响。