接上回,如何用 LlamaIndex 搭建聊天机器人?

news2024/11/30 14:53:58

LlamaIndex 是领先的开源数据检索框架,能够在各种应用中发挥优势,其中一个典型的应用就是在企业内部搭建聊天机器人。

对于企业而言,随着文档数量不断增多,文档管理会变得愈发困难。因此,许多企业会基于内部知识库搭建聊天机器人。在搭建过程中,需要关注三个要点:如何切割数据、保存哪些元数据以及如何路由查询。

01.为什么要用 LlamaIndex 搭建聊天机器人?

在上一篇文章中,我们使用 Zilliz Cloud(全托管的 Milvus 云服务)搭建了一个最基本的检索增强生成(RAG)(https://zilliz.com/use-cases/llm-retrieval-augmented-generation)聊天机器人。在本教程中我们可以继续使用 Zilliz Cloud 免费版,大家也可以使用自己的 Milvus(https://milvus.io/) 实例,在 notebook 中快速启动并使用 Milvus Lite(https://milvus.io/docs/milvus_lite.md)。

上一篇文章中我们将文章进行切割,获取许多小的文本块。当输入问题“什么是大型语言模型?”进行简单的检索时,得到的返还文本块在语义上与问题相似,但并没有得到问题的答案。因此,在本项目中,我们使用同样的向量数据库作为后端,但使用不同的检索过程来进一步获得更好的问答结果。在项目中,我们将使用 LlamaIndex 来实现高效的检索。

LlamaIndex(https://zilliz.com/product/integrations/Llamaindex)是一个框架,可以帮助我们在大型语言模型之上处理数据。LlamaIndex 提供的一个主要抽象是“索引”。索引是数据分布的模型。在此基础上,LlamaIndex 还提供了将这些索引转化为查询引擎的能力,查询引擎利用大型语言模型和 embedding 模型来组织高效的查询并检索相关结果。

02.LlamaIndex 和 Milvus 对于 Chat Towards Data Science 的作用

那么,LlamaIndex 是如何帮助我们协调数据检索?Milvus 又如何帮助搭建聊天机器人的呢?我们可以用 Milvus 作为后端,用于 LlamaIndex 的持久性向量存储(persistent vector store)。使用 Milvus 或 Zilliz Cloud 实例后,可以从一个 Python 原生且没有协调的应用程序转换到由 LlamaIndex 驱动的检索应用程序。

设置 notebook,使用 Zilliz 和 LlamaIndex

正如之前文章所提到的,对于这一系列的项目 Chat Towards Data Science |如何用个人数据知识库构建 RAG 聊天机器人?(上),我们选择 Zilliz Cloud。连接到 Zilliz Cloud 和连接到 Milvus 的步骤基本上完全相同。关于如何连接到 Milvus 并将 Milvus 作为本地向量存储,可参见示例比较向量 embedding。

在 notebook 中我们需要安装三个库,通过 pip install llama-index python-dotenv openai来安装,使用python-dotenv管理环境变量。

获取导入后,需要用load_dotenv()加载.env文件。这个项目需要的三个环境变量是 OpenAI API key、Zilliz Cloud 集群的URI 以及 Zilliz Cloud 集群的 token。

! pip install llama-index python-dotenv openai
import osfrom dotenv import load_dotenv
import openai

load_dotenv()

openai.api_key = os.getenv("OPENAI_API_KEY")

zilliz_uri = os.getenv("ZILLIZ_URI")
zilliz_token = os.getenv("ZILLIZ_TOKEN")

将现有的 Collection 带入 LlamaIndex

将现有的 collection 带入 LlamaIndex 这一步骤中有些小挑战。LlamaIndex 有其自己创建和访问向量数据库 collection 的结构,但是此处不直接使用。原生的 LlamaIndex 向量存储接口和带入自己的模型之间的主要区别是 embedding 向量和元数据的访问方式。为了实现本教程,我还写了一些代码并贡献到了 LlamaIndex (https://github.com/run-llama/llama_index/commit/78ed06c95313e933cc255ac17bcd592e3f4b2be1)项目中!

LlamaIndex 默认使用 OpenAI 的 embedding,但我们使用 HuggingFace 模型生成了 embedding。因此,必须传入正确的 embedding 模型。此外,本次使用了一个不同的字段来存储文本,我们使用 “paragraph”,而 LlamaIndex 默认使用“_node_content”。

这一部分需要从 LlamaIndex 导入四个模块。首先,需要 MilvusVectorStore 来使用 Milvus 与 LlamaIndex。我们还需要VectorStoreIndex模块来用 Milvus 作为向量存储索引,用 ServiceContext 模块来传入我们想要使用的服务。最后导入HuggingFaceEmbedding模块,这样就可以使用来自 Hugging Face 的开源 embedding 模型了。

至于获取embedding模型,我们只需要声明一个 HuggingFaceEmbedding 对象并传入模型名称。本教程中使用的是 MiniLM L12 模型。接下来,创建一个 ServiceContext 对象,以便可以传递 embedding 模型。

from llama_index.vector_stores import MilvusVectorStore
from llama_index import VectorStoreIndex, ServiceContext
from llama_index.embeddings import HuggingFaceEmbedding

embed_model = HuggingFaceEmbedding(model_name="sentence-transformers/all-MiniLM-L12-v2")
service_context = ServiceContext.from_defaults(embed_model=embed_model)

当然,我们还需要连接到 Milvus 向量存储。这一步我们传递 5 个参数:我们的 Collection 的 URI、访问我们的 Collection 的 token、使用的 Collection 名称(默认是“Llamalection”)、使用的相似度类型,以及对应于哪个元数据字段存储文本的 key。

vdb = MilvusVectorStore(
    uri = zilliz_uri,
    token = zilliz_token,
    collection_name = "tds_articles",
    similarity_metric = "L2",
    text_key="paragraph"
)

使用 LlamaIndex 查询 Milvus Collection

现在,我们已经连接至现有的 Milvus Collection 并拉取了需要的模型,接下来讲讲如何进行查询。

首先,创建一个 ServiceContext 对象,以便可以传递 Milvus 向量数据库。然后,将 Milvus Collection 转化为向量存储索引。这也是通过上面创建的 ServiceContext 对象传入 embedding 模型的地方。

有了一个初始化的向量存储索引对象后,只需要调用as_query_engine()函数将其转化为查询引擎。本教程中,通过使用与之前相同的问题 “什么是大型语言模型?”来比较直接的语义搜索和使用 LlamaIndex 查询引擎的区别。

vector_index = VectorStoreIndex.from_vector_store(vector_store=vdb, service_context=service_context)
query_engine = vector_index.as_query_engine()
response = query_engine.query("What is a large language model?")

为了使输出更易于阅读,我导入了pprint并用它来打印响应。

from pprint import pprint
pprint(response)

下方是我们使用 LlamaIndex 进行检索得到的响应,这比简单的语义搜索得到的结果要好得多:

alt

03.总结

本次,我们使用了 LlamaIndex 和现有的 Milvus Collection 来改进上一篇文章中搭建的聊天机器人。上一个版本使用了简单的语义相似性通过向量搜索来寻找答案,但结果并不是很好。相较之下,用 LlamaIndex 搭建查询引擎返回的结果更好。

本项目最大的挑战是如何带入已有的 Milvus Collection。现有的 Collection 并没有使用 embedding 向量维度的默认值,也没有使用用于存储文本的元数据字段的默认值。这两点的解决方案是通过 ServiceContext 传递特定的 embedding 模型和在创建 Milvus Vector Store 对象时定义正确的文本字段。

创建向量存储对象后,使用 Hugging Face embedding 将其转化为索引,然后将该索引转化为查询引擎。查询引擎利用 LLM 来理解问题、收集响应和返回更好的响应。

本文由 mdnice 多平台发布

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

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

相关文章

企业办公为什么要选择局域网im即时通讯软件

办公沟通对于企业来说至关重要,而选择局域网IM即时通讯软件作为沟通工具,有以下几个重要原因: 安全性保障:使用局域网IM即时通讯软件,所有的通信数据都在企业内部网络中传输,不会经过公共互联网。这极大地…

C代码内存区域划分

C代码内存区域划分 1、初始化不为零的(全局变量、静态全局变量和静态局部变量)放在.data段 2、初始化为0,和未初始化的(全局变量、静态全局变量和静态局部变量)放在.bss 3、编译阶段未初始化的全局变量放在COM块&…

win10、win11解决应用商店、xbox错误代码0x80072efd、0x80131505的方法

文章目录 问题解决方法win10修改方法找到网络和共享中心找到Internet属性点击局域网设置解决后效果 win11的解决方法打开Internet选项找到局域网设置局域网设置 问题 在window上使用win10或者win11自带的系统时,应用商店、xbox报错错误代码0x80072efd、0x80131505。…

【Synopsys工具使用】VCS使用与Makefile脚本调用

文章目录 一、文件导入二、VCS仿真(使用可视化界面)三、VCS仿真(使用Maefile文件)3.1 Makefile文件编写3.2 仿真文件编写规范3.3 Makefile文件使用 一、文件导入 新建一个文件夹新建一个文件夹(图中IC_work)   创建一个目录&…

【考研数学】概率论与数理统计 —— 第八章 | 假设检验

文章目录 一、基本概念与原理1. 假设检验2. 两类错误3. 小概率原理与显著性水平 二、假设检验的基本步骤三、一个正态总体均值和方差的假设检验四、两个正态总体的假设检验写在最后 一、基本概念与原理 1. 假设检验 设总体分布已知,但含有未知参数,对总…

学PYTHON必须学算法吗?老程序员告诉你真相!

Python是一种非常流行的编程语言,广泛应用于数据科学、人工智能、Web开发、自动化、脚本编程等各种领域。对于很多Python开发工作,尤其是与应用开发、数据分析和Web开发相关的职位,算法并不是绝对必须的技能。 然而,在某些领域和职…

通过 Hilbert 变换实现单边带调制

目录 简介 双边带调制 单边带调制 理想的 Hilbert 变换 频谱移位器 SSB 调制的高效实现 总结 该例子说明如何使用离散 Hilbert 变换来实现单边带调制。Hilbert 变换可应用于调制器和解调器、语音处理、医学成像、波达方向 (DOA) 测量,以及任何简化设计的复信…

“Redis在分布式系统中的应用与优化“

文章目录 引言一、Redis的简介1. Redis的基本概念2. Redis在分布式系统中的优势 二、Windows、CentOS安装RedisCentOS安装RedisWindows安装Redis 三、Redis的常用命令总结 引言 在当今互联网时代,随着数据量的不断增长和用户访问量的激增,分布式系统的应…

将一个Series序列转化为数据框Dataframe格式Series.to_frame()

【小白从小学Python、C、Java】 【计算机等考500强证书考研】 【Python-数据分析】 将一个Series序列 转化为Dataframe格式 Series.to_frame() [太阳]选择题 关于以下代码的说法中正确的是? import pandas as pd s pd.Series([1,2],name"myValue") print("【显…

【QT】如何理解Widget::Widget(QWidget *parent) :QWidget(parent)

‪qwidget.cpp所在路径&#xff1a;D:\Qt\Qt5.9.9\5.9.9\Src\qtbase\src\widgets\kernel\qwidget.cpp 本文重点&#xff1a;如何理解下面这段代码? 一、类的继承和派生 widget.h #ifndef WIDGET_H #define WIDGET_H#include <QWidget>class Widget : public QWidget {…

【PID专题】控制算法PID之微分控制(D)的原理和示例代码

微分&#xff08;D&#xff09;项是PID控制器的一个组成部分&#xff0c;它对系统的控制输出做出反应&#xff0c;以减小系统的过度调节和减小响应的快速变化。微分项的作用是在控制系统中引入一个滞后效应&#xff0c;以帮助系统平稳响应。 以下是微分&#xff08;D&#xff0…

PP-OCRv4-server-det模型训练

PP-OCRv4-server-det项目地址https://aistudio.baidu.com/projectdetail/paddlex/6792800 1、数据校验 2、 模型训练 3、评估测试 4、模型部署

OpenCV实战——OpenCV.js介绍

OpenCV实战——OpenCV.js介绍 0. 前言1. OpenCV.js 简介2. 网页编写3. 调用 OpenCV.js 库4. 完整代码相关链接 0. 前言 本节介绍如何使用 JavaScript 通过 OpenCV 开发计算机视觉算法。在 OpenCV.js 之前&#xff0c;如果想要在 Web 上执行一些计算机视觉任务&#xff0c;必须…

Linux之sched_setscheduler调度策略总结(六十)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 人生格言&#xff1a; 人生…

CMake:探究编译和编译命令

CMake:探究编译和编译命令 导言项目结构相关源码结果 导言 本篇通过展示如何使用来自对应的Check<LANG>SourceCompiles.cmake标准模块的check_<lang>_source_compiles函数&#xff0c;以评估给定编译器是否可以将预定义的代码编译成可执行文件。该命令可帮助确定:…

Idea 对容器中的 Java 程序断点远程调试

第一种&#xff1a;简单粗暴型 直接在java程序中添加log.info()&#xff0c;根据需要打印信息然后打包覆盖&#xff0c;根据日志查看相关信息 第二种&#xff1a;远程调试 在IDEA右上角点击编辑配置设置相关参数在Dockerfile中加入 "-jar", "-agentlib:jdwp…

数据库连接池大小的调整原则

配置连接池是开发人员经常犯的错误。配置池时需要理解几个原则&#xff08;对于某些人来说可能违反直觉&#xff09;。 想象一下&#xff0c;您有一个网站&#xff0c;虽然可能不是 Facebook 规模的&#xff0c;但仍然经常有 10,000 个用户同时发出数据库请求&#xff0c;每秒…

4.RDD编程指南

概述 spark 提供的重要的抽象是一个 弹性分布式数据集(RDD) &#xff0c;能被并行操作的&#xff0c;在集群上分区的集合元素。RDDs 可以通过 hadoop 文件(或共它的 hadoop 支持的文件系统)&#xff0c;或者编程中的 scala 集合&#xff0c;转换它创建 RDD。用户还可以要求 sp…

【Linux】:基础IO

基础IO 一.C语音文件操作1.fopen2.fwrite3.fopen以a方式打开 二.Linux下一切皆文件三.系统调用接口四.文件描述符-fd 共识原理&#xff1a; 1.文件属性内容。 2.文件分为打开文件和未打开文件。 3.打开的文件&#xff1a;进程打开。 4.未打开的文件&#xff1a;在磁盘里存放着。…

在Node.js中,什么是中间件(middleware)?它们的作用是什么?

聚沙成塔每天进步一点点 ⭐ 专栏简介 前端入门之旅&#xff1a;探索Web开发的奇妙世界 欢迎来到前端入门之旅&#xff01;感兴趣的可以订阅本专栏哦&#xff01;这个专栏是为那些对Web开发感兴趣、刚刚踏入前端领域的朋友们量身打造的。无论你是完全的新手还是有一些基础的开发…