使用 Neo4j 和 LangChain 集成非结构化知识图增强 QA

目前基于大模型的信息检索有两种方法,一种是基于微调的方法,一种是基于 RAG 的方法。

信息检索和知识提取是一个不断发展的领域,随着大型语言模型(LLM)和知识图的出现,这一领域发生了显着的变化,特别是在多跳问答的背景下。

接下来我们继续深入,跟着文章完成一个项目,该项目利用 Neo4j 矢量索引和 Neo4j 图数据库的强大功能来实现检索增强生成系统,旨在为用户查询提供精确且上下文丰富的答案。

该系统采用向量相似性搜索来检索非结构化信息,同时访问图数据库来提取结构化数据,以确保响应不仅全面,而且锚定在验证过的知识中。

这种方法对于解决多跳问题尤其重要,因为单个查询可能需要分解为多个子问题,并且可能需要来自大量文档的信息才能生成准确的答案。

图片

在数据既丰富又复杂的时代,上述系统成为一个至关重要的工具,它确保用户查询得到的答案既包含广泛的知识,又保持验证准确性,无缝地弥合了非结构化数据和结构化知识图之间的鸿沟。

最后一步,系统将所检索到的非结构化和结构化信息传递给新的大型语言模型 Mistral-7b,用于文本生成。这种集成确保生成的响应不仅依赖于模型中内置的广泛知识,还经过特定实时数据的微调和丰富,这些数据来自向量和图形数据库的检索,从而提供更加详尽、准确和与上下文相关的信息,以提升用户体验。

用通俗易懂方式讲解系列

  • 用通俗易懂的方式讲解:自然语言处理初学者指南(附1000页的PPT讲解)
  • 用通俗易懂的方式讲解:NLP 这样学习才是正确路线
  • 用通俗易懂的方式讲解:28张图全解深度学习知识!
  • 用通俗易懂的方式讲解:不用再找了,这就是 NLP 方向最全面试题库
  • 用通俗易懂的方式讲解:实体关系抽取入门教程
  • 用通俗易懂的方式讲解:灵魂 20 问帮你彻底搞定Transformer
  • 用通俗易懂的方式讲解:大模型算法面经指南(附答案)
  • 用通俗易懂的方式讲解:十分钟部署清华 ChatGLM-6B,实测效果超预期
  • 用通俗易懂的方式讲解:内容讲解+代码案例,轻松掌握大模型应用框架 LangChain
  • 用通俗易懂的方式讲解:如何用大语言模型构建一个知识问答系统
  • 用通俗易懂的方式讲解:最全的大模型 RAG 技术概览
  • 用通俗易懂的方式讲解:利用 LangChain 和 Neo4j 向量索引,构建一个RAG应用程序

技术交流群

前沿技术资讯、算法交流、求职内推、算法竞赛、面试交流(校招、社招、实习)等、与 10000+来自港科大、北大、清华、中科院、CMU、腾讯、百度等名校名企开发者互动交流~

我们建了NLP面试与技术交流群, 想要进交流群、需要源码&资料、提升技术的同学,可以直接加微信号:mlc2060。加的时候备注一下:研究方向 +学校/公司+CSDN,即可。然后就可以拉你进群了。

方式①、添加微信号:mlc2060,备注:技术交流
方式②、微信搜索公众号:机器学习社区,后台回复:技术交流

在这里插入图片描述

01 GraphCypherQAChain

GraphCypherQAChain 类在自然语言问题查询图数据库(特别是 Neo4j)领域发挥着重要作用。它利用 LLM 从用户输入的问题生成 Cypher 查询,然后执行这些查询在 Neo4j 图形数据库中,并根据查询结果提供答案。

这一工具使用户能够检索特定数据,而无需编写复杂的 Cypher 查询,从而使存储在图形数据库中的数据更容易访问和互动。

02 Mistral 7B

Mistral 7B 是最新的大型语言模型,因其在一系列基准测试中的卓越性能而受到认可,展示了处理各种语言任务和查询的熟练程度,如下图所示。

图片

在检索增强生成 (RAG) 架构中,Mistral 7B 发挥着关键作用,它根据向量和图形搜索检索到的信息合成和生成文本,确保输出不仅上下文丰富,而且能够根据用户的查询精确定制。它有效地弥合了非结构化数据和结构化知识图之间的差距,提供混合了预先训练的知识和实时、经过验证的数据的答案。

03 执行

让我们从安装依赖项开始。

pip install langchain openai wikipedia tiktoken neo4j python-dotenv transformers
pip install -U sagemaker

Neo4j 向量索引

我们首先导入必要的库和模块,为数据集准备、Neo4j 向量索引的接口以及使用 Mistral 7B 的文本生成功能奠定基础。使用 dotenv,它可以安全地加载环境变量,保护 OpenAI API 和 Neo4j 数据库的敏感信息。

import os
import re
from langchain.vectorstores.neo4j_vector import Neo4jVector
from langchain.document_loaders import WikipediaLoader
from langchain.embeddings.openai import OpenAIEmbeddings
from langchain.text_splitter import CharacterTextSplitter, RecursiveCharacterTextSplitter
from transformers import AutoModelForSeq2SeqLM, AutoTokenizer
from dotenv import load_dotenv

load_dotenv()
os.environ["OPENAI_API_KEY"] = os.getenv('OPENAI_API_KEY')
os.environ["NEO4J_URI"] = os.getenv('NEO4J_URI')
os.environ["NEO4J_USERNAME"] = os.getenv('NEO4J_USERNAME')
os.environ["NEO4J_PASSWORD"] = os.getenv('NEO4J_PASSWORD')

在这里,我们使用 Leonhard Euler 的维基百科页面来进行我们的实验。我们使用该 bert-base-uncased 模型来标记文本。WikipediaLoader 加载指定页面的原始内容,然后使用 LangChain 的 RecursiveCharacterTextSplitter 将其分成更小的文本片段。

该拆分器确保每个块最大化为 200 个标记,其中重叠 20 个标记,遵守嵌入模型的上下文窗口限制,并确保不会丢失上下文的连续性。

tokenizer = AutoTokenizer.from_pretrained("bert-base-uncased")

def bert_len(text):
    tokens = tokenizer.encode(text)
    return len(tokens)

raw_documents = WikipediaLoader(query="Leonhard Euler").load()
text_splitter = RecursiveCharacterTextSplitter(
          chunk_size = 200,
          chunk_overlap  = 20,
          length_function = bert_len,
          separators=['\n\n', '\n', ' ', ''],
      )

documents = text_splitter.create_documents([raw_documents[0].page_content])

分块文档作为节点实例化到 Neo4j 向量索引中。它使用 Neo4j 图数据库和 OpenAI 嵌入的核心功能来构建该向量索引。

# Instantiate Neo4j vector from documents
neo4j_vector = Neo4jVector.from_documents(
    documents,
    OpenAIEmbeddings(),
    url=os.environ["NEO4J_URI"],
    username=os.environ["NEO4J_USERNAME"],
    password=os.environ["NEO4J_PASSWORD"]
)

在提取向量索引中的文档后,我们对示例用户查询执行向量相似度搜索,并检索前 2 个最相似的文档。

query = "Who were the siblings of Leonhard Euler?"
vector_results = neo4j_vector.similarity_search(query, k=2)
for i, res in enumerate(vector_results):
    print(res.page_content)
    if i != len(vector_results)-1:
        print()
vector_result = vector_results[0].page_content

图片

构建知识图谱

受到 NaLLM 项目的高度启发,我们使用他们的开源项目从非结构化数据构建知识图。

下面是使用 Leonhard Euler 的维基百科文章中的单个文档块构建的知识图。

图片

在深入研究该项目可以学到很多关于使用 LLM 构建知识图谱的知识。例如,以下是从非结构化文本中捕获实体和关系的提示:

"""
You are a data scientist working for a company that is building a graph database. Your task is to extract information from data and convert it into a graph database.
Provide a set of Nodes in the form [ENTITY_ID, TYPE, PROPERTIES] and a set of relationships in the form [ENTITY_ID_1, RELATIONSHIP, ENTITY_ID_2, PROPERTIES].
It is important that the ENTITY_ID_1 and ENTITY_ID_2 exists as nodes with a matching ENTITY_ID. If you can't pair a relationship with a pair of nodes don't add it.
When you find a node or relationship you want to add try to create a generic TYPE for it that  describes the entity you can also think of it as a label.

Example:
Data: Alice lawyer and is 25 years old and Bob is her roommate since 2001. Bob works as a journalist. Alice owns a the webpage www.alice.com and Bob owns the webpage www.bob.com.
Nodes: ["alice", "Person", {"age": 25, "occupation": "lawyer", "name":"Alice"}], ["bob", "Person", {"occupation": "journalist", "name": "Bob"}], ["alice.com", "Webpage", {"url": "www.alice.com"}], ["bob.com", "Webpage", {"url": "www.bob.com"}]
Relationships: ["alice", "roommate", "bob", {"start": 2021}], ["alice", "owns", "alice.com", {}], ["bob", "owns", "bob.com", {}]
"""

有很多有趣的功能,同时可以进行改进。

Neo4j DB QA 链

接下来,我们导入必要的库来设置 Neo4j DB QA 链。

from langchain.chat_models import ChatOpenAI
from langchain.chains import GraphCypherQAChain
from langchain.graphs import Neo4jGraph

构建图表后,我们需要连接到 Neo4jGraph 实例并可视化模式。

graph = Neo4jGraph(
    url=os.environ["NEO4J_URI"], username=os.environ["NEO4J_USERNAME"], password=os.environ["NEO4J_PASSWORD"]
)

print(graph.schema)
Node properties are the following:
[{'labels': 'Person', 'properties': [{'property': 'name', 'type': 'STRING'}, 
{'property': 'nationality', 'type': 'STRING'}, 
{'property': 'death_date', 'type': 'STRING'}, 
{'property': 'birth_date', 'type': 'STRING'}]}, 
{'labels': 'Location', 'properties': [{'property': 'name', 'type': 'STRING'}]}, 
{'labels': 'Organization', 'properties': [{'property': 'name', 'type': 'STRING'}]}, 
{'labels': 'Publication', 'properties': [{'property': 'name', 'type': 'STRING'}]}]

Relationship properties are the following:
[]
The relationships are the following:
['(:Person)-[:worked_at]->(:Organization)', 
'(:Person)-[:influenced_by]->(:Person)', 
'(:Person)-[:born_in]->(:Location)', 
'(:Person)-[:lived_in]->(:Location)', 
'(:Person)-[:child_of]->(:Person)', 
'(:Person)-[:sibling_of]->(:Person)', 
'(:Person)-[:published]->(:Publication)']

抽象 GraphCypherQAChain 所有细节并输出自然语言问题(NLQ)的自然语言响应。然而,在内部,它使用 LLM 生成该问题的 Cypher 查询,并从图形数据库中检索结果,最后使用该结果生成最终的自然语言响应,再次使用 LLM。

chain = GraphCypherQAChain.from_llm(
    ChatOpenAI(temperature=0), graph=graph, verbose=True
)

graph_result = chain.run("Who were the siblings of Leonhard Euler?")

图片

graph_result
'The siblings of Leonhard Euler were Maria Magdalena and Anna Maria.'

Mistral-7b-指令

我们在 AWS SageMaker 环境中从 Hugging Face 设置 Mistral-7B 终端节点。

import json
import sagemaker
import boto3
from sagemaker.huggingface import HuggingFaceModel, get_huggingface_llm_image_uri

try:
    role = sagemaker.get_execution_role()
except ValueError:
    iam = boto3.client('iam')
    role = iam.get_role(RoleName='sagemaker_execution_role')['Role']['Arn']
    
hub = {
    'HF_MODEL_ID':'mistralai/Mistral-7B-Instruct-v0.1',
    'SM_NUM_GPUS': json.dumps(1)
}

huggingface_model = HuggingFaceModel(
    image_uri=get_huggingface_llm_image_uri("huggingface",version="1.1.0"),
    env=hub,
    role=role, 
)

最终响应是通过构造提示来制作的,该提示包括指令、向量索引中的相关数据、图形数据库中的相关信息以及用户的查询。

然后将此提示传递给 Mistral-7b 模型,模型根据提供的信息生成有意义且准确的响应。

mistral7b_predictor = huggingface_model.deploy(
    initial_instance_count=1,
    instance_type="ml.g5.4xlarge",
    container_startup_health_check_timeout=300,
)

query = "Who were the siblings of Leonhard Euler?"
final_prompt = f"""You are a helpful question-answering agent. Your task is to analyze 
and synthesize information from two sources: the top result from a similarity search 
(unstructured information) and relevant data from a graph database (structured information). 
Given the user's query: {query}, provide a meaningful and efficient answer based 
on the insights derived from the following data:

Unstructured information: {vector_result}. 
Structured information: {graph_result}.
"""

response = mistral7b_predictor.predict({
    "inputs": final_prompt,
})

print(re.search(r"Answer: (.+)", response[0]['generated_text']).group(1))
The siblings of Leonhard Euler were Maria Magdalena and Anna Maria.

要点

Neo4j 向量检索与 GraphCypherQAChainMistral-7b 的集成提供了一个强大的系统来处理复杂数据,有效地弥合了大量非结构化数据和复杂的图形知识之间的差距,通过综合两个数据源的信息,为用户查询提供全面、准确的响应。

利用 Neo4j 进行向量相似性搜索和图形数据库检索,可确保生成的响应不仅通过 Mistral-7b 的大量预先训练的知识获得信息,而且还通过来自向量和图形数据库的实时数据进行上下文丰富和验证。

最后,作者的目标是在未来的实验中尝试多跳查询,因为最初建立模块化管道对于适应快速发展的人工智能领域是必要的。

04 总结

该项目强调了 Neo4j Vector Index 和 LangChain 的有效组合,GraphCypherQAChain 分别可以浏览非结构化数据和图形知识,然后使用 Mistral-7b 生成明智且准确的响应。

通过使用 Neo4j 从向量索引和图形数据库检索相关信息,系统确保生成的响应不仅上下文丰富,而且锚定在经过验证的实时知识中。

该实现展示了检索增强生成的实际应用,其中利用来自不同数据源的综合信息来生成响应,这些响应是预先训练的知识和特定的实时数据的和谐混合,从而提高了预测的准确性和相关性。对用户查询的响应。

参考资料

https://medium.com/neo4j/enhanced-qa-integrating-unstructured-and-graph-knowledge-using-neo4j-and-langchain-6abf6fc24c27

https://github.com/neo4j/NaLLM/tree/main

https://medium.com/neo4j/harnessing-large-language-models-with-neo4j-306ccbdd2867

https://medium.com/neo4j/knowledge-graphs-llms-fine-tuning-vs-retrieval-augmented-generation-30e875d63a35

https://medium.com/neo4j/knowledge-graphs-llms-multi-hop-question-answering-322113f53f51

https://medium.com/neo4j/langchain-library-adds-full-support-for-neo4j-vector-index-fa94b8eab334

https://mistral.ai/news/announcing-mistral-7b/

https://www.youtube.com/watch?v=Hg4ahTQlBm0

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

2.4 网络层01

2.4 网络层01 2.4.1 网络层概述 网络层的主要任务是实现网络互连,进而实现数据包在各网络之间的传输。 异构网络内部的计算机要想实现通信是不需要实现网络互联的,异构网络之间要想实现通信就必须实现网络互连。 路由器工作在五层协议体系结构的网络…

HCIA的路由协议

动态路由协议/静态路由协议 静态路由协议和动态路由协议的区别: 静态路由协议的缺点: 配置繁琐 针对拓扑的变化不能够自动收敛 只适用于小型网络 静态路由协议优点: 占用资源少 安全 稳定 动态路由协议的优点: 配置简单 针对拓…

风丘科技为您提供完整的ADAS测试方案

一 方案概述 随着5G通讯与互联网的快速发展,智能汽车和ADAS辅助系统的研究与发展在世界范围内也在如火如荼地进行。风丘科技紧跟时代脚步,经多年积累沉淀,携手整车厂与高校共同研发打造出了一套完整且适用于国内ADAS测试的系统方案。 | ADAS…

YOLOv5改进 | 二次创新篇 | 升级版本Dyhead检测头替换DCNv3 实现完美升级(全网独家首发)

一、本文介绍 本文给大家带来的改进机制是在DynamicHead上替换DCNv3模块,其中DynamicHead的核心为DCNv2,但是今年新更新了DCNv3其作为v2的升级版效果肯定是更好的,所以我将其中的核心机制替换为DCNv3给Dyhead相当于做了一个升级,效果也比之前的普通版本要好,这个机制我认…

从0开始python学习-49.pytest之日志封装和allure封装

目录 日志封装 1. 在pytest.ini中配置日志的格式 2. 生成日志对象--在请求封装中写 3. 把日志写入文件--在请求封装中写 allure封装 1. 在yaml用例中写入需要的模块、接口等内容 2. 在测试用例封装的函数中通过allure.dynamic的方法写入需要的数据 日志封装 1. 在pytest.…

知识付费saas租户平台:发掘企业知识宝藏,开启专属知识付费新时代

产品服务 线上线下课程传播 线上线下活动管理 项目撮合交易 找商机找合作 一对一线下交流 企业文化宣传 企业产品销售 明理信息科技知识付费saas租户平台 更多服务 实时行业资讯 动态学习交流 分销代理推广 独立知识店铺 覆盖全行业 个人IP打造 独立小程序 私…

第十届教育和培训技术国际会议 (ICETT 2024)即将召开!

2024年第十届教育和培训技术国际会议(ICETT 2024)将于2024年4月11-13日在中国澳门召开,由澳门理工大学主办,香港教育大学协办。作为一项历史悠久的年度盛会,ICETT已在新加坡、芬兰、韩国等地成功举办了九届。本次会议依…

3DGS 其一:3D Gaussian Splatting for Real-Time Radiance Field Rendering

3DGS 其一:3D Gaussian Splatting for Real-Time Radiance Field Rendering 1. 预备知识1.1 球谐函数1.2 Splatting1.3 α \alpha α blending1.4 多维高斯的协方差矩阵1.4.1 高斯与椭球体的关系1.4.2 世界坐标系下的三维高斯到二维像素平面投影过程 2. 3D Gaussia…

PICO Developer Center 创建和调试 ADB 命令

PICO 开发者中心概览 ADB 是一个轻量级的 Android 调试桥(Android Debug Bridge,简称 ADB),用于与 Android 设备进行通信和调试。ADB提供了许多有用的功能,使开发人员能够轻松地管理和调试设备上的应用程序。 你可以使用 PDC 工具来调试系统…

按键检测|中断检测

一.按键检测 1.硬件原理 当未按下按键时,GPIO_5为低电平,按下按键GPIO_5变为高电平。 根据引脚编号找到引脚名称 根据引脚名称找到引脚编号 裸机程序控制外设 特点:读数据手册、设寄存器值 找出外设有哪些相关寄存器找出外设相关寄存器如何…

Kafka-消费者-Consumer Group Rebalance设计

在同一个Consumer Group中,同一个Topic的不同分区会分配给不同的消费者进行消费,那么为消费者分配分区的操作是在Kafka服务端完成的吗?分区是如何进行分配呢?下面来分析Rebalance操作的原理。 方案一 Kafka最开始的解决方案是通过ZooKeeper的Watcher…

Nginx 简介

1、概念介绍 Nginx ("engine x") 是一个轻量级、高性能的 WEB 服务器软件和反向代理服务器。 Nginx 是由 Igor Sysoev 为俄罗斯访问量第二的 Rambler.ru 站点开发的,第一个公开版本 0.1.0 发布于 2004 年 10 月 4 日。其将源代码以类 BSD 许可证的形式发…

手机崩溃日志的查找与分析

手机崩溃日志的查找与分析 摘要 本文介绍了一款名为克魔助手的iOS应用日志查看工具,该工具可以方便地查看iPhone设备上应用和系统运行时的实时日志和崩溃日志。同时还提供了崩溃日志的分析查看模块,可以对苹果崩溃日志进行符号化、格式化和分析&#x…

【Spring实战】30 创建自己的 Spring Boot HelloWorld Starter

文章目录 1. 定义2. 创建3. 依赖4. 编写自动配置类5. 编写 HelloWorldService 类6. 编写 Starter 配置文件7. 打包并发布到本地仓库7. 引入 HelloWorld Starter8. 使用 HelloWorld结语 Spring Boot Starter 是一项强大的功能,可以帮助我们轻松集成和配置各种常用组件…

微信小程序中的两种页面跳转方式

方式一(声明式导航): 利用<navigator></navigator> url:要跳转页面的地址 open-type:要打开的页面的类型 &#xff08;不在底部导航中添加的为非导航页面&#xff0c;在的为导航页面&#xff09; 非导航页面跳转过去后左上角会出现返回箭头&#xff0c;导航页面…

KNN算法原理及应用

理解KNN 算法原理 KNN是监督学习分类算法&#xff0c;主要解决现实生活中分类问题。 根据目标的不同将监督学习任务分为了分类学习及回归预测问题。 监督学习任务的基本流程和架构&#xff1a; &#xff08;1&#xff09;首先准备数据&#xff0c;可以是视频、音频、文本、…

appium之联动pycharm

前置条件&#xff1a; 1.java环境安装好了 2.android-sdk安装好&#xff08;uiautomatorviewer 也可以把这个启动起来&#xff09; 3.appium安装好 4.adb devices查看下设备是否连接 pycharm入门代码--固定写法 from appium import webdriver# 定义字典变量 desired_caps …

机器学习笔记——机器学习的分类

1 机器学习是啥 机器学习是人工智能的一个分支&#xff0c;它是一门研究机器获取新知识和新技能&#xff0c;并识别现有知识的学问。 机器学习已广泛应用于数据挖掘、计算机视觉、自然语言处理、生物特征识别、搜索引擎、医学诊断、检测信用卡欺诈、证券市场分析、DNA 序列测…

Luckysheet类似excel的在线表格(vue)

参考文档&#xff1a;快速上手 | Luckysheet文档 一、引入 在vue项目的public文件夹下的index.html的<head>标签里面引入 <link relstylesheet hrefhttps://cdn.jsdelivr.net/npm/luckysheetlatest/dist/plugins/css/pluginsCss.css /><link relstylesheet hre…

c# 视频播放之Vlc.DotNet.Forms

先说下优缺点 优点&#xff1a;与电脑无关&#xff0c;能播放主流编码格式视频。 缺点&#xff1a;只能播放本地视频&#xff0c;网络视频播放不了。 下面是具体操作和代码 1. 安装Vlc.DotNet.Forms 和 VideoLAN.LibVLC.Windows Vlc.DotNet.Forms 是播放库&#xff0c;Vid…