目录
简介
简单聊天机器人示例
为聊天机器人添加流式响应
添加 Markdown、图片、音频或视频
总结
上一篇
Gradio.Net (https://github.com/feiyun0112/Gradio.Net)是一个开源的 .NET 库,它是 Gradio 的 .NET 移植版本,允许你为机器学习模型、API 或任何 C# 函数快速构建演示或 Web 应用程序,无需任何 JavaScript、CSS 或 Web 开发经验!
简介
重要提示:如果您刚入门,建议使用ChatInterface来创建聊天机器人——这是一个高级抽象,可以快速创建精美的聊天机器人应用,通常只需一行代码即可完成。
本教程将展示如何使用 Gradio.Net 低级 Blocks API 从零开始构建聊天机器人 UI。这将让您完全掌控聊天机器人的界面。您将从创建一个简单的文字聊天机器人开始,然后添加流式文字响应,最后构建一个能处理媒体文件的聊天机器人。
简单聊天机器人示例
让我们从一个简单的示例开始。机器人随机回复"你好吗?"、"今天是美好的一天"或"我非常饿"等消息。以下是 Gradio.Net 的实现代码:
using Gradio.Net; using Gradio.Net.Components; // Simple chatbot that randomly responds with preset messages using var demo = gr.Blocks(); using (demo) { var chatbot = gr.Chatbot(); var msg = gr.Textbox(); var clear = gr.ClearButton(new List<Component> { msg, chatbot }); static (object, object) Respond(object message, object chatHistory) { var history = (chatHistory as List<Dictionary<string, object>> ?? new()).ToList(); string botMessage = new[] { "How are you?", "Today is a great day", "I'm very hungry" }[new Random().Next(3)]; history.Add(new Dictionary<string, object> { ["role"] = "user", ["content"] = message?.ToString() ?? "" }); history.Add(new Dictionary<string, object> { ["role"] = "assistant", ["content"] = botMessage }); Thread.Sleep(2000); return ("", history); } Func<object, object, (object, object)> fn = Respond; msg.Submit(fn: fn, inputs: new List<Component> { msg, chatbot }, outputs: new List<Component> { msg, chatbot }); } await demo.Launch();这里有三个 Gradio.Net 组件:
Chatbot:其值存储整个对话历史,为用户和机器人之间的响应列表。
Textbox:用户输入消息并按回车/提交以触发聊天机器人响应。
ClearButton:清除文本框和整个聊天历史的按钮。
我们有一个Respond()函数,接受整个聊天历史,追加一条随机消息,等待 2 秒,然后返回更新后的聊天历史。
为聊天机器人添加流式响应
有几种方式可以改善上述聊天机器人的用户体验:
流式传输响应,让用户不必等太久
让用户消息立即显示在聊天历史中,同时生成机器人响应
以下是实现代码:
using Gradio.Net; using Gradio.Net.Components; // Streaming chatbot with user message appearing immediately using var demo = gr.Blocks(); using (demo) { var chatbot = gr.Chatbot(); var msg = gr.Textbox(); var clear = gr.Button("Clear"); static (object, object) User(object userMessage, object history) { var hist = (history as List<Dictionary<string, object>> ?? new()).ToList(); hist.Add(new Dictionary<string, object> { ["role"] = "user", ["content"] = userMessage?.ToString() ?? "" }); return ("", hist); } static IEnumerable<object> Bot(object history) { var hist = (history as List<Dictionary<string, object>> ?? new()).ToList(); string botMessage = new[] { "How are you?", "I love you", "I'm very hungry" }[new Random().Next(3)]; hist.Add(new Dictionary<string, object> { ["role"] = "assistant", ["content"] = "" }); foreach (char ch in botMessage) { hist[^1]["content"] = hist[^1]["content"]?.ToString() + ch; Thread.Sleep(50); yield return hist.ToList(); } } Func<object, object, (object, object)> userFn = User; Func<object, IEnumerable<object>> botFn = Bot; msg.Submit(fn: userFn, inputs: new List<Component> { msg, chatbot }, outputs: new List<Component> { msg, chatbot }, queue: false) .Then(fn: botFn, inputs: chatbot, outputs: chatbot); clear.Click(fn: (object _) => (object)null!, inputs: null, outputs: chatbot, queue: false); } await demo.Launch();您会注意到,当用户提交消息时,我们通过.Then()链式绑定了两个事件:
第一个方法
User():使用用户消息更新聊天机器人并清除输入字段。由于我们希望这立即发生,设置 queue: false。第二个方法
Bot():逐字符构建消息并 yield中间输出。Gradio.Net 会自动将任何带有 yield关键字的函数转换为流式输出接口。
添加 Markdown、图片、音频或视频
gr.Chatbot组件支持 Markdown 子集,包括粗体、斜体和代码块。例如:
static List<Dictionary<string, object>> Bot(List<Dictionary<string, object>> history) { var response = new Dictionary<string, object> { ["role"] = "assistant", ["content"] = "**很酷!**" }; history.Add(response); return history; }此外,它还可以处理媒体文件,如图片、音频和视频。您可以使用MultimodalTextbox组件轻松上传各类媒体文件。要传入媒体文件,必须传入一个包含path键指向本地文件的字典:
using Gradio.Net; using Gradio.Net.Components; using Gradio.Net.Events; // Multimodal streaming chatbot with image/file upload support and like/dislike buttons static void PrintLikeDislike(LikeData likeData) { Console.WriteLine($"Index: {likeData.Index}, Value: {likeData.Value}, Liked: {likeData.Liked}"); } static (object, object) AddMessage(object history, object message) { var hist = (history as List<Dictionary<string, object>> ?? new()).ToList(); var msgDict = message as Dictionary<string, object> ?? new(); var userContent = new List<object>(); if (msgDict.TryGetValue("files", out var files) && files is System.Collections.IEnumerable fileEnum && files is not string) foreach (var f in fileEnum) userContent.Add(new Dictionary<string, object> { ["path"] = f?.ToString() ?? "" }); if (msgDict.TryGetValue("text", out var text) && text != null) userContent.Add(text.ToString() ?? ""); hist.Add(new Dictionary<string, object> { ["role"] = "user", ["content"] = userContent }); return (hist, gr.MultimodalTextbox(value: null, interactive: false)); } static IEnumerable<object> Bot(object history) { var hist = (history as List<Dictionary<string, object>> ?? new()).ToList(); string response = "**That's cool!**"; hist.Add(new Dictionary<string, object> { ["role"] = "assistant", ["content"] = "" }); foreach (char ch in response) { hist[^1]["content"] = hist[^1]["content"]?.ToString() + ch; Thread.Sleep(50); yield return hist.ToList(); } } using var demo = gr.Blocks(); using (demo) { var chatbot = gr.Chatbot(elemId: "chatbot", likeUserMessage: true); var chatInput = gr.MultimodalTextbox( interactive: true, fileCount: "multiple", placeholder: "Enter message or upload file...", showLabel: false, sources: new List<string> { "microphone", "upload" } ); Func<object, object, (object, object)> addFn = AddMessage; Func<object, IEnumerable<object>> botFn = Bot; Action<LikeData> likeFn = PrintLikeDislike; var chatMsg = chatInput.Submit(fn: addFn, inputs: new List<Component> { chatbot, chatInput }, outputs: new List<Component> { chatbot, chatInput }); var botMsg = chatMsg.Then(fn: botFn, inputs: chatbot, outputs: chatbot, apiName: "bot_response"); botMsg.Then(fn: () => gr.MultimodalTextbox(interactive: true), inputs: null, outputs: chatInput); chatbot.Like(fn: likeFn, inputs: null, outputs: null); } await demo.Launch();总结
本章介绍了如何使用 Gradio.Net Blocks API 从零开始构建自定义聊天机器人:
使用
gr.Chatbot、gr.Textbox和 gr.ClearButton构建简单聊天界面通过事件链(
.Then())和 yield实现流式响应使用
gr.MultimodalTextbox支持文字和媒体文件输入使用
chatbot.Like()为消息添加点赞/踩功能支持 Markdown、图片、音频和视频等富内容展示
引入地址