【Gradio】Chatbot | 如何使用 Gradio Blocks 创建自定义聊天机器人

news2024/11/19 19:29:37

简介

重要提示:如果您刚开始接触,我们建议使用 gr.ChatInterface 来创建聊天机器人——它是一个高级抽象,使得可以快速创建漂亮的聊天机器人应用程序,往往只需一行代码。在这里了解更多信息。

本教程将展示如何使用 Gradio 的低级 Blocks API 从头开始制作聊天机器人 UI。这将使您完全控制您的聊天机器人 UI。您将首先创建一个简单的聊天机器人来显示文本,第二个聊天机器人来流式传输文本响应,最后一个聊天机器人还可以处理媒体文件。我们创建的聊天机器人界面将如下所示:

0fc75080e9855e77966ba8cf2c34bd83.png

先决条件:我们将使用 gradio.Blocks 类来构建我们的聊天机器人演示。如果您还不熟悉它,可以先阅读 Blocks 指南。另外,请确保您使用的是 Gradio 的最新版本: pip install --upgrade gradio 。

一个简单的聊天机器人演示 

让我们从重现上面的简单演示开始。你可能已经注意到,我们的机器人对任何输入只是随机回答“你好吗?”,“我爱你”,或者“我非常饿”。以下是用 Gradio 创建这个的代码:

import gradio as gr  # 导入gradio库
import random  # 导入random库,用于生成随机数
import time  # 导入time库,用于控制时间相关的功能


# 使用gr.Blocks创建一个Gradio界面
with gr.Blocks() as demo:
    chatbot = gr.Chatbot()  # 创建一个聊天机器人组件
    msg = gr.Textbox()  # 创建一个文本框组件,用于用户输入消息
    clear = gr.ClearButton([msg, chatbot])  # 创建一个清除按钮,用于清除文本框和聊天机器人的内容


    # 定义一个响应函数,用于处理用户消息和聊天历史
    def respond(message, chat_history):
        # 机器人随机选择一条消息作为回复
        bot_message = random.choice(
            ["How are you?", "I love you", "I'm very hungry"])
        # 将用户消息和机器人消息添加到聊天历史中
        chat_history.append((message, bot_message))
        # 等待2秒钟
        time.sleep(2)
        # 返回空字符串和更新后的聊天历史
        return "", chat_history


    # 当文本框提交时,调用respond函数,并更新文本框和聊天机器人的内容
    msg.submit(respond, [msg, chatbot], [msg, chatbot])


# 启动应用程序
demo.launch()

这里有三个 Gradio 组件:

  • 一个 Chatbot ,它的值存储了用户和机器人之间对话的完整历史,作为响应对的列表。

  • 一个 Textbox ,用户可以在其中输入他们的消息,然后按回车/提交以触发聊天机器人的回应

  • 一个 ClearButton 按钮来清除文本框和整个聊天机器人的历史记录

我们有一个单一的函数, respond() ,它接收聊天机器人的整个历史记录,在记录中添加一个随机消息,等待2 秒钟,然后返回更新后的聊天历史。 respond() 函数在返回时也会清除文本框。

当然,在实践中,你会用你自己更复杂的函数来替换 respond() ,这个函数可能会调用一个预训练的模型或者一个 API 来生成回应。

将流媒体添加到您的聊天机器人 

我们可以通过几种方式来改善上述聊天机器人的用户体验。首先,我们可以流式传输回应,这样用户就不必等待消息生成那么长时间。其次,我们可以让用户消息立即显示在聊天历史中,同时生成聊天机器人的回应。以下是实现该功能的代码:

7bb54715ce15f58602c4a940233b005d.png

import gradio as gr  # 导入Gradio库
import random  # 导入random库,用于生成随机回复
import time  # 导入time库,用于控制延迟


# 使用Gradio的Blocks构建一个应用程序界面
with gr.Blocks() as demo:
    chatbot = gr.Chatbot()  # 创建一个聊天机器人组件
    msg = gr.Textbox()  # 创建一个文本框组件,用于用户输入消息
    clear = gr.Button("Clear")  # 创建一个按钮组件,用于清除聊天历史


    # 定义一个函数,用于处理用户消息并更新聊天历史
    def user(user_message, history):
        return "", history + [[user_message, None]]


    # 定义一个函数,用于生成机器人的回复并逐字符更新聊天历史
    def bot(history):
        bot_message = random.choice(["How are you?", "I love you", "I'm very hungry"])
        history[-1][1] = ""
        for character in bot_message:
            history[-1][1] += character
            time.sleep(0.05)  # 每个字符之间添加0.05秒的延迟
            yield history


    # 当用户提交消息时,先调用user函数,然后调用bot函数
    msg.submit(user, [msg, chatbot], [msg, chatbot], queue=False).then(
        bot, chatbot, chatbot
    )
    # 当点击清除按钮时,清除聊天历史
    clear.click(lambda: None, None, chatbot, queue=False)
    
# 启用队列功能
demo.queue()
# 启动应用程序
demo.launch()

757fa5e716bee141945dbb09bb7f20a9.png

您会注意到,当用户提交他们的消息时,我们现在将三个事件与 .then() 链接起来:

  1. 第一种方法 user() 会用用户的消息更新聊天机器人,并清空输入字段。这个方法还会使输入字段变为非交互式的,这样用户在聊天机器人回应时就不能发送其他消息。因为我们希望这能立即发生,我们设置了 queue=False ,如果启用了队列,它将跳过任何队列。聊天机器人的历史记录中附加了 (user_message, None) , None 表示机器人尚未回应。

  2. 第二种方法, bot() 会用机器人的回应更新聊天机器人的历史记录。我们不是创建一个新消息,而是用机器人的回应替换之前创建的 None 消息。最后,我们逐个字符地构建消息,并且 yield 在它们被构建的过程中的中间输出。Gradio 会自动将任何带有 yield 关键字的函数转变为流输出接口。

  3. 第三种方法使输入字段再次变得互动,以便用户可以向机器人发送另一条消息。

当然,在实践中,你会用你自己更复杂的函数来替换 bot() ,这个函数可能会调用一个预训练的模型或者一个 API 来生成回应。

最后,我们通过运行 demo.queue() 来启用排队,这对于流式传输中间输出是必需的。您可以通过滚动到本页面顶部的演示来尝试改进后的聊天机器人。

喜欢/不喜欢聊天消息 

一旦您创建了您的 gr.Chatbot ,您就可以增加用户喜欢或不喜欢消息的功能。如果您希望用户对机器人的回复进行投票或标记不当的结果,这可能会很有用。

要将此功能添加到您的聊天机器人中,只需将一个 .like() 事件附加到您的聊天机器人即可。拥有 .like() 事件的聊天机器人将会在每条机器人消息旁边自动显示一个点赞图标和一个点踩图标。

.like() 方法要求您传入一个函数,当用户点击这些图标时会调用该函数。在您的函数中,应该有一个参数,其类型为 gr.LikeData 。Gradio 会自动为这个参数提供一个包含有关点赞或不喜欢消息的信息的对象。以下是一个简单的示例,展示如何让用户对聊天消息表示喜欢或不喜欢:

8353e89a4f3f491718af82b20dfff04f.png

import gradio as gr  # 导入Gradio库


# 定义一个问候函数,它接收历史记录和用户输入,返回更新后的历史记录
def greet(history, input):
    return history + [(input, "Hello, " + input)]  # 将用户输入和问候语添加到历史记录中


# 定义一个投票函数,它接收点赞数据
def vote(data: gr.LikeData):
    if data.liked:
        print("You upvoted this response: " + data.value)  # 如果用户点赞,打印点赞信息
    else:
        print("You downvoted this response: " + data.value)  # 如果用户点踩,打印点踩信息
    


# 使用Gradio的Blocks创建一个新的应用程序
with gr.Blocks() as demo:
    chatbot = gr.Chatbot()  # 创建一个聊天机器人组件
    textbox = gr.Textbox()  # 创建一个文本框组件,用于用户输入消息
    # 当用户在文本框中提交消息时,调用greet函数,并更新聊天机器人的内容
    textbox.submit(greet, [chatbot, textbox], [chatbot])
    # 为聊天机器人添加点赞/点踩功能
    chatbot.like(vote, None, None)  # 添加这行代码会在聊天机器人中显示点赞/点踩图标
    
# 启动应用程序
demo.launch()

3f35a2704ddb406b3f3e6f4c68d09554.png

添加 Markdown、图片、音频或视频 

gr.Chatbot 组件支持部分 Markdown 语法,包括粗体、斜体和代码。例如,我们可以编写一个这样的函数,它对用户的消息作出响应,并用粗体显示“太酷了!”:

def bot(history):
    response = "**That's cool!**"
    history[-1][1] = response
    return history

此外,它可以处理媒体文件,如图像、音频和视频。您可以使用 MultimodalTextbox 组件轻松地将所有类型的媒体文件上传到您的聊天机器人。要传入媒体文件,我们必须像这样将文件作为两个字符串的元组传入: (filepath, alt_text) 。 alt_text 是可选的,所以您也可以只传入一个元素的元组 (filepath,) ,像这样:

def add_message(history, message):
    for x in message["files"]:
        history.append(((x["path"],), None))  
    if message["text"] is not None:
        history.append((message["text"], None))
    return history, gr.MultimodalTextbox(value=None, interactive=False, file_types=["image"])

将这些结合起来,我们可以创建一个多模态聊天机器人,它有一个多模态文本框,用户可以提交文本和媒体文件。代码的其余部分与之前大致相同:

a95fefb38243dd61c19195fc59abcce5.png

这段代码创建了一个Gradio聊天机器人,用户可以通过多模态文本框输入文本消息或上传文件,并且可以对聊天机器人的回复进行点赞或点踩。机器人的回复是预设的文本,并且支持流式文本,即字符会逐个显示,模拟打字效果。整个应用程序使用Gradio库构建,它允许快速创建交互式的机器学习或其他类型的应用程序。此外,应用程序支持队列功能,可以处理多个用户的请求。

import gradio as gr  # 导入Gradio库,用于创建交互式应用程序
import os  # 导入os库,用于操作系统功能,如文件路径操作
import time  # 导入time库,用于控制时间相关的功能


# 这是一个多模态输入的聊天机器人演示,支持文本、Markdown、LaTeX、代码块、图片、音频和视频输入。同时展示了对流式文本的支持。


def print_like_dislike(x: gr.LikeData):
    print(x.index, x.value, x.liked)  # 定义一个函数,打印用户对聊天机器人回复的点赞或点踩的数据


def add_message(history, message):
    for x in message["files"]:  # 遍历消息中的文件
        history.append(((x,), None))  # 将文件添加到历史记录中
    if message["text"] is not None:  # 如果消息中包含文本
        history.append((message["text"], None))  # 将文本消息添加到历史记录中
    return history, gr.MultimodalTextbox(value=None, interactive=False)  # 返回更新后的历史记录和一个多模态文本框


def bot(history):
    response = "**That's cool!**"  # 定义机器人的响应文本
    history[-1][1] = ""  # 清空历史记录中最后一条消息的机器人回复部分
    for character in response:  # 遍历响应文本中的每个字符
        history[-1][1] += character  # 将字符逐个添加到机器人回复中
        time.sleep(0.05)  # 每添加一个字符后暂停0.05秒
        yield history  # 生成更新后的历史记录


with gr.Blocks() as demo:  # 使用Gradio的Blocks创建一个新的应用程序
    chatbot = gr.Chatbot(
        [],
        elem_id="chatbot",
        bubble_full_width=False  # 创建一个聊天机器人组件,设置不使用全宽度的气泡
    )#创建一个Chatbot组件,用于显示聊天记录。初始聊天记录为空,设置元素ID为chatbot,并禁用气泡全宽显示
    #创建一个MultimodalTextbox组件,用于用户输入。设置为可交互,允许上传图像文件,并设置占位符文本。
    chat_input = gr.MultimodalTextbox(interactive=True, file_types=["image"], placeholder="Enter message or upload file...", show_label=False)  # 创建一个多模态文本框,允许用户输入消息或上传文件
    # 将chat_input的提交事件绑定到add_message函数,当用户提交输入时,调用add_message函数更新聊天记录。
    chat_msg = chat_input.submit(add_message, [chatbot, chat_input], [chatbot, chat_input])  # 当用户提交消息时,调用add_message函数,并更新聊天机器人的内容
    bot_msg = chat_msg.then(bot, chatbot, chatbot, api_name="bot_response")  # 然后调用bot函数,生成机器人的响应
    bot_msg.then(lambda: gr.MultimodalTextbox(interactive=True), None, [chat_input])  # 然后更新多模态文本框,以便用户可以继续输入


    chatbot.like(print_like_dislike, None, None)  # 为聊天机器人添加点赞/点踩功能


demo.queue()  # 启用队列功能
demo.launch()  # 启动应用程序

1f988a11b9407a81aa34f2cdefbb7f2b.png

完成了!这就是构建聊天机器人模型界面所需的全部代码。最后,我们将在指南中附上一些在空间上运行的聊天机器人的链接,以便您了解还有哪些可能:

  • project-baize/Baize-7B:一个风格化的聊天机器人,允许您停止生成以及重新生成响应。

  • MAGAer13/mPLUG-Owl:一个多模态聊天机器人,允许您对回答进行点赞和点踩。

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

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

相关文章

【网络安全】简单的免杀方法(非常详细)零基础入门到精通,收藏这一篇就够了_免杀加壳工具

目录 一、免杀的概念 二、免杀系统搭建 三、免杀工具介绍 1、myccl 2、C32asm 3、OD 4、LordPE 5、ImportREC 6、VC6.0/visual studio 7、数字签名 四、关于杀软排名不分前后 1、360。 2、金山毒霸 3、江民 4、瑞星 5、安天防线 6、卡巴斯基 7、NOD32 8、诺…

【日记】被客户一顿输出该怎么办(431 字)

正文 上午有个客户在电话里对着我一顿输出,说他们没有发票财务账务没法处理怎么怎么的。话里话外满满一股 “全是你们的错” 的味道。 当时我很想笑,大姐,你对我输出有啥用啊。票是上级行开的,我们又没有开票权限,对我…

openEuler23.09安装MySQL8.4.0

在openEuler-23.09上安装MySQL8.4.0 一、MySQL数据库服务环境搭建 操作系统版本 openEuler-23.09-x86_64-dvd.iso ,安装步骤此处省略。。。 MySQL8.4.0下载地址 https://dev.mysql.com/downloads/mysql/ 1.1、下载及上传mysql二进制安装包 上传mysql-8.4.0-linu…

游戏中插入音效

一、背景音乐 准备:素材音乐 方法: 1、方法1: (1) 将背景音乐 bgAudio 拖放到Hierarchy面板 (2) 选中 bgAudio,勾选开始运行就播放、循环播放。调节音量(volume) 2、方法2: (1) Create Empty&#x…

Zabbix自定义监控JAVA进程

一.定义脚本 二 .ZABBIX得agent允许以root身份执行 三. Zabbix测试自定item是否成功 四.ZABBIX服务端web添加新得item项 五.查看最新数据,取值成功

002.Linux CentOS7 安装

我 的 个 人 主 页:👉👉 失心疯的个人主页 👈👈 入 门 教 程 推 荐 :👉👉 Python零基础入门教程合集 👈👈 虚 拟 环 境 搭 建 :👉&…

客户端输入网址后发生的全过程解析(协议交互、缓存、渲染)

目录 1. 输入 URL 并按下回车键2. DNS 解析3. TCP 连接4. 发送 HTTP 请求5. 服务器处理请求6. 发送 HTTP 响应7. 浏览器接收响应8. 渲染网页9. 执行脚本10. 处理其他资源11. TLS/SSL 加密(如果使用 HTTPS)握手过程 12. 协议协商和优化 总结 1. 输入 URL …

有关排序的算法

目录 选择法排序 冒泡法排序 qsort排序(快速排序) qsort排序整型 qsort排序结构体类型 排序是我们日常生活中比较常见的问题,这里我们来说叨几个排序的算法。 比如有一个一维数组 arr[8] {2,5,3,1,7,6,4,8},我们想要把它排成升序&#…

苹果将推出全新AI培训课程;生成式AI手机市场将迎来爆发式增长

🦉 AI新闻 🚀 苹果将推出全新AI培训课程 摘要:IT之家消息,苹果宣布,今年秋季将在6个国家的18所开发者学院推出AI培训课程,目标群体为学生、导师和校友。课程涵盖机器学习模型的构建及部署,Cor…

姜萍的启示:分数不是唯一,天赋引领专业选择超越名校

你好,我是三桥君。 24年高考帷幕落下,一场新的思考与选择悄然来临。 对于每一位高考考生,学校和专业都是开启大学新生活的两个前置必选项。 在这关键时刻,全网媒体却被一则关于“一名17岁中专女学生姜萍在全球数学竞赛获得第12名”…

数字孪生涉及到的9大技术栈,都是难啃骨头呀。

数字孪生涉及到多个技术栈,包括但不限于以下几个方面: 数据采集和传感器技术: 数字孪生需要实时获取物理世界的数据,因此需要使用各种传感器技术(如温度传感器、压力传感器、运动传感器等)来采集数据&…

排序(3)【归并排序】【计数排序】【排序算法度及其稳定性分析】

一.归并排序 归并排序(MERGE-SORT)是建立在归并操作上的一种有效的排序算法,该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有…

C++ 66 之 类模版

#include <iostream> #include <string> using namespace std;// 习惯性 < >中 类模板用class 普通的函数模板就用typename // template<class NAMETYPE, class AGETYPE> template<class NAMETYPE, class AGETYPE int> // 可以设置默认的类型值…

集团门户网站的设计

管理员账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;管理员管理&#xff0c;论坛管理&#xff0c;集团文化管理&#xff0c;基础数据管理&#xff0c;公告通知管理 前台账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;论坛&#xff0…

收银系统源码-千呼新零售2.0【线下促销】

千呼新零售2.0系统是零售行业连锁店一体化收银系统&#xff0c;包括线下收银线上商城连锁店管理ERP管理商品管理供应商管理会员营销等功能为一体&#xff0c;线上线下数据全部打通。 适用于商超、便利店、水果、生鲜、母婴、服装、零食、百货等连锁店使用。 详细介绍请查看下…

在LangChain中,LLM(大型语言模型)和LLM Chain的区别是什么?

简单来说&#xff0c;LLM是一个大型语言模型&#xff0c;而LLM Chain是由多个LLM或其他组件组成的链式结构&#xff0c;用于在LangChain中构建复杂的自然语言处理流程。 Direct LLM Interface: 直接大型语言模型&#xff08;LLM&#xff09;接口&#xff1a; llm Open…

【NOI-题解】1234. 任意输入一正整数N,要求把它拆成质因子的乘积。1446. 人口增长问题

文章目录 一、前言二、问题问题&#xff1a;1234. 任意输入一正整数N&#xff0c;要求把它拆成质因子的乘积。问题&#xff1a;1446. 人口增长问题 三、感谢 一、前言 本章节主要对循环应用的题目进行讲解&#xff0c;包括《1234. 任意输入一正整数N&#xff0c;要求把它拆成质…

防止员工离职导致数据泄露,员工离职后把文件带出公司

中科数安的电脑文件资料透明加密防泄密系统确实能够在一定程度上防止员工离职导致的数据泄露。以下是具体的分析&#xff1a; www.weaem.com 访问控制与权限管理&#xff1a;系统实施了严格的权限管理制度&#xff0c;对核心文件和数据资源进行细致的访问权限划分。这意味着&am…

【数据结构与算法】稀疏矩阵(三元组,十字链表存储)详解

给出稀疏矩阵的节省内存的存贮结构并写出相应的输入、输出算法。 稀疏矩阵是一个大部分元素为0的矩阵。为了节省内存&#xff0c;我们可以只存储非零元素。一种常见的存储结构是三元组&#xff0c;每个三元组包含一个非零元素的行索引、列索引和值。 #include <stdio.h>…

BC-Linux 8.6最小化安装的服务器启用GNOME图形化界面

本文记录了BC-Linux 8.6最小化安装的服务器如何启用GNOME图形化界面的过程。 一、服务器环境 1、系统版本 [rootlocalhost ~]# cat /etc/os-release NAME"BigCloud Enterprise Linux" VERSION"8.6 (Core)" ID"bclinux" ID_LIKE"rhel fe…