懒懒笔记 | 课代表带你梳理【RAG课程 19:基于知识图谱的RAG】
大家好呀!这里是你们的课代表懒懒~不知不觉,我们已经来到课程的最后一节,为我们的坚持和努力点赞!
通过之前的学习,我们已经学会了如何使用RAG增强大模型的能力。有细心的小伙伴发现,传统的RAG在召回上存在碎片化的局限。为了解决传统RAG存在的问题,知识图谱RAG应运而生,本节课就让懒懒带大家回顾如何搭建知识图谱RAG吧!
知识图谱RAG,超越朴素RAG!
朴素RAG:😔
- 检索返回的内容孤立、缺乏结构关联。
- 回答在需要跨文档、跨段落推理的场景中,召回片段之间缺乏逻辑和语义连贯性。
- 无法识别文档间的主题关系,信息冗余与漏召。
知识图谱RAG:😊
- 实体-关系-属性的三元组形式显式建模语义关联,使系统能够清晰刻画知识之间的语义路径。
- 在图谱上进行结构感知的检索或路径遍历,更有针对性地召回与用户问题语义相关、逻辑连贯的信息。
- 跨文档实体的对齐与融合,增强主题聚合与复杂推理能力。
知识图谱:让机器理解世界的“知识网络”
一切从图说起🔥
(图(Graph)结构)
图是一种由一组节点(或称为顶点)和节点之间的边组成的数据结构,例如图1 可以表示地铁路线图,每个顶点表示一个站点,每个边表示站点之间的连通性。
知识图谱(Knowledge Graph, KG)是一种用 “图” 结构表示知识的方式,通常由三元组组成,其中每个三元组包含一个实体、关系以及与该实体相关的另一个实体,结构形式为 (实体1)—[关系]→(实体2)。
(知识图谱示例(图源网络))
知识图谱有三个重要组成部分,即实体,关系和属性,每个部分的解释如下:
- 实体(Entity):知识图谱的基本构成单位,代表现实世界中的物品、概念、事件等。例如图2中的每个人物、城市、课程都是实体。🤔
- 关系(Relationship):描述实体间联系的方式,通常用边来表示。比如图2中男士与Bonn的关系是“lives in”,表示这位男士生活在Bonn City。🤔
- 属性(Attribute):实体或关系的附加信息。例如图2中Bonn City有“Type”,“Population”和“Area”三个属性。🤔
从文档中构建知识图谱
拆解流程🔥
RAG系统的“智能外挂”:知识图谱如何赋能RAG?
构建知识图谱
要构建基于知识图谱的RAG系统,就像是在搭建一座“知识摩天楼”。
现成的结构化数据(比如数据库、RDF、Neo4j)就像预制好的砖块,拆开就能直接用,省时又省力。
而非结构化数据(比如那些长篇大论的文字)嘛,就像一堆散落的乐高零件,需要你仔细翻找,才能拼出点有用的东西,比如人名、地名、日期,以及它们之间的“小八卦”(比如“谁创办了什么”“谁住在哪儿”)。
怎么处理这些“碎片”呢?
可以采用传统的信息抽取方法,主要分两步:
- NER(命名实体识别):像一位“考古专家”,负责从文本中挖掘出关键的实体,例如人物、组织、地点等;
- 关系抽取:这位专家则专注于搞清楚实体之间的“人际关系”,比如“张三是某公司的创始人”。
当然,还有另一种更“现代”的做法——直接派出大型语言模型(LLM)这个“全能大工匠”。它能在一句话中同时识别实体、提取关系,甚至顺带润色输出,效率极高。
所以,搭建知识图谱就是这么一件“从零件到艺术品”的事情,有了这些工具,轻松又有趣!
图3 利用大模型构建知识图谱流程
处理文本构建知识图谱就像拆书搭积木,步骤如下:
- 文本分块:先把长文本切成小块,方便操作,这步和普通RAG的“切片”手法一样。
- 提取图元素:用LLM发“指令”从每块文本里找出关键积木:
- 第一步:找实体(例如名字、类型、描述),就像从一堆零件里挑出有用的砖块。
- 第二步:找关系(谁和谁有啥联系,比如“合作”“位于”),把砖块之间的连接线画出来。
- 合并实体和关系:最后,把不同文本块中重复的积木合并,拼成一个完整、连贯的知识图谱!
简单来说,就是“切片-找积木-拼完整”,过程清晰又高效!😮
使用知识图谱召回
其流程如图所示:
(Knowledge Graph Based RAG 流程示例)
基于知识图谱的RAG系统回答过程有这样几个步骤!😮
- 检索阶段,根据用户输入问题从知识图谱中召回相关的实体、关系以及原文内容。
- 增强阶段,将召回的结构化结果整合为额外的上下文信息,与用户输入一起提供给大模型,以增强其理解和推理能力。
- 生成阶段,系统通过大模型生成答案,该过程与朴素RAG系统一致。
两大知识图谱RAG系统供你挑选
GraphRAG
GraphRAG通过构建知识图谱和分层社区结构,将局部信息聚合为全局理解。
其核心优势在于:
- 利用LLM从文档中提取实体、关系和事实声明构建知识图谱,通过图结构索引捕捉语义关联。
- 通过分层社区检测,使用图社区算法将图谱划分为紧密关联的社区,递归生成从局部到全局的摘要。
- 采用Map-Reduce式回答生成方法,借助社区摘要的并行处理与聚合,生成全面且多样的全局回答。
GraphRAG工作流程
1.将文档拆分为文本块,并使用LLM提取其中的实体、关系及事实声明
2.基于提取结果构建知识图谱,将实体和关系转化为图节点和边,对重复实例进行聚合并生成节点描述,同时根据关系出现频率设定边的权重。
3.利用Leiden算法对图谱进行递归划分,形成嵌套的社区结构,每个社区代表一个语义主题,构建从局部到全局的层级结构。
社区新概念!
微软 GraphRAG 在知识图谱的基础上增加了一个社区(Community)的概念。
社区是 GraphRAG 中的高级结构,表示一组相关实体的集合。每个社区包含以下字段:
ID:社区的唯一标识符。 Level:社区的层级(如 0、1、2 等)。 Entity IDs:社区中包含的实体 ID 列表。 Relation IDs:社区中包含的关系 ID 列表。 Text Block IDs:社区中包含的文本块 ID 列表。 Description:社区的描述信息。 Summary:社区的摘要信息。
GraphRAG 在是构建Knowledge Graph后,增加了一个社区摘要(Community Summaries)的生成环节。这一策略使得系统在检索时只关注与查询高度相关的社区,而不是检索整个图。社区摘要对数据全局结构和语义的高度概括, 即使没有问题, 用户也可以通过浏览不同层次的社区摘要来理解语料库!
社区摘要生成由两步组成:
- 社区检测:使用图分析算法,获得具有高度连接性的实体簇
- 摘要提取:使用LLM根据社区中的实体和关系,提取各类型总结。
(微软 Graph RAG 的社区聚类效果图)
Light RAG
LightRAG的知识图谱是比较基础的 分片+实体/关系
LightRAG 就像一位“轻装上阵”的知识图谱专家,甩掉了复杂的社区聚类,直接构建知识图谱,支持增量更新——新数据只需补充节点和关系,无需重建全图,方便又高效!🧠
它的检索方式也很聪明,采用了双层检索策略:
- 低层级检索:专注细节,锁定具体实体的信息,比如“某人是谁”“某地在哪”。→
- 高层级检索:关注全局,处理宏观主题和趋势,比如“某领域的发展方向”。→
这种设计让 LightRAG 能快速适应动态数据场景,同时保证检索既全面又精准,堪称高效实用的“知识捕手”!
(LightRAG 整体结构(图源 LightRAG 论文))
LightRAG通过以下步骤实现知识图谱的构建与检索:
1.实体和关系抽取:从文档中提取实体和关系(如实体名称、类型、描述等),完成后进行去重操作,然后进行图索引,构建知识图谱。
-
节点属性:包括实体名称、类型、描述、来源文档ID。
-
关系属性:包括起点实体、终点实体、关键词、描述、来源文档ID。
2.关键词提取:
-
具体关键词:关注精确信息(如实体名称、属性),用于底层级检索。
-
抽象关键词:关注宏观主题或领域信息,用于高层级检索。
3.双层级检索:
-
低层级检索:针对具体关键词,查找特定实体及其属性,提供详细信息。
(示例关键词:如“beekeeper”“hive”,获取具体实体的属性和关系。)
-
高层级检索:针对抽象关键词,分析宏观主题、趋势或多个实体间的关系。
(示例关键词:如“agriculture”“production”,提供全局性见解。)
4.动态更新:当有新数据加入时,仅需更新新增的节点和边,无需重建整个知识图谱,降低计算成本。
通过这种设计,LightRAG能够高效处理具体细节和宏观主题问题,为用户提供精准且深度的答案!
LightRAG VS GraphRAG🤦
🌐对于Legal Dataset,共94篇文章,约5000K Token(约5个水浒传大小)。GraphRAG 生成了 1399 个communities,平均每个社区报告生成需要5000Token, 其中 610 个 level-2 communities, 平均每个level-2的社区占用1000Token。下表对比了创建知识图谱和一次检索所消耗的LLM Token。C_Max为API单次请求最多Token限制,T_extract 代表提取实体和关系消耗Token数,C_extract则表示提取产生的API调用次数。🤦
处理阶段 | query-召回 | 文档创建(5000K Token ) | ||
方案 | GraphRAG | LightRAG | GraphRAG | LightRAG |
Token消耗 | 610*1000 | < 100 | 1399*5000 + T_extract | T_extract |
API 调用次数 | 610*1000/C_Max | 1 | 1399 + C_extract | C_extract |
实战演练:知识图谱RAG对复杂query的提升
我们基于LightRAG进行实战,来看看需要的配置吧!
Dataset
-
水浒传_utf8.txt (约912K Tokens)
切分及召回
-
NaiveRAG Chunk 1200 Token; top_k: 10
-
LightRAG Chunk 1200 Token ; relation/entity top_k: 60
使用LightRAG构建知识图谱
Step0️⃣: 环境准备。
🔨vLLM
pip install vllm
🔨LightRAG
pip install lightrag-hku
🔨infinity
pip install infinity-emb
🔨LazyLLM
pip3 install lazyllm lazyllm install full
-
Git clone https://github.com/HKUDS/LightRAG 并安装lightrag pip install "lightrag-hku[api]"
-
下载语料 水浒传.txt 转为 utf8,并重命名放入比如"novel/shuihu.txt"
-
主动创建保存知识图谱的目录
Step1️⃣: 使用VLLM/Ollama等工具部署openai 兼容格式的LLM服务。
⚠️注:由于文章较长,尝试过多个平台的在线模型,即使换不同的语料,依然会有触发“内容安全限制”的情况。所以只能选择本地部署的LLM。
下载模型(Qwen 2.5-32B-Instruct),推荐从ModelScope下载:
注:由于文章较长,尝试过多个平台的在线模型,即使换不同的语料,依然会有触发“内容安全限制”的情况。所以只能选择本地部署的LLM。
下载模型(Qwen 2.5-32B-Instruct),推荐从ModelScope下载:
python -m vllm.entrypoints.openai.api_server --model /mnt/lustre/share_data/lazyllm/models/Qwen2.5-32B-Instruct/ --served-model-name qwen2 --max_model_len 16144 --host 0.0.0.0 --port 12345
Step2️⃣: 部署embedding 服务或使用已有平台的openai兼容格式的embedding在线服务。
下载模型(bge-large-zh-v1.5),推荐从ModelScope下载:
infinity_emb v2 --model-id "/mnt/lustre/share_data/lazyllm/models/bge-large-zh-v1.5" --port 19001 --served-model-name bge-large
Step3️⃣:参照 examples/lightrag_openai_compatible_demo.py 修改LLM服务和embedding服务的配置 配置llm_model_func和embedding_func 的三个参数:model, base_url, api_key。
✅设置处理的文件名和保存知识图谱的文件夹路径
-
WORKING_DIR 为 知识图谱保存的文件夹路径
-
PATH_TO_TXT 为 待解析的小说 <水浒传>,注意检查是否为utf8格式
✅修改llm_model的配置
-
base_url 改为 http://{ip}:{port}/v1
-
model_name 改为 vLLM中配置的 qwen2
✅修改openai_embed的配置
-
base_url 改为 http://{ip}:{port}
-
model_name 改为 infinity中配置的 bge-large
Step4️⃣: 调整examples/lightrag_openai_compatible_demo.py 中的main 函数 设置知识图谱的存储目录WORKING_DIR 和文本文件的路径 PATH_TO_TXT。
async def main(): WORKING_DIR = "****" PATH_TO_TXT = "shuihu.txt" try: embedding_dimension = await get_embedding_dim() print(f"Detected embedding dimension: {embedding_dimension}") rag = LightRAG( working_dir=WORKING_DIR, llm_model_func=llm_model_func, embedding_func=EmbeddingFunc( embedding_dim=embedding_dimension, max_token_size=8192, func=embedding_func, ), ) with open(PATH_TO_TXT, "r", encoding="utf-8") as f: await rag.ainsert(f.read()) except Exception as e: print(f"An error occurred: {e}")
Step5️⃣: 运行Demo,并检查WORKING_DIR中是否有graph_chunk_entity_relation.graphml 生成,其大小约为5M左右表示成功。
LazyLLM融合LightRAG
让我们看看整体的流程图吧!
- Step 1: 参考LightRAG构建知识图谱中的方式部署本地LLM和embedding服务✔️
- Step 2: 设置LightRAG知识图谱的存储目录
working_dir
和文本文件的路径txt_path
,并配置LazyLLM知识库目录dataset_path
✔️
import os import asyncio import lazyllm from lazyllm import pipeline, parallel, bind, Retriever from lightrag import LightRAG, QueryParam from lightrag.kg.shared_storage import initialize_pipeline_status from lightrag.utils import setup_logger, EmbeddingFunc from lightrag.llm.openai import openai_complete, openai_embed class LightRAGRetriever: def __init__(self, working_dir, txt_path, mode="hybrid"): self.working_dir = working_dir self.txt_path = txt_path self.mode = mode self.api_key = "empty" self.rag = None self.loop = asyncio.new_event_loop() setup_logger("lightrag", level="INFO") if not os.path.exists(working_dir): os.makedirs(working_dir) self.loop.run_until_complete(self.initialize_rag()) async def initialize_rag(self): self.rag = LightRAG( working_dir=self.working_dir, embedding_func=EmbeddingFunc( embedding_dim=1024, max_token_size=8192, func=lambda texts: openai_embed( texts=texts, model="bge-large", base_url="http://0.0.0.0:19001", api_key=self.api_key, ) ), llm_model_func=openai_complete, llm_model_name="qwen2", llm_model_kwargs={"base_url": "http://0.0.0.0:12345/v1", "api_key": self.api_key}, ) await self.rag.initialize_storages() await initialize_pipeline_status() with open(self.txt_path, "r", encoding="utf-8") as f: content = f.read() await self.rag.ainsert(content) def __call__(self, query): return self.loop.run_until_complete( self.rag.aquery( query, param=QueryParam(mode=self.mode, top_k=3, only_need_context=True) ) ) def close(self): if self.rag: try: self.loop.run_until_complete(self.rag.finalize_storages()) except Exception as e: print(f"关闭LightRAG时出错: {e}") finally: self.loop.close() self.rag = None def main(): kg_retriever = None try: documents = lazyllm.Document(dataset_path="****") prompt = ('请你参考所给的信息给出问题的答案。') print("正在初始化知识图谱检索器...") kg_retriever = LightRAGRetriever( working_dir="****", txt_path="****" ) print("知识图谱检索器初始化完成!") bm25_retriever = lazyllm.Retriever( doc=documents, group_name="CoarseChunk", similarity="bm25_chinese", topk=3 ) def bm25_pipeline(query): nodes = bm25_retriever(query) return "".join([node.get_content() for node in nodes]) def context_combiner(*args): bm25_result = args[0] kg_result = args[1] return ( f"知识图谱召回结果:\n{kg_result}" f"BM25召回结果:\n{bm25_result}\n\n" ) with lazyllm.pipeline() as ppl: with parallel() as ppl.multi_retrieval: ppl.multi_retrieval.bm25 = bm25_pipeline ppl.multi_retrieval.kg = kg_retriever ppl.context_combiner = context_combiner ppl.formatter = (lambda nodes, query: dict(context_str=nodes, query=query)) | bind(query=ppl.input) ppl.llm = ( lazyllm.OnlineChatModule().prompt( lazyllm.ChatPrompter( instruction=prompt, extra_keys=['context_str'] ) ) ) lazyllm.WebModule(ppl, port=23466).start().wait() except Exception as e: print(f"\n处理过程中发生错误: {e}") import traceback traceback.print_exc() if __name__ == "__main__": main()
Step 3: 运行Demo,则会启动Web端服务,即可向LLM提出问题啦。
————————————
通过这次的深入学习与实战,我们不仅了解了如何让知识图谱RAG“抽取实体、建图索引、逻辑推理”,更真正掌握了:一个能从碎片化信息中构建语义关联、支持复杂推理的RAG系统,不再只是简单的检索工具,而是具备全局视角与结构化思考能力的智能助手!
从分块抽取让系统“识别知识点”,到构建知识图谱为RAG搭建“语义网络”,再到高低层级检索实现从细节到全局的全面回答,我们一步步,把RAG从文本问答助手,进化成了语义理解+知识聚合的超级推理专家。
这不仅是功能的叠加,更是一次认知能力的全面升级!知识图谱RAG不再仅仅“回忆知识”,它开始学会“理解语义”、“关联信息”、“生成深度洞察”。
————————————
更多技术交流,欢迎移步“LazyLLM”GZH!

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
专访 | 贾文洋:鸿蒙生态技术全景与开发实例分享
6 月 20 至 22 日,华为开发者大会 HDC 在东莞松山湖圆满落幕,与全球开发者一起,用代码编制智慧时代的经纬。同期,开源中国也携手 HarmonyOS 于线上也举办了鸿蒙创想・创新场景共建挑战赛,以技术社区为场景共建之阵地,进一步激发各路开发者的创新思维。 截止 6 月 25 日,本次挑战赛已收获了 50+ 份作品,涵盖高性能 UI 组件、多设备响应式 / 自适应组件、AI 辅助工具、以及各种 API/SDK 等,可谓是彰显了 HarmonyOS 的蓬勃生命力。借此契机,开源中国邀请到了中国科学院软件研究所高级工程师、资深鸿蒙应用研发专家贾文洋老师做客开源中国直播间,以他个人的鸿蒙应用开发经验及作品,带大家深入探讨全流程的鸿蒙应用开发流程。 以下为采访内容整理。 受访人:贾文洋 Title:中国科学院软件研究所高级工程师、资深鸿蒙应用研发专家 简介:多年来致力于鸿蒙应用生态建设,曾主导了三款鸿蒙应用 —— 教考应用、输入法应用、AI 绘本智能应用的开发,其中教考应用和输入法应用已在商业场景中落地。 鸿蒙生态技术全景 鸿蒙生态以分布式架构打破设备边界,融合 AI 实现智能交互,配...
- 下一篇
SQLShift 重磅更新:支持 SQL Server 存储过程转换至 GaussDB!
SQLShift 作为一款多元异构数据库的 SQL 方言转换工具,在过去两个月,陆续支持了 Oracle 存储过程 ➝ OceanBase/PostgreSQL 的语法转换,本期让我们一起看看又有哪些新能力吧! 新特性速览 ✔️ SQL Server 存储过程 ➝ GaussDB 函数重构:支持 T-SQL → PL/pgSQL 的智能转换,结构/语义全面适配。 ✔️ 批量转换能力:支持一次性转换几十至上百个存储过程,自动识别语法风险! 一、SQL Server 存储过程 ➝ GaussDB 的智能转换 SQLShift 本次升级最大的亮点,在于对 SQL Server 与 GaussDB 之间复杂语义差异的精准映射与语法重构。 🔍 多维度评估语法兼容性 对 SQL Server 存储过程引用的结构定义、系统视图、数据类型等语法元素评估其在 GaussDB 的兼容性,覆盖300+语法点,实现异构数据库之间的语法精准映射,部分语法类型效果如下: 语法元素类别 SQL Server 语法示例 转换为 GaussDB 语法 结构定义 如 CREATE PROCEDURE... 重写为 CR...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- CentOS7编译安装Gcc9.2.0,解决mysql等软件编译问题
- Docker使用Oracle官方镜像安装(12C,18C,19C)
- CentOS7,8上快速安装Gitea,搭建Git服务器
- CentOS8安装MyCat,轻松搞定数据库的读写分离、垂直分库、水平分库
- CentOS7编译安装Cmake3.16.3,解决mysql等软件编译问题
- Docker快速安装Oracle11G,搭建oracle11g学习环境
- SpringBoot2全家桶,快速入门学习开发网站教程
- Jdk安装(Linux,MacOS,Windows),包含三大操作系统的最全安装
- MySQL8.0.19开启GTID主从同步CentOS8
- CentOS8编译安装MySQL8.0.19