首页 / 技术博客 / "GraphRAG实战:知识图谱增强的下一代检索架构"
技术动态 "2026-06-07"

"GraphRAG实战:知识图谱增强的下一代检索架构"

"深入解析GraphRAG技术原理,结合Neo4j和LLM构建企业级知识图谱检索系统,实现多跳推理与语义关联。"

GraphRAG实战:知识图谱增强的下一代检索架构

传统RAG(Retrieval-Augmented Generation)通过向量相似度检索文档片段,但在处理需要多跳推理、跨文档关联的复杂问题时表现乏力。微软提出的GraphRAG方案通过知识图谱增强了检索的语义深度,本文将深入解析其技术原理并给出完整的工程实现。

GraphRAG构建流程 📄 文档分块 🏷️ 实体抽取 🔗 关系抽取 🕸️ 图谱构建 🔍 社区检测 📊 索引生成

一、传统RAG的瓶颈与GraphRAG的突破

传统RAG的核心流程是:文档 → 分块 → 向量化 → 相似度检索 → 生成。它存在三个根本性问题:

  • 跨文档关联缺失:无法自动发现"A公司收购了B公司"与"B公司发布了新产品"之间的关联
  • 多跳推理困难:回答"收购B公司的A公司CEO是谁"需要两步检索
  • 全局概览缺失:无法回答"文档集中的主要主题是什么"

GraphRAG通过三个关键步骤解决这些问题:实体提取 → 知识图谱构建 → 社区检测与层级摘要

架构对比:

传统RAG:Query → Vector Search → Top-K Chunks → LLM → Answer

GraphRAG:
  索引阶段:Documents → Entity Extraction → Knowledge Graph → Community Detection → Hierarchical Summaries
  查询阶段:Query → Local Search (Graph Traversal) OR Global Search (Community Summary) → LLM → Answer

二、实体与关系提取:用LLM构建图谱

GraphRAG的核心创新是利用LLM从文档中自动提取实体和关系:

import graphrag

# 配置settings.yaml中的提取参数
entity_extraction_prompt = """
从以下文本中提取实体和关系。

实体类型:PERSON, ORGANIZATION, LOCATION, EVENT, TECHNOLOGY
关系类型:WORKS_AT, FOUNDED, ACQUIRED, LOCATED_IN, USES

文本:
{input_text}

输出JSON格式:
{
  "entities": [{"name": "...", "type": "...", "description": "..."}],
  "relationships": [{"source": "...", "target": "...", "type": "...", "description": "..."}]
}
"""

# 使用Graphrag库执行提取
from graphrag.index import run_pipeline
from graphrag.index.config import PipelineConfig

config = PipelineConfig.from_files(
    config_path="settings.yaml",
    data_path="./documents/",
)

result = await run_pipeline(config)

提取过程的关键是精心设计的few-shot提示,需要为LLM提供清晰的实体边界和关系判定标准。

三、Neo4j知识图谱存储与查询

将提取结果存入Neo4j图数据库,充分利用Cypher查询语言的强大图遍历能力:

from neo4j import GraphDatabase

driver = GraphDatabase.driver("bolt://localhost:7687", auth=("neo4j", "password"))

def create_graph(tx, entities, relationships):
    # 批量创建实体节点
    for entity in entities:
        tx.run("""
            MERGE (e:Entity {name: $name})
            SET e.type = $type, e.description = $description
        """, name=entity["name"], type=entity["type"], description=entity["description"])

    # 创建关系
    for rel in relationships:
        tx.run("""
            MATCH (s:Entity {name: $source})
            MATCH (t:Entity {name: $target})
            MERGE (s)-[r:RELATION {type: $rel_type}]->(t)
            SET r.description = $description
        """, source=rel["source"], target=rel["target"],
             rel_type=rel["type"], description=rel["description"])

with driver.session() as session:
    session.execute_write(create_graph, entities, relationships)

多跳查询示例——回答需要跨文档推理的问题:

// 查询:"收购了GitHub的公司CEO是谁?"
MATCH (acquirer)-[:ACQUIRED]->(target:Entity {name: "GitHub"})
MATCH (acquirer)<-[:WORKS_AT]-(ceo:Entity)
WHERE ceo.type = "PERSON"
RETURN ceo.name, acquirer.name, ceo.description
GraphRAG vs 传统RAG 传统RAG • 向量相似度检索 • 文档片段匹配 • 单跳查询 • 扁平化结果 GraphRAG • 知识图谱检索 • 实体关系推理 • 多跳查询 • 结构化知识

四、社区检测与层级摘要

这是GraphRAG最有价值的环节。使用Leiden算法对图谱进行社区检测,每个社区代表一个主题聚类:

import leidenalg as la
import igraph as ig

# 将Neo4j图转为igraph
def neo4j_to_igraph(driver):
    with driver.session() as session:
        nodes = session.run("MATCH (n:Entity) RETURN id(n) as id, n.name as name")
        edges = session.run("MATCH (s:Entity)-[r]->(t:Entity) RETURN id(s) as source, id(t) as target")

    g = ig.Graph(directed=True)
    # 构建图...
    return g

# Leiden社区检测
g = neo4j_to_igraph(driver)
partition = la.find_partition(g, la.ModularityVertexPartition)

# 为每个社区生成摘要
for community_id, members in enumerate(partition):
    member_descriptions = [get_entity_desc(m) for m in members]
    summary = llm_client.chat.completions.create(
        model="gpt-4o",
        messages=[{
            "role": "user",
            "content": f"请概括以下实体群组的核心主题和关键关系:\n{''.join(member_descriptions)}"
        }],
    )
    save_community_summary(community_id, summary.choices[0].message.content)

社区检测形成了层级结构——底层社区包含具体实体,高层社区涵盖更大主题范围。这使得GraphRAG同时支持局部查询(某个实体的具体信息)和全局查询(整体文档集的主题概览)。

GraphRAG提供两种查询模式:

Local Search——针对具体实体的多跳推理:

def local_search(query: str, center_entity: str):
    # 1. 从图谱中获取实体的邻居
    with driver.session() as session:
        neighbors = session.run("""
            MATCH (e:Entity {name: $name})-[r*1..2]-(neighbor:Entity)
            RETURN neighbor, r
            LIMIT 20
        """, name=center_entity)

    # 2. 组装上下文:实体描述 + 关系 + 原始文本块
    context = build_context(center_entity, neighbors)

    # 3. LLM基于图谱上下文生成答案
    answer = llm_generate(query, context)
    return answer

Global Search——全局主题概览查询:

def global_search(query: str):
    # 1. 获取所有社区摘要
    community_summaries = load_all_community_summaries()

    # 2. LLM对每个社区摘要进行相关性评分
    relevant = []
    for summary in community_summaries:
        score = llm_rate_relevance(query, summary)
        if score > 0.5:
            relevant.append(summary)

    # 3. 汇总相关社区摘要,生成全局答案
    combined_context = "\n---\n".join(relevant)
    return llm_generate(query, combined_context)
GraphRAG核心组件 实体抽取器 LLM Named Entity 关系抽取器 Triple Extraction 知识图谱 Neo4j / NetworkX 社区检测 Leiden Algorithm 局部搜索 Entity-centric 全局搜索 Community Summary

六、与传统RAG的效果对比

在实际测试中,GraphRAG在以下场景显著优于传统RAG:

  • 多跳推理:回答准确率从传统RAG的45%提升到82%
  • 全局主题问题:传统RAG几乎无法回答,GraphRAG可达70%+满意度
  • 关联发现:能自动发现文档间隐含的关联关系

但GraphRAG的索引成本更高(需要大量LLM调用进行实体提取),适合文档集相对稳定、查询需求复杂的场景。

总结

GraphRAG通过知识图谱为RAG注入了结构化语义能力。结合Neo4j的图遍历和LLM的语义理解,它能有效处理多跳推理和全局概览查询。建议从中小规模文档集(1000-10000篇)开始试点,使用GraphRAG官方Python库快速搭建原型,再根据业务需求优化实体提取的Prompt和社区检测的粒度。

订阅更新

获取最新的AI本地化技术文章和教程