Gradio全解8——ChatInterfaceChatbot:聊天界面类与聊天机器人(2)——ChatInterface的自定义函数和界面
Gradio全解8——ChatInterface&Chatbot:聊天界面类与聊天机器人(2)——ChatInterface的自定义函数和界面
- 8.2 ChatInterface的自定义函数和界面
- 8.2.1 自定义聊天函数
- 1. 交替同意和反对
- 2. 流式输出消息
- 8.2.2 自定义聊天界面
- 1. 自定义观感
- 2. YesMan示例
本章目录如下:
- 《ChatInterface&Chatbot:聊天界面类与聊天机器人(1)——ChatInterface类示例与构造参数》
- 《ChatInterface&Chatbot:聊天界面类与聊天机器人(2)——ChatInterface的自定义函数和界面》
- 《ChatInterface&Chatbot:聊天界面类与聊天机器人(3)——ChatInterface的多模态功能与附加输入输出》
- 《ChatInterface&Chatbot:聊天界面类与聊天机器人(4)——返回复杂响应与直接修改Chatbot值》
- 《ChatInterface&Chatbot:聊天界面类与聊天机器人(5)——通过API加载、聊天历史和用户反馈》
- 《ChatInterface&Chatbot:聊天界面类与聊天机器人(6)——gr.ChatInterface与流行LLM库和API结合》
- 《ChatInterface&Chatbot:聊天界面类与聊天机器人(7)——组件gr.Chatbot及gr.ChatMessage》
- 《ChatInterface&Chatbot:聊天界面类与聊天机器人(8)——组件Chatbot的特殊Events》
- 《ChatInterface&Chatbot:聊天界面类与聊天机器人(9)——使用Blocks创建自定义聊天机器人》
- 《ChatInterface&Chatbot:聊天界面类与聊天机器人(10)——使用显示思考和引用构建UI》
8.2 ChatInterface的自定义函数和界面
除了8.1节中提到的自定义chatbot,ChatInterface还有其它自定义功能,本节将其分为自定义函数和自定义聊天界面两方面讲解。
8.2.1 自定义聊天函数
在使用gr.ChatInterface()时,首先要定义聊天函数。在最简单的情况下,聊天函数应接受两个参数:message和history(参数可以任意命名,但必须按此顺序),说明如下:
- message:一个字符串,表示最新的用户消息。
- history:一个包含role和content键的OpenAI格式的字典列表,表示之前的对话历史,还可能包含表示消息元数据的其他键,例如:
[{"role": "user", "content": "What is the capital of France?"},{"role": "assistant", "content": "Paris"}
]
而聊天函数只需返回一个字符串值,表示聊天机器人基于聊天历史和最新消息的响应。下面让我们看几个由不同聊天函数实现不同功能的聊天机器人示例。
1. 交替同意和反对
前面的示例非常简单,它没有考虑用户输入和之前的对话历史。以下示例展示了如何结合用户输入和历史记录:
import gradio as gr
def alternatingly_agree(message, history):if len([h for h in history if h['role'] == "assistant"]) % 2 == 0:return f"Yes, I do think that: {message}"else:return "I don't think so"
gr.ChatInterface(fn=alternatingly_agree, type="messages"
).launch()
提示:目前版本需要在gr.ChatInterface中设置type=“messages”,因为其默认值(type=“tuples”)已被弃用,并将在未来的Gradio版本中移除。
2. 流式输出消息
在聊天函数中,我们可以使用关键字yield生成一系列响应,每个响应携带部分消息并替换前一个响应,再结合函数time.sleep()就得到一个流式聊天机器人,示例代码:
import time
import gradio as gr
def slow_echo(message, history):for i in range(len(message)):time.sleep(0.3)yield "You typed: " + message[: i+1]
gr.ChatInterface(fn=slow_echo, type="messages"
).launch()
运行演示如图8-3:
当响应正在流式传输时,“Submit”按钮会变成一个“Stop”按钮,可用于停止生成器函数。
提示:尽管每次迭代时都会生成最新的消息,但Gradio只会将每条消息的“差异”从服务器发送到前端,从而减少了网络上的延迟和数据消耗。
8.2.2 自定义聊天界面
除了自定义聊天函数,我们最常用的就是自定义聊天界面,比如自定义标题、主题、示例、组件Chatbot或Textbox等。
1. 自定义观感
如果读者熟悉Gradio的gr.Interface类,会发现gr.ChatInterface包含许多与之相同的参数,可以使用这些参数来自定义聊天机器人的观感。例如:
- 使用参数title和description在聊天机器人上方添加标题和描述。
- 分别使用参数theme和css添加主题或自定义CSS。
- 添加示例,甚至可以启用cache_examples,优化用户体验。
- 自定义Chatbot(例如更改高度或添加占位符)或Textbox,例如设置最大字符数或添加占位符)。
我们可以使用参数examples向gr.ChatInterface添加预设示例,该参数接受一个字符串示例列表,所有示例在发送消息之前都以“按钮”形式出现在聊天机器人中。如果我们希望将图像或其他文件作为示例的一部分,可以使用字典格式而不是字符串:{"text": "What's in this image?", "files": ["cheetah.jpg"]}
,其中文件消息将作为单独的消息添加到聊天机器人历史记录中。还可以使用example_labels参数更改每个示例的显示标签,使用example_icons参数为每个示例添加图标。这两个参数都接受一个字符串列表,其长度应与示例列表相同。如果我们希望缓存示例以便预先计算并立即显示结果,请设置cache_examples=True
。下面看一个示例。
2. YesMan示例
本节展示如何应用本节讨论参数:
import gradio as gr
def yes_man(message, history):if message.endswith("?"):return "Yes"else:return "Ask me anything!"
gr.ChatInterface(yes_man,type="messages",chatbot=gr.Chatbot(height=300, type="messages", placeholder="<strong>Your Personal Yes-Man</strong><br>Ask Me Anything</br>"),textbox=gr.Textbox(placeholder="Ask me a yes or no question", container=False, scale=7),title="Yes Man",description="Ask Yes Man any question",theme="ocean",examples=["Hello", "Am I cool?", "Are tomatoes vegetables?"],cache_examples=True,
).launch()
运行演示如图8-4:
请注意:①聊天界面添加的gr.Chatbot的“placeholder”,该占位符在用户开始聊天之前显示,接受Markdown或HTML格式文本,并会在聊天机器人中垂直且水平居中显示;②在gr.Chatbot组件中仍需设置type="messages"
,否则会报错:“Data incompatible with the messages format”。