手把手系列!无需 OpenAI 即可搭建 RAG 应用

news2024/11/16 17:33:58

OpenAI 是时下最火爆的大语言模型(LLM),不过除了 OpenAI 以外,还有许多不同的 LLM。此前,我们发布的许多篇文章中都介绍了如何使用 LangChain、Milvus 和 OpenAI 搭建众多 RAG 应用,这次我们来试试不一样的 LLM。

接下来我将用 Nebula 替代 OpenAI,Hugging Face 上的 Embedding 向量模型代替 OpenAI 模型。

01.对话式 RAG 应用技术栈

对话式 RAG 是最常见的 RAG 应用,也就是我们常说的 RAG 聊天机器人。在之前的文章中,我们介绍了 RAG 应用典型的技术栈——CVP(注:CVP 全称为 ChatGPT + Vector Database + Prompt as code,即 ”以 ChatGPT 为代表的 LLM + 向量数据库 + Prompt”)。本文搭建的 RAG 应用将在此技术栈基础上进行微调,将 ChatGPT 的 LLM 替换为 Hugging Face 上的 Embedding 模型,将 LangChain 用于管理 Prompt,并使用 Milvus 作为向量数据库。此外,我们会用 SymbI AI 提供的 LLM。

LangChain

LangChain 框架,提供了一套工具、组件和接口,是开发大语言模型应用的利器,帮助我们简化 LLM 应用开发的过程。我们之前讲过如何用 LangChain 和 OpenAI 搭建带有记忆缓存的问答机器人,本文将依然使用 LangChain 开发 RAG 应用。

Symbl AI

Symbl AI 提供基于对话数据训练的对话式 LLM——Nebula。Nebula 可与 LangChain 集成。本文中,我们就将使用 Nebula 模型,用于替代此前教程中使用过的 OpenAI GPT-3.5。

Milvus

本文所搭建的应用中最核心的部分便是向量数据库。向量数据库用于处理由非结构化数据转化而来的 Embedding 向量,接下来我们将用 Milvus 存储对话。

Hugging Face

Hugging Face 是一个庞大的模型库,可与 LangChain 集成。本文将用到 Hugging Face 中的 Embedding 模型,用于替代此前教程中使用的 OpenAI 模型。

02.如何快速搭建一个对话式 RAG 应用

本次搭建过程主要包含以下三个环节:

  • 设置技术栈

  • 创建对话

  • 向应用提问

设置技术栈

我们需要安装 LangChain、Milvus (Lite)、PyMilvus、python-dotenv、Sentence Transformers。在代码前半部分中,通过 LangChain 导入 Vector Store Retriever Memory、 Conversation Chain 和 Prompt Template 对象,用这些导入创建对话,并存入 RAG 应用的“记忆”中。

此外,还需要导入 osload_dotenv,用于加载环境变量。与此前的教程不同,本次不再导入 OpenAI 的 API 密钥,而是 Nebula 的 API 密钥。

! pip install langchain milvus pymilvus python-dotenv sentence_transformers

from langchain.memory import VectorStoreRetrieverMemory
from langchain.chains import ConversationChain
from langchain.prompts import PromptTemplate
import osfrom dotenv import load_dotenv
load_dotenv()
api_key = os.getenv("NEBULA_KEY")

从 Milvus Lite 中导入 default_server 并启动 Milvus 向量数据库。接着继续从 LangChain 导入 Hugging Face Embedding 模型,默认导入的模型为 all-mpnet-base-v2,该模型生成 768 维向量。

from milvus import default_server
default_server.start()

from langchain_community.embeddings import HuggingFaceEmbeddings
is this model by default: sentence-transformers/all-mpnet-base-v2
embeddings = HuggingFaceEmbeddings()

以下主要用于“清理”此前创建的 LangChain Collection,如果之前没有同时使用过 LangChain 和 Milvus,请忽略以下代码。

from pymilvus import utility, connections
connections.connect(host="127.0.0.1", port=default_server.listen_port)
utility.drop_collection('LangChainCollection')

创建对话

现在,让我们创建并存储对话。

首先从 LangChain 导入一个 Milvus 向量数据库用于存储向量数据,传入创建的 Hugging Face Embedding 函数以及 Milvus Lite 实例的 server 和 endpoint 用于连接至 Milvus。最后,传入 consistency_level 参数,从而设置数据一致性等级,参数值为 Strong,即最高级别的数据一致性。

from langchain.vectorstores import Milvus
vectordb = Milvus.from_documents(
   {},
   embeddings,
   connection_args={"host": "127.0.0.1", "port": default_server.listen_port},
   consistency_level="Strong")

用 LangChain 设置 Vector store retriever,传入 Milvus Collection 和搜索参数。本教程中,我们只希望获取 Top-K(K=1) 个结果。

接下来需要准备一些对话内容,本例中,我将在对话中给出一些我的个人信息。大家在搭建的过程中可以随意输入自己想要输入的对话内容。随机输入一些对话内容后,我们就需要将这些对话存入应用的“记忆”中,用作后续对话的上下文。

在保存对话上下文时,我们向记忆对象传入两个 dictionary。本例中分别为 inputoutput,大家可以灵活探索 save_context 函数。

retriever = Milvus.as_retriever(vectordb, search_kwargs=dict(k=1))
memory = VectorStoreRetrieverMemory(retriever=retriever)
about_me = [
   {"input": "My favorite snack is chocolate","output": "Nice"},
   {"input": "My favorite sport is swimming","output": "Cool"},
   {"input": "My favorite beer is Guinness","output": "Great"},
   {"input": "My favorite dessert is cheesecake","output": "Good to know"},
   {"input": "My favorite musician is Taylor Swift","output": "I also love Taylor Swift"}
]
for example in about_me:
   memory.save_context({"input": example["input"]}, {"output": example["output"]})

输入问题

一切准备就绪,就可以开始向 RAG 应用提问了。本文的 RAG 应用借助 Milvus 向量数据库而有了记忆——能够记住我们迄今为止的所有对话内容。开始提问前,先检查一下,确保 RAG 应用已经记住了我们的对话内容。

我问 RAG 应用是否还记得我最喜欢的歌手是谁(答案:Taylor Swift)。收到提问后,RAG 应用的记忆缓存部分就开始工作了。我们的提问(即 Prompt)会通过 Embedding 模型被转化为向量,随后应用会搜索对话记录。

print(memory.load_memory_variables({"prompt": "who is my favorite musician?"})["history"])

响应如下所示:

alt

接着,我们来创建 Prompt 模板。此时需要用到 LLM,只需导入 Nebula 并传入其 API 密钥即可,Prompt 可以看作是多条字符串,用括号注释来传入变量。

我们向 LangChain prompt 模版中传入 Prompt 字符串和变量名称。准备好 Prompt 模版、LLM 和应用“记忆”后,就可以使用对话链(Conversation Chain)进行对话。

from langchain_community.llms.symblai_nebula import Nebula
llm = Nebula(nebula_api_key=api_key)
_DEFAULT_TEMPLATE = """The following is a friendly conversation between a human and an AI. The AI is talkative and provides lots of specific details from its context. If the AI does not know the answer to a question, it truthfully says it does not know.
Relevant pieces of previous conversation:
{history}
(You do not need to use these pieces of information if not relevant)
Current conversation:
Human: {input}
AI:"""
PROMPT = PromptTemplate(
   input_variables=["history", "input"], template=_DEFAULT_TEMPLATE
)
conversation_with_summary = ConversationChain(
   llm=llm,
   prompt=PROMPT,
   memory=memory,verbose=True
)

先输入第一个问题:

conversation_with_summary.predict(input="Hi Nebula, what's up?")

响应如下所示:

alt

基于 Nebula 的训练数据以及刚才提供的对话示例数据,可以从响应中看出,LLM 判断我们“人类”会继续进行对话。

现在,我们试试向应用提问“Who did I say was my favorite musician?”,看看它能否回答出我最喜欢的歌手。(敲黑板!此前我们已经在对话中提及我最喜欢的歌手是 Taylor Swift,这个信息应该已经存储在应用的“记忆”里了。)

conversation_with_summary.predict(input="Who did I say was my favorite musician?")

问答式 RAG 应用的响应如下所示:

alt

03.总结

至此,我们已经尝试了用 Symbl AI 的 Nebula 大语言模型替代常用的 OpenAI 模型,并搭建了一个对话式 RAG 应用。在后续的文章中,我们将继续用其他 LLM 搭建更多 RAG 应用,敬请期待!

本文由 mdnice 多平台发布

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

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

相关文章

【制作100个unity游戏之23】实现类似七日杀、森林一样的生存游戏1(附项目源码)

本篇最终效果演示 文章目录 本篇最终效果演示系列目录前言环境素材绘制地形 实现人物移动指示显示物品名称源码完结 系列目录 【制作100个unity游戏之23】实现类似七日杀、森林一样的生存游戏1(附项目源码) 【制作100个unity游戏之23】实现类似七日杀、森…

在FreeRTOS上使用软定时器的ESP32开发指南

在FreeRTOS上使用软定时器的ESP32开发指南 在ESP32的开发中,使用FreeRTOS实时操作系统可以有效地提高多任务处理和系统稳定性。其中,软定时器是一项非常有用的功能,它可以让我们在系统中创建定时任务,而无需硬件定时器的支持。 …

基于cubeMX的正点原子miniSTM32对W25Q64的存储使用

一、实现目标 使用cubeMX建立项目工程,结合正点原子提供的hal库对W25Q64闪存调用的例程,实现W25Q64的读写。 二、实现过程 1、首先建立cubeMX工程,其他项设置不再叙述,只看连接W25Q64的SPI设置,这里使用SPI1&#xf…

css display 左右对齐 技巧

.list_number{ display: flex; } .list_name_number{ width:100px; } //左边固定width .list_name_type{ //右边给flex:2 自动撑开 flex:2; }

docker(上)

笔记资料参考与尚硅谷 前提知识课程介绍课程定位学习建议 1前提知识 boot cloud git push pull redis nginx mysql... Linux centos ubuntu 2课程介绍 2.1 2018 vs 2022 2.2 k8s(雷峰崖) 2.3 大纲 3课程定位(因材施教量体裁衣…

Web08--JavaScript高级

1、BOM对象 BOM:browser object model 浏览器对象模型 BOM对象包括window对象、screen对象、history对象、location对象、navigator对象。 1.1 window对象 所有的浏览器都支持window对象。它表示的浏览器窗口 window对象是js中的顶层对象,所有的j…

DOS经典软件,落下帷幕,国产新一代中文编程体系兴起

互联网的演变犹如狂风巨浪,一些我们以为早已遗忘的软件却深深烙印在心底,特别是对于那些经历了DOS到Windows时代变革的人们来说,这种感觉尤为强烈。 DOS软件,曾是80后青春岁月中的璀璨星辰,如今虽已成为历史的遗迹&am…

Redis内存空间节省小技巧

背景:为提升会员对当前等级的权益感知,需对用户仍未领取的权益进行弹框或消息位置推荐,会员需推荐权益有10项,且项权益均需需校验当日推荐次数并做推送限制,推荐次数记入Redis缓存,会员数据庞大&#xff0c…

[实战]加密传输数据解密

前言 下面将分享一些实际的渗透测试经验,帮助你应对在测试中遇到的数据包内容加密的情况。我们将以实战为主,技巧为辅,进入逆向的大门。 技巧 开局先讲一下技巧,掌握好了技巧,方便逆向的时候可以更加快速的找到关键函数…

代码随想录 Leetcode226.翻转二叉树

题目: 代码(首刷看解析 2024年1月25日): class Solution { public:TreeNode* invertTree(TreeNode* root) {if(root nullptr) return root;swap(root->left,root->right);invertTree(root->left);invertTree(root->right);retu…

Java面试提纲

JDK 1 jdk1.8版本后的新特性有哪些? Java Development Kit (JDK) 1.8(也称为Java 8)在2014年3月发布,引入了许多重要的新特性,以下是其中的一些关键特性: Lambda表达式: Java 8引入了lambda表达式&#x…

java大数据hadoop2.9.2 Linux安装mariadb和hive

一、安装mariadb 版本centos7 1、检查Linux服务器是否已安装mariadb yum list installed mariadb* 2、如果安装了,想要卸载 yum remove mariadb rm -rf /etc/my.cnf rm -rf /var/lib/mysql 才能完全删除 3、安装mariadb 在线网络安装 yum install -y mari…

java常见的面试问题

目录 一、异常 1、 throw 和 throws 的区别? 2、 final、finally、finalize 有什么区别? 3、try-catch-finally 中哪个部分可以省略? 4、try-catch-finally 中,如果 catch 中 return 了,finally 还会执行吗&#…

vue3 实现自定义radio

需求背景解决效果bgRadio.vue 需求背景 实现一个自定义选中样式的 radio 解决效果 bgRadio.vue <!--/** * author: liuk * date: 2024/01/25 * describe: 背景单选框 * email: 1229223630qq.com */--> <template><div class"radio-wrap"><l…

Linux 互斥锁、读写锁、条件变量以及信号量

互斥锁 同步与互斥概述 现代操作系统基本都是多任务操作系统&#xff0c;即同时有大量可调度实体在运行。在多任务操作系统中&#xff0c;同时运行的多个任务可能&#xff1a; 都需要访问/使用同一种资源多个任务之间有依赖关系&#xff0c;某个任务的运行依赖于另一个任务 …

AP5216 平均电流型LED降压恒流驱动IC 手电筒汽车摩托车灯芯片

产品描述 AP5216 是一款 PWM工作模式, 高效率、外围简单、内置功率管&#xff0c;适用于5V&#xff5e;100V输入的高精度降压 LED 恒流驱动芯片。输出最大功率可达9W&#xff0c;最大电流 1.0A。AP5216 可实现全亮/半亮功能切换&#xff0c;通过MODE 切换&#xff1a;全亮/半亮…

Java 集合Map相关面试题

&#x1f4d5;作者简介&#xff1a; 过去日记&#xff0c;致力于Java、GoLang,Rust等多种编程语言&#xff0c;热爱技术&#xff0c;喜欢游戏的博主。 &#x1f4d7;本文收录于java面试题系列&#xff0c;大家有兴趣的可以看一看 &#x1f4d8;相关专栏Rust初阶教程、go语言基…

如何使用docker实现越权漏洞-webug靶场搭建(超详解)

越权漏洞-webug靶场搭建 1.打开docker systemctl start docker 2.查找webug docker search webug 3.拉取docker.io/area39/webug 镜像 docker pull docker.io/area39/webug 4.查看镜像 docker images 5.创建容器 docker run -d -p 8080:80 --name webug docker.io/area39/we…

哈夫曼树(Huffman)

哈夫曼树 Huffman 编码问题 问题引入 什么是编码&#xff1f; 简单说就是建立【字符】到【数字】的对应关系&#xff0c;如下面大家熟知的 ASC II 编码表&#xff0c;例如&#xff0c;可以查表得知字符【a】对应的数字是十六进制数【0x61】 \000102030405060708090a0b0c0d…

五款焊在电脑上的效率软件

在当今快节奏的商业环境中&#xff0c;提高工作效率成为了每个人都渴望实现的目标。尤其是在面对繁忙的工作日程、庞杂的任务清单和团队合作的压力时&#xff0c;我们需要一些可靠的工具来帮助我们更好地管理时间、组织工作和提高生产力。幸运的是&#xff0c;现在有许多高效的…