【Gradio】构建自定义多模态聊天机器人

55a77da8d3b7cae7ed98c7fa8c6f539e.png

这是我们构建自定义多模态聊天机器人组件两部分系列的第一部分。在第一部分中,我们将修改 Gradio 聊天机器人组件,使其能够在同一消息中显示文本和媒体文件(视频、音频、图片)。在第二部分中,我们将构建一个自定义的文本框组件,该组件能够向聊天机器人发送多模态消息(文本和媒体文件)。

您可以跟随这篇文章的作者,通过以下 YouTube 视频实现聊天机器人组件!

这里是我们的多模态聊天机器人组件将会是什么样子的预览:

ab509c942f7d8496538aea0f2d2f01fa.png

第 1 部分 - 创建我们的项目 

对于这个演示,我们将调整现有的 Gradio Chatbot 组件,以便在同一消息中显示文本和媒体文件。让我们通过模板化 Chatbot 组件源代码来创建一个新的自定义组件目录。

gradio cc create MultimodalChatbot --template Chatbot

我们准备好出发了!

✍️ 提示:确保在 pyproject.toml 文件中修改 Author 键。

第 2a 部分 - 后端数据模型 

在您最喜欢的代码编辑器中打开 multimodalchatbot.py 文件,让我们开始修改组件的后端。

我们将要做的第一件事是创建我们组件的 data_model 。 data_model 是您的 Python 组件将接收并发送给运行 UI 的 JavaScript 客户端的数据格式。您可以在后端指南中了解更多关于 data_model 的信息。

对于我们的组件,每个聊天机器人消息将包含两个键:一个 text 键用于显示文本消息,以及一个可选的媒体文件列表,可以显示在文本下方。

从 gradio.data_classes 导入 FileData 和 GradioModel 类,并修改现有的 ChatbotData 类,使其看起来如下:

# 定义文件消息类,继承自 GradioModel
class FileMessage(GradioModel):
    # 文件数据,类型为 FileData
    file: FileData
    # 可选的替代文本,类型为可选的字符串
    alt_text: Optional[str] = None


# 定义多模态消息类,继承自 GradioModel
class MultimodalMessage(GradioModel):
    # 文本消息,类型为可选的字符串
    text: Optional[str] = None
    # 文件消息,类型为 FileMessage 类的列表,是可选的
    files: Optional[List[FileMessage]] = None


# 定义聊天机器人数据类,继承自 GradioRootModel
class ChatbotData(GradioRootModel):
    # 聊天数据,类型为包含多模态消息类的元组的列表
    root: List[Tuple[Optional[MultimodalMessage], Optional[MultimodalMessage]]]


# 定义多模态聊天机器人组件,继承自 Component
class MultimodalChatbot(Component):
    ...
    # 多模态聊天机器人组件的数据模型为聊天机器人数据类
    data_model = ChatbotData

✍️ 提示:`data_model`是使用`Pydantic V2`实现的。请阅读此处的文档。

我们已经完成了最困难的部分!

第 2b 部分 - 预处理和后处理方法 

对于 preprocess 方法,我们将保持简单,将一个 MultimodalMessage 列表传递给使用此组件作为输入的 python 函数。这将允许我们组件的用户使用 .text 和 .files 属性访问聊天机器人数据。这是您可以在实现中修改的设计选择!我们可以像这样返回带有 root 属性的 ChatbotData 的消息列表:

# 定义预处理方法,输入参数为聊天数据,类型为 ChatbotData 或 None
def preprocess(
    self,
    payload: ChatbotData | None,
) -> List[MultimodalMessage] | None:
    # 如果输入参数为空,则直接返回
    if payload is None:
        return payload
    # 如果存在聊天数据,则返回其中的 root 属性,即所有的聊天消息
    return payload.root

✍️ 提示:了解`preprocess`和`postprocess`方法背后的原理,请参阅关键概念指南

在 postprocess 方法中,我们将强制 python 函数返回的每条消息都是一个 MultimodalMessage 类。我们还将清理 text 字段中的任何缩进,以便它可以在前端正确显示为 markdown。

我们可以保留 postprocess 方法并修改 _postprocess_chat_messages

# 定义后处理聊天消息的方法,输入参数为多模态消息,类型为 MultimodalMessage 或 字典 或 None
def _postprocess_chat_messages(
    self, chat_message: MultimodalMessage | dict | None
) -> MultimodalMessage | None:
    # 如果聊天消息为空,则直接返回 None
    if chat_message is None:
        return None
    # 如果聊天消息是一个字典,则将其转化为 MultimodalMessage 类型
    if isinstance(chat_message, dict):
        chat_message = MultimodalMessage(**chat_message)
    # 清理聊天消息的文本,使用 cleandoc 方法对文本进行清理,如果文本不存在,则返回一个空字符串
    chat_message.text = inspect.cleandoc(chat_message.text or "")
    # 遍历消息中的所有文件
    for file_ in chat_message.files:
        # 使用 get_mimetype 方法获取文件的 MIME 类型,并设置给文件的 mime_type 属性
        file_.file.mime_type = client_utils.get_mimetype(file_.file.path)
    # 返回处理过后的聊天消息
    return chat_message

在我们结束后端代码之前,让我们修改 example_value 和 example_payload 方法,以返回 ChatbotData 的有效字典表示形式:

# 定义example_value方法,返回一个任意类型的值
def example_value(self) -> Any:
    # 返回一个示例聊天信息(仅包含文本“Hello!”)的列表
    return [[{"text": "Hello!", "files": []}, None]]


# 定义example_payload方法,返回一个任意类型的值
def example_payload(self) -> Any:
    # 返回一个示例聊天信息(仅包含文本
### 创建自定义聊天机器人构建指南 #### 使用 Gradio 的低级 Blocks API 开发聊天机器人 UI 为了创建一个具有高度定制化的聊天机器人用户界面,可以利用 Gradio 提供的低级 Blocks API 来实现这一目标。此方法允许开发者对聊天机器人的外观和交互逻辑进行全面掌控[^1]。 ```python import gradio as gr def respond(message, history): response = f"Echo: {message}" return response with gr.Blocks() as demo: chatbot = gr.Chatbot() msg = gr.Textbox(label="Enter message here:") clear = gr.Button("Clear") def user(user_message, history): return "", history + [[user_message, None]] def bot(history): last_user_msg = history[-1][0] response = respond(last_user_msg, history[:-1]) history[-1][1] = response return history msg.submit(user, [msg, chatbot], [msg, chatbot], queue=False).then( bot, chatbot, chatbot ) demo.launch() ``` 这段代码展示了如何设置基本的消息传递机制以及如何让聊天机器人即时响应用户的输入并更新对话记录[^5]。 #### 支持多媒体内容的多模态聊天机器人 除了纯文本交流外,有时还需要支持图片、音频或其他类型的媒体文件作为聊天的一部分。为此,可以通过修改 `GradioChatbot` 组件来增强其功能,使其能够在单条消息内同时呈现文字与媒体资源[^3]。 ```python class MultimodalChatbot(gr.components.Component): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) @staticmethod def update(value=None): pass # 实现具体的更新逻辑 gradio cc create MultimodalChatbot --template Chatbot ``` 这里给出了一个多模态聊天机器人类的基础框架,实际应用时需进一步完善其中的方法以适应具体需求。 #### 流式传输回复提升用户体验 为了让聊天体验更加流畅自然,在接收到部分结果后即刻向用户反馈而非等到整个答复完成再一次性发送出去是非常重要的改进措施之一。这种技术被称为“流式传输”,它能显著减少等待时间给使用者带来的焦虑感。 ```python async def stream_response(message, history): partial_reply = "" full_reply = await get_full_answer_async(message) # 假设这是获取完整答案的方式 for char in full_reply: partial_reply += char yield partial_reply await asyncio.sleep(0.02) # 控制字符逐个显示的速度 # 更新之前的 bot 函数调用为异步版本 chat_history = [] for chunk in stream_response(msg.value, chat_history): chatbot.update(chat_history=chat_history.append([None, chunk])) ``` 以上片段说明了怎样逐步构建起一个既美观又实用的自定义聊天机器人解决方案。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值