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

简介

重要提示:如果您刚开始接触,我们建议使用 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] += charactertime.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] = responsereturn 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.mzph.cn/pingmian/30018.shtml

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

相关文章

vue3中实现3D地图——three.js

需求点 地图区域大小随着父盒子大小变动,窗口缩放自动适配每个区域显示不同颜色和高度,描边每个区域显示名字label和icon点击区域改变其透明度,并且弹窗显示信息窗口点击点也可以可以自由放大缩小,360度旋转 包 npm install d3^…

背景渐变动画登录页

b站视频演示效果: 效果图: 完整代码: <!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>背景…

大模型商业化:李开复向左,张亚勤向右

文&#xff5c;白 鸽 “零一万物坚决做To C&#xff0c;不做赔钱的To B&#xff0c;要做能赚钱的To B。”2024年6月14日&#xff0c;在智源大会上&#xff0c;零一万物创始人李开复如此坚定地说道。 而与之相对&#xff0c;中国工程院院士、清华大学智能产业研究院&…

2024/06/18--代码随想录算法8/17| 股票问题

121.买卖股票的最佳时机 力扣链接 动规五部曲 确定dp数组&#xff08;dp table&#xff09;以及下标的含义 dp[i][0] 表示第i天持有股票所得最多现金,dp[i][1] 表示第i天不持有股票所得最多现金确定递推公式 dp[i][0] max(dp[i-1][0], -price[i]) dp[i][1]max(dp[i-1][1], …

QTimeEdit、QDateEdit、QDateTimeEdit、QCalendarWidget

实验 QTime和字符串相互转换 QDate和字符串相互转换 QDateTime和字符串相互转换 QCalendarWidget使用 year&#xff0c;month&#xff0c;day&#xff0c;minute&#xff0c;second&#xff0c;msec&#xff0c;dayOfWeek, dayto方法/属性的使用 布局 datetimeexample.cpp #inc…

智慧之选:Vatee万腾平台,引领未来的创新引擎

在数字化浪潮席卷全球的今天&#xff0c;我们身处一个信息爆炸、技术革新的时代。在这样的大背景下&#xff0c;选择一个能够引领我们走向未来的平台显得尤为重要。而Vatee万腾平台&#xff0c;正是这样一个不容错过的智慧之选。 Vatee万腾平台&#xff0c;作为一个集创新、科技…

PostgreSQL源码分析——口令认证

认证机制 对于数据库系统来说&#xff0c;其作为服务端&#xff0c;接受来自客户端的请求。对此&#xff0c;必须有对客户端的认证机制&#xff0c;只有通过身份认证的客户端才可以访问数据库资源&#xff0c;防止非法用户连接数据库。PostgreSQL支持认证方法有很多&#xff1…

Stable Diffusion 3 Medium 正式开源

Stable Diffusion 3 Medium 正式开源 Stability AI宣布Stable Diffusion 3 Medium现已开源&#xff0c;这是最新的文本生成图像AI模型&#xff0c;被官方声称为“迄今为止最先进的开源模型”&#xff0c;其性能超过了Midjourney 6。 这款Stable Diffusion 3 Medium模型拥有2…

【SpringBoot项目常见细化错误】(保姆级教程)Result Maps collection already contains value for

SpringBoot项目常见错误 1.当Mybatis报错 Result Maps collection already contains value for一、重复点击Mybatis-Generator导致配置文件重复生成XML二、正确配置Yml仔细检查有没有多了或者少了一个空格三、spring boot mybatis四、应该用resultMap来接收返回值&#xff0c;…

Blazor的SSR服务端渲染是不是交互式的

从.NET8开始&#xff0c;Blazor引入了SSR服务端渲染&#xff0c;归功于MVC和RazePage的沉淀&#xff0c;虽然来得晚&#xff0c;但一经发布&#xff0c;就将Blazor推向了新的高度。从今年开始&#xff0c;Youtube上关于Blazor的优质教学视频&#xff0c;以肉眼可见的速度在增加…

[保姆级教程]uniapp实现接口请求和请求方法二次封装

文章目录 新建文件配置方法发送请求使用 新建文件 现在src中新建一个api目录 新建index.js和request.js文件 配置方法发送请求 request.js中输入以下内容 const http {baseUrl: http://127.0.0.1:8000,request(config) {config beforeRequest(config)config.url this…

前端工具篇

在线工具 https://tool.lu/ 程序员工具箱 http://tool.pfan.cn/apitest 配色 https://webkul.github.io/coolhue/ 在线字符串和16进制互转 https://kw360.net/ox2str/ 代码美化截图 https://carbon.now.sh/?bgrgba 菜鸟工具 https://www.jyshare.com/ 文件格式转换 htt…

C++智能指针auto_ptr(有缺陷已废弃)

一、auto_ptr不能共享所有权 auto_ptr类没有拷贝构造函数。可以看出将Right对象的资源释放掉了。 在下面的操作中&#xff0c;ptr1的值给ptr2&#xff0c;那么此时ptr1的值将会为nullptr。在构造和赋值都发生了所有权的转移。调用函数的时候&#xff0c;接收参数的时候同样也会…

Rapidfuzz,一个高效的 Python 模糊匹配神器

目录 01初识 Rapidfuzz 什么是 Rapidfuzz? 为什么选择 Rapidfuzz? 安装 Rapidfuzz 配置 Rapidfuzz 02基本操作 简单比率计算 03高级功能 查找单个最佳匹配 查找多个最佳匹配 使用阈值优化性能 04实战案例…

IPython大师课:提升数据科学工作效率的终极工具

IPython是一个增强的Python交互式shell&#xff0c;它提供了丰富的功能和易用性改进&#xff0c;特别适合进行数据分析、科学计算和一般的Python开发。本文将全面介绍IPython的基本概念、使用方法、主要作用以及注意事项。 一、IPython简介 1. IPython的起源 IPython最初由Fe…

【Android】使用Binder(AIDL)实现利用自定义Bean进行的进程间通信(二)

项目前置 这是我之前写的关于Binder的一些知识点和使用基本数据类型在通信的文章&#xff0c;感兴趣的可以看一下: Binder&#xff08;一&#xff09;Binder的介绍和AIDL使用Binder的实例 项目目标 在两个APP之间进行数据传递&#xff0c;使用Android推荐的Binder通讯&#…

使用Flink接受kafka中的数据并对数据进行ETL

做这个开发是因为&#xff1a;在实际开发操作中&#xff0c;你的kafka主题中会有大量的数据但是需求并不需要所有数据&#xff0c;所有我们要对数据进行清洗&#xff0c;把需要的数据保存在flink流中&#xff0c;为下流的开发做好数据保障&#xff01; 首先创建工具类 再写一…

Golang | Leetcode Golang题解之第151题反转字符串中的单词

题目&#xff1a; 题解&#xff1a; import ("fmt" )func reverseWords(s string) string {//1.使用双指针删除冗余的空格slowIndex, fastIndex : 0, 0b : []byte(s)//删除头部冗余空格for len(b) > 0 && fastIndex < len(b) && b[fastIndex]…

视频与音频的交响:探索达摩院VideoLLaMA 2的技术创新

一、简介 文章&#xff1a;https://arxiv.org/abs/2406.07476 代码&#xff1a;https://github.com/DAMO-NLP-SG/VideoLLaMA2 VideoLLaMA 2是由阿里巴巴集团的DAMO Academy团队开发的视频大型语言模型&#xff08;Video-LLM&#xff09;&#xff0c;旨在通过增强空间-时间建模…

高考分数线一分一段统计汇总(熟练SQL窗口函数)

高考分数线一分一段统计汇总(使用SQL窗口函数) select 总分数&#xff0c; 一分一段人数&#xff0c; sum(一分一段人数) over( order by 总分数 desc) as 累计排名 from( select 总分数&#xff0c; count(考生号) as 一分一段人数 from &#xff08; select 考生号&…