石小疯 发表于 2025-4-23 16:39:23

利用GraphRAG+LangChain+Ollama:LLaMa 3.1跑关照识图谱与向量数据库集成(Neo4j)

我将向你展示如何利用 LLama 3.1(一个本地运行的模子)来执行GraphRAG操作,总共就50号代码。。。
起首,什么是GraphRAG?GraphRAG是一种通过考虑实体和文档之间的关系来执行检索加强生成的方式,关键概念是节点和关系。
https://i-blog.csdnimg.cn/img_convert/823f8f9203ec76fedd2b70a6d55ece99.jpeg
▲ 知识图谱与向量数据库集成
   知识图谱与向量数据库集成是GraphRAG 架构之一:这种方法利用知识图谱和向量数据库来网络相干信息。知识图谱的构建方式可以捕捉向量块之间的关系,包罗文档条理布局。知识图谱在从向量搜索中检索到的块附近提供布局化实体信息,从而通过有价值的附加上下文丰富提示。这个丰富的提示被输入到 LLM 中进行处置惩罚,然后 LLM 生成响应。末了,生成的答案返回给用户。此架构实用于客户支持、语义搜索和个性化推荐等用例。
节点代表从数据块中提取的实体或概念,例如人、组织、事件或地点。
知识图谱中,每个节点都包含属性和特性,这些属性为实体提供了更多上下文信息。
然后我们界说节点之间的毗连关系,这些毗连可以包罗各种类型的关联,例如条理布局(如父子关系)、时间次序(如前后关系)或因果关系(因果关系)。
关系还具有形貌毗连性子和强度的属性。当你有很多文档时,你会得到一个很好的图来形貌所有文档之间的关系。
   让我们看一个非常简单的例子,在我们的数据会合,节点可以代表像苹果公司和蒂姆·库克如许的实体,而关系则可以形貌蒂姆·库克是苹果公司的 CEO。
这种方法非常强大,但一个巨大的缺点是它**计算本钱很高,因为你必须从每个文档中提取实体,并利用 LLM 计算关系图。**这就是为什么利用像 LLaMa 3.1 如许本地运行的模子来接纳这种方法非常棒。
保姆级教程开始
在本文中,我们将团结利用LangChain、LLama 和 Ollama ,以及 Neo4j 作为图数据库。我们将创建一个关于一个拥有多家餐厅的大型意大利家庭的信息图,所以这里有很多关系需要建模。
先利用Ollama拉取llama3.1 8b模子:
https://i-blog.csdnimg.cn/img_convert/bb1fb0af86ae7b9619eb89ccfc16e2c3.png
所有代码的链接我放在文末。。。
打开代码文件,来到VS Code 中,你可以在左边看到我们将利用的多个文件。
设置运行Neo4j数据库
在进入代码之前,我们将设置 Neo4j。我为你创建了一个 Docker Compose 文件。所以我们将利用 neo4j 文件夹,内里有一个 jar 文件,这是我们创建图所需的插件。
https://i-blog.csdnimg.cn/img_convert/0de4f186a7476daeaec401d295ffdbd7.png
要创建我们的数据库,只需运行 docker compose up:
https://i-blog.csdnimg.cn/img_convert/6223f73ae869465f6d2ceba9cbc0dbef.png
这将设置所有内容,并且可以直接利用。可能需要几秒钟,之后你会看到数据库正在运行。
https://i-blog.csdnimg.cn/img_convert/fbf54c5e6611c6ff93a0e006cacc583d.png
安装依赖
然后我们可以进入 Jupyter Notebook,起首安装所需的包:
我们需要安装 LangChain、OpenAI 的 LangChain、Ollama、LangChain Experimental,因为图办理方案目前在 LangChain 实验包中。
我们还需要安装 Neo4j,以及用于在 Jupyter Notebook 中表现图的 py2neo 和 ipywidgets。
代码语言:javascript
复制
%pip install --upgrade --quietlangchain langchain-community langchain-openai langchain-ollama langchain-experimental neo4j tiktoken yfiles_jupyter_graphs python-dotenv
导入类
安装完这些包后,我们可以导入所需的类。我们将从 LangChain 中导入多个类,例如 Runnable Pass Through、Chat Prompt Template、Output Parser 等。
我们还导入 Neo4j 的图类,这在 LangChain Community 包的 Graphs 模块中。我们还导入 Chat OpenAI 作为 Ollama 的后备模子。
在 LangChain Experimental 包中,我们有一个 Graph Transformer 模块,我们将从那里导入 LLM Graph Transformer,它利用复杂的提示将数据转换为可以存储在图数据库中的形式。
我们还将导入 Neo4j 的图数据库,不仅作为图数据库利用,还可以作为普通的向量数据库利用。
代码语言:javascript
复制
from langchain_core.runnables importRunnablePassthrough
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.pydantic_v1 import BaseModel, Field
from langchain_core.output_parsers import StrOutputParser
import os
from langchain_community.graphs import Neo4jGraph
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain_openai import ChatOpenAI
from langchain_community.chat_models import ChatOllama
from langchain_experimental.graph_transformers import LLMGraphTransformer
from neo4j import GraphDatabase
from yfiles_jupyter_graphs import GraphWidget
from langchain_community.vectorstores import Neo4jVector
from langchain_openai import OpenAIEmbeddings
from langchain_community.document_loaders import TextLoader
from langchain_community.vectorstores.neo4j_vector import remove_lucene_chars

from dotenv import load_dotenv

load_dotenv()
我们将接纳混淆方法,既利用图知识,也利用尺度的文档搜索方式,即通过嵌入模子来搜索与查询最相似的文档。
我们还将利用 dotenv 包,并在 Jupyter Notebook 中加载情况变量。在 .env 文件中,有一个 OpenAI API 密钥、一个 Neo4j URI、Neo4j 用户名和密码。你可以按原样利用这些信息,但在仓库中,它们将被定名为 .env.example。
https://i-blog.csdnimg.cn/img_convert/1c0c34e4a7265c86932c28514bdaf2c7.jpeg
下一步是创建与数据库的毗连。所以我们实例化 Neo4j 图类,
https://i-blog.csdnimg.cn/img_convert/cfeb887aa3b29f9e3d04b03a6b3bf7e2.jpeg
这将建立与 Neo4j 的毗连。
准备dummy_text.txt 数据集
https://i-blog.csdnimg.cn/img_convert/b49d2be78c92747b5c46616727305a50.jpeg
你可以看到它形貌了这个意大利家庭的大量信息,包罗差别的名字、关系,如 Antonio 的妹妹 Amo、祖母等。这些信息稍后都将在我们的图中呈现。
我们将利用文本加载器将其加载到内存中,
https://i-blog.csdnimg.cn/img_convert/31ec1afa7c9e1adcb4ac9e82782432a9.png
然后利用文天职割器将其分割成多个块,这是尺度的方法,以便 LLM 更轻易处置惩罚信息。
LLM图转换函数创建文档块之间的所有关系
加载后,我们将设置我们的 LLM 图变换器,它负责将文档转换为 Neo4j 可以处置惩罚的形式。
https://i-blog.csdnimg.cn/img_convert/a387f729943b5814eab97bdc6ee8d6bb.png
基于情况变量 llm_type,目前我没有设置,所以默认是 Ollama。我们将实例化 ChatOllama 或 ChatOpenAI,然后将其通报给 LLM 图变换器的构造函数。
convert_to_graph_documents 方法将创建文档块之间的所有关系。我们传入创建的文档,计算可能需要一些时间,纵然是这个很小的例子,也花了我大约 3 分钟时间,所以稍等半晌。
运行效果来了:这是一个图文档,你可以看到我们有一个 nodes 属性,它是一个包含差别节点的列表,具有 ID。我们可以看到 ID 类似于 Micos Family,类型是 Family,然后我们还有更多的节点,如 Love 概念节点、Tradition 等等。
https://i-blog.csdnimg.cn/img_convert/a255fef168d3f84fe4d22204726b7070.png
他们之间也有关系,这些关系将被存储在 Neo4j 中。
可视化我们的图
当前我们还没有启动数据库,所以我们需要先运行 add_graph_documents 方法,提供图文档,然后将所有内容存储在 Neo4j 中。这也可能需要几秒钟时间。文档存储到数据库后,我们可以可视化它们。
https://i-blog.csdnimg.cn/img_convert/b3301df5ea5ec19a1e9fb9e6d6b820a9.jpeg
起首我们要毗连到数据库,我们将利用驱动方法,传入我们的 URI(存储在 Neo4j URI 情况变量中),还需要提供用户名和密码进行身份验证,并创建驱动实例。然后我们创建一个新会话,并利用会话的 run 方法对 Neo4j 运行查询。我们将利用这个查询语句:
https://i-blog.csdnimg.cn/img_convert/1e3df17a9c0c77811cbac8c1022a3aa0.png
如果你不熟悉 Neo4j 可能会觉得有点复杂,但它的意思是 Neo4j 应该返回所有通过 mentions 类型的关系毗连的节点对,我们想返回 s, r, 和 t。s 是起始节点,r 是结束节点,t 是关系。
我们可以运行这个方法,并实际可视化我们的图:
https://i-blog.csdnimg.cn/img_convert/37db0667fa5616c643b91262a372dba3.png
现在我们可以向下滚动,这里我们可以看到这是我们的文档的完备知识图谱。正如你所看到的,这相当多,我们可以通过滚动来深入了解更多信息。这里我们可以看到一些实体,比如 Petro 是一个人,我们可以看到 Petro 喜欢厨房、喜欢大海,并且是另一个人 Sophia 的家长。
https://i-blog.csdnimg.cn/img_convert/9a4c36aeafa7c78185dbaa96e35a3805.gif
所以我们可以看到差别的实体通过差别的关系建模,终极你得到了这个非常大的知识图谱。我以为纵然是对于我们的小数据集,这也实际上是很多内容。我个人非常喜欢这种图。现在我们来看一下这不仅仅是美观,实际上也很有用。
图的存储做完了,再来一个向量存储
下一步是从 Neo4j 创建一个向量存储,所以我们将利用 Neo4jVector 类,并利用 from_existing_graph 方法,在这里我们只传入嵌入模子,从现有图中计算嵌入。如许我们也可以执行向量搜索,终极我们将把这个向量索引转换成一个检索器,以便有一个尺度化的接口。
https://i-blog.csdnimg.cn/img_convert/f4ac060a8624cae296782bd95f0b91a3.png
为图数据库准备实体(Prompt实体识别)
现在我们有一个图数据库,存储了我们的文档,也有了普通的向量存储。现在我们可以执行检索加强生成。由于我们利用图数据库,我们需要从查询中提取实体,以便从图数据库中执行检索步骤。
图数据库需要这种实体,所以我们将创建一个名为 Entities 的自界说模子,继承自 BaseModel,我们希望提取实体,这可以通过提供这个属性 entities 来完成,它是一个字符串列表。这里是 LLM 的形貌,所以我们希望提取文本中的所有人、组织和业务实体。
https://i-blog.csdnimg.cn/img_convert/03140cc7b470135c36fbfdde7be2bcc7.png
▲ Langchain教程操作有类似
然后我们创建一个 ChatPromptTemplate,系统消息是你正在从文本中提取组织、个人和业务实体。然后我们提供用户输入,并将我们的提示模板通报给 LLM,与布局化输出一起利用,这利用了 Entities 类。我将向你展示其效果。
我们得到了我们的实体链,并可以像如许调用它。我们传入标题 “Who are Nonna and Giovanni Corrado?”,所以我们有两个名字,执行调用方法后,我们可以看到输出是一个字符串列表,只有名字,
https://i-blog.csdnimg.cn/img_convert/e281ccf21517e8a279eb42fc5bec2c0c.png
这些名字将用于查询图数据库。接下来是在 graph_retriever 函数中调用这个方法。起首从查询中提取实体,然后对 Neo4j 运行查询,我将向你展示终极效果。
https://i-blog.csdnimg.cn/img_convert/4c7d68a544a8d84d2497cadca09d07e5.png
我们创建了 graph_rae 函数,传入标题,提取实体,然后查询数据库。
我们问 “Who is Nonna?”,如果运行这个查询,我们可以看到 Nonna 拥有哪些节点和毗连。她影响了 Conato,教导了孙子们,影响了新鲜意大利面,影响了 Amico,是家族的女族长。
https://i-blog.csdnimg.cn/img_convert/780d7fcb3be6e14f5629f1c29e6d194e.png
https://i-blog.csdnimg.cn/img_convert/420cdaaecb5e45a38bb6b603f6662e71.png
https://i-blog.csdnimg.cn/img_convert/3e1c7c5f8abfea4ffba7c3ca21d0110b.png
创建一个混淆检索器
然后我们创建一个混淆检索器,利用 graph_retriever 和我们的向量存储检索器。我们界说一个函数 full_retriever,在这里设置我们的 graph_retriever 函数,并利用向量检索器,调用其 invoke 方法,获取最相干的文档。我们有了关系图和基于余弦相似度的最相干文档,终极我们将所有文档团结,返回终极数据集。这就是 full_retriever 的作用。
https://i-blog.csdnimg.cn/img_convert/f81c8134a3350fa2311bd787888bd4b1.png
终极链
然后我们创建一个终极链,这是一个普通的 RAG 链,你在险些所有初学者教程中都会找到如许的链。我们有两个变量,context 和 question,context 是向量存储或其他数据库的输出,question 是我们的标题。所有这些都将发送给 LLM,我们创建一个模板,然后利用 Lang 和表达式语言在这里创建我们的终极链。这将创建一个 runnable_parallel,我将展示其 invoke 方法。
https://i-blog.csdnimg.cn/img_convert/3093806adbbbb2cad132b7c2e6c7ef9e.png
我们只利用一个字符串输入,通报给 full_retriever 函数,保持标题稳定,然后将 context 和 question 通报给我们的提示,以填充这些变量。填充这些变量后,我们将所有内容通报给 LLM,并将 LLM 的输出通报给字符串输出解析器。
现在我们可以问 “Who is Nonna Lucia? Did she teach anyone about restaurants or cooking?” 所有关于关系的东西,执行效果:
https://i-blog.csdnimg.cn/img_convert/abacd2e4e69b53af9d3e258c27b5d4e0.png
代码语言:javascript
复制
Generated Query: Nonna~2 AND Lucia~2
'Nonna Lucia is the matriarch of the Caruso family and a culinary mentor. She taught her grandchildren the art of Sicilian cooking, including recipes for Caponata and fresh pasta.'
**我们可以看到答案是 Nonna Lucia 是 Corrado 家族的女族长和烹饪导师。她教导了她的孙子们西西里烹饪的艺术,**这确实是正确的。
这就是如何利用 Neo4j 执行图数据库 RAG。
附件:
以前看过的一个叫PP-Structure文档分析的项目,
信息抽出其中的实体识别。。。
https://i-blog.csdnimg.cn/img_convert/828aba59ec4d7a26c81e3ef178e599e2.png
▲ 信息抽取 是天然语言处置惩罚中的底子标题,即从天然语言文本中,抽取出特定的事件或毕竟信息,资助我们将海量内容自动分类、提取和重构。
https://i-blog.csdnimg.cn/img_convert/9f142a940798ffdf6626d1d556c047b6.png
如何系统的去学习大模子LLM ?

大模子时代,火爆出圈的LLM大模子让程序员们开始重新评估自己的本领。 “AI会取代那些行业?”“谁的饭碗又将不保了?”等标题热议不断。
毕竟上,抢你饭碗的不是AI,而是会利用AI的人。
继科大讯飞、阿里、华为等巨头公司发布AI产品后,很多中小企业也陆续进场!超高年薪,挖掘AI大模子人才! 现在大厂老板们,也更倾向于会AI的人,普通程序员,还有应对的机会吗?
与其焦虑……

不如成为「掌握AI工具的技术人」,毕竟AI时代,谁先尝试,谁就能占得先机!
但是LLM相干的内容很多,现在网上的老课程老教材关于LLM又太少。所以现在小白入门就只能靠自学,学习本钱和门槛很高。
针对所有自学碰到困难的同砚们,我帮大家系统梳理大模子学习脉络,将这份 LLM大模子资料 分享出来:包罗LLM大模子书籍、640套大模子行业陈诉、LLM大模子学习视频、LLM大模子学习路线、开源大模子学习教程等,
页: [1]
查看完整版本: 利用GraphRAG+LangChain+Ollama:LLaMa 3.1跑关照识图谱与向量数据库集成(Neo4j)