知识图谱查询与 RAG
课程简介
用 Cypher/SPARQL 查询图谱,将图谱结果注入 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 中的独特优势
- 混合检索策略(图+向量+关键词)效果最佳
延伸阅读
- 📺 B 站播放列表:Knowledge Graphs for RAG — 知识图谱增强检索
- 📚 更多学习资源,请访问 deeplearning.ai 官网