从代码上深入学习GraphRag

news2025/4/8 11:43:18

网上关于该算法的解析都停留在大概流程上,但是具体解析细节未知,由于代码是PipeLine形式因此阅读起来比较麻烦,本文希望通过阅读项目代码来解析其算法的具体实现细节,特别是如何利用大模型来完成图谱生成和检索增强的实现细节。

GraphRag的创新

RAG的目标是通过知识库增强内容生成的质量,通常做法是将检索出来的文档作为提示词的上下文,一并提供给大模型让其生成更可靠的答案。传统的Rag方法在大部分情况下效果都很好,但在处理复杂任务时却面临一些挑战,如多跳推理(multi-hop reasoning)或联系不同信息片段全面回答问题。不适用于摘要、总结性的问题。

GraphRAG将知识图谱技术应用到RAG,利用大模型,同时在知识图谱的基础上使用图社区摘要解决总结性查询任务的问题。

一、数据加载

支持csv和txt的格式。

二、分割文档

分割参数包括分割的每一块的token数、块之间的重叠数。使用 tiktoken 库来对文本进行编码和解码,并基于token进行分割。

使用Tokenizer对输入文本进行编码,得到一个令牌ID列表。根据设定的每个块的最大令牌数(tokensperchunk)和块之间的重叠令牌数(chunkoverlap)来迭代分割文本。在每次迭代中,它会取出一定数量的令牌ID,使用Tokenizer的解码方法将其转换回字符串,形成一个文本块。然后更新起始索引,跳过重叠的令牌,继续分割剩余的文本,直到所有文本都被处理。

补充:

其他的分词方法

tiktoken 是一个用于 OpenAI 模型的快速 BPE(字节对编码)标记器。

BPE 是一种简单的数据压缩算法,它通过迭代地合并最频繁出现的字节对来构建词汇表。

WordPiece:由 Google 开发,用于处理未知词汇和稀有词汇。

在训练数据上统计单词、子词和其他字符序列的出现频率。选择能够最大化训练数据似然的字符序列,将其添加到词汇表中。

SentencePiece:是一个无监督的文本编码器,可以用于子词分词和语言建模。

其他的chunk计算方法

三、形成嵌入向量

1.分割后的文本片段被发送到LLM以生成嵌入向量

2.LLM如何生成嵌入向量

    大模型形成的特征作为嵌入向量。

3.生成的向量如何存储

  VectorStoreDocument对象,该对象包含文本的ID、文本内容、嵌入向量以及其他属性(如标题)。嵌入之后的向量存储:文本嵌入向量的存储方式取决于是否配置了向量存储(vector store)以及具体的存储配置。如果在策略配置中提供了vector_store部分,那么文本嵌入向量将被存储在向量存储中。如果没有提供vector_store配置,那么嵌入向量将直接存储在内存中的DataFrame里。

azure_ai_search, lancedb

4.有哪些嵌入的大模型,如何选择

bge and nomic embed text

BGE通常是指使用BERT或其变体来生成文本嵌入的方法,适用于文本相似性分析、文档分类、情感分析等。

nomic embed text:支持多种任务,包括分类、检索、聚类、重排序和语义文本相似度(STS)计算。

四、调用大模型生成实体、关系和摘要等

最终生成实体-摘要-社区-社区摘要。

实体和关系

1.在什么数据的基础上生成实体和关系

  输入数据是文本,具体来说,是一个包含多个文档的列表,每个文档是一个字典,其中包含文档的ID和文本内容。

2.如何生成实体和关系

定义一个默认的实体类型列表DEFAULT_ENTITY_TYPES,包括组织、人物、地理位置和事件。

实体格式:("entity"<>实体标识<>实体类型<>实体描述)

关系格式:("relationship"<>实体1标识<>实体2标识<>关系描述<>关系强度)

可以选择两种方式来生成实体:

graph_intelligence:使用图智能库提取实体。调用大模型。

run_extract_entities--GraphExtractor

通过prompt来指导大模型生成实体。

不用大模型可以选择nltk:使用NLTK库提取实体和关系。没有使用大模型。

3.如何存储生成的结果

提取后的实体保存在一个列表中,每个实体是一个字典,包含实体的名称和其他属性。

如何处理实体歧义和关系重叠问题。

在GraphRag的实体生成过程中实体只有去除相同名称以及循环避免遗漏的处理,没有提醒大模型进行实体消歧和对齐,可以优化prompt。 

实体描述

1.输入数据格式和内容

输入数据是一个 DataFrame,其中包含图的字符串表示。

2.如何生成摘要

使用语言模型(LLM)来提取和总结实体图中的实体描述。

3.保存的数据格式

提取后的实体内容保存在SummarizedDescriptionResult对象中,该对象包含两个属性:itemsdescription

 它是一个简单的数据结构,用于封装提取结果。

图社区

社区检测_和_知识图谱嵌入

使用社区检测算法将图划分为模块化社区。

1.在什么数据的基础上生成图社区

  在实体数据上

2.生成图社区的过程

社区检测:生成实体社区的层次结构。

  networkx库用于图处理,以及 graspologic.partition.hierarchical_leiden 用于社区检测。

社区检测(Community Detection)是一种常用的技术,用于发现图中的紧密相连的节点集合,这些节点集合在内部有较多的连接,而与集合外部的节点连接较少。

首先,需要有一个图(Graph),它由节点(Nodes)和边(Edges)组成。在代码中,这通常是通过 networkx 库来表示的。

import networkx as nx

# 创建一个图
G = nx.Graph()

# 添加节点和边
G.add_nodes_from([1, 2, 3, 4, 5])
G.add_edges_from([(1, 2), (2, 3), (3, 4), (4, 5), (5, 1)])

   定义聚类方法,处理聚类结果,聚类算法执行后,会返回一个包含社区信息的字典。这个字典通常以社区级别为键,以包含社区 ID 和节点列表的字典为值。

    优化模块度(一个衡量社区质量的指标)来快速识别社区。

 节点的度:对于无向图,一个节点的度是指与该节点相连的边的数量。在无向图中,每条边连接两个节点,因此每条边会为两个节点各增加一度。

知识图谱嵌入

   使用 Node2Vec 算法生成知识图谱的向量表示。这将使我们能够理解我们的知识图谱的隐含结构,并提供一个额外的向量空间,用于在查询阶段搜索相关概念。

  将图数据嵌入到向量空间中,使用 node2vec 算法生成节点的嵌入向量,并返回一个有序的字典,其中包含节点的标识符和它们的嵌入向量。

  为什么要把图节点生成嵌入向量:

  node2vec是一种随机游走的算法, 

  node2vec使用了一种灵活的随机游走策略,它结合了两种游走策略:深度优先搜索(DFS)和广度优先搜索(BFS)。这种策略允许算法在探索节点邻域时平衡局部和全局的结构信息。一旦生成了随机游走序列,node2vec使用Skip-Gram模型来学习节点的嵌入。Skip-Gram的目标是给定一个节点(中心节点),预测它的上下文节点。通过优化目标函数(例如,最大化上下文节点的对数概率),使用梯度下降等优化算法更新节点的嵌入向量。

  一旦我们完成了知识图谱增强步骤,我们会对 实体 和 关系 表进行发射,之后再进行文本域的文本嵌入。

3.输出结果

社区信息,包括社区级别、社区ID和属于该社区的节点列表。

社区摘要

自下而上地生成每个社区层级及其组成部分的摘要。如果社区 A 是最高层级的社区,我们将获得有关整个知识图谱的报告。如果社区是较低级别的,则我们将获得有关局部集群的报告。

生成社区报告

使用 LLM 生成每个社区的摘要。这将使我们能够了解每个社区中包含的不同信息,并从高层次或低层次的角度提供对知识图谱的范围性理解。这些报告包含管理概述,并引用社区子结构中的关键实体、关系。

总结社区报告

在这一步中,每个_社区报告_会经过 LLM 进行摘要,供简要使用。

社区嵌入

通过生成社区报告、社区报告摘要和社区报告标题的文本嵌入,生成我们社区的向量表示。

五、检索

局部检索

适用于需要理解文档中提到的特定实体的问题。

1.将query在存储实体信息的向量库中检索出相关实体。

       代码路径:graphrag\query\context_builder\entity_extraction.py

       提供了三种查询相关性实体的方法:

       map_query_to_entities(默认用的是这个)

       通过文本嵌入向量来查找与查询最相关的实体,查询文本嵌入向量(在文本分块后数据库中实际存储的向量)与查询向量的相关性,然后返回对应文本向量的实体。

       graphrag\vector_stores\lancedb.py similarity_search_by_text。

       其他实现实体检索的方法:

       find_nearest_neighbors_by_entity_rank:通过实体的直接关系和排名来查找最相关的实体。

       找出与目标实体直接相连的关系。

       确定与目标实体有关系的实体名称,并排除掉排除列表中的实体。

       从所有实体中检索这些相关实体的列表,并根据实体的排名进行排序。

       返回前 k 个实体。

       find_nearest_neighbors_by_graph_embeddings

       通过图嵌入(graph embeddings)查找与给定实体最相似的实体。

2.将第一步实体相关的chunk信息、社区摘要、实体详情、实体关系、实体Covarites按一定的格式组织作为上下文。对这些候选数据源进行优先排序和过滤, 以适应预定义大小的单一上下文窗口, 用于生成对用户查询的响应。

   怎么优先排序?

    chunk信息:关系数量:文本单元与实体的关系数量是排序的一个重要因素,这表明代码旨在优先考虑与更多关系相关的文本单元。实体顺序:实体在列表中的顺序也是一个排序因素,这可能意味着先出现的实体可能更重要或更相关。上下文限制:通过max_tokens参数限制了上下文文本的长度,确保不会超出令牌限制。

   社区摘要:

关系和协变量上下文:在build_relationship_contextbuild_covariates_context函数中,关系和协变量可能根据它们与实体的关联强度或其他属性(如权重或排名)进行排序。
3.如果有历史聊天记录想历史聊天记录也作为上下文的一部分。

      graphrag\query\context_builder\conversation_history.py在对话系统中存储、管理和格式化对话历史。
4.让LLM根据上下文生成回答(prompt路径为graphrag/query/structured_search/local_search/system_prompt.py)。

如何高效地存储和查询嵌入向量,特别是在大规模知识图谱中。

向量存储的索引策略和数据结构。

全局检索

以 map-reduce 方式搜索所有 AI 生成的社区报告来生成答案。这是一种资源密集型方法,但通常对于需要整体理解数据集的问题能给出很好的响应。因为基准的 RAG 依赖于对数据集中语义相似文本内容的向量搜索。查询中没有任何指示它找到正确信息的内容。LLM 生成的知识图的结构告诉我们整个数据集的结构(因此也是主题)。这使得私有数据集可以被组织成有意义的语义聚类,并进行预摘要。

1.将所有社区摘要shuffle并分块作为上下文,另将历史对话构成的上下文与这些社区摘要块拼接在一起作为上下文。

2.用map机制将前一步的多个上下文让LLM评估它们对于回答用户问题是否有帮助并进行0-100的打分。过滤掉分数为0的上下文。

  prompt:graphrag\query\structured_search\global_search\map_system_prompt.py

3.将前一步得到的结果合并且按照分数大小进行降序排序,并将这些信息加入到LLM上下文窗口,让LLM生成最终的回答。

全局搜索的响应质量很大程度上取决于所选的用于获取社区报告的社区层次结构级别。较低层次的层次结构带有其详细报告,往往会产生更详尽的响应,但可能也会增加生成最终响应所需的时间和 LLM 资源,因为需要处理更多的报告。

Global查询的步骤如下(如下图所示)(prompt在graphrag/query/structured_search/global_search/map_system_prompt.py 和 graphrag/query/structured_search/global_search/reduce_system_prompt.py:

写的比较好的笔记:

基于社区发现的GraphRAG思路_graphrag 社区-CSDN博客

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2329682.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【Redis】通用命令

使用者通过redis-cli客户端和redis服务器交互&#xff0c;涉及到很多的redis命令&#xff0c;redis的命令非常多&#xff0c;我们需要多练习常用的命令&#xff0c;以及学会使用redis的文档。 一、get和set命令&#xff08;最核心的命令&#xff09; Redis中最核心的两个命令&…

微前端随笔

✨ single-spa&#xff1a; js-entry 通过es-module 或 umd 动态插入 js 脚本 &#xff0c;在主应用中发送请求&#xff0c;来获取子应用的包&#xff0c; 该子应用的包 singleSpa.registerApplication({name: app1,app: () > import(http://localhost:8080/app1.js),active…

C++中的浅拷贝和深拷贝

浅拷贝只是将变量的值赋予给另外一个变量&#xff0c;在遇到指针类型时&#xff0c;浅拷贝只会把当前指针的值&#xff0c;也就是该指针指向的地址赋予给另外一个指针&#xff0c;二者指向相同的地址&#xff1b; 深拷贝在遇到指针类型时&#xff0c;会先将当前指针指向地址包…

车载诊断架构 --- 整车重启先后顺序带来的思考

我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 周末洗了一个澡,换了一身衣服,出了门却不知道去哪儿,不知道去找谁,漫无目的走着,大概这就是成年人最深的孤独吧! 旧人不知我近况,新人不知我过…

【C++11(下)】—— 我与C++的不解之缘(三十二)

前言 随着 C11 的引入&#xff0c;现代 C 语言在语法层面上变得更加灵活、简洁。其中最受欢迎的新特性之一就是 lambda 表达式&#xff08;Lambda Expression&#xff09;&#xff0c;它让我们可以在函数内部直接定义匿名函数。配合 std::function 包装器 使用&#xff0c;可以…

Windows 10/11系统优化工具

家庭或工作电脑使用时间久了&#xff0c;会出现各种各样问题&#xff0c;今天给大家推荐一款专为Windows 10/11系统设计的全能优化工具&#xff0c;该软件集成了超过40项专业级实用程序&#xff0c;可针对系统性能进行深度优化、精准调校、全面清理、加速响应及故障修复。通过系…

浅谈在HTTP中GET与POST的区别

从 HTTP 报文来看&#xff1a; GET请求方式将请求信息放在 URL 后面&#xff0c;请求信息和 URL 之间以 &#xff1f;隔开&#xff0c;请求信息的格式为键值对&#xff0c;这种请求方式将请求信息直接暴露在 URL 中&#xff0c;安全性比较低。另外从报文结构上来看&#xff0c…

LightRAG实战:轻松构建知识图谱,破解传统RAG多跳推理难题

作者&#xff1a;后端小肥肠 &#x1f34a; 有疑问可私信或评论区联系我。 &#x1f951; 创作不易未经允许严禁转载。 姊妹篇&#xff1a; 2025防失业预警&#xff1a;不会用DeepSeek-RAG建知识库的人正在被淘汰_deepseek-embedding-CSDN博客 从PDF到精准答案&#xff1a;Coze…

C++多线程编码二

1.lock和try_lock lock是一个函数模板&#xff0c;可以支持多个锁对象同时锁定同一个&#xff0c;如果其中一个锁对象没有锁住&#xff0c;lock函数会把已经锁定的对象解锁并进入阻塞&#xff0c;直到多个锁锁定一个对象。 try_lock也是一个函数模板&#xff0c;尝试对多个锁…

垃圾回收——三色标记法(golang使用)

三色标记法(tricolor mark-and-sweep algorithm)是传统 Mark-Sweep 的一个改进&#xff0c;它是一个并发的 GC 算法&#xff0c;在Golang中被用作垃圾回收的算法&#xff0c;但是也会有一个缺陷&#xff0c;可能程序中的垃圾产生的速度会大于垃圾收集的速度&#xff0c;这样会导…

Windows环境下开发pyspark程序

Windows环境下开发pyspark程序 一、环境准备 1.1. Anaconda/Miniconda&#xff08;Python环境&#xff09; 如果不怕包的版本管理混乱&#xff0c;可以直接使用已有的Python环境。 需要安装anaconda/miniconda&#xff08;python3.8版本以上&#xff09;&#xff1a;Anaconda…

SSM婚纱摄影网的设计

&#x1f345;点赞收藏关注 → 添加文档最下方联系方式咨询本源代码、数据库&#x1f345; 本人在Java毕业设计领域有多年的经验&#xff0c;陆续会更新更多优质的Java实战项目希望你能有所收获&#xff0c;少走一些弯路。&#x1f345;关注我不迷路&#x1f345; 项目视频 SS…

1110+款专业网站应用程序UI界面设计矢量图标figma格式素材 Icon System | 1,100+ Icons Easily Customize

1110款专业网站应用程序UI界面设计矢量图标figma格式素材 Icon System | 1,100 Icons Easily Customize 产品特点 — 24 x 24 px 网格大小 — 2px 线条描边 — 所有形状都是基于矢量的 — 平滑和圆角 — 易于更改颜色 类别 &#x1f6a8; 警报和反馈 ⬆️ 箭头 &…

Llama 4 家族:原生多模态 AI 创新的新时代开启

0 要点总结 Meta发布 Llama 4 系列的首批模型&#xff0c;帮用户打造更个性化多模态体验Llama 4 Scout 是有 170 亿激活参数、16 个专家模块的模型&#xff0c;同类中全球最强多模态模型&#xff0c;性能超越以往所有 Llama 系列模型&#xff0c;能在一张 NVIDIA H100 GPU 上运…

正则表达式(Regular Expression,简称 Regex)

一、5w2h&#xff08;七问法&#xff09;分析正则表达式 是的&#xff0c;5W2H 完全可以应用于研究 正则表达式&#xff08;Regular Expressions&#xff09;。通过回答 5W2H 的七个问题&#xff0c;我们可以全面理解正则表达式的定义、用途、使用方法、适用场景等&#xff0c…

JMeter脚本录制(火狐)

录制前准备&#xff1a; 电脑&#xff1a; 1、将JMeter证书导入&#xff0c;&#xff08;bin目录下有一个证书&#xff0c;需要安装这个证书到电脑中&#xff09; 2、按winr&#xff0c;输入certmgr.msc&#xff0c;打开证书&#xff0c;点击下一步&#xff0c;输入JMeter证书…

基于SpringBoot的“高校社团管理系统”的设计与实现(源码+数据库+文档+PPT)

基于SpringBoot的“高校社团管理系统”的设计与实现&#xff08;源码数据库文档PPT) 开发语言&#xff1a;Java 数据库&#xff1a;MySQL 技术&#xff1a;SpringBoot 工具&#xff1a;IDEA/Ecilpse、Navicat、Maven 系统展示 总体功能结构图 局部E-R图 系统首页页面 用户…

C# Winform 入门(3)之尺寸同比例缩放

放大前 放大后 1.定义当前窗体的宽度和高度 private float x;//定义当前窗体的宽度private float y;//定义当前窗台的高度 2.接收当前窗体的尺寸大小 x this.Width;//存储原始宽度ythis.Height;//存储原始高度setTag(this);//为控件设置 Tag 属性 3.声明方法&#xff0c;获…

infinityfree最新免费建站详细教程_无需备案_5G空间_无限流量_免费域名_免费SSL

一、明确目标—是否要使用 1.为什么选择InfinityFree&#xff1f; 对于初学者、学生或只是想尝试网站搭建的个人用户来说&#xff0c;InfinityFree提供了一个绝佳的免费解决方案。这个国外免费的虚拟主机服务提供&#xff1a; 5GB存储空间 - 足以存放个人博客、作品集或小型…

打造高效英文单词记忆系统:基于Python的实现与分析

在当今全球化的世界中,掌握一门外语已成为必不可少的技能。对于许多学习者来说,记忆大量的英文单词是一个漫长而艰难的过程。为了提高学习效率,我们开发了一个基于Python的英文单词记忆系统。这个系统结合了数据管理、复习计划、学习统计和测试练习等多个模块,旨在为用户提…