
RAG vs KAG:两种检索引擎的对比与融合

在企业级 RAG 系统中,检索引擎的选择直接影响最终的生成质量。
RAG 引擎基于文档内容的向量化分块,通过 Embedding 向量相似度 + BM25 混合检索实现语义匹配。
KAG 引擎基于知识图谱的 Neo4j 实体关系,通过 LLM 实体识别 → Neo4j 多跳遍历实现结构化推理。
两者各有优劣:RAG 擅长语义匹配和理解用户意图,KAG 擅长结构化推理和发现隐含关联。
最佳实践是通过 RRF(Reciprocal Rank Fusion)加权融合,权重可调,实现互补优势。
核心对比
数据来源
RAG 引擎:文档内容(向量化分块)
- 将文档切分成小块(chunk)
- 每个chunk 通过 Embedding 模型转换为向量
- 向量存储在向量数据库中(如 Pinecone、Milvus、Weaviate)
- 检索时通过向量相似度找到最相关的文档块
KAG 引擎:知识图谱(Neo4j 实体关系)
- 将非结构化文本转化为结构化知识图谱
- 实体(Entity)和关系(Relation)存储在图数据库中(如 Neo4j)
- 通过 LLM 识别用户查询中的实体
- 在知识图谱中进行多跳遍历,找到相关联的实体和关系
检索方式
RAG 引擎:Embedding 向量相似度 + BM25 混合检索
用户查询 → Embedding 模型 → 查询向量
↓
向量相似度计算(Cosine Similarity)
↓
Top-K 相关文档块特点:
- 语义匹配 — 理解用户意图,即使查询词不匹配也能找到相关内容
- BM25 强化 — 结合关键词匹配,提升精确匹配的召回率
- 快速检索 — 向量索引支持大规模文档的毫秒级检索
KAG 引擎:LLM 实体识别 → Neo4j 多跳遍历
用户查询 → LLM 实体识别 → 提取关键实体
↓
Neo4j 图遍历(多跳查询)
↓
相关实体 + 关系路径特点:
- 结构化推理 — 通过图遍历发现实体之间的隐含关联
- 多跳查询 — 支持复杂的关系推理(如「A的朋友的同事」)
- 可解释性 — 返回的结果包含推理路径,易于理解和验证
核心优势
RAG 引擎:语义匹配,理解用户意图
优势:
语义理解 — 即使查询词与文档词不匹配,也能通过语义相似度找到相关内容
- 例如:查询「如何提升团队效率」可以找到「提高生产力的方法」
灵活性 — 适用于各种类型的非结构化文本(PDF、Word、网页等)
- 不需要预先定义实体和关系
快速部署 — 文档向量化流程成熟,支持大规模文档库
- 向量数据库性能优秀,支持毫秒级检索
用户友好 — 支持自然语言查询,用户无需了解底层数据结构
- 例如:「我们公司的离职率为什么这么高?」也能找到相关文档
劣势:
缺乏结构化推理 — 无法发现实体之间的隐含关联
- 例如:无法自动发现「A公司的CEO是B,B同时也是C公司的董事」
召回偏差 — 向量检索可能召回语义相似但实际不相关的内容
- 例如:查询「苹果手机」可能召回「水果苹果」的内容
黑盒检索 — 检索结果缺乏可解释性,用户难以理解为什么召回这些内容
- 无法提供推理路径
KAG 引擎:结构化推理,发现隐含关联
优势:
结构化推理 — 通过图遍历发现实体之间的隐含关联
- 例如:查询「马斯克的公司」可以找到 Tesla、SpaceX、X(Twitter)等
多跳查询 — 支持复杂的关系推理
- 例如:「马斯克的公司的竞争对手」可以通过多跳遍历找到
高精度 — 基于实体和关系的精确匹配,召回率更高
- 减少语义相似但实际不相关的召回
可解释性 — 返回的结果包含推理路径,易于理解和验证
- 用户可以看到「如何从A找到B」的完整路径
劣势:
构建成本高 — 需要将非结构化文本转化为知识图谱
- 需要定义本体(Ontology)、实体识别、关系抽取等
灵活性差 — 只能查询已定义的实体和关系
- 无法处理未在知识图谱中的实体
维护成本高 — 知识图谱需要持续更新和维护
- 新增文档需要重新进行实体识别和关系抽取
查询复杂度高 — 用户需要了解知识图谱的结构
- 自然语言查询需要经过 LLM 实体识别,可能识别错误
适用场景
RAG 引擎适用场景:
- 通用文档问答 — 企业知识库、技术文档、合同审查等
- 开放域问答 — 新闻资讯、学术论文、行业报告等
- 快速原型验证 — 需要快速搭建 RAG 系统的场景
- 大规模文档库 — 需要处理海量非结构化文本的场景
KAG 引擎适用场景:
- 结构化数据查询 — 企业组织架构、供应链关系、股权穿透等
- 复杂关系推理 — 金融风控、供应链追溯、社交网络分析等
- 高精度问答 — 需要精确匹配实体和关系的场景
- 可解释性要求高 — 需要提供推理路径和溯源的场景
融合策略:RRF 加权融合
RRF(Reciprocal Rank Fusion)原理
RRF 是一种简单但有效的融合方法,用于合并多个检索系统的排序结果。
公式:
RRF_score(d) = Σ (k / (k + rank_i(d)))其中:
d是文档rank_i(d)是文档d在第i个检索系统中的排名k是平滑参数(通常取 60)
特点:
- 简单高效 — 只需要排序结果,不需要评分归一化
- 鲁棒性强 — 对单个检索系统的偏差不敏感
- 可调权重 — 可以为不同检索系统设置权重
RAG + KAG 融合架构
融合策略:
用户查询
↓
┌─────────────────────────────────────┐
│ RAG 引擎 KAG 引擎 │
│ ↓ ↓ │
│ 文档块 实体-关系 │
│ ↓ ↓ │
│ 向量相似度 Neo4j 遍历 │
│ ↓ ↓ │
│ Top-K 文档块 Top-K 实体路径 │
└─────────────────────────────────────┘
↓
RRF 加权融合(权重可调)
↓
融合后的 Top-K 结果
↓
LLM 生成回答实现示例(伪代码):
def rrf_fusion(rag_results, kag_results, rag_weight=1.0, kag_weight=1.0, k=60):"
"""
RRF 加权融合
Args:
rag_results: RAG 引擎的检索结果(已排序)
kag_results: KAG 引擎的检索结果(已排序)
rag_weight: RAG 引擎的权重
kag_weight: KAG 引擎的权重
k: RRF 平滑参数
Returns:
融合后的排序结果
"""
scores = {}
# 计算 RAG 引擎的分数
for rank, doc in enumerate(rag_results, start=1):
doc_id = doc['id']
scores[doc_id] = rag_weight * (k / (k + rank))
# 计算 KAG 引擎的分数
for rank, entity in enumerate(kag_results, start=1):
entity_id = entity['id']
if entity_id in scores:
scores[entity_id] += kag_weight * (k / (k + rank))
else:
scores[entity_id] = kag_weight * (k / (k + rank))
# 按分数排序
sorted_results = sorted(scores.items(), key=lambda x: x[1], reverse=True)
return sorted_results权重调优策略
权重调整原则:
RAG 权重 > KAG 权重(适用于通用文档问答)
- 例如:
rag_weight=0.7, kag_weight=0.3 - 场景:企业知识库、技术文档、合同审查
- 例如:
KAG 权重 > RAG 权重(适用于结构化数据查询)
- 例如:
rag_weight=0.3, kag_weight=0.7 - 场景:企业组织架构、供应链关系、股权穿透
- 例如:
RAG 权重 = KAG 权重(适用于混合场景)
- 例如:
rag_weight=0.5, kag_weight=0.5 - 场景:需要同时考虑文档内容和知识图谱的场景
- 例如:
动态权重调整:
根据查询类型动态调整权重:
def dynamic_weight_adjustment(query):
"""
根据查询类型动态调整权重
Args:
query: 用户查询
Returns:
(rag_weight, kag_weight)
"""
# 检测查询类型
if contains_entity_relation(query):
# 包含实体关系查询,增加 KAG 权重
return 0.3, 0.7
elif contains_general_question(query):
# 通用问题,增加 RAG 权重
return 0.7, 0.3
else:
# 默认均衡权重
return 0.5, 0.5
def contains_entity_relation(query):
"""检测查询是否包含实体关系"""
# 使用 LLM 识别查询中的实体和关系
# 如果识别到明确的实体和关系,返回 True
pass
def contains_general_question(query):
"""检测是否是通用问题"""
# 如果查询是开放性问题,返回 True
pass核心对比总结
| 维度 | RAG 引擎 | KAG 引擎 |
|---|---|---|
| 数据来源 | 文档内容(向量化分块) | 知识图谱(Neo4j 实体关系) |
| 检索方式 | Embedding 向量相似度 + BM25 | LLM 实体识别 → Neo4j 多跳遍历 |
| 核心优势 | 语义匹配,理解用户意图 | 结构化推理,发现隐含关联 |
| 适用场景 | 通用文档问答、开放域问答 | 结构化数据查询、复杂关系推理 |
| 部署成本 | 低(文档向量化流程成熟) | 高(需要构建知识图谱) |
| 维护成本 | 低(新增文档自动向量化) | 高(需要持续更新知识图谱) |
| 查询灵活性 | 高(支持自然语言查询) | 低(只能查询已定义的实体关系) |
| 召回精度 | 中(语义相似但可能不相关) | 高(精确匹配实体关系) |
| 可解释性 | 低(黑盒检索) | 高(包含推理路径) |
| 检索速度 | 快(毫秒级) | 中(图遍历较慢) |
最佳实践
1. 根据场景选择引擎
场景 1:企业知识库(通用文档问答)
- 推荐:RAG 引擎
- 原因:文档类型多样,不需要复杂关系推理
- 实施:文档向量化 + 向量数据库
场景 2:企业组织架构(结构化数据查询)
- 推荐:KAG 引擎
- 原因:需要查询员工、部门、汇报关系等结构化信息
- 实施:构建组织架构知识图谱 + Neo4j
场景 3:供应链追溯(复杂关系推理)
- 推荐:KAG 引擎
- 原因:需要多跳遍历供应商、零部件、产品等关系
- 实施:构建供应链知识图谱 + Neo4j
场景 4:混合场景(文档 + 知识图谱)
- 推荐:RAG + KAG 融合
- 原因:需要同时考虑文档内容和知识图谱
- 实施:RRF 加权融合
2. 权重调优建议
初始权重: rag_weight=0.5, kag_weight=0.5
根据反馈调优:
- 如果用户反馈召回内容不相关 → 增加 KAG 权重
- 如果用户反馈召回内容不全面 → 增加 RAG 权重
- 如果用户反馈召回速度太慢 → 增加 RAG 权重(RAG 检索更快)
3. 监控指标
关键指标:
- 召回率(Recall) — 检索到的相关文档占所有相关文档的比例
- 精确率(Precision) — 检索到的文档中相关文档的比例
- NDCG(Normalized Discounted Cumulative Gain) — 排序质量的评估指标
- 检索延迟(Latency) — 检索响应时间
- 用户满意度 — 用户对检索结果的反馈
关键洞察
- RAG 和 KAG 各有优劣,没有绝对的优劣之分
收尾金句:
- RAG 擅长语义匹配和理解用户意图
- KAG 擅长结构化推理和发现隐含关联
- 最佳实践是通过 RRF 加权融合,权重可调
- 根据场景选择引擎,根据反馈调优权重
- 融合策略可以实现互补优势,提升检索质量
RAG vs KAG
两种检索引擎的对比与融合
