今日,Flutter 官方正式发布了它们关于 AI 大模型的 package 项目: genui ,它是一个非常有趣和前沿的探索类型的项目,它的目标是帮助开发者构建由生成式 AI 模型驱动的动态、对话式用户界面

也就是它与传统 App 中“写死的”静态界面不同,是一个可以基于 AI 模型,支持由 AI 根据与用户的实时对话动态生成 UI 的 SDK 。

当然,它并不是一个完全 Free 的动态 UI 项目,虽然看起来它是动态的,甚至可以用来做热更新,但是实际上也是存在限制条件。

首先它的作用是:应用能够实时渲染由 AI 返回的结构化数据 ,也就是 JSON 数据,所以实际上 flutter_genui 是一个基于文本描述,然后经过 AI 返回结构化数据进行渲染驱动的过程:

在 SDK 里,主要是通过一个名为 UiAgent 的接口,它负责管理与 AI 之间的交互循环,简化了开发流程

而对于 UI ,开发者可以定义一个 AI “允许使用” 的 Flutter Widget 词汇表 Catalog ,AI 将基于这个 Catalog 来构建 UI,比如官方的 Demo 就提供了类似的 catalog 目录来限制 UI 风格:

具体来说,就是定义好的各种 CoreCatalogItems 通过 GenUiManagercatalog 配置,让 AI 知道应该用哪些组件来生成需要的 UI :

这其中 CatalogItem 就像是每个 Widget 的“角色卡”,它核心规定了三件重要的事情:

  • name: Widget 的名字(例如 “Column”, “Text”, “ElevatedButton”),这是给 AI 看的,AI 会通过这个名字来指定使用哪个 Widget
  • dataSchema: 一个 Schema 对象,它用 JSON Schema 的格式,精确定义了这个 Widget 需要的所有参数,包括参数名、类型(字符串、数字、布尔等)和是否必需,这为 AI 提供了结构化的指令
  • widgetBuilder: 它负责接收 AI 返回的、符合 dataSchema 规范的 JSON 数据,并将其真正地渲染成一个 Flutter Widget

如果么有定义任何自定义组件,而是直接使用了 CoreCatalogItems.asCatalog() ,那么 AI 在生成 UI 时就只能使用 flutter_genui 内置的最核心的几个基础组件。

具体效果如下图所示,甚至在整个过程中,flutter_genui 能够捕捉用户的交互行为(如按钮点击、文本输入),并将这些事件作为上下文信息发送回 AI,以便 AI 在下一轮对话中做出响应:

而对于 flutter_genui,主要的核心对象有:

  • UiAgent (门面): 这是开发者主要交互的入口点,它封装了 GenUiManagerAiClient,是整个流程的协调者。
  • Catalog (Widget 目录): 定义了 AI 可以使用的 Widget 集合,每个 CatalogItem 包含 Widget 的名称、数据结构(Schema)和渲染它的构建函数
  • AiClient (AI 客户端): 负责与大语言模型通信的接口,GeminiAiClient 是其针对 Gemini 模型的具体实现,可以拓展支持其他模型
  • GenUiManager (UI 状态管理器): 管理所有动态生成的 UI 界面(称为 “Surfaces”)的状态,它提供了 addOrUpdateSurfacedeleteSurface 等工具供 AI 调用,并通过流(Stream)将更新通知给 UI
  • GenUiSurface (UI 渲染器): 一个 Flutter Widget,负责根据 GenUiManager 提供的 UiDefinition 递归地构建和渲染整个 UI 树

比如以下是一个简单的例字,展示了如何使用 UiAgent

import 'package:flutter/material.dart';
import 'package:flutter_genui/flutter_genui.dart';void main() {// 初始化 Firebase 等runApp(const MyApp());
}class MyApp extends StatefulWidget {const MyApp({super.key});State<MyApp> createState() => _MyAppState();
}class _MyAppState extends State<MyApp> {late final UiAgent _uiAgent;final List<GenUiUpdate> _updates = [];void initState() {super.initState();_uiAgent = UiAgent('You are a helpful AI assistant that builds UIs.',catalog: CoreCatalogItems.asCatalog(),onSurfaceAdded: _onSurfaceAdded,);}void _onSurfaceAdded(SurfaceAdded update) {setState(() {_updates.add(update);});}void _sendPrompt(String text) {if (text.trim().isEmpty) return;_uiAgent.sendRequest(UserMessage.text(text));}void dispose() {_uiAgent.dispose();super.dispose();}Widget build(BuildContext context) {return MaterialApp(home: Scaffold(appBar: AppBar(title: const Text('GenUI Demo')),body: Column(children: [Expanded(//  渲染动态 UI 界面child: ListView.builder(itemCount: _updates.length,itemBuilder: (context, index) {final update = _updates[index];return GenUiSurface(host: _uiAgent.host,surfaceId: update.surfaceId,onEvent: (event) {// UiAgent 会自动处理事件},);},),),// 聊天输入框 Widget ,调用 _sendPrompt// ····],),),);}
}

另外,在前面我们说过,AI 返回的是一个结构化的 JSON 数据,而对于 genui 来说,他底层会有一个dart_schema_builder 的基础工具包支持,它的核心作用是让你能够用 Dart 代码来创建和验证 JSON Schema

可以把它理解成一个“翻译器”,在 flutter_genui 的世界里,AI 需要知道它有哪些 UI 组件 (Widgets) 可以使用,以及每个组件需要哪些参数,这些规则就是通过 JSON Schema 来定义

简单说,它的作用是:

  • 用 Dart 构建 JSON Schema: 开发者不需要手动编写复杂的 JSON 文件来定义规则,而是可以通过 Dart 的链式调用来构建,例如,你可以定义一个“卡片”组件,规定它必须有一个 title (字符串类型) 和一个 description (也是字符串),还有一个可选的 imageUrl
  • 数据验证: 它可以根据你定义的 Schema 来验证一个 JSON 对象是否合法,这在接收 AI 返回的数据时至关重要,可以确保 AI 给出的 UI “指令”是完整且格式正确的,避免程序因数据格式错误而崩溃
  • 为 AI 提供“工具”的蓝图: flutter_genui 会将使用 dart_schema_builder 创建的 Schema 发送给大语言模型,这等于告诉 AI:“你可以使用这些工具(Widget),每个工具的参数和格式必须遵守这份说明书。”

也就是,对于 genui 底层,会使用 dart_schema_builder 为 Flutter Widgets (例如 InformationCard, ItineraryDay) 定义好 Schema,将这些定义好的 Widgets 注册到 flutter_genuiCatalog

之后用户输入文本,UiAgent 启动,AiClient 将对话和从 Catalog 中提取的 Schemas 发送给 LLM,LLM 返回一个符合某个 Schema 的 JSON 指令,UiAgentGenUiManager 解析该指令,更新 UI 状态。

最后 GenUiSurface 监听到状态变化,使用 Catalog 中的构建函数,将 JSON 数据渲染成用户可见的 Flutter 界面。

所以最终 UI 是通过 GenUiManager + GenUiSurface 渲染出来,具体大概流程为:

  • GenUiManager 负责管理所有 UI 界面的当前状态,内部有一个 _surfaces map,用来存储所有 UI 界面(Surface)的定义,每个 Surface 都有一个唯一的 surfaceId,其对应的值是一个 ValueNotifier<UiDefinition?>,这意味着当 UiDefinition 改变时,可以通知监听者

  • 在 AI 更新时,GenUiManager 会更新 _surfaces map 中对应 surfaceIdUiDefinition,然后通过一个 StreamController (_surfaceUpdates) 发出 SurfaceAddedSurfaceUpdated 事件,这个广播是 UI 能够自动重建的关键。

  • GenUiSurface 是一个 StatefulWidget,它是将抽象的 UiDefinition 渲染为用户可见界面的最终执行者,它监听了 surfaceIdValueNotifier ,并有一个递归 _buildWidget 函数

  • GenUiSurface 会从根 widget ID 开始,从 UiDefinition 中查找 widget 的 JSON 数据,然后调用 widget.host.catalog.buildWidget 方法,buildWidget 方法会找到对应的 CatalogItem 并执行其 widgetBuilder,从而创建出 Flutter Widget

所以可以看到,genui 的核心是利用 AI 大模型的 UI 组织能力,让它通过用户的描述和已有的控件目录,动态渲染和生成所需的 UI 控件。

话说回来,这里说到 AI 生成的核心产物是 UiDefinition 对象,它本质上是一个 JSON 结构,JSON 作为纯文本数据其实是可以保存的,比如我们对这部分数据进行拦截缓存,并在启动时加载渲染,实际上这也是一个有限能力的热更新模型

另外,目前使用 flutter_genui 最方便的默认实现是基于 Firebase 使用默认的 FirebaseAiClient ,它实现了与 Firebase AI(特别是 Gemini 模型)进行通信的支持,官方默认提供的 simple_chattravel_app 都是使用它。

你也可以在通过 AiClient 抽象接口实现自己自定义的 client 。

所以,你觉得 genui 有前景吗?

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

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Redis常用数据结构及其底层实现

Redis常用数据结构主要有String List Set Zset Hash BitMap Hyperloglog Stream GeoString:Redis最常用的一种数据结构,Sting类型的数据存储结构有三种int、embstr、raw1.int:用来存储long以下的整形embstr raw 都是用来存字符串&#xff0c;其中小于44字节的字符串用embstr存 …

O3.4 opencv图形拼接+答题卡识别

一图形拼接逻辑导入必要的库pythonimport cv2 import numpy as np import sys导入cv2库用于图像处理&#xff0c;numpy库用于数值计算&#xff0c;sys库用于与 Python 解释器进行交互&#xff0c;例如退出程序。定义图像显示函数def cv_show(name, img):cv2.imshow(name, img)c…

SQL注入常见攻击点与防御详解

SQL注入是一种非常常见且危险的Web安全漏洞。攻击者通过将恶意的SQL代码插入到应用程序的输入参数中&#xff0c;欺骗后端数据库执行这些非预期的命令&#xff0c;从而可能窃取、篡改、删除数据或获得更高的系统权限。以下是详细、准确的SQL注入点分类、说明及举例&#xff1a;…

EKSPod 资源利用率配置修复:从占位符到完整资源分析系统

概述 在 Kubernetes 集群管理过程中,资源利用率的监控和优化是保证应用性能和成本效益的关键环节。近期,我们对 EKSPod 管理界面的资源利用率显示功能进行了全面修复,将原先简单的占位符文本升级为完整的资源分析系统。本文将详细介绍这次修复的背景、方案、实现细节和最终…

Linux内核(架构)

文章目录Linux内核架构概述核心子系统详解1、进程管理2、内存管理3、虚拟文件系统(VFS)4、设备驱动模型掌握Linux内核核心技术阶段1&#xff1a;基础准备阶段2&#xff1a;内核基础阶段3&#xff1a;深入子系统阶段4&#xff1a;高级主题&#xff08;持续学习&#xff09;调试和…

基于数据挖掘的单纯冠心病与冠心病合并糖尿病的证治规律对比研究

标题:基于数据挖掘的单纯冠心病与冠心病合并糖尿病的证治规律对比研究内容:1.摘要 背景&#xff1a;冠心病和冠心病合并糖尿病在临床上较为常见&#xff0c;且二者在证治方面可能存在差异&#xff0c;但目前相关系统研究较少。目的&#xff1a;对比基于数据挖掘的单纯冠心病与冠…

即梦AI快速P图

原图&#xff1a; 模型选择3.0效果比较好&#xff0c;提示词“根据提供图片&#xff0c;要求把两边脸变小&#xff0c;要求把脸变尖&#xff0c;要求眼妆变淡&#xff0c;眼睛更有神&#xff0c;要求提亮面部肤色要求面部均匀&#xff0c;面部要磨皮!鼻头高光和鼻翼两边阴影变淡…

【办公类-109-04】20250913圆牌卡片(接送卡被子卡床卡入园卡_word编辑单面)

背景需求: 为了发被子,我做了全校批量的圆形挂牌,可以绑在“被子包”提手上,便于再操场上发放被子时,很多老师可以协助根据学号发放。 https://blog.csdn.net/reasonsummer/article/details/149755556?spm=1011.2415.3001.5331https://blog.csdn.net/reasonsummer/arti…

Shoptnt 促销计算引擎详解:策略模式与责任链的完美融合

在电商系统中&#xff0c;促销计算是业务逻辑最复杂、变更最频繁的模块之一。它不仅需要处理多种促销类型&#xff08;满减、折扣、优惠券等&#xff09;&#xff0c;还要管理它们之间的优先级和互斥关系。 Shoptnt 设计了一套基于 策略模式 (Strategy Pattern) 和 责任链模式…

【HTTP 请求格式】从请求行 到 请求体

引言 在前后端开发中&#xff0c;前端和后端之间的交互主要依赖于 HTTP&#xff08;HyperText Transfer Protocol&#xff0c;超文本传输协议&#xff09;。HTTP 是互联网通信的基础&#xff0c;它定义了客户端&#xff08;通常是浏览器或App&#xff09;和服务器之间如何交换数…

【自记】SQL 中 GROUPING 和 GROUPING SETS 语句的案例说明

我们用一个生活中的例子来理解&#xff0c;比如你开了家小超市&#xff0c;想统计「销售额」&#xff0c;但需要从多个角度看&#xff08;比如按 “日期 商品”、“仅日期”、“仅商品”、“整体总销售额”&#xff09;。假设你的销售数据长这样&#xff08;简化版&#xff09…

C语言第五课:if、else 、if else if else 控制语句

C语言第五课&#xff1a;if、else 、if else if else 控制语句if else 、if else if else 联合使用编程快速学习平台if else 、if else if else 联合使用 代码示列 #include <stdio.h> int main(){//设置中文编码输出到控制台system("chcp 65001");//今天星…

七彩喜智慧养老:用科技温暖晚年,让关爱永不掉线

“当银发潮遇见科技力&#xff0c;养老方式正在发生一场静悄悄的变革。”你有没有想过&#xff1a;当父母年迈独居时&#xff0c;如何确保他们的安全&#xff1f;当老人突然摔倒&#xff0c;如何第一时间获得救助&#xff1f;当慢性病需要长期管理&#xff0c;如何避免频繁奔波…

window显示驱动开发—为头装载和专用监视器生成自定义合成器应用(二)

显示相关的 API 的比较 API用途和目标受众DisplayInformation用于检索 CoreWindow 的呈现和布局属性。HdmiDisplayInformation用于枚举和设置受限模式集的仅限 Xbox 的 API。 高度专用于 Xbox 媒体应用方案。DisplayMonitor用于查询物理监视器设备的属性。 不公开有关操作系统…

Linux 高性能 I/O 事件通知机制的核心系统调用—— `epoll_ctl`

epoll 是 Linux 上处理大量文件描述符 I/O 事件的高效模型&#xff0c;而 epoll_ctl 则是你用来指挥 epoll 实例&#xff08;epoll instance&#xff09;的“遥控器”&#xff0c;负责向它添加、修改或删除需要监视的文件描述符&#xff08;FD&#xff09;及其感兴趣的事件。1.…

mysql 必须在逗号分隔字符串和JSON字段之间二选一,怎么选

如果必须在逗号分隔字符串和JSON字段之间二选一&#xff0c;那么 JSON字段是明显更好的选择。以下是详细的对比分析&#xff1a;对比结论&#xff08;直接看这里&#xff09;方面JSON字段逗号分隔字符串胜出方查询能力✅ 丰富的JSON函数支持❌ 只能使用LIKE模糊查询JSON数据验证…

DPI和DIP的区别

DPI 和 DIP 是两个在计算机图形和移动开发领域常见的术语&#xff0c;它们都与屏幕显示和尺寸有关&#xff0c;但含义和用途不同。 DPI (Dots Per Inch) 定义&#xff1a;DPI 的全称是 Dots Per Inch&#xff0c;即每英寸点数。它是一个衡量物理密度的单位&#xff0c;表示在…

数据帮助我们理解未知世界

主持人 尼古拉安根&#xff1a; 大家好&#xff0c;我是挪威南方财富基金首席执行官尼古拉安根。今天非常荣幸能与大卫斯皮格尔哈尔特爵士对话。坦率地说&#xff0c;他不仅是世界上最优秀的统计学家之一&#xff0c;也是我见过的最佳风险沟通者。他撰写了大量优秀著作&#xf…

在使用git的很多操作是保持工作区干净

这是一条铁律下面是错误操作&#xff1a;自己明明写完了代码&#xff0c;想要提交。此时你的工作区长这样你的提交顺序是&#xff1a;git pull -> git commit -> git push但是现实往往不这样&#xff0c;万一拉下来的代码和你当前工作区的代码有冲突&#xff0c;你必须要…

通过语法推导树快速求短语,简单短语和句柄

第一步&#xff1a;写出规范推导&#xff08;最右&#xff09;序列 规范推导就是最右推导。我们的目标是从起始符号 E 出发&#xff0c;通过每步替换最右边的非终结符&#xff0c;最终得到句型 R(Pi)。 文法 G[E]: E :: RP | PP :: (E) | iR :: RP | RP* | P | P* 推导过程&…