大模型WebUI:Gradio全解11——Chatbot:融合大模型的多模态聊天机器人(1)

news2025/1/10 13:30:54

大模型WebUI:Gradio全解11——Chatbots:融合大模型的聊天机器人(1)

  • 前言
  • 本篇摘要
  • 11. Chatbot:融合大模型的多模态聊天机器人
    • 11.1 gr.ChatInterface()快速创建Chatbot
      • 11.1.1 定义聊天函数
        • 1. 随机回答“是”或“否”的聊天机器人
        • 2. 交替同意和反对的聊天机器人
        • 3. 流式聊天机器人
      • 11.1.2 自定义聊天界面
        • 1. 自定义观感
        • 2. 多模态聊天界面
      • 11.1.3 附加输入输出
        • 1. additional_inputs:附加输入
        • 2. additional_outputs:附加输出
      • 11.1.4 返回复杂响应
        • 1. 返回Gradio组件
        • 2. 提供预设回复
        • 3. 返回多条消息
      • 11.1.5 通过API加载聊天机器人
        • 1. load_chat:从OpenAI API端点
        • 2. /chat:通过页面API端点
      • 11.1.6 聊天历史和用户反馈
        • 1. 聊天历史记录
        • 2. 收集用户反馈
    • 参考文献

前言

本系列文章主要介绍WEB界面工具Gradio。Gradio是Hugging Face发布的简易webui开发框架,它基于FastAPI和svelte,便于开发多功能界面和部署人工智能模型,是当前热门的非常易于开发和展示机器学习大语言模型LLM及扩散模型DM的UI框架。本系列文章分为前置概念和实战演练两部分。前置概念先介绍Gradio的详细技术架构、历史、应用场景、与其他框架Gradio/NiceGui/StreamLit/Dash/PyWebIO的区别,然后详细介绍了著名的资源网站Hugging Face,因为Gradio演示中经常用到Hugging Face的models及某些场景需要部署在spaces,这里包括三类资源models/datasets/spaces的使用、六类工具库transformers/diffusers/datasets/PEFT/accelerate/optimum实战。实战演练部分先讲解了多种不同的安装、运行和部署方式,安装包括Linux/Win/Mac三类系统安装,运行包括普通方式和热重载方式,部署包括本地部署、HuggingFace托管、FastAPI挂载和Gradio-Lite浏览器集成;然后按照先整体再细节的逻辑,讲解Gradio的多种高级特性,包括三种Gradio Clients(python/javascript/curl)、Gradio Tools、Gradio的模块架构和环境变量等,方便读者对Gradio整体把握;最后深入细节,也是本系列文章的核心,先实践基础功能Interface、Blocks和Additional Features,再详解高级功能Chatbots、Data Science And Plots和Streaming。本系列文章讲解细致,涵盖Gradio大部分组件和功能,代码均可运行并附有大量运行截图,方便读者理解,Gradio一定会成为每个技术人员实现奇思妙想的最称手工具。

本系列文章目录如下:

  1. 《Gradio全解1——Gradio简介》
  2. 《Gradio全解1——Gradio的安装与运行》
  3. 《Gradio全解2——剖析Hugging Face:详解三类资源models/datasets/spaces》
  4. 《Gradio全解3——剖析Hugging Face:实战六类工具库transformers/diffusers/datasets/PEFT/accelerate/optimum》
  5. 《Gradio全解4——Gradio的3+1种部署方式实践》
  6. 《Gradio全解4——浏览器集成Gradio-Lite》
  7. 《Gradio全解5——Gradio Client:python客户端》
  8. 《Gradio全解5——Gradio Client:javascript客户端》
  9. 《Gradio全解5——Gradio Client:curl客户端》
  10. 《Gradio全解6——Gradio Tools:将Gradio用于LLM Agents》
  11. 《Gradio全解7——Gradio库的模块架构和环境变量》
  12. 《Gradio全解8——Interface:高级抽象界面类(上)》
  13. 《Gradio全解8——Interface:高级抽象界面类(下)》
  14. 《Gradio全解9——Blocks:底层区块类(上)》
  15. 《Gradio全解9——Blocks:底层区块类(下)》
  16. 《Gradio全解10——Additional Features:补充特性(上)》
  17. 《Gradio全解10——Additional Features:补充特性(下)》
  18. 《Gradio全解11——Chatbot:融合大模型的多模态聊天机器人(上)》
  19. 《Gradio全解11——Chatbot:融合大模型的多模态聊天机器人(下)》
  20. 《Gradio全解系列12——Data Science And Plots:数据科学与绘图》
  21. 《Gradio全解13——Streaming:数据流(上)》
  22. 《Gradio全解13——Streaming:数据流(下)》

本篇摘要

本篇介绍如何使用Gradio创建聊天机器人,主要内容包括gr.ChatInterface快速创建Chatbot、与流行LLM库及API结合、使用Agents和Tools智能代理工具、使用Blocks创建Chatbot、Chatbot的特殊Events、通过Gradio应用创建Discord Bot/Slack Bot/Website Widget。

11. Chatbot:融合大模型的多模态聊天机器人

本章介绍如何使用Gradio创建聊天机器人。聊天机器人是大型语言模型(LLMs)的一个流行应用,通过Gradio,我们可以轻松构建LLM演示并与其它用户分享,或者自己使用直观的聊天机器人界面进行开发尝试。本章主要内容包括gr.ChatInterface快速创建Chatbot、与流行LLM库及API结合、使用Agents和Tools智能代理工具、使用Blocks创建Chatbot、Chatbot的特殊Events、通过Gradio应用创建Discord Bot/Slack Bot/Website Widget。

11.1 gr.ChatInterface()快速创建Chatbot

本教程使用gr.ChatInterface(),这是一个高级抽象类,通常只需一行Python代码就可以快速创建聊天机器人界面。它可以轻松支持多模态聊天机器人或需要进一步定制的聊天机器人。本节内容主要包括定义聊天函数、自定义聊天界面、附加输入输出、返回复杂响应、通过API加载聊天机器人、聊天历史和用户反馈。
前提条件:请确保使用的是最新版Gradio,升级命令:$ pip install --upgrade gradio

11.1.1 定义聊天函数

在使用gr.ChatInterface()时,首先要做的是定义聊天函数。在最简单的情况下,聊天函数应接受两个参数:message和history(参数可以任意命名,但必须按此顺序):

  • message:一个字符串,表示用户的最新消息;
  • history:一个包含role和content键的openai-style的字典列表,表示之前的对话历史,还可能包含表示消息元数据的其他键。例如,history可能如下所示:
[
    {"role": "user", "content": "What is the capital of France?"},
    {"role": "assistant", "content": "Paris"}
]

而聊天函数只需返回一个字符串值,表示聊天机器人基于聊天历史和最新消息的响应。下面让我们看几个由不同聊天函数实现不同功能的聊天机器人示例。

1. 随机回答“是”或“否”的聊天机器人

让我们编写一个随机回答“是”或“否”的聊天函数,将其插入gr.ChatInterface()并调用.launch()方法来创建Web界面,示例如下:

import random

def random_response(message, history):
    return random.choice(["Yes", "No"])
import gradio as gr

gr.ChatInterface(
    fn=random_response, 
    type="messages"
).launch()

提示:始终在gr.ChatInterface中设置type=“messages”,而默认值(type=“tuples”)已被弃用,并将在未来的Gradio版本中移除。
以下是运行演示截图,可以自己试试看:
在这里插入图片描述

2. 交替同意和反对的聊天机器人

当然,前面的示例非常简单,它没有考虑用户输入或之前的对话历史。以下是另一个简单的示例,展示了如何结合用户输入和历史记录:

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与流行的LLM结合。

3. 流式聊天机器人

在聊天函数中,我们可以使用yield生成一系列部分响应,每个响应替换前一个响应,这样将得到一个流式聊天机器人,就是这么简单!下面是示例代码:

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()

运行演示如下:
在这里插入图片描述
当响应正在流式传输时,“Submit”按钮会变成一个“Stop”按钮,可用于停止生成器函数。
提示:尽管每次迭代时都会生成最新的消息,但Gradio只会将每条消息的“差异”从服务器发送到前端,从而减少了网络上的延迟和数据消耗。

11.1.2 自定义聊天界面

除了聊天函数,我们最常用的就是自定义聊天界面,比如自定义示例、Chatbot或Textbox,或实现多模态聊天界面。

1. 自定义观感

如果熟悉Gradio的gr.Interface类,可以发现gr.ChatInterface包含许多相同的参数,我们可以使用这些参数来自定义聊天机器人的观感。例如:

  • 使用title和description参数在聊天机器人上方添加标题和描述;
  • 分别使用theme和css参数添加主题或自定义CSS;
  • 添加示例,甚至可以启用cache_examples,使用户更易体验我们的Chatbot;
  • 自定义Chatbot(例如更改高度或添加占位符)或文本框(例如设置最大字符数或添加占位符)。

下面以添加示例和自定义chatbot或文本框为例进行说明。我们可以使用examples参数向gr.ChatInterface添加预设示例,该参数接受一个字符串示例列表,所有示例在发送消息之前都以“按钮”形式出现在聊天机器人中。如果我们希望将图像或其他文件作为示例的一部分,可以使用以下字典格式而不是字符串:{"text": "What's in this image?", "files": ["cheetah.jpg"]},其中格式为文件的消息将作为单独的消息添加到聊天机器人历史记录中。

我们还可以使用example_labels参数更改每个示例的显示文本,使用example_icons参数为每个示例添加图标。这两个参数都接受一个字符串列表,其长度应与示例列表相同。如果我们希望缓存示例以便预先计算并立即显示结果,请设置cache_examples=True。

如果想自定义组成ChatInterface的gr.Chatbot或gr.Textbox,则可以传入自己的Chatbot或Textbox组件。以下是我们如何应用本节讨论的参数的示例:

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()

运行演示如下:
在这里插入图片描述请注意:(1)聊天界面添加的gr.Chatbot的“placeholder”,该占位符在用户开始聊天之前显示,接受 Markdown或HTML格式文本,并会在聊天机器人中垂直且水平居中显示;(2)在gr.Chatbot组件中仍需设置type="messages",否则会报错:“Data incompatible with the messages format”。

2. 多模态聊天界面

我们可能希望为聊天界面添加多模态功能,比如希望用户能够上传图像或文件到聊天机器人并询问相关问题。这时可以向gr.ChatInterface类传递一个参数(multimodal=True),使聊天机器人具备“多模态”功能。当multimodal=True时,聊天函数的特征会略有变化,如下所述:

  • 函数的第一个参数(之前称为message)应接受一个字典,该字典由提交的文本和上传的文件组成,格式如下:
{
    "text": "user input", 
    "files": [
        "updated_file_1_path.ext",
        "updated_file_2_path.ext", 
        ...
    ]
}
  • 聊天函数的第二个参数history将保持与之前相同的openai-style的字典格式。然而,如果历史记录中包含上传的文件,content键的值将不再是一个字符串,而是一个包含文件路径的单元素元组。每个文件将作为历史记录中的一条单独消息。因此,在上传两个文件并提问后,历史记录可能如下所示:
[
    {"role": "user", "content": ("cat1.png")},
    {"role": "user", "content": ("cat2.png")},
    {"role": "user", "content": "What's the difference between these two images?"},
]

设置multimodal=True时,聊天函数的返回类型不会改变(即在最简单的情况下,仍应返回一个字符串值)。我们将在后续返回复杂响应中讨论更复杂的情况,例如返回文件。

当自定义多模态聊天界面时,textbox参数应该传递gr.MultimodalTextbox的实例。以下是一个示例,展示了如何设置和自定义多模态聊天界面:

import gradio as gr

def count_images(message, history):
    num_images = len(message["files"])
    total_images = 0
    for message in history:
        if isinstance(message["content"], tuple):
            total_images += 1
    return f"You just uploaded {num_images} images, total uploaded: {total_images+num_images}"

demo = gr.ChatInterface(
    fn=count_images, 
    type="messages", 
    examples=[
        {"text": "No files", "files": []}
    ], 
    multimodal=True,
    textbox=gr.MultimodalTextbox(file_count="multiple", file_types=["image"])
)

demo.launch()

运行截图如下:
在这里插入图片描述
从示例中可以看到,通过组件gr.MultimodalTextbox(),我们可以同时上传多个图像、音频、视频类文件并可配有文字说明,其参数说明如下:

  • value: 类型为str | dict[str, str | list] | Callable | None,默认为None。显示在MultimodalTextbox中的默认值。可以是一个字符串值,或者一个字典形式的对象,例如:
    {“text”: “sample text”, “files”: [{path: “files/file.jpg”, orig_name: “file.jpg”, url: “http://image_url.jpg”, size: 100}]}。如果是一个可调用对象(函数),则每当应用加载时都会调用该函数来设置组件的初始值。
  • sources:类型为list[Literal[‘upload’, ‘microphone’]] | Literal[‘upload’, ‘microphone’] | None,默认为None。指定允许的输入来源列表。“upload” 会创建一个按钮,用户可以通过点击上传或拖放文件;“microphone” 会创建一个麦克风输入。如果为None,则默认值为 [“upload”]。
  • file_count: 类型为Literal[‘single’, ‘multiple’, ‘directory’],默认为“single”,如果设置为"directory",用户将上传所选目录中的所有文件。在"multiple"或"directory"的情况下,返回类型将是每个文件的列表。
  • file_types:类型为list[str] | None,默认为None。"file"允许上传任何文件,"image"仅允许上传图片文件,"audio"仅允许上传音频文件,"video"仅允许上传视频文件,“text” 仅允许上传文本文件。

读者可根据自己需要设置,更多参数请参照官方文档。

11.1.3 附加输入输出

附加输入输出功能为聊天函数添加额外的输入或输出,以便实现更复杂和定制化的功能。

1. additional_inputs:附加输入

我们可能希望在聊天函数中添加额外的输入,并通过聊天界面向用户展示这些输入。例如添加一个用于系统提示的文本框,或者一个设置聊天机器人响应中令牌数量的滑块。gr.ChatInterface类支持 additional_inputs参数,该参数可用于添加额外的输入组件。关于additional inputs,在Interface和Blocks中已讲过,可作为参考,此处稍有不同,请注意区分。

additional_inputs参数接受一个组件或组件列表。我们可以直接传递组件实例,或者使用它们的字符串快捷方式(例如使用 “textbox” 而不是gr.Textbox())。如果传递组件实例,并且它们尚未被渲染,那么这些组件将出现在聊天机器人下方的 gr.Accordion()中。以下是一个完整的示例:

import gradio as gr
import time

def echo(message, history, system_prompt, tokens):
    response = f"System prompt: {system_prompt}\n Message: {message}."
    for i in range(min(len(response), int(tokens))):
        time.sleep(0.05)
        yield response[: i + 1]

demo = gr.ChatInterface(
    echo,
    type="messages",
    additional_inputs=[
        gr.Textbox("You are helpful AI.", label="System Prompt"),
        gr.Slider(10, 100),
    ],
)

demo.launch()

运行截图如下:
在这里插入图片描述
如果传递给additional_inputs的组件已经在父级gr.Blocks()中渲染过,那么它们不会在折叠面板中重新渲染,这为设置输入组件的布局提供了灵活性。在下面的示例中,我们将 gr.Textbox()放置在聊天机器人界面的顶部,同时将滑块保留在下方:

with gr.Blocks() as demo:
    system_prompt = gr.Textbox("You are helpful AI.", label="System Prompt")
    slider = gr.Slider(10, 100, render=False)

    gr.ChatInterface(
        echo, additional_inputs=[system_prompt, slider], type="messages"
    )

拖动滑条并输入信息,运行截图如下:
在这里插入图片描述
我们还可以为额外输入添加示例值。将列表的列表传递给examples参数,其中每个内部列表代表一个样本,每个内部列表的长度应为1 + len(additional_inputs),其第一个元素应为聊天消息的示例值,随后的每个元素应为额外输入的示例值,按顺序排列。当提供额外输入时,示例将以表格形式呈现在聊天界面下方。

如需要创建自定义更高的内容,最好使用低级的gr.Blocks() API构建聊天机器人界面,后续会单独讲述使用Blocks创建聊天机器人界面。

2. additional_outputs:附加输出

与接受额外输入到聊天函数中的方式相同,我们还可以返回额外输出。只需将组件列表传递给gr.ChatInterface中的additional_outputs参数,并从聊天函数中为每个组件返回额外的值。以下是一个提取代码并将其输出到单独的gr.Code组件中的示例:

import gradio as gr

python_code = """
def fib(n):
    if n <= 0:
        return 0
    elif n == 1:
        return 1
    else:
        return fib(n-1) + fib(n-2)
"""

js_code = """
function fib(n) {
    if (n <= 0) return 0;
    if (n === 1) return 1;
    return fib(n - 1) + fib(n - 2);
}
"""

def chat(message, history):
    if "python" in message.lower():
        return "Type Python or JavaScript to see the code.", gr.Code(language="python", value=python_code)
    elif "javascript" in message.lower():
        return "Type Python or JavaScript to see the code.", gr.Code(language="javascript", value=js_code)
    else:
        return "Please ask about Python or JavaScript.", None

with gr.Blocks() as demo:
    code = gr.Code(render=False)
    with gr.Row():
        with gr.Column():
            gr.Markdown("<center><h1>Write Python or JavaScript</h1></center>")
            gr.ChatInterface(
                chat,
                examples=["Python", "JavaScript"],
                additional_outputs=[code],
                type="messages"
            )
        with gr.Column():
            gr.Markdown("<center><h1>Code Artifacts</h1></center>")
            code.render()

demo.launch()

运行截图如下:
在这里插入图片描述
注意:与额外输入的情况不同,传递给additional_outputs的组件必须在gr.Blocks上下文中预先定义——它们不会自动渲染。如果需要在gr.ChatInterface之后渲染它们,可以在首次定义时设置render=False,然后在gr.Blocks()的适当部分调用.render()进行渲染,如上例所示。

11.1.4 返回复杂响应

我们之前提到过,在最简单的情况下,聊天函数应返回一个字符串响应,该响应将在聊天机器人中呈现为文本。然而也可以返回更复杂的响应,比如返回Gradio组件、提供预设回复或返回多条消息。

1. 返回Gradio组件

目前,以下Gradio组件可以显示在聊天界面中:gr.Image、gr.Plot、gr.Audio、gr.HTML、gr.Video、gr.Gallery和gr.File。只需从函数中返回这些组件之一,即可与gr.ChatInterface一起使用。
以下是一个返回音频文件的示例:

import gradio as gr

def music(message, history):
    if message.strip():
        return gr.Audio("https://github.com/gradio-app/gradio/raw/main/test/test_files/audio_sample.wav")
    else:
        return "Please provide the name of an artist"

gr.ChatInterface(
    music,
    type="messages",
    textbox=gr.Textbox(placeholder="Which artist's music do you want to listen to?", scale=7),
).launch()

运行截图如下:
在这里插入图片描述
类似地,可以使用gr.Image返回图片文件,使用gr.Video返回视频文件,或者使用gr.File组件返回任意文件。

2. 提供预设回复

我们可能希望提供预设回复,供用户在与聊天机器人对话时选择。为此,可以从聊天函数中返回一个完整的OpenAI-style的消息字典,并在返回的字典中添加options键来设置这些回复。字典应包含以下键:

  • role:设置为"assistant";
  • content:设置为一个字典,其中键为path,值为您要返回的文件路径或URL;
  • options键对应的值应该是一个字典列表,每个字典包含一个value(当点击该回复时发送给聊天函数的值,是一个字符串)和一个可选的label(如果提供,则作为预设回复显示的文本,而不是value)。

以下示例展示了如何使用预设回复:

import gradio as gr
import random

example_code = """
Here's an example Python lambda function:

lambda x: x + {}

Is this correct?
"""

def chat(message, history):
    if message == "Yes, that's correct.":
        return "Great!"
    else:
        return {
            "role": "assistant",
            "content": example_code.format(random.randint(1, 100)),
            "options": [
                {"value": "Yes, that's correct.", "label": "Yes"},
                {"value": "No"}
                ]
            }

demo = gr.ChatInterface(
    chat,
    type="messages",
    examples=["Write an example Python lambda function."]
)

demo.launch()

运行截图如下:
在这里插入图片描述
点击按钮Yes后,会直接使用预设恢复“Yes, that’s correct.”,然后聊天机器人回复“Great!"结束会话。

3. 返回多条消息

我们还可以通过返回上述任意类型的消息列表(甚至可以混合使用),从而使聊天函数中返回多条助手消息。例如,你可以发送一条带有文件的消息,如下例所示:

import gradio as gr

def echo_multimodal(message, history):
    response = []
    response.append("You wrote: '" + message["text"] + "' and uploaded:")
    if message.get("files"):
        for file in message["files"]:
            response.append(gr.File(value=file))
    return response

demo = gr.ChatInterface(
    echo_multimodal,
    type="messages",
    multimodal=True,
    textbox=gr.MultimodalTextbox(file_count="multiple"),
)

demo.launch()

运行截图如下:
在这里插入图片描述注意组件gr.MultimodalTextbox的设置,此时函数返回输入信息和上传的文件。

11.1.5 通过API加载聊天机器人

需要说明的是,除了利用gr.ChatInterface()快速创建Chatbot,还可以从API端点加载聊天机器人,有两种方法实现:gr.load_char()和/chat。

1. load_chat:从OpenAI API端点

通过函数gr.load_chat(),我们可以从Ollama或任何兼容OpenAI API的端点快速加载聊天机器人。假如有一个提供兼容OpenAI API端点的聊天服务器(如果没有,可以跳过这部分),那么可以用一行代码启动一个 ChatInterface。

首先,运行pip install openai;然后,使用自己的URL、模型和可选的token进行加载,如下所示:

import gradio as gr

gr.load_chat("http://localhost:11434/v1/", model="llama3.2", token=None).launch()

目前还没有关于这部分的详细资料,感兴趣的读者请关注官方后续的gr.load_chat()文档说明。

2. /chat:通过页面API端点

一旦我们构建了Gradio聊天界面并将其托管在Hugging Face Spaces或其他地方,就可以通过简单API的端点:/chat进行查询。该端点只需要用户的消息(如果使用additional_inputs参数设置了任何额外输入,则可能还需要这些输入),并会返回响应,内部会跟踪已发送的历史消息。API端点截图如下:
在这里插入图片描述
要使用该端点,可以通过Gradio Python客户端或Gradio JS客户端,详见之前的Gradio Clients章节。或者,我们也可以将聊天界面部署到其他平台,例如:

  1. Discord Bot;
  2. Slack Bot;
  3. Website widget。

关于这三部分操作将在本章后续讲述,请持续关注进步。

11.1.6 聊天历史和用户反馈

用户聊天过程中,维护聊天历史记录至关重要,同时也可以通过用户反馈与用户互动。

1. 聊天历史记录

我们可以为ChatInterface启用持久化聊天历史记录功能,这允许用户维护多个对话并轻松切换。启用持久化聊天历史记录功能后,对话会使用浏览器的本地存储(local storage)在用户浏览器中本地且私密地保存。因此,如果将ChatInterface部署在Hugging Face Spaces等平台上时,每个用户都将拥有自己独立的聊天历史记录,不会干扰其他用户的对话。这意味着多个用户可以同时与同一个ChatInterface交互,同时保留各自的私密对话历史。

要启用持久化聊天历史记录功能,只需设置gr.ChatInterface(save_history=True)(如下一节示例所示)。用户随后会在侧边栏中看到他们之前的对话,并可以继续之前的聊天或开始新的对话。

2. 收集用户反馈

为了收集关于聊天模型的反馈,可以设置gr.ChatInterface(flagging_mode=“manual”),用户将能够对助手的回复进行点赞或点踩。每个被标记的回复以及整个聊天历史记录都会保存到应用工作目录中的CSV文件中(可以通过flagging_dir参数配置标记目录)。

我们还可以通过flagging_options参数更改反馈选项。默认选项是“喜欢”和“不喜欢”,分别显示为点赞和点踩图标。其他任何选项都会显示在专用的标记图标下。以下示例展示了一个同时启用了聊天历史记录(如前一节所述)和用户反馈功能的ChatInterface:

import time
import gradio as gr

def slow_echo(message, history):
    for i in range(len(message)):
        time.sleep(0.05)
        yield "You typed: " + message[: i + 1]

demo = gr.ChatInterface(
    slow_echo,
    type="messages",
    flagging_mode="manual",
    flagging_options=["Like", "Spam", "Inappropriate", "Other"],
    save_history=True,
)

demo.launch()

运行截图如下:
在这里插入图片描述

参考文献

  1. Gradio - guides - Additional Features

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

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

相关文章

springboot + vue+elementUI图片上传流程

1.实现背景 前端上传一张图片&#xff0c;存到后端数据库&#xff0c;并将图片回显到页面上。上传组件使用现成的elementUI的el-upload。、 2.前端页面 <el-uploadclass"upload-demo"action"http://xxxx.xxx.xxx:9090/file/upload" :show-file-list&q…

开源生成式物理引擎Genesis,可模拟世界万物

这是生成大模型时代 —— 它们能生成文本、图像、音频、视频、3D 对象…… 而如果将所有这些组合到一起&#xff0c;我们可能会得到一个世界&#xff01; 现在&#xff0c;不管是 LeCun 正在探索的世界模型&#xff0c;还是李飞飞想要攻克的空间智能&#xff0c;又或是其他研究…

【PPTist】批注、选择窗格

前言&#xff1a;本篇文章研究批注和选择窗格两个小功能 一、批注 批注功能就是介个小图标 点击可以为当前页的幻灯片添加批注&#xff0c;还能删除之前的批注 如果我们增加了登录功能&#xff0c;还可以在批注上显示当前的用户名和头像&#xff0c;不过现在是写死的。 左侧…

Vue进阶(贰幺贰)npm run build多环境编译

文章目录 一、前言二、实施三、总结&#xff1a;需要打包区分不同环境四、拓展阅读 一、前言 项目开发阶段&#xff0c;会涉及打包部署到多个环境应用场景&#xff0c;在不同环境中&#xff0c;需要进行项目层面的区分&#xff0c;做不同的操作&#xff0c;可以利用打包的--mo…

Elasticsearch—索引库操作(增删查改)

Elasticsearch中Index就相当于MySQL中的数据库表 Mapping映射就类似表的结构。 因此我们想要向Elasticsearch中存储数据,必须先创建Index和Mapping 1. Mapping映射属性 Mapping是对索引库中文档的约束&#xff0c;常见的Mapping属性包括&#xff1a; type&#xff1a;字段数据类…

“AI智慧组卷系统:让考试变得更简单、更公平!

大家好&#xff0c;我是一名资深的产品经理&#xff0c;今天咱们就来聊聊教育领域的一款黑科技产品——AI智慧组卷系统。在这个信息技术飞速发展的时代&#xff0c;AI技术已经渗透到了我们生活的方方面面&#xff0c;教育行业也不例外。下面我就用大白话给大家介绍一下这个AI智…

单元测试概述入门

引入 什么是测试&#xff1f;测试的阶段划分&#xff1f; 测试方法有哪些&#xff1f; 1.什么是单元测试&#xff1f; 单元测试&#xff1a;就是针对最小的功能单元&#xff08;方法&#xff09;&#xff0c;编写测试代码对其正确性进行测试。 2.为什么要引入单元测试&#x…

三、Angular 路由

一、简介 Angular 的路由服务是一个可选的服务&#xff0c;它用来呈现指定的 URL 所对应的视图。它并不是Angular 核心库的一部分&#xff0c;而是位于 angular/router 包中。像其他 Angular 包一样&#xff0c;路由服务在用户需要时才从此包中导入。 [1]. 创建路由模块 默认…

【MATLAB】绘制投资组合的有效前沿

文章目录 一、数据准备二、有效前沿三、代码3.1 数据批量读取、预处理3.2 绘制可行集3.3 绘制有效前沿3.4 其它-最大夏普率 一、数据准备 准备多个股票的的历史数据&#xff0c;目的就是找到最优的投资组合。 下载几个标普500里面的公式的股票数据吧&#xff0c;下载方法也可…

JuiceFS 2024:开源与商业并进,迈向 AI 原生时代

即将过去的 2024 年&#xff0c;是 JuiceFS 开源版本推出的第 4 年&#xff0c;企业版的第 8 个年头。回顾过去这一年&#xff0c;JuiceFS 社区版依旧保持着快速成长的势头&#xff0c;GitHub 星标突破 11.1K&#xff0c;各项使用指标增长均超过 100%&#xff0c;其中文件系统总…

重生之我在异世界学编程之C语言:枚举联合篇

大家好&#xff0c;这里是小编的博客频道 小编的博客&#xff1a;就爱学编程 很高兴在CSDN这个大家庭与大家相识&#xff0c;希望能在这里与大家共同进步&#xff0c;共同收获更好的自己&#xff01;&#xff01;&#xff01; 本文目录 引言正文枚举&#xff08;Enum&#xff0…

6 分布式限流框架

限流的作用 在API对外互联网开放的情况下&#xff0c;是无法控制调用方的行为的。当遇到请求激增或者黑客攻击的情况下&#xff0c;会导致接口占用大量的服务器资源&#xff0c;使得接口响应效率的降低或者超时&#xff0c;更或者导致服务器宕机。 限流是指对应用服务进行限制…

【Linux系列】如何使用 nohup 命令在后台运行脚本

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

门禁系统与消防报警的几种联动方式

1、规范中要求的出入口系统与消防联动 1.1《建筑设计防火规范》GB 50016-2018 1.2《民用建筑电气设计规范》JGJ 16-2008  14.4出入口控制系统 3 设置在平安疏散口的出入口限制装置&#xff0c;应与火灾自动报警系统联动;在紧急状况下应自动释放出入口限制系统&…

Express 加 sqlite3 写一个简单博客

例图&#xff1a; 搭建 命令&#xff1a; 前提已装好node.js 开始创建项目结构 npm init -y package.json:{"name": "ex01","version": "1.0.0","main": "index.js","scripts": {"test": &q…

GetMaterialApp组件的功能与用法

文章目录 1. 知识回顾2. 使用方法2.1 源码分析2.2 常用属性3. 示例代码4. 内容总结我们在上一章回中介绍了"Get包简介"相关的内容,本章回中将介绍GetMaterialApp组件.闲话休提,让我们一起Talk Flutter吧。 1. 知识回顾 我们在上一章回中已经介绍过GetMaterialApp组…

LabVIEW之树形控件

一、树形控件基本构成 树形控件这个名称非常形象&#xff0c;其如同树一样&#xff0c;是典型的分层结构。树形控件的属性和方法使用非常灵活&#xff0c;树形控件的内容既可以静态编辑&#xff0c;也可以通过编程来动态填充。静态编辑树形控件适用于内容不变的应用场景&#…

Inno Setup制作安装包,安装给win加环境变量

加 ; 加环境变量&#xff0c;开启&#xff0c;下面一行 ChangesEnvironmentyes 和 ; 加环境变量wbrj变量名&#xff0c;{app}\project\bin变量值&#xff0c;{app}\后接文件名&#xff0c;{app}表示安装路径。下面一行,{olddata};原来的值上拼接 Root: HKLM; Subkey: “SYSTEM\…

张朝阳惊现CES展,为中国品牌 “代言”的同时,或将布局搜狐新战略!

每年年初&#xff0c;科技圈的目光都会聚焦在美国拉斯维加斯&#xff0c;因为这里将上演一场被誉为 “科技春晚” 的年度大戏 ——CES 国际消费电子展。作为全球规模最大、最具影响力的科技展会之一&#xff0c;CES 吸引了来自 160 多个国家的创新者和行业领导者&#xff0c;是…

UDS诊断之0x27服务—结合实例讲解

前言&#xff1a; 本文讲解的是比较深入一点知识&#xff0c;对于一些刚入门的同学&#xff0c;建议直接先看一遍14229规范&#xff0c;然后找一个实际项目练练手&#xff01;然后再来看本文&#xff0c;相信你会对0x27服务有更深的认知&#xff01;&#xff01;&#xff01; …