易速鲜花聊天客服机器人的开发(下)

目录

“聊天机器人”项目说明

方案 1 :通过 Streamlit 部署聊天机器人

方案2 :通过 Gradio 部署聊天机器人

总结


上一节,咱们的聊天机器人已经基本完成,这节课,我们要看一看如何把它部署到网络上。

“聊天机器人”项目说明

简单回顾一下这个项目的设计。

第一步: 通过LangChain的ConversationChain,实现一个最基本的聊天对话工具。

第二步: 通过LangChain中的记忆功能,让这个聊天机器人能够记住用户之前所说的话。

第三步: 通过LangChain中的检索功能,整合易速鲜花的内部文档资料,让聊天机器人不仅能够基于自己的知识,还可以基于易速鲜花的业务流程,给出专业的回答。

第四步(可选): 通过LangChain中的数据库查询功能,用户可以输入订单号来查询订单状态,或者看看有没有存货等等。

第五步: 在网络上部署及发布这个聊天机器人,供企业内部员工和易速鲜花用户使用。

在上一个项目中,我们是通过 Flask 部署的人脉工具。Flask是一个通用的、微型的Web应用框架,非常适合创建各种Web应用程序,不仅仅局限于机器学习或数据科学项目。Flask为开发者提供了很高的灵活性,你可以自定义路由、模板、前端和后端的交互等等。对于初学者,Flask可能需要更长时间来学习,尤其是需要结合其他前端技术或数据库技术时。

不过,对于机器学习项目来说,我们还有其他部署方案。比如 Streamlit 和 Gradio,就为机器学习和数据科学应用提供了快速、专门化的解决方案。如果你的项目目标是快速展示和验证模型效果,那么 Streamlit 和 Gradio 是优秀的选择。这些框架提供了简单易用的 API 和丰富的可视化组件,让你可以用少量代码快速构建交互式应用程序,提高你的开发效率,也可以更好地展示工作成果。

下面,我就带着你用这两种机器学习部署框架来展示我们的聊天机器人。

方案 1 :通过 Streamlit 部署聊天机器人

首先来看看Streamlit。这是一个挺有名的专门为数据科学家和机器学习工程师设计的开源Python库,它可以迅速地将Python脚本转化为交互式Web应用。

Streamlit 的一些主要特点和亮点包括:

  • 简易性:Streamlit 的真正魅力在于它的简单性,只需几行代码,你就可以为其数据或模型创建交互式应用。
  • 无需前端经验:与传统的Web开发框架相比,使用 Streamlit,你不需要深入了解HTML、CSS或JavaScript,所有交互都是通过Python代码来管理的。
  • 实时交互:当你更改代码或数据时,Streamlit 应用会实时更新,这为迭代和实验提供了极大的便利。
  • 内置组件:Streamlit 附带了许多内置的可视化和交互组件,如滑块、按钮、表格等,可以无缝集成到你的应用中。
  • 数据集可视化:除了基本的图形和图表,Streamlit 还支持其他数据可视化库,如 Plotly、Matplotlib 和 Altair,使你能够轻松地展示数据。
  • 设计简洁:Streamlit 的界面设计简洁而优雅,使得应用程序看起来既专业又时尚。
  • 部署和共享:尽管 Streamlit 专注于创建应用,但它也有与部署和分享相关的工具和整合,如 Streamlit Sharing,允许你免费托管其应用。
  • 社区与生态系统:Streamlit 拥有一个积极的开源社区,定期提供新的功能更新、组件和扩展。

我们用下面的语句,安装Streamlit。

pip install streamlit

然后,简单的几行代码,就可以做出一个网页版的小程序。

import streamlit as st# 设置标题
st.title('平方计算器')# 创建一个滑块
number = st.slider("Select a number:", min_value=0, max_value=100)# 显示选中数字的平方
st.write(f"Square of {number} is {number ** 2}")

用 streamlit run <your_script_name>.py(注意,必须是streamlit run命令,而不是通过python命令来跑程序)来运行程序,就可以在浏览器中看到它。

streamlit run 01_SimpleStreamlit.py

此时,在 localhost 的 8501 端口,程序开始启动。

下面就通过 Streamlit 来重构聊天机器人。

# 导入所需的库
import os
import streamlit as st
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain.embeddings import OpenAIEmbeddings
from langchain.vectorstores import Qdrant
from langchain.memory import ConversationSummaryMemory
from langchain.chat_models import ChatOpenAI
from langchain.chains import ConversationalRetrievalChain
from langchain.document_loaders import PyPDFLoader
from langchain.document_loaders import Docx2txtLoader
from langchain.document_loaders import TextLoader# 设置OpenAI API密钥
os.environ["OPENAI_API_KEY"] = 'Your OpenAI Key'  # ChatBot类的实现
class ChatbotWithRetrieval:def __init__(self, dir):# 加载Documentsbase_dir = dir # 文档的存放目录documents = []for file in os.listdir(base_dir): file_path = os.path.join(base_dir, file)if file.endswith('.pdf'):loader = PyPDFLoader(file_path)documents.extend(loader.load())elif file.endswith('.docx') or file.endswith('.doc'):loader = Docx2txtLoader(file_path)documents.extend(loader.load())elif file.endswith('.txt'):loader = TextLoader(file_path)documents.extend(loader.load())# 文本的分割text_splitter = RecursiveCharacterTextSplitter(chunk_size=200, chunk_overlap=0)all_splits = text_splitter.split_documents(documents)# 向量数据库self.vectorstore = Qdrant.from_documents(documents=all_splits, # 以分块的文档embedding=OpenAIEmbeddings(), # 用OpenAI的Embedding Model做嵌入location=":memory:",  # in-memory 存储collection_name="my_documents",) # 指定collection_name# 初始化LLMself.llm = ChatOpenAI()# 初始化Memoryself.memory = ConversationSummaryMemory(llm=self.llm, memory_key="chat_history", return_messages=True)# 设置Retrieval Chainretriever = self.vectorstore.as_retriever()self.qa = ConversationalRetrievalChain.from_llm(self.llm, retriever=retriever, memory=self.memory)def chat_loop(self):print("Chatbot 已启动! 输入'exit'来退出程序。")while True:user_input = input("你: ")if user_input.lower() == 'exit':print("再见!")break# 调用 Retrieval Chain  response = self.qa(user_input)print(f"Chatbot: {response['answer']}")# Streamlit界面的创建
def main():st.title("易速鲜花聊天客服")# Check if the 'bot' attribute exists in the session stateif "bot" not in st.session_state:st.session_state.bot = ChatbotWithRetrieval("OneFlower")user_input = st.text_input("请输入你的问题:")if user_input:response = st.session_state.bot.qa(user_input)st.write(f"Chatbot: {response['answer']}")if __name__ == "__main__":main()

以下是使用 Streamlit 进行的更改和添加功能的简要说明。

  1. 界面创建:

    a. st.title("易速鲜花聊天客服"):设置 Web 应用程序的标题为“易速鲜花聊天客服”。  

  2. 会话状态:

    a. 使用 st.session_state 来存储用户会话状态。这是 Streamlit 的一个特性,允许你在用户与应用程序交互时保存变量。

    b. if "bot" not in st.session_state:检查是否已经有一个 bot 实例存在于 session state 中。如果没有,就创建一个新的 ChatbotWithRetrieval 实例,并将其保存到 session state。这样做的好处是可以避免在每次用户与应用程序交互时重新初始化机器人。  

  3. 用户交互:

    a. user_input = st.text_input("请输入你的问题:"):创建一个文本输入框供用户输入问题。当用户输入内容并提交后,代码会获取用户的输入,并使用聊天机器人的 qa 方法来获取响应。

    b. st.write(f"Chatbot: {response['answer']}"):在应用程序界面上显示机器人的响应。  

  4. 主函数中,当脚本被执行时,它将启动 Streamlit 服务器,并显示创建的 Web 应用程序。

用 streamlit run 运行程序,就可以开始聊天了!

方案2 :通过 Gradio 部署聊天机器人

与 Streamlit 不同,Gradio 界面更侧重于模型的交互,据说上手也更简单。这使得 Gradio 非常适合展示和测试机器学习模型。我在GitHub上看到很多新的开源LLM都是提供一个Gradio UI界面来进行测试的。相比之下, Streamlit 则提供了更丰富的 Web 应用开发功能。

到底有多简单,等会你看到 Gradio UI的界面,你就明白我的意思了。

下面,我们先安装这个包。

pip install gradio

通过 Gradio 框架重构聊天机器人的程序代码如下:

# 导入所需的库
import os
import gradio as gr
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain.embeddings import OpenAIEmbeddings
from langchain.vectorstores import Qdrant
from langchain.memory import ConversationSummaryMemory
from langchain.chat_models import ChatOpenAI
from langchain.chains import ConversationalRetrievalChain
from langchain.document_loaders import PyPDFLoader
from langchain.document_loaders import Docx2txtLoader
from langchain.document_loaders import TextLoader# 设置OpenAI API密钥
os.environ["OPENAI_API_KEY"] = 'Your OpenAI Key'  class ChatbotWithRetrieval:def __init__(self, dir):# 加载Documentsbase_dir = dir # 文档的存放目录documents = []for file in os.listdir(base_dir): file_path = os.path.join(base_dir, file)if file.endswith('.pdf'):loader = PyPDFLoader(file_path)documents.extend(loader.load())elif file.endswith('.docx') or file.endswith('.doc'):loader = Docx2txtLoader(file_path)documents.extend(loader.load())elif file.endswith('.txt'):loader = TextLoader(file_path)documents.extend(loader.load())# 文本的分割text_splitter = RecursiveCharacterTextSplitter(chunk_size=200, chunk_overlap=0)all_splits = text_splitter.split_documents(documents)# 向量数据库self.vectorstore = Qdrant.from_documents(documents=all_splits, # 以分块的文档embedding=OpenAIEmbeddings(), # 用OpenAI的Embedding Model做嵌入location=":memory:",  # in-memory 存储collection_name="my_documents",) # 指定collection_name# 初始化LLMself.llm = ChatOpenAI()# 初始化Memoryself.memory = ConversationSummaryMemory(llm=self.llm, memory_key="chat_history", return_messages=True)# 初始化对话历史self.conversation_history = ""# 设置Retrieval Chainretriever = self.vectorstore.as_retriever()self.qa = ConversationalRetrievalChain.from_llm(self.llm, retriever=retriever, memory=self.memory)def get_response(self, user_input):  # 这是为 Gradio 创建的新函数response = self.qa(user_input)# 更新对话历史self.conversation_history += f"你: {user_input}\nChatbot: {response['answer']}\n"return self.conversation_historyif __name__ == "__main__":folder = "OneFlower"bot = ChatbotWithRetrieval(folder)# 定义 Gradio 界面interface = gr.Interface(fn=bot.get_response,  # 使用我们刚刚创建的函数inputs="text",  # 输入是文本outputs="text",  # 输出也是文本live=False,  # 实时更新,这样用户可以连续与模型交互title="易速鲜花智能客服",  # 界面标题description="请输入问题,然后点击提交。"  # 描述)interface.launch()  # 启动 Gradio 界面

以下是 Gradio 部分代码的详细解释。

  1. get_response(self, user_input):这个新函数是为 Gradio 创建的,它接收用户输入作为参数,并返回机器人的响应。为了保持聊天历史连续性,此函数将每次的用户输入和机器人的响应添加到 conversation_history,并返回整个聊天历史。  
  2. 使用 gr.Interface() 来定义 Gradio 界面。fn=bot.get_response:设置界面的主函数为刚刚创建的 get_response 函数。live=False:确保实时更新是关闭的,这意味着用户需要点击提交按钮来发送他们的问题,而不是一边打字,一边生成回答的流模式(比较适合展示生成式模型)。  
  3. 启动 Gradio 界面。interface.launch():调用这个方法会启动 Gradio 的 Web 服务器,并在默认的 Web 浏览器中打开一个新窗口,显示刚刚定义的界面,用户可以通过这个界面与机器人交互。

运行程序,聊天机器人在本地端口 7860 上启动。

这里,输入输出窗口的配置更加清晰,而且相对于原来的只记录一轮对话的机器人,这里我们增加了历史对话信息记录功能。

总结

Streamlit 和 Gradio 都是让数据科学家和开发者能够快速为机器学习模型创建 Web UI 的框架。

  • Streamlit 是为数据应用、仪表板和可视化设计的。它提供了多种小部件,使得用户可以与数据和模型进行交互。它非常 Pythonic,意味着它的使用方式非常自然,对于熟悉Python的人来说非常直观。
  • Gradio 更多是为了展示和演示机器学习模型。它提供了一种快速的方法,使非技术用户也能与机器学习模型进行交互,无需编写复杂的代码。

以下是对它们特点进行的对比总结。

无论选择哪个框架,你都可以在非常短的时间内为你的应用创建一个Web UI。至于选择哪个,更多取决于你的具体需求和个人喜好。

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

STM32笔记(串口IAP升级)

一、IAP简介 IAP&#xff08;In Application Programming&#xff09;即在应用编程&#xff0c; IAP 是用户自己的程序在运行过程中对 User Flash 的部分区域进行烧写&#xff0c;目的是为了在产品发布后可以方便地通过预留的通信口对产 品中的固件程序进行更新升级。 通常实…

斐波那契堆与二叉堆在Prim算法中的性能比较:稀疏图与稠密图的分析

斐波那契堆与二叉堆在Prim算法中的性能比较:稀疏图与稠密图的分析 引言基本概念回顾Prim算法的时间复杂度分析稀疏图中的性能比较稠密图中的性能比较|E| 和 |V| 的关系伪代码与C代码示例结论引言 在图论中,Prim算法是一种用于求解最小生成树(MST)的贪心算法。其性能高度依…

使用argo workflow 实现springboot 项目的CI、CD

文章目录 基础镜像制作基础镜像设置镜像源并安装工具git下载和安装 Maven设置环境变量设置工作目录默认命令最终dockerfile 制作ci argo workflow 模版volumeClaimTemplatestemplatesvolumes完整workflow文件 制作cd argo workflow 模版Workflow 结构Templates 定义创建 Kubern…

BUUCTF—Reverse—不一样的flag(7)

是不是做习惯了常规的逆向题目&#xff1f;试试这道题&#xff0c;看你在能不能在程序中找到真正的flag&#xff01;注意&#xff1a;flag并非是flag{XXX}形式&#xff0c;就是一个’字符串‘&#xff0c;考验眼力的时候到了&#xff01; 注意&#xff1a;得到的 flag 请包上 f…

insmod一个ko提供基础函数供后insmod的ko使用的方法

一、背景 在内核模块开发时&#xff0c;多个不同的内核模块&#xff0c;有时候可能需要都共用一些公共的函数&#xff0c;比如申请一些平台性的公共资源。但是&#xff0c;这些公共的函数又不方便去加入到内核镜像里&#xff0c;这时候就需要把这些各个内核模块需要用到的一些…

LangGraph中的State管理

本教程将介绍如何使用LangGraph库构建和测试状态图。我们将通过一系列示例代码&#xff0c;逐步解释程序的运行逻辑。 1. 基本状态图构建 首先&#xff0c;我们定义一个状态图的基本结构和节点。 定义状态类 from langgraph.graph import StateGraph, START, END from typi…

MATLAB中Simulink的基础知识

Simulink是MATLAB中的一种可视化仿真工具&#xff0c; 是一种基于MATLAB的框图设计环境&#xff0c;是实现动态系统建模、仿真和分析的一个软件包&#xff0c;被广泛应用于线性系统、非线性系统、数字控制及数字信号处理的建模和仿真中。 Simulink提供一个动态系统建模、仿真和…

最小生成树-Prim与Kruskal算法

文章目录 什么是最小生成树&#xff1f;Prim算法求最小生成树Python实现&#xff1a; Kruskal算法求最小生成树并查集 Python实现&#xff1a; Reference 什么是最小生成树&#xff1f; 在图论中&#xff0c;树是图的一种&#xff0c;无法构成闭合回路的节点-边连接组合称之为…

关闭AWS账号后,服务是否仍会继续运行?

在使用亚马逊网络服务&#xff08;AWS&#xff09;时&#xff0c;用户有时可能会考虑关闭自己的AWS账户。这可能是因为项目结束、费用过高&#xff0c;或是转向使用其他云服务平台。然而&#xff0c;许多人对关闭账户后的服务状态感到困惑&#xff0c;我们九河云和大家一起探讨…

Could not locate device support files.

报错信息&#xff1a;Failure Reason: The device may be running a version of iOS (13.6.1 17G80) that is not supported by this version of Xcode.[missing string: 869a8e318f07f3e2f42e11d435502286094f76de] 问题&#xff1a;xcode15升级到xcode16之后&#xff0c;13.…

Linux文件基础

目录 一、文件类型 二、文件权限 三、权限修改 Linux中一切皆文件&#xff0c;文件目录分布呈树状数据结构&#xff0c;/是根目录&#xff0c;目录的源头 一、文件类型 类型字符说明普通-Linux中最多的一种文件类型&#xff0c;包括 纯文本文件(ASCII)、二进制文件(binary…

自然语言处理基础之文本预处理

一. NLP介绍 1957年, 怛特摩斯会议 二. 文本预处理 文本预处理及作用 将文本转换成模型可以识别的数据 文本转化成张量(可以利用GPU计算), 规范张量的尺寸. 科学的文本预处理可以有效的指导模型超参数的选择, 提升模型的评估指标 文本处理形式 分词 词性标注 命名实体识别…

外卖点餐系统小程序

目录 开发前准备 项目展示项目分析项目初始化封装网络请求 任务1 商家首页 任务分析焦点图切换中间区域单击跳转到菜单列表底部商品展示 任务2 菜单列表 任务分析折扣信息区设计菜单列表布局请求数据实现菜单栏联动单品列表功能 任务3 购物车 任务分析设计底部购物车区域添加商…

彻底理解如何保证ElasticSearch和数据库数据一致性问题

一.业务场景举例 需求&#xff1a; 一个卖房业务&#xff0c;双十一前一天&#xff0c;维护楼盘的运营人员突然接到合作开发商的通知&#xff0c;需要上线一批热门的楼盘列表&#xff0c;上传完成后&#xff0c;C端小程序支持按楼盘的名称、户型、面积等产品属性全模糊搜索热门…

单片机将图片数组调出来显示MPU8_8bpp_Memory_Write

界面显示图片是很常见的需求&#xff0c;使用外挂的FLASH是最常用的方法。但是如果图片需求不大&#xff0c;比如说我们只要显示一个小图标&#xff0c;那么为了节省硬件成本&#xff0c;是不需要外挂一颗FLASH芯片的&#xff0c;我们可以将图标转成数组&#xff0c;存在单片机…

VS的安装和配置

目录 概述 安装Visual Studio 下载引导安装包 在线安装&#xff08;推荐&#xff09; 使用Visual Studio进行开发 创建项目 配置项目 项目 VS 解决方案&#xff08;重要&#xff09; 命名 完成项目创建 创建源文件 编写代码 VS项目目录的说明&#xff08;补充&…

linux模拟HID USB设备及wireshark USB抓包配置

文章目录 1. 内核配置2. 设备配置附 wireshark USB抓包配置 linux下模拟USB HID设备的简单记录&#xff0c;其他USB设备类似。 1. 内核配置 内核启用USB Gadget&#xff0c;使用fs配置usb device信息。 Device Drivers ---> [*] USB support ---><*> USB …

【C++】vector的使用

1. vector的构造 (constrator)构造函数声明 接口说明 vector(); (重点) 无参构造 vector (const vector& x); &#xff08;重点&#xff09; 拷贝构造 vector (InputIterator first, InputIterator last); 使用迭代器区间进行初始化构造 vector (size_type n, co…

Easy Excel 通过【自定义批注拦截器】实现导出的【批注】功能

目录 Easy Excel 通过 【自定义批注拦截器】实现导出的【批注】功能需求原型&#xff1a;相关数据&#xff1a;要导出的对象字段postman 格式导出对象VO 自定义批注拦截器业务代码&#xff1a; 拦截器代码解释&#xff1a;详细解释&#xff1a;格式优化&#xff1a; Easy Excel…

Qt/C++基于重力模拟的像素点水平堆叠效果

本文将深入解析一个基于 Qt/C 的像素点模拟程序。程序通过 重力作用&#xff0c;将随机分布的像素点下落并水平堆叠&#xff0c;同时支持窗口动态拉伸后重新计算像素点分布。 程序功能概述 随机生成像素点&#xff1a;程序在初始化时随机生成一定数量的像素点&#xff0c;每个…