原文链接: gradio.app/creating-a-…
聊天机器人广泛应用于自然语言处理(NLP)研究和工业界。由于聊天机器人设计用于直接由客户和最终用户使用,因此重要的是验证聊天机器人在面对各种输入提示时是否按预期行为。
使用Gradio,您可以轻松构建聊天机器人模型的演示,并与用户共享,或者使用直观的聊天机器人GUI进行尝试。 本教程将展示如何使用Gradio创建几种不同类型的聊天机器人界面:首先是简单的文本显示,然后是流式文本响应,最后是可以处理媒体文件的聊天机器人。我们创建的聊天机器人界面将如下所示:
先决条件:我们将使用gradio.Blocks类来构建聊天机器人演示。如果您对此还不熟悉,可以先阅读Blocks指南
简单的聊天机器人演示
让我们从重新创建上面的简单演示开始。正如您可能注意到的那样,我们的机器人只是随机回复“你好吗?”,“我爱你”或“我很饿”作为任何输入。
以下是使用Gradio创建此功能的代码:
import gradio as gr
import random
import time
with gr.Blocks() as demo:
chatbot = gr.Chatbot()
msg = gr.Textbox()
clear = gr.Button("清除")
def respond(message, chat_history):
bot_message = random.choice(["你好吗?", "我爱你", "我很饿"])
chat_history.append((message, bot_message))
time.sleep(1)
return "", chat_history
msg.submit(respond, [msg, chatbot], [msg, chatbot])
clear.click(lambda: None, None, chatbot, queue=False)
demo.launch()
这里有三个Gradio组件: 一个聊天机器人,其值以用户和机器人之间的响应对的列表形式存储对话的整个历史记录。 一个文本框,用户可以在其中输入消息,然后按下回车/提交以触发聊天机器人的响应。 一个清除按钮,用于清除整个聊天机器人的历史记录。 我们有一个名为respond()的函数,它接受聊天机器人的整个历史记录作为输入,附加一个随机消息,等待1秒钟,然后返回更新后的聊天历史记录。当返回时,respond()函数还清除文本框。
当然,在实际应用中,您会用自己更复杂的函数替换respond()函数,该函数可能调用预训练模型或API生成响应。
最后,当单击清除按钮时,我们将Chatbot的值设置为None,以清除其整个历史记录。在此处尝试该聊天机器人:
将流式处理添加到聊天机器人
我们可以通过几种方式改进上面的聊天机器人用户体验。 首先,我们可以流式处理响应,以便用户不必等待太长时间才能生成消息。其次,我们可以让用户消息立即显示在聊天历史记录中,同时生成聊天机器人的响应。以下是实现此功能的代码:
import gradio as gr
import random
import time
with gr.Blocks() as demo:
chatbot = gr.Chatbot()
msg = gr.Textbox()
clear = gr.Button("清除")
def user(user_message, history):
return "", history + [[user_message, None]]
def bot(history):
bot_message = random.choice(["你好吗?", "我爱你", "我很饿"])
history[-1][1] = ""
for character in bot_message:
history[-1][1] += character
time.sleep(0.05)
yield history
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()
您会注意到,当用户提交消息时,我们现在使用.then()方法链接了两个事件:
第一个方法user()用用户消息更新聊天机器人,并清除输入字段。因为我们希望立即执行此操作,所以我们设置queue=False,这样如果已启用队列,就会跳过任何队列。聊天机器人的历史记录附加了(user_message,None),其中None表示机器人尚未回复。
第二个方法bot()用机器人的响应更新聊天机器人历史记录。我们不创建新的消息,而是用机器人的响应替换先前创建的None消息。最后,我们逐个字符构造消息并生成正在构建的中间输出。Gradio会自动将任何带有yield关键字的函数转换为流式输出接口。
当然,在实际应用中,您会用自己更复杂的函数替换bot()函数,该函数可能调用预训练模型或API生成响应。
最后,我们通过运行demo.queue()启用排队,这是流式输出所需的。您可以通过滚动到本页面顶部的演示来尝试改进的聊天机器人。
添加Markdown、图像、音频或视频
gr.Chatbot组件支持部分Markdown语法,包括加粗、斜体和代码。例如,我们可以编写一个函数,以加粗形式回复用户的消息,例如"That's cool!":
def bot(history):
response = "**That's cool!**"
history[-1][1] = response
return history
此外,它还可以处理图像、音频和视频等媒体文件。要传递媒体文件,我们必须将文件作为包含两个字符串的元组传入,例如:(文件路径,替代文本)。替代文本是可选的,所以您也可以只传入一个只有一个元素的元组(文件路径,),例如:
def add_file(history, file):
history = history + [((file.name,), None)]
return history
将这些组合在一起,我们可以创建一个多模态聊天机器人,其中包含一个文本框供用户提交文本,一个文件上传按钮供提交图像/音频/视频文件。其余的代码与之前几乎相同:
import gradio as gr
def add_text(history, text):
history = history + [(text, None)]
return history, ""
def add_file(history, file):
history = history + [((file.name,), None)]
return history
def bot(history):
response = "**That's cool!**"
history[-1][1] = response
return history
with gr.Blocks() as demo:
chatbot = gr.Chatbot([], elem_id="chatbot").style(height=750)
with gr.Row():
with gr.Column(scale=0.85):
txt = gr.Textbox(
show_label=False,
placeholder="输入文本并按回车键,或上传图像",
).style(container=False)
with gr.Column(scale=0.15, min_width=0):
btn = gr.UploadButton("📁", file_types=["image", "video", "audio"])
txt.submit(add_text, [chatbot, txt], [chatbot, txt]).then(
bot, chatbot, chatbot
)
btn.upload(add_file, [chatbot, btn], [chatbot]).then(
bot, chatbot, chatbot
)
demo.launch()
您已经完成了!这就是构建聊天机器人模型界面所需的全部代码。最后,我们将以一些在Spaces上运行的聊天机器人链接结束我们的指南,以便您可以了解其他可能性:
- project-baize/Baize-7B:一个带有停止生成和重新生成响应功能的样式化聊天机器人。
- MAGAer13/mPLUG-Owl:一个多模态聊天机器人,允许您对响应进行赞和踩。