配音

知识图谱查询与 RAG

课程简介

用 Cypher/SPARQL 查询图谱,将图谱结果注入 RAG 流程。

🎬 本课程视频:Knowledge Graphs for RAG — 知识图谱增强检索


知识图谱查询与 RAG 注入

一、图查询语言概述

知识图谱的价值在于能够精确地检索结构化的信息。而检索的方式就是通过图查询语言。目前最主流的两种图查询语言是 Cypher(Neo4j 的查询语言)和 SPARQL(W3C 标准的 RDF 查询语言)。

二、Cypher 查询语言

2.1 基本语法

Cypher 是 Neo4j 图数据库的声明式查询语言,语法设计直观易懂。它的核心语法模式匹配使用 ASCII 艺术风格来表示图结构。

(节点:标签 {属性})
[关系:类型 {属性}]

节点模式

// 匹配所有公司节点
MATCH (c:Company)
RETURN c

// 匹配特定公司
MATCH (c:Company {name: 'Apple'})
RETURN c

// 匹配公司的名称和市值
MATCH (c:Company {name: 'Apple'})
RETURN c.name, c.market_cap

关系模式

// 苹果公司的 CEO
MATCH (c:Company {name: 'Apple'})<-[:CEO]-(p:Person)
RETURN p.name

// 苹果公司生产的所有产品
MATCH (c:Company {name: 'Apple'})-[:PRODUCES]->(p:Product)
RETURN p.name, p.release_date

多跳模式

// 两跳查询:苹果公司 CEO 曾在哪些公司任职
MATCH (c:Company {name: 'Apple'})<-[:CEO]-(p:Person)-[:WORKED_FOR]->(other:Company)
RETURN p.name, other.name

// 可变长度路径:找到与苹果公司有 2-4 跳关系的公司
MATCH (c:Company {name: 'Apple'})-[*2..4]-(related:Company)
RETURN DISTINCT related.name

2.2 创建与更新

// 创建节点
CREATE (p:Person {name: 'Tim Cook', birth_year: 1960})

// 创建关系
MATCH (p:Person {name: 'Tim Cook'})
MATCH (c:Company {name: 'Apple'})
CREATE (p)-[:CEO {since: 2011}]->(c)

// 更新属性
MATCH (p:Person {name: 'Tim Cook'})
SET p.title = 'CEO'

// 合并操作(不存在则创建,存在则更新)
MERGE (p:Person {name: 'Tim Cook'})
ON CREATE SET p.birth_year = 1960
ON MATCH SET p.last_updated = datetime()

2.3 高级查询

聚合查询

// 统计每个行业的公司数量
MATCH (c:Company)
RETURN c.industry, count(c) AS company_count
ORDER BY company_count DESC

// 查找与某公司关系最紧密的其他公司
MATCH (c:Company {name: 'Apple'})-[r]-(related:Company)
RETURN related.name, count(r) AS relation_strength
ORDER BY relation_strength DESC
LIMIT 10

子查询

// 查找在 Apple 和 Google 都工作过的人
MATCH (p:Person)-[:WORKED_FOR]->(c1:Company {name: 'Apple'})
WHERE EXISTS {
  MATCH (p)-[:WORKED_FOR]->(c2:Company {name: 'Google'})
}
RETURN p.name

三、SPARQL 查询语言

3.1 SPARQL 基础

SPARQL 是 W3C 标准化的 RDF 图查询语言。它面向的是 RDF(Resource Description Framework)数据模型。

基本查询模式

# 查询所有公司的名称
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX com: <http://example.org/company/>

SELECT ?name ?founded
WHERE {
  ?company rdf:type com:Company .
  ?company com:name ?name .
  ?company com:foundedYear ?founded .
}

SPARQL 的优势
- 联邦查询:可以查询多个异构数据源
- 标准化的推理能力:支持 RDFS 和 OWL 推理
- 广泛的语义网生态支持

3.2 Cypher vs SPARQL 选型

维度 Cypher SPARQL
所属生态系统 Neo4j(属性图) RDF/语义网
查询语法 ASCII art 图模式,直观 Triple pattern,学术风格
多跳查询 自然优雅 需要较长语法
联邦查询 不支持原生 原生支持
推理支持 有限 原生支持(OWL/RDFS)
主流应用场景 企业知识图谱、推荐系统 开放数据、Linked Data

四、将图查询注入 RAG

4.1 架构设计

将知识图谱查询集成到 RAG 管道中,需要以下步骤:

用户问题
    ↓
1. 问题解析:判断是否需要图查询
    ↓(如果需要)
2. 自然语言到图查询转换
    ↓
3. 执行图查询
    ↓
4. 结果格式化
    ↓
5. 注入 LLM 上下文 → 生成回答

4.2 自然语言到 Cypher 转换

利用 LLM 将自然语言问题转换为图查询语句:

def nl_to_cypher(user_question, schema_context):
    '''
    使用 LLM 将自然语言转换为 Cypher 查询
    '''
    prompt = f'''
    知识图谱的 Schema 如下:

    节点类型:Company(id, name, industry, founded_year)
    节点类型:Person(id, name, birth_year)
    节点类型:Product(id, name, category, price)

    关系类型:CEO (Person → Company)
    关系类型:PRODUCES (Company → Product)
    关系类型:COMPETES_WITH (Company → Company)
    关系类型:WORKED_FOR (Person → Company)

    请将以下问题转换为 Cypher 查询语句:

    问题:{user_question}

    只返回 Cypher 查询语句。
    '''
    response = llm.generate(prompt)
    return response.strip()

4.3 结果注入

图查询返回的结构化结果需要转换为一段自然语言文本,再拼入提示词上下文:

def format_kg_result(result_rows):
    '''将图查询结果格式化为自然语言'''
    if not result_rows:
        return "知识图谱中没有找到相关信息。"

    formatted = "以下是从知识图谱中检索到的相关信息:
"
    for row in result_rows[:10]:  # 限制最多 10 条
        formatted += f"- {row}
"

    return formatted

4.4 检索策略

单跳检索:直接查询与问题相关的实体和关系。适用于简单事实查询。

多跳检索:沿关系路径进行 2-3 跳的遍历。适用于需要推理的复杂问题。

子图提取:以中心实体为核心,提取其邻域子图。适用于需要全面了解某个实体的场景。

// 子图提取:获取苹果公司的完整信息
MATCH (c:Company {name: 'Apple'})
OPTIONAL MATCH (c)-[r1]-(related)
OPTIONAL MATCH (related)-[r2]-(further)
WHERE c IS NOT NULL
RETURN c, r1, related, r2, further
LIMIT 100

五、实际案例:企业知识图谱问答

class KGRAGQASystem:
    '''融合知识图谱的 RAG 问答系统'''

    def __init__(self, neo4j_client, llm_client):
        self.kg = neo4j_client
        self.llm = llm_client

    def answer(self, question):
        # 1. 判断是否需要图查询
        needs_kg = self._classify_question(question)

        if needs_kg:
            # 2. 生成图查询
            cypher = self._generate_cypher(question)

            # 3. 执行查询
            results = self.kg.run(cypher)

            # 4. 格式化结果
            kg_context = self._format_results(results)
        else:
            kg_context = ""

        # 5. 生成最终答案
        response = self._generate_answer(question, kg_context)
        return response

    def _classify_question(self, question):
        prompt = f"判断以下问题是否需要查询知识图谱:{question}。返回 YES 或 NO。"
        result = self.llm.generate(prompt)
        return "YES" in result

六、总结

Cypher 和 SPARQL 是两种主流的图查询语言。Cypher 语法直观,适合用 ASCII art 风格表达图模式,是企业知识图谱的首选。SPARQL 是 W3C 标准,适合开放数据和联邦查询场景。将图查询注入 RAG 管道包括问题解析、查询生成、结果格式化和上下文注入四个步骤,需要根据实际场景选择合适的检索策略。

七、图查询与向量检索的混合策略

在现代 RAG 系统中,纯图查询还不够。最佳实践是混合检索策略:

7.1 三种检索方式的互补

检索方式 优势 劣势 适用场景
图查询 精确、结构化、可解释 需要精确匹配 事实性问答
向量检索 语义理解、模糊匹配 结果不精确 语义搜索
关键词检索 精确匹配、高召回 无语义理解 术语搜索

7.2 混合检索的实现

def hybrid_retrieve(question, graph_db, vector_db, keyword_index):
    # 1. 图查询获取精确事实
    graph_results = graph_db.query(nl_to_cypher(question))

    # 2. 向量检索获取语义相似内容
    vector_results = vector_db.similarity_search(question)

    # 3. 关键词检索获取精确匹配
    keyword_results = keyword_index.search(question)

    # 4. 融合排序
    return fuse_results([graph_results, vector_results, keyword_results])

八、总结

图查询语言是连接自然语言和图数据库的桥梁。

关键要点回顾:
- Cypher 语法直观易学,适合 Neo4j 属性图
- SPARQL 是 W3C 标准,支持联邦查询
- 图查询注入 RAG 需经五步流程
- 多跳检索是知识图谱在 RAG 中的独特优势
- 混合检索策略(图+向量+关键词)效果最佳

七、图查询与向量检索的混合策略

在现代 RAG 系统中,纯图查询还不够。最佳实践是混合检索策略:

7.1 三种检索方式的互补

检索方式 优势 劣势 适用场景
图查询 精确、结构化、可解释 需要精确匹配 事实性问答
向量检索 语义理解、模糊匹配 结果不精确 语义搜索
关键词检索 精确匹配、高召回 无语义理解 术语搜索

7.2 混合检索的实现

def hybrid_retrieve(question, graph_db, vector_db, keyword_index):
    # 1. 图查询获取精确事实
    graph_results = graph_db.query(nl_to_cypher(question))

    # 2. 向量检索获取语义相似内容
    vector_results = vector_db.similarity_search(question)

    # 3. 关键词检索获取精确匹配
    keyword_results = keyword_index.search(question)

    # 4. 融合排序
    return fuse_results([graph_results, vector_results, keyword_results])

八、总结

图查询语言是连接自然语言和图数据库的桥梁。

关键要点回顾:
- Cypher 语法直观易学,适合 Neo4j 属性图
- SPARQL 是 W3C 标准,支持联邦查询
- 图查询注入 RAG 需经五步流程
- 多跳检索是知识图谱在 RAG 中的独特优势
- 混合检索策略(图+向量+关键词)效果最佳

七、图查询与向量检索的混合策略

在现代 RAG 系统中,纯图查询还不够。最佳实践是混合检索策略:

7.1 三种检索方式的互补

检索方式 优势 劣势 适用场景
图查询 精确、结构化、可解释 需要精确匹配 事实性问答
向量检索 语义理解、模糊匹配 结果不精确 语义搜索
关键词检索 精确匹配、高召回 无语义理解 术语搜索

7.2 混合检索的实现

def hybrid_retrieve(question, graph_db, vector_db, keyword_index):
    # 1. 图查询获取精确事实
    graph_results = graph_db.query(nl_to_cypher(question))

    # 2. 向量检索获取语义相似内容
    vector_results = vector_db.similarity_search(question)

    # 3. 关键词检索获取精确匹配
    keyword_results = keyword_index.search(question)

    # 4. 融合排序
    return fuse_results([graph_results, vector_results, keyword_results])

八、总结

图查询语言是连接自然语言和图数据库的桥梁。

关键要点回顾:
- Cypher 语法直观易学,适合 Neo4j 属性图
- SPARQL 是 W3C 标准,支持联邦查询
- 图查询注入 RAG 需经五步流程
- 多跳检索是知识图谱在 RAG 中的独特优势
- 混合检索策略(图+向量+关键词)效果最佳

延伸阅读