当前位置: 首页 > news >正文

Gradio.Net 开发指南 -- 如何使用 Gradio.Net Blocks 创建自定义聊天机器人

目录

简介

简单聊天机器人示例

为聊天机器人添加流式响应

添加 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 秒,然后返回更新后的聊天历史。

为聊天机器人添加流式响应

有几种方式可以改善上述聊天机器人的用户体验:

  1. 流式传输响应,让用户不必等太久

  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()链式绑定了两个事件:

  1. 第一个方法 ‎User():使用用户消息更新聊天机器人并清除输入字段。由于我们希望这立即发生,设置 ‎queue: false

  2. 第二个方法 ‎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、图片、音频和视频等富内容展示

引入地址

http://www.jsqmd.com/news/1399122/

相关文章:

  • 浏览器请求管理入门:用Header Editor修改请求头,五个步骤上手网络调试
  • 提升gh_mirrors/gr/grpc-tutorial性能:终极Keep-alive配置与连接管理技巧
  • Docker-SSH终极指南:如何为任何容器添加SSH访问能力
  • CICFlowMeter与网络安全数据集:CICIDS2017与CICDDoS2019生成方法
  • Witch Hat Atelier Spell Simulator魔法识别原理:从手绘到数字魔法的奇妙旅程
  • 揭秘国内路灯行业佼佼者,选对品牌照亮前行路 - 官方资讯
  • 老 Mac 也能用上新版 macOS?OpenCore Legacy Patcher 上手全记录
  • Jane Street OCaml Workshop项目架构解析:从dune配置到模块设计最佳实践
  • PDF处理神器实测:免费开源的PDF补丁丁,书签编辑与文档合并一篇搞定
  • PDF补丁丁:5分钟上手的免费PDF处理全能工具箱
  • lm-watermarking vs 传统水印:为什么LLM专用水印技术不可替代?
  • 手把手跑通 RR 引导系统:20 分钟从启动盘到黑群晖上线
  • 直播里二维码只闪几秒?MHY_Scanner扫码登录工具把“抢码“变成“秒登“
  • PhotoGIMP免费替代Photoshop:3分钟零成本迁移,从订阅制到开源编辑器的完整体验
  • 一套能直接用的 WPF 工业上位机(HMI)框架,带源码
  • 告别烦人弹窗:免费开源的 uBlock Origin 如何帮你搞定网页广告拦截
  • 从“按键机器“到“战术指挥“:剑网3自动化减负工具 JX3Toy 轻松上手
  • backoff性能测试:如何验证你的退避策略是否高效?
  • PDF补丁丁实战手册:从杂乱PDF到带目录电子书,30分钟上手的免费全能工具箱
  • 革命性多GPU工具tensor_parallel:一行代码实现PyTorch模型线性加速
  • 北京全案设计哪家强?性价比高手把手教你选 - 官方资讯
  • anydoc 文档转换工具终极指南:14 种格式一键转 Markdown,到底怎么玩?
  • 大竹县装修公司推荐哪家 千缘装饰 17323355557 - 米諾
  • 3 分钟完成 Motrix 浏览器扩展配置:让所有下载任务自动交给下载管理器
  • 不想手写CRUD接口?DreamFactory API生成平台让数据库几分钟变身完整REST服务
  • DeepTutor上手全攻略:这款开源AI学习助手,为什么值得装在你的电脑上
  • 揭秘!国内太阳能路灯工厂实力大比拼,哪家更胜一筹? - 官方资讯
  • 5分钟免费搞定:用PhotoGIMP把GIMP变成你熟悉的Photoshop界面
  • MediaCrawler快速实战:从零跑通五大平台的社交媒体数据采集
  • 如何在RTX 5090上流畅运行32B模型?Qwen3-VL-32B Ultra-Heretic INT8 ConvRot部署与性能优化指南