15.9K Star!知识库RAG还能这么玩?基于 GraphRag 打造知识图谱增强的 LLM - 以解读《红楼梦》为例

最近尝试把《红楼梦》接入大模型(LLM),用于打造知识检索增强的智能体-红楼解读大师,效果一直不太理想:

本地部署 AI 智能体,Dify 搭建保姆级教程(下):知识库 RAG + API 调用,我捏了个红楼解读大师

最近又发现了一个 GitHub 高赞项目 - GraphRAG,微软开源。

首先通过 LLM 进行实体提取、关系提取,将知识库构建成知识图谱,然后再基于知识图谱,利用 LLM 回答用户问题。

赞啊,知识库原来还可以这么玩,实操一番后,今天分享给大家!

温馨提醒:GraphRAG 的 Token 消费量非常大,已实现 Token 自由的小伙伴可无视。

1. GraphRAG 是什么

项目地址:https://github.com/microsoft/graphrag

官方文档:https://microsoft.github.io/graphrag/

官方介绍:GraphRAG 是一种结构化、分层的检索增强生成 (RAG) 方法,与使用纯文本片段的朴素语义搜索方法不同。 GraphRAG 的处理流程包括从原始文本中提取知识图、构建社区层次结构、为这些社区生成摘要,然后在执行基于 RAG 的任务时利用这些结构。

大白话解释一下:GraphRAG 是一个数据转换套件,旨在利用 LLM 从非结构化文本中提取有价值的结构化数据,进而构建成知识图谱。

啥是图谱?

图谱有两个最重要的概念:节点和边。

比如在知乎:你和猴哥都是一个节点,你关注猴哥就构成一条边,你给猴哥点赞也构成一条边,你我和构成的边,都是图谱的一部分。

发布至今,已有 15.9K Star,并且项目还在持续迭代中。

2. 安装使用

首先,Python 虚拟环境中一键安装:

pip install graphrag

然后,创建一个项目文件夹 - graphrag,然后在其中新建 input 文件夹,用于存放知识库数据:

mkdir graphrag
mkdir graphrag/input

把你的知识库文件夹装入 graphrag/input后,一键初始化项目:

python -m graphrag.index --init --root graphrag/

这一步,如果遇到如下报错:

from past.utils import old_div
ModuleNotFoundError: No module named 'past'

提示缺少past模块,future库提供了向后兼容的接口。安装future,即可确保程序正常。

pip install future

给大家看下,初始化成功后,我的项目目录:

graphrag/
├── .env
├── input
│   └── 红楼梦.txt
├── prompts
│   ├── claim_extraction.txt
│   ├── community_report.txt
│   ├── entity_extraction.txt
│   └── summarize_descriptions.txt
└── settings.yaml

这里主要有两个配置文件需要修改:

其中:

  • .env 中填入要采用的大模型的 api_key
  • settings.yaml 中主要修改 llm 和 embedding 相关信息,比如大模型名称和 api 地址。

注意:这里的 LLM API 需要兼容 OpenAI 格式;这里我选用 siliconflow 中免费的 llm 和 embedding 给大家做展示。如果需要在 Gephi 等软件中查看图谱的 graphml 文件,也可以设置:graphml: true

prompts 文件夹是整个项目中用到的提示词,非常重要,决定了最终图谱的质量,不过可以先保持官方的默认值,试试看,不行再来调整!

配置完成后,一键开启构建索引:

python -m graphrag.index --root graphrag/

下图日志显示,开始切割文本了:

开始提取实体:

注:满纸荒唐言的《红楼梦》共计 73w 字,所以处理时间比较长,大家也可以先用一个简单的例子快速跑通流程。

3. 踩坑预警

实际跑的时候,还是踩了一些坑,有必要也跟大家分享一下。

踩坑 1

如果中途因为上游 LLM 速率限制,报错了,可以在环境变量中设置一下timestamp,接着之前的任务继续跑:

踩坑 2siliconflow 免费版 embedding 限速严重。

尝试了siliconflow 的多个 embedding 模型,哪怕并发改到1,依然无法完成任务。

为此尝试了以下两种 embedding 方案:

  • 本地 ollama 模型:run 了下面这个snowflake-arctic-embed模型,但 Ollama 的嵌入模型居然不兼容 OpenAI 格式,果断放弃。关于如何用 Ollama 跑本地大模型,可以围观教程:Ollama 部署和实战,看这篇就够了
 ollama rm snowflake-arctic-embed
  • 智谱 AI 的 embedding-2:因为我已接入了 OneAPI,所以可以通过 OpenAI 格式调用,我把 batch_size 调整为 1,才终于搞定 embedding。
    关于如何使用 OneAPI,可以围观教程:OneAPI-接口管理和分发神器

4. 图谱展示

耗时数小时,终于把一本《红楼梦》的知识图谱构建完毕,总计完成以下几个任务:

⠧ GraphRAG Indexer 
├── Loading Input (text) - 1 files loaded (0 filtered) ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 100% 0:00:00 0:00:00
├── create_final_entities
├── create_final_nodes
├── create_final_communities
├── join_text_units_to_entity_ids
├── create_final_relationships
├── join_text_units_to_relationship_ids
├── create_final_community_reports
├── create_final_text_units
├── create_base_documents
└── create_final_documents
🚀 All workflows completed successfully.

怎么查看生成的节点和边?

生成结果保存在artifacts/文件夹下, 均为.parquet 文件。

为了在 vscode 中查看 .parquet ,需要先安装一个插件 parquet-viewer,安装成功后,会自动将 .parquet 展示为 json,非常方便!

给大家展示一下生成的节点,最终描述都是英文,类型也有不少错误,看来提示词还是得重新搞成中文!

生成的边:

这效果,比简单的段落切分,强太多了!

5. 考考它吧

专为《红楼梦》打造的知识图谱,终于搞定了!

我们来考考它,graphrag 提供了两种检索方式。

  • 局部检索:基于实体进行推理,结合来自图的结构化数据和来自文档的非结构化数据,在查询时,用相关实体信息增强 LLM 上下文。适合回答需要了解特定实体的问题(例:“洋甘菊的治疗特性是什么?”)。
  • 全局检索:基于数据集进行推理,将私有数据集组织成有意义的语义集群。LLM在响应用户查询时使用这些集群来总结这些主题。

此外,基于这个图谱,还可以让 LLM 帮你生成关于该数据集的各种问题!

5.1 几个例子

全局检索-红楼梦的主题是什么

python -m graphrag.query --root graphrag --method global "红楼梦的主题是什么?"

回答展示:

SUCCESS: Global Search Response: 
《红楼梦》的主题涵盖了多个方面,主要包括:

1. **家族衰败**:小说以贾、王、史、薛四大家族的兴衰为背景,展现了封建社会的腐朽和衰落。通过家族的兴衰史,揭示了封建社会的种种矛盾和问题 [Data: Reports (385, 205, 538, 420, 434, 596, 159, 480, 314, 421, 431, 148, 41, 439, 136, 136), (614, 358, 433, 78, 649, 654, 269, 616, 9, 360, 25, 549, 659, 93, 595), (476, 295, 553, 543, 611, 320, 134, 370, 364, 31, 8, 673, 99, 432, 218), (516, 442, 495, 672, 552, 665, 551, 77, 147, 132, 5, 492, 162, 312), (511, 494, 359, 372, 268, 371, 210, 216, 144, 597, 592, 668, 474, 664, 143, 427)]。

2. **人性探讨**:小说深入探讨了人性的复杂性和矛盾,如贾宝玉的叛逆、林黛玉的多愁善感等,展现了人性的光辉与阴暗 [Data: Reports (205, 434, 596, 159, 480, 314, 421, 431, 148, 41, 439, 136), (554, 417, 484, 300, 504, 375, 536, 156, 280, 435, 671, 272, 285, 11), (546, 637, 195, 612, 657, 544, 670, 278, 559, 386, 145, 304, 266, 666), (516, 442, 495, 672, 552, 665, 551, 77, 147, 132, 5, 492, 162, 312), (511, 494, 359, 372, 268, 371, 210, 216, 144, 597, 592, 668, 474, 664, 143, 427)]。

3. **社会批判**:小说对封建礼教、官场腐败、社会不公等进行了深刻的批判,具有强烈的社会意义 [Data: Reports (385, 205, 538, 420, 434, 596, 159, 480, 314, 421, 431, 148, 41, 439, 136), (614, 358, 433, 78, 649, 654, 269, 616, 9, 360, 25, 549, 659, 93, 595), (476, 295, 553, 543, 611, 320, 134, 370, 364, 31, 8, 673, 99, 432, 218), (516, 442, 495, 672, 552, 665, 551, 77, 147, 132, 5, 492, 162, 312), (511, 494, 359, 372, 268, 371, 210, 216, 144, 597, 592, 668, 474, 664, 143, 427)]。

4. **爱情与婚姻**:小说中的爱情与婚姻关系错综复杂,反映了当时社会的婚姻制度和家庭观念 [Data: Reports (385, 205, 538, 420, 434, 596, 159, 480, 314, 421, 431, 148, 41, 439, 136), (614, 358, 433, 78, 649, 654, 269, 616, 9, 360, 25, 549, 659, 93, 595), (476, 295, 553, 543, 611, 320, 134, 370, 364, 31, 8, 673, 99, 432, 218), (516, 442, 495, 672, 552, 665, 551, 77, 147, 132, 5, 492, 162, 312), (511, 494, 359, 372, 268, 371, 210, 216, 144, 597, 592, 668, 474, 664, 143, 427)]。

5. **哲学思考**:小说还探讨了人生、命运、爱情、婚姻、家族关系等主题,展现了人性的复杂性和社会的残酷现实 [Data: Reports (629, 613), (614, 358, 433, 78, 649, 654, 269, 616, 9, 360, 25, 549, 659, 93, 595), (476, 295, 553, 543, 611, 320, 134, 370, 364, 31, 8, 673, 99, 432, 218), (516, 442, 495, 672, 552, 665, 551, 77, 147, 132, 5, 492, 162, 312), (511, 494, 359, 372, 268, 371, 210, 216, 144, 597, 592, 668, 474, 664, 143, 427)]。

综上所述,《红楼梦》是一部深刻反映封建社会末期社会矛盾和人物命运的史诗性作品,其主题丰富多样,具有极高的文学价值和历史意义

局部查询-刘姥姥进大观园时带了谁

python -m graphrag.query --root graphrag --method local "刘姥姥进大观园时带了谁"

回答展示:

SUCCESS: Local Search Response: 
刘姥姥进入大观园时,并没有携带其他人。根据提供的数据,我们可以看到与刘姥姥相关的记录中,并没有提及她带了其他人一同进入大观园。具体来说:

- 在“Entities”表中,关于刘姥姥的条目(id: 967)中,描述了她是来自贾家外部的村民,以她的朴素和谦逊著称,并在贾家寻求帮助。然而,该描述并未提及她带了其他人。
- 在“Relationships”表中,也没有任何记录表明刘姥姥带了其他人进入大观园。

因此,根据现有数据,我们可以得出结论:刘姥姥进入大观园时,并没有携带其他人。

全局查询-刘姥姥进大观园时带了谁

python -m graphrag.query --root graphrag --method global "刘姥姥进大观园时带了谁"

回答展示:

SUCCESS: Global Search Response: 
刘姥姥进大观园时,带了她的孙子板儿。这一信息在多份分析师报告中得到了确认,包括报告编号104、656和546。根据这些报告,可以确定板儿是刘姥姥的孙子,且在刘姥姥进入大观园时,孙子板儿与她一同前往。目前的数据表中并未提及刘姥姥是否带了其他人员一同进入大观园,因此可以推断,此次陪同刘姥姥进入大观园的只有她的孙子板儿。

写在最后

不得不说 GraphRAG 是个宝藏项目,本文通过一个简单的案例,带你快速上手 GraphRAG,希望给饱受传统 RAG 困扰的小伙伴一点启发。

如果本文对你有帮助,不妨点个免费的赞收藏备用。

你学会了吗?有任何问题欢迎通过公众号找到我,一起打怪升级。

  • 11
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值