1. 项目概述:KAG与RAG技术路线对比
在当今信息爆炸的时代,如何从海量文本中快速准确地检索出所需信息,成为了自然语言处理领域的重要课题。知识图谱增强生成(KAG)和检索增强生成(RAG)作为两种主流的技术路线,各有其独特的优势和应用场景。本文将以《三国演义》这一经典文本为例,深入剖析这两种技术的实现细节和性能差异。
KAG(Knowledge-Augmented Generation)技术路线通过构建结构化的知识图谱,将文本中的实体、关系等信息抽取出来,形成语义网络。这种方式的优势在于能够捕捉文本中明确的实体关系和事件脉络。例如,在《三国演义》中,"关羽温酒斩华雄"这一事件可以清晰地表示为"关羽"与"华雄"两个人物实体之间的"斩杀"关系,并关联到具体的章回节点。
相比之下,RAG(Retrieval-Augmented Generation)则采用向量化的方式,将文本分割成片段后转换为高维向量,通过计算向量间的相似度来检索相关内容。这种方法更擅长捕捉语义层面的相似性,对于模糊查询或语义相近但表述不同的内容有更好的召回效果。
提示:在实际项目中,选择KAG还是RAG需要考虑多个因素,包括文本特性、查询类型、系统资源等。结构化程度高的文本更适合KAG,而语义复杂的文本可能更适合RAG。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 系统架构与核心模块设计
2.1 整体架构设计
本项目的系统架构采用了模块化设计,主要分为数据处理层、存储层和检索层三个部分。数据处理层负责原始文本的预处理和特征提取;存储层包含向量数据库(Qdrant)和图数据库(Neo4j)两种存储方案;检索层则实现了基于不同技术的查询接口。
这种分层设计使得系统具有良好的扩展性,可以方便地添加新的数据处理模块或替换存储后端。例如,如果需要支持新的文本类型,只需在数据处理层增加相应的预处理模块,而不需要改动其他部分的代码。
2.2 核心模块功能分解
2.2.1 向量处理管线
向量处理管线是RAG技术的核心,主要包括以下几个关键步骤:
-
文本分割:采用滑动窗口算法,将《三国演义》文本分割成适当大小的片段。窗口大小和重叠率的设置直接影响后续检索效果。经过多次实验,我们发现设置窗口大小为512字符,重叠率为128字符时,能在保持语义完整性和检索精度之间取得较好平衡。
-
向量化处理:使用BGE(Bidirectional Encoder)模型将文本片段转换为768维的向量表示。这一步骤需要注意向量归一化处理,确保不同片段向量的尺度一致,避免影响相似度计算。
-
向量入库:将生成的向量及其元数据(包括原文、章节信息等)存储到Qdrant向量数据库中。这里需要特别注意批量插入时的性能优化和错误处理机制。
2.2.2 知识图谱处理管线
知识图谱处理管线更为复杂,涉及多个处理阶段:
-
实体关系抽取:使用LLM大语言模型从文本中识别实体(人物、地点、事件等)及其关系。这一步骤的准确性直接影响后续图谱质量。我们设计了专门的提示词模板,引导模型输出结构化的JSON结果。
-
图谱构建:将抽取结果导入Neo4j图数据库,建立节点和关系。除了显式抽取的关系外,我们还补充了"APPEARS_IN"等基础关系,将实体与出现的章回关联起来。
-
图谱校验:通过Schema探查和样本检查确保图谱结构的完整性和一致性。这一步骤常常能发现实体类型不一致或关系缺失等问题。
3. 数据准备与处理流程
3.1 原始数据预处理
《三国演义》文本需要经过仔细的预处理才能用于后续分析。我们首先对原始文本进行了以下处理:
-
章节分割:根据回目格式"第X回 XXX"将文本分割成独立的章回。这一步骤使用正则表达式实现,确保分割准确。
-
文本清洗:去除各种版本的异体字、标点符号不一致等问题,统一文本格式。特别是注意处理全角/半角字符和繁简转换问题。
-
基础标注:为每个章回添加元数据,包括回目编号、标题等。这些元数据将作为后续处理的上下文信息。
3.2 RAG数据准备流程
RAG路线的数据准备着重于文本分割和向量化:
-
滑动窗口分割:在章回内部,采用滑动窗口算法进行二次分割。经过测试,我们发现包含3-5个完整句子的片段效果最佳。
-
片段标注:为每个文本片段添加丰富的元数据,包括:
- 所属章回标题和编号
- 在原文中的位置信息
- 包含的关键实体(可选)
-
向量化配置:选择适合古汉语文本的嵌入模型,并调整参数。我们发现BGE模型在保持古汉语语义方面表现优异。
3.3 KAG数据准备流程
KAG路线的数据准备更为复杂,涉及知识抽取和图谱构建:
-
实体关系抽取:使用LLM模型分阶段抽取:
- 第一阶段:识别文本中的命名实体(人物、地点、组织等)
- 第二阶段:识别实体间的关系
- 第三阶段:关联实体事件与具体章回
-
结果后处理:对LLM输出进行标准化处理:
- 统一实体别名(如"关羽"和"关云长")
- 规范化关系类型(如将"杀死"、"斩杀"统一为"击杀")
- 补充必要属性(如事件的时间、地点等)
-
图谱模式设计:设计合理的节点类型和关系类型,确保图谱具有良好的可查询性和扩展性。我们的设计包括:
- 节点类型:Character(人物)、Location(地点)、Event(事件)、Chapter(章回)
- 关系类型:APPEARS_IN(出现在)、RELATED_TO(相关)、PART_OF(属于)等
4. 存储方案实现细节
4.1 向量存储方案(Qdrant)
Qdrant作为高性能向量数据库,在本项目中承担RAG路线的存储任务。我们在实现中注意了以下关键点:
-
集合配置:根据文本特点优化集合参数:
- 向量维度:768维(匹配BGE模型输出)
- 距离度量:余弦相似度(更适合语义检索)
- 分片配置:根据数据量合理设置分片数
-
数据建模:设计高效的payload结构,包含:
json复制{ "text": "片段内容", "chapter_title": "章回标题", "chapter_index": 5, "entity_list": ["关羽", "华雄"] } -
性能优化:实现批量插入与错误重试机制,处理网络不稳定等情况。我们实现了指数退避的重试策略,确保数据完整入库。
4.2 图谱存储方案(Neo4j)
Neo4j图数据库存储结构化知识图谱,我们在实现中解决了以下关键问题:
-
数据模型设计:采用属性图模型,精心设计:
- 节点标签体系:区分不同类型实体
- 属性设置:平衡查询效率与存储空间
- 关系类型:明确语义,避免歧义
-
索引策略:为常用查询字段创建索引:
cypher复制CREATE INDEX FOR (c:Character) ON (c.name); CREATE INDEX FOR (e:Event) ON (e.name); CREATE INDEX FOR (ch:Chapter) ON (ch.title); -
导入优化:采用批量事务处理,控制事务大小在100-200个操作之间,避免内存溢出同时保持较好性能。
-
数据一致性:实现校验脚本,定期检查:
- 孤立节点(无任何关系的节点)
- 关系完整性(起始和结束节点存在)
- 属性完整性(必需属性不为空)
5. 检索系统实现与评测
5.1 统一评测集设计
为确保公平比较,我们设计了统一的评测集sanguo-eval-unified.json,包含多种类型的问题:
- 章回定位类:"关羽温酒斩华雄出自哪一回?"
- 人物关系类:"诸葛亮和司马懿是什么关系?"
- 事件查询类:"赤壁之战的主要参与者有哪些?"
- 综合问答类:"刘备三顾茅庐时带了哪些人?"
每个问题都配有标准答案和可接受的变体形式,支持灵活的匹配规则。评测集的设计考虑了问题类型的分布和难度平衡。
5.2 RAG检索实现
RAG检索流程包括以下关键步骤:
- 查询向量化:使用与文档相同的嵌入模型将查询转换为向量。
- 相似度检索:在Qdrant中搜索TopK最相似的文档片段。
- 结果重排序:根据元数据信息(如章节重要性、实体匹配度)对结果进行精排。
- 答案生成:提取最相关片段或组合多个片段生成最终答案。
我们特别优化了以下方面:
- 查询预处理:对问题进行实体识别和关键词提取,辅助检索
- 混合检索:结合稠密向量检索和稀疏关键词匹配
- 结果过滤:基于元数据(如章节范围)过滤不相关结果
5.3 KAG检索实现
KAG检索流程更为复杂,涉及LLM的多步处理:
-
查询分析:使用LLM解析查询意图,识别:
- 目标实体
- 查询类型(属性查询、关系查询等)
- 相关约束条件
-
Cypher生成:基于分析结果,生成查询图谱的Cypher语句。为提高准确性,我们实现了:
- Schema感知:利用数据库Schema信息指导查询生成
- 模板填充:对常见查询类型使用参数化模板
- 多轮验证:执行前进行语法和逻辑验证
-
查询执行:在Neo4j中执行Cypher查询,获取结果。
-
结果后处理:对查询结果进行排序、截断和格式化,生成最终答案。
5.4 评测指标与结果分析
我们采用以下指标评估系统性能:
- Recall@K:在前K个结果中能够找到正确答案的概率。
- MRR(平均倒数排名):衡量正确答案排名的指标。
- 响应时间:系统处理查询的平均时间。
评测结果显示:
- RAG在Recall@5上达到约0.8,表现优异
- KAG的Recall@5约为0.4-0.6,仍有提升空间
- 响应时间方面,RAG通常更快(平均200-300ms),而KAG需要500-800ms
深入分析发现:
-
RAG优势场景:
- 关键词明确的查询("温酒斩华雄")
- 语义相似但表述不同的查询("关羽斩华雄的情节")
-
KAG优势场景:
- 结构化查询("赤壁之战中曹操的损失")
- 关系推理("刘备和孙权的关系变化")
6. 工程实践与问题解决
6.1 常见问题与解决方案
在项目实施过程中,我们遇到了各种技术挑战,以下是典型问题及解决方案:
-
向量不一致问题:
- 现象:相同的文本在不同时间生成的向量略有差异
- 原因:模型推理时的随机性及浮点精度问题
- 解决:固定随机种子,统一使用Float32精度
-
图谱抽取不完整:
- 现象:LLM遗漏重要实体或关系
- 原因:提示词设计不够明确,上下文窗口有限
- 解决:优化提示词,分阶段抽取,增加后处理校验
-
Cypher生成错误:
- 现象:生成的查询语法错误或逻辑不合理
- 原因:LLM对Schema理解不足
- 解决:实现Schema探查和查询验证机制
6.2 性能优化实践
为确保系统高效运行,我们实施了多项优化措施:
-
向量检索优化:
- 实现查询缓存,避免重复计算
- 采用近似最近邻搜索(ANN)提高效率
- 优化payload结构,减少网络传输量
-
图谱查询优化:
- 为常用查询模式创建预计算视图
- 优化Cypher语句,避免全图扫描
- 实现查询计划分析工具,识别性能瓶颈
-
资源管理:
- 限制并发查询数量
- 实现负载均衡机制
- 监控系统资源使用情况
6.3 可复现性保障
为确保实验结果可复现,我们建立了完整的工程规范:
-
版本控制:
- 代码、配置和数据版本严格对应
- 使用Git子模块管理依赖项
-
环境管理:
- 容器化部署(Docker)
- 详细的依赖项说明文件
-
实验记录:
- 完整的实验参数记录
- 结果数据的版本管理
- 可视化报表自动生成
7. 可视化分析与报告生成
7.1 报表系统设计
我们开发了专门的评测报告系统,主要功能包括:
- 数据聚合:收集RAG和KAG的评测结果
- 指标计算:自动计算Recall、MRR等指标
- 可视化展示:生成直观的图表和对比分析
- 问题诊断:标记常见错误模式
报表系统采用Python实现,主要依赖Pandas进行数据处理,Matplotlib和Plotly进行可视化。
7.2 关键可视化图表
- 召回率对比图:直观展示RAG和KAG在不同问题类型上的表现差异。
- 排名分布图:显示正确答案在结果列表中的排名分布情况。
- 响应时间分布:比较两种技术的查询响应时间。
- 错误模式分析:统计常见错误类型及其占比。
这些可视化结果帮助我们快速识别系统弱点,指导优化方向。
7.3 报表使用实践
生成的HTML报表支持以下实用功能:
- 结果筛选:按问题类型、难度等条件过滤
- 详情查看:点击单个问题查看完整处理流程
- 差异对比:并排显示RAG和KAG的处理结果
- 导出分享:支持PDF和图片格式导出
报表系统的使用命令如下:
bash复制python scripts/eval_report.py \
--rag doc/eval/report/rag-recall.jsonl \
--kag doc/eval/report/kag-recall.jsonl \
--out doc/eval/report/report.html
8. 进阶优化与未来方向
8.1 混合检索策略
基于当前实验结果,我们探索了RAG和KAG的混合使用方案:
- 并行检索:同时使用两种技术检索,然后融合结果
- 级联检索:先用KAG缩小范围,再用RAG精排
- 加权融合:根据查询类型动态调整两种技术的权重
初步测试显示,混合策略可以结合两者优势,Recall@5提升约10-15%。
8.2 查询理解增强
我们正在开发更强大的查询理解模块:
- 意图识别:精确判断查询类型(事实型、推理型等)
- 实体链接:将查询中的提及链接到知识图谱中的实体
- 约束提取:识别查询中的显式和隐式约束条件
这将显著提高Cypher生成的准确性和检索精度。
8.3 自优化机制
为实现系统的持续改进,我们设计了以下自优化机制:
- 反馈学习:记录用户对结果的反馈,用于优化检索策略
- 自动扩充:识别高频未命中查询,自动补充相关知识
- 参数调优:基于评测结果自动调整算法参数
这些机制将使系统能够不断适应新的查询模式和用户需求。
8.4 扩展应用场景
当前系统主要针对《三国演义》文本,但架构设计考虑了通用性,可扩展至:
- 其他文学名著:如《红楼梦》《水浒传》等
- 专业文档:技术文档、法律条文等结构化文本
- 多模态数据:结合文本、图像、表格等多种信息
每种扩展场景都需要针对性地调整数据处理和检索策略。
