微信扫码
添加专属顾问
我要投稿
GraphRAG系统突破传统RAG局限,结合知识图谱与向量搜索,实现更精准的文档检索与生成。 核心内容: 1. GraphRAG如何解决传统RAG的局限性 2. 系统架构设计与关键组件解析 3. 实际应用场景与未来潜力展望
在人工智能领域,基于私有文档的问答系统一直是研究和应用的热点。传统的检索增强生成(RAG)技术虽然已经取得了显著的进步,但由于其单纯依赖向量相似度,往往难以捕捉实体之间的重要上下文关系。为了突破这一局限,GraphRAG应运而生,它将向量搜索与知识图谱相结合,不仅能够理解语义相似性,还能深入把握概念之间的关系,为文档检索与生成带来了革命性的变革。本文将详细介绍如何使用LangChain、Gemini和Neo4j构建一个生产就绪的GraphRAG系统,探索其架构设计、核心组件和实现细节,并展望其在实际应用中的潜力。
传统的RAG系统在处理文档时,主要依靠向量相似度来检索相关信息。这种方法虽然在很多情况下有效,但却存在一个根本性的缺陷:它无法充分理解文档中实体之间的复杂关系。例如,在处理法律文档时,传统RAG可能难以把握“当事人”“律师”“案件”之间的关联;在处理技术文档时,也可能无法理解“组件”“接口”“依赖”之间的关系。
GraphRAG的出现完美地解决了这一问题。它通过将知识图谱与向量嵌入相结合,实现了从单纯的语义相似性检索到关系感知检索的跨越。与传统RAG相比,GraphRAG具有以下显著优势:
GraphRAG的核心创新在于将非结构化文本转化为结构化的知识图谱,同时保留向量表示。这种双重表示方法使得系统既能利用向量搜索的高效性,又能借助知识图谱的关系推理能力,从而在文档理解和问答任务中取得更好的效果。
GraphRAG系统采用分层架构,巧妙地将向量搜索与知识图谱结合在一起,形成了一个完整的查询处理管道。系统的核心架构如图1所示,主要包括以下关键阶段:
系统首先需要加载和处理文档,目前支持.docx格式的文件。这一阶段的主要任务是将原始文档转换为系统可以处理的格式,并为后续的语义分块做准备。
基于嵌入的文本分割技术将文档分割成合适的块。这种方法不同于传统的固定长度分块,而是根据语义相关性进行分割,确保每个块包含完整的语义单元,从而提高后续检索的准确性。
利用大型语言模型(LLM)的强大能力,从文档中提取实体和关系。这是GraphRAG的核心环节之一,通过LLM可以自动识别文档中的人物、组织、概念和政策等实体,并发现它们之间的各种关系。
采用内存向量存储和Neo4j图数据库相结合的方式。内存向量存储提供了快速的向量检索能力,而Neo4j则负责存储和管理知识图谱,两者相辅相成,共同为系统提供高效的数据访问能力。
将图遍历和向量相似度检索相结合,形成强大的混合检索能力。这种检索方式不仅能够找到语义相似的文档块,还能通过知识图谱遍历找到与查询相关的实体和关系,从而提供更全面、更准确的回答。
文档加载与分块是GraphRAG系统的第一个环节,其主要功能是将.docx格式的文档加载到系统中,并将其分割成适合处理的语义块。以下是该模块的核心实现:
def load_and_chunk_documents() -> List[Document]:
"""加载并使用语义分块处理.docx文件"""
documents = []
docx_files = glob.glob("./documents/*.docx") # 根据需要调整路径
if not docx_files:
print("未找到.docx文件")
return documents
# 初始化语义分块器
text_splitter = SemanticChunker(embeddings)
for docx_file in docx_files:
print(f"处理 {docx_file}...")
# 加载文档
loader = Docx2txtLoader(docx_file)
raw_docs = loader.load()
# 应用语义分块
chunks = text_splitter.split_documents(raw_docs)
# 添加元数据
for chunk in chunks:
chunk.metadata["source"] = os.path.basename(docx_file)
documents.extend(chunks)
print(f"已加载 {len(documents)} 个文档块")
return documents
该模块的工作流程如下:首先使用glob模块查找指定路径下的所有.docx文件,然后为每个文件创建一个Docx2txtLoader实例来加载文档内容。接着,使用SemanticChunker进行语义分块,这种分块方式基于嵌入模型,能够根据文本的语义相关性进行分割,确保每个块都是一个完整的语义单元。最后,为每个块添加元数据,记录其来源文件,以便后续追溯。
LLM图转换器是GraphRAG系统的核心组件,它负责从文档中提取实体和关系,并将其转换为知识图谱的结构。以下是该组件的初始化和使用方法:
# 初始化LLM图转换器
print("初始化LLM图转换器...")
llm_transformer = LLMGraphTransformer(llm=llm)
# 将文档转换为图文档
print("将文档转换为图格式...")
graph_documents = llm_transformer.convert_to_graph_documents(documents)
print(f"创建了 {len(graph_documents)} 个图文档")
LLM图转换器的主要功能包括:
这一组件的核心是利用大型语言模型的理解和推理能力,自动从非结构化文本中提取结构化的知识图谱信息。这种方法大大减少了人工构建知识图谱的工作量,同时也提高了知识图谱的准确性和完整性。
Neo4j是GraphRAG系统中知识图谱的存储和管理工具,它提供了高效的图数据存储和查询能力。以下是将提取的图文档存储到Neo4j的实现:
def store_graph_documents(graph_documents: List):
"""将图文档存储到Neo4j"""
print("将图数据存储到Neo4j...")
# 清除现有数据(可选)
graph.query("MATCH (n) DETACH DELETE n")
for graph_doc in graph_documents:
# 添加节点
for node in graph_doc.nodes:
node_type = node.type.replace(" ", "_") # 为Neo4j清理节点类型
graph.query(
f"MERGE (n:{node_type} {{id: $id}})",
{"id": node.id}
)
# 添加关系
for rel in graph_doc.relationships:
rel_type = rel.type.replace(" ", "_")
graph.query(
f"""
MATCH (source {{id: $source_id}})
MATCH (target {{id: $target_id}})
MERGE (source)-[r:{rel_type}]->(target)
""",
{
"source_id": rel.source.id,
"target_id": rel.target.id
}
)
print("图数据存储成功")
在存储过程中,首先会清除Neo4j中的现有数据(可选操作),然后遍历每个图文档,将其中的节点和关系分别添加到Neo4j中。对于节点,使用MERGE语句确保节点的唯一性;对于关系,同样使用MERGE语句建立节点之间的关系。这种存储方式能够高效地处理大量的节点和关系,为后续的图遍历和查询提供支持。
RAG链是GraphRAG系统的最终执行组件,它将向量搜索和图检索结合在一起,形成一个完整的问答流程。以下是RAG链的创建实现:
def create_rag_chain(vector_store):
"""创建包含图和向量检索的RAG链"""
# 根据数据创建策略
traversal_config = Eager(
select_k=5,
start_k=2,
adjacent_k=3,
max_depth=2
)
# 创建图检索器
graph_retriever = GraphRetriever(
store=vector_store,
strategy=traversal_config,
)
# 文档格式化函数
def format_docs(docs):
return "\n\n".join(doc.page_content for doc in docs)
# 提示模板
prompt = ChatPromptTemplate.from_template("""
基于提供的上下文回答问题。
上下文: {context}
问题: {question}
回答:
""")
# 创建链
chain = (
{
"context": graph_retriever | format_docs,
"question": RunnablePassthrough()
}
| prompt
| llm
| StrOutputParser()
)
return chain
RAG链的创建过程主要包括以下几个步骤:首先配置图遍历策略,包括选择的节点数、起始节点数、相邻节点数和最大深度等参数;然后创建图检索器,将向量存储和遍历策略结合起来;接着定义文档格式化函数,将检索到的文档内容格式化为适合LLM处理的格式;最后创建提示模板,并将各个组件串联起来,形成一个完整的RAG链。
这个RAG链的工作流程是:首先使用图检索器结合向量搜索和图遍历获取相关的上下文文档,然后将这些文档格式化为提示模板所需的格式,接着将问题和上下文一起输入到LLM中生成回答,最后将LLM的输出解析为字符串格式返回给用户。
在运行GraphRAG系统之前,需要先部署Neo4j图数据库。使用Docker是最简单的部署方式,以下是具体的部署步骤:
docker run \
--name neo4j-graphrag \
-p 7474:7474 -p 7687:7687 \
-d \
-v $PWD/neo4j/data:/data \
-v $PWD/neo4j/logs:/logs \
-v $PWD/neo4j/import:/var/lib/neo4j/import \
-v $PWD/neo4j/plugins:/plugins \
--env NEO4J_AUTH=neo4j/your-password \
neo4j:latest
这条命令会拉取最新的Neo4j镜像并运行一个容器,将容器的7474端口(HTTP)和7687端口(Bolt)映射到主机的相应端口,同时将容器的数据、日志、导入和插件目录挂载到主机的指定位置,以便数据持久化。环境变量NEO4J_AUTH用于设置Neo4j的用户名和密码。
在项目根目录下创建一个.env文件,内容如下:
# Neo4j配置
NEO4J_URI=bolt://localhost:7687
NEO4J_USERNAME=neo4j
NEO4J_PASSWORD=your-password
# Google AI配置
GOOGLE_API_KEY=your-google-api-key
这个文件包含了Neo4j和Google AI的配置信息,系统会在运行时加载这些环境变量。
可以使用以下代码验证Neo4j是否成功部署并可连接:
from langchain_neo4j import Neo4jGraph
# 测试连接
try:
graph = Neo4jGraph(
url="bolt://localhost:7687",
username="neo4j",
password="your-password"
)
print("Neo4j连接成功!")
except Exception as e:
print(f"Neo4j连接失败: {e}")
系统部署完成后,需要进行测试以确保其正常工作。以下是测试GraphRAG系统的代码:
def test_graphrag_system(chain):
"""使用示例查询测试GraphRAG系统"""
test_queries = [
"文档中讨论的主要主题是什么?",
"知识图谱中的实体是如何连接的?",
"你能解释一下关键概念之间的关系吗?"
]
for query in test_queries:
print(f"\n🔍 查询: {query}")
try:
response = chain.invoke(query)
print(f"回答: {response[:200]}...")
except Exception as e:
print(f"错误: {e}")
# 检查图统计信息
try:
nodes_count = graph.query("MATCH (n) RETURN count(n) as count")[0]["count"]
rels_count = graph.query("MATCH ()-[r]->() RETURN count(r) as count")[0]["count"]
print(f"\n图统计: {nodes_count} 个节点, {rels_count} 条关系")
except Exception as e:
print(f"获取图统计信息错误: {e}")
测试函数包含了几个典型的查询,用于验证系统在不同场景下的表现。同时,还会查询Neo4j以获取图中的节点和关系数量,以便了解知识图谱的构建情况。
知识图谱的可视化对于理解和分析GraphRAG系统的工作原理非常重要。Neo4j提供了强大的可视化功能,以下是可视化知识图谱的步骤:
访问Neo4j浏览器:在Web浏览器中打开http://localhost:7474/browser/preview/。
使用在Docker部署时设置的用户名和密码登录Neo4j浏览器。
在查询面板中运行以下查询以可视化知识图谱:
MATCH (n)-[r]->(m) RETURN n, r, m LIMIT 500
这条查询会匹配所有节点及其之间的关系,并返回最多500个结果用于可视化。
探索不同的查询:
查看所有节点类型:
MATCH (n) RETURN DISTINCT labels(n) as NodeTypes
按类型统计节点数量:
MATCH (n) RETURN labels(n) as NodeType, count(n) as Count
查找高度连接的节点:
MATCH (n)-[r]-()
RETURN n, count(r) as connections
ORDER BY connections DESC
LIMIT 10
探索特定关系:
MATCH (n)-[r:MANAGES]->(m)
RETURN n, r, m
Neo4j浏览器提供了丰富的可视化功能,包括交互式图、节点详情查看、关系信息展示、过滤功能和导出选项等,帮助用户更好地理解和分析知识图谱。
53AI,企业落地大模型首选服务商
产品:场景落地咨询+大模型应用平台+行业解决方案
承诺:免费场景POC验证,效果验证后签署服务协议。零风险落地应用大模型,已交付160+中大型企业
2025-06-19
企业级 RAG Agent 开发指南:RAG Agent 开发的 10 条实战准则
2025-06-19
RAG工程落地:回答内容和检索片段(chunk)对应关系追踪
2025-06-19
为什么说『RAG开箱即用』是最大的AI技术谎言?
2025-06-18
大模型三大步 -- 上下文检索RAG
2025-06-18
企业级RAG系统规模化部署十条经验
2025-06-18
RAG之父:企业级 RAG 系统落地的实战经验
2025-06-17
深度解析 RAG(Retrieval-Augmented Generation)技术原理
2025-06-16
最新|Milvus_local_RAG,笔记本也能跑的本地知识库&RAG来了
2025-03-24
2025-03-24
2025-03-24
2025-03-28
2025-04-01
2025-03-23
2025-04-13
2025-04-19
2025-04-09
2025-04-16
2025-06-19
2025-06-13
2025-06-09
2025-06-06
2025-05-30
2025-05-29
2025-05-29
2025-05-23