Flutter GenUI 0.9 與 A2UI 0.9 發布,全動態 UI 支援,AI 在 App 裡直接生成介面

在之前的 《Flutter 官方 LLM 動態 UI 庫 flutter_genui 發布,讓 App UI 自己生成 UI》 我們就聊過,Flutter 已經支援讓 Agent 在 App 執行中動態生成元件,而現在 GenUI 和對應的 A2UI 這次也都更新了全新協議,所以這波我們也整體回顧一下這整套全新的 AI 動態 UI 方案。

目前在 Flutter 上整個 AI 生成 UI 可以分為兩層:

  • Agent 負責生成受協議約束的 UI 意圖
  • 用戶端負責用元件目錄和執行時期把它渲染成真實 UI

也就是說,A2UI 模型輸出的也不是 Dart、JS、HTML 這種具體程式碼,實際上輸出的是一種結構化的 UI 描述,因為協議是通用的,然後這裡再由 GenUI 對接後渲染成 Flutter 的元件。

A2UI

所以我們還是需要聊一聊這個協議,因為它不只是 Flutter 專用

正常流程上,Flutter 需要透過 A2UI 取得描述,Flutter 端會透過 GenUI runtime 解析這些描述,再結合 Catalog、DataModel、SurfaceController 等機制,把它變成一套可以「互動、更新、回流」給 Agent 的 Flutter Widget:

所以其實這裡 A2UI 就是 Agent-to-UI 的協議層,它可以用在 Flutter,也可以用在 CMP、RN、Vue 等各種場景。

我一直覺得它最大的用處就是做 Agent 應用,比如在 AI 對話或者客服場景,A2UI 可以直接給出結果而不是文字,當使用者說:

  • 「幫我規劃旅行預算」
  • 然後 Agent 可以直接生成卡片、日期選擇器、預算圖表、可選列表等等,讓使用者直接互動和選擇

那你說這和讓 AI 生成程式碼有什麼區別?其實還真沒太大本質區別,只是如果你輸出的是程式碼,那麼可用性就低了,而且還需要額外的編譯渲染。

而 A2UI 是模型生成受 schema 約束的 UI 指令,用戶端再用「已經註冊的元件」完成渲染,整體效能和速度會好不少,當然靈活性也會差一些:

那這次 A2UI v0.9 有什麼特別?主要是這個版本做了很多核心調整:

1、 “Standard components” 改成 “Basic components”

在這次的 A2UI v0.9 把原來的「Standard components」改為「Basic components」,也就是 A2UI 現在不會內建什麼標準設計,因為「前端、行動端、企業應用」一般都有自己的設計風格,比如 Flutter App 裡會有自己的 ProductCardOrderStatusViewMetricChartPermissionNoticeDeviceControlPanel 等設計場景。

所以 A2UI 這次調整成「Basic components」,核心是想提供一套參考元件、基礎元件和範例元件,所以這次協議變更也明確了一個標準:

  • A2UI 不綁定某一個前端框架
  • A2UI 也不強制某一套 UI 元件
  • A2UI 只定義 Agent 如何表達 UI 意圖
2、Web renderer 統一

A2UI v0.9 版本還引入 shared web-core,同時更新了 React、Flutter、Angular 等 renderer,所以 A2UI 在 0.9 版本開始生態不再是 Flutter-only 或者 React-only 方案,而是同一份 A2UI 輸出,可以被不同 renderer 解析並渲染:

這其實很重要,因為這代表 A2UI 邏輯可以在不同語言和框架下多端適配,這對現階段的 AI Coding 場景來說很實用。


3、Agent SDK

當然,最重要的是 A2UI v0.9 提供了 Agent SDK,而 Agent 支援生成「合法、可解析且可驗證」的 A2UI 輸出,Agent 的整體核心圍繞 schema、prompt、解析、修復、驗證 來完成工程化閉環:

這裡的關鍵點在於,A2UI 解決了「模型輸出不穩定」問題,輸出的結果在工程裡可以透過 Agent SDK 自己修復問題,比如生成 system prompt、描述元件 catalog、解析模型輸出、修復部分格式等場景,最終輸出轉換成客戶端可以消費的 A2UI message。

4、新增

其他部分 A2UI v0.9 還新增和強化了幾類能力:

  • client-defined functions:客戶端可以暴露一組受控函式給 Agent 呼叫,例如驗證表單、計算價格、檢查本地狀態、觸發某個有限能力,當然這裡必須強調「受控」,因為客戶端不能隨便把任意高風險能力暴露給模型,這是血的教訓
  • client-to-server data syncing:使用者在 UI 裡操作表單、進度條、選擇器後,狀態可以同步給伺服器端 Agent,Agent 可以基於最新狀態繼續推理,而不是每一輪都重新讓使用者用文字描述
  • improved error handling:模型輸出結構化 UI 時一定會出現格式錯誤、屬性缺失、元件不存在、狀態引用錯誤等問題,協議和 runtime 必須能夠處理這些錯誤
  • simplified modular schema:讓不同元件集、不同 renderer、不同 Agent 能力更容易組合在一起

當然,最重要的是這次修改後 Transport 更開放了,現在 transport interface 可以執行在 MCP、WebSocket、REST、AG-UI、A2A 等不同傳輸方式上,比如:

  • A2A / WebSocket / REST / MCP / AG-UI 主要解決怎麼傳
  • A2UI 負責「傳的 UI 語意是什麼」
  • Flutter / React / Angular renderer 負責「最後怎麼渲染」

所以也可以看出來,A2UI 的定位更像是 Agentic UI 的中介協議層,主要用在 Agent 和 UI runtime 之間的語意表達。

Flutter GenUI

那到這裡就很清楚了,Flutter GenUI 就是 A2UI 在 Flutter 的執行時 SDK,它主要負責把 Agent 輸出的結構化 UI 指令解析成 Flutter 可渲染的 UI,當然,除此之外它還支援了 使用者互動、資料綁定、Surface 生命週期、下一輪 Agent 對話 等場景,GenUI 算是 A2UI 上的一套完整實作架構:

如果從使用鏈路上看其實鏈條還是很長的,不過這裡主要需要關注的是三個點:

  • 串流解析:LLM 不一定要一次性回傳完整 UI,transport adapter 可以接收 chunks,再由 parser 轉成事件
  • 狀態驅動:輸出後的 UI 不只是靜態輸出,而是和 DataModel 綁定,使用者操作可以更新狀態重新渲染
  • 互動回流:使用者在 UI 上的點擊、輸入、選擇,不只是單純本地事件,還可以成為下一輪 Agent 推理的上下文

所以可以看出來,GenUI 不是一套簡單的 UI 生成,甚至你可以認為它是一套 App 端的 SSR 都行,而這次 GenUI 0.9 也做了大更新,開始從耦合演變成分層結構。

因為舊的 GenUI 思路更像是一個集中的 GenUiConversationContentGenerator 處理,AI 輸出、A2UI 訊息、文字流、錯誤流的處理邏輯會被放在較強耦合的臭象裡,而新方案根據職責對實作進行了拆分:

事實上這個調整還是很重要的,因為它讓 Flutter GenUI 更方便接入到不同模型、Agent 後端和傳輸協議裡,比如現在你可以接:

  • Firebase AI Logic
  • Gemini API
  • 自建 Python Agent
  • A2A server
  • WebSocket Agent
  • REST Agent
  • 本地模型
  • 其他 LLM provider

因為現在 GenUI 沒有把「模型怎麼呼叫」寫死在 SDK,而是把模型接入、協議解析、狀態管理和 Flutter 渲染分開。

而 0.9 的另外一個變化就是 Prompt First,也就是現在不只是單純依賴 structured output,因為並不是所有模型、provider、和執行環境都能穩定支援嚴格 structured output。

所以為了讓更多模型可以支援 GenUI,這次 GenUI 選擇透過 PromptBuilder 把 Catalog、A2UI schema、生成規則注入 system prompt,讓模型按 A2UI 格式輸出,同時 GenUI runtime 也圍繞 Surface 生命週期定義了幾類場景:

實際上 Prompt First 的優勢是相容性更好,能適配更多 LLM provider,當然代價是 system prompt 會變得更長,token 成本會升高。

那實際上整個 GenUI 是怎麼工作的?首先第一個要理解的就是 Catalog。

Catalog

Catalog 是 Flutter GenUI 裡非常重要的定義,它定義了 AI 可以使用哪些元件,以及每個元件有哪些屬性、事件和渲染方式,簡單來說類似:

bash 体验AI代码助手 代码解读复制代码CatalogItem
  元件名稱
  元件屬性 schema
  Flutter builder function
  可選描述 / 範例

因為模型生成的不是 Dart 程式碼,而是類似這樣的 UI 意圖:

css 体验AI代码助手 代码解读复制代码{
  "type": "Button",
  "properties": {
    "label": "確認",
    "action": "submit"
  }
}

而 Flutter 客戶端看到這個資料後,會去 Catalog 裡找 Button 對應的 builder,再渲染成真實 Flutter Widget。

所以 Catalog 最重要的作用就是:

  • 模型不能隨便生成任意程式碼,只能使用你開放的元件和屬性
  • 設計風格一致,UI 組合都是用你定義好的元件
  • 只開放業務上允許的元件,比如訂單卡片、裝置圖表、權限說明、配置面板,權限可控

所以它也不是傳統意義上的熱更新,GenUI 的 A2UI message 只是讓 UI 做 createSurfaceupdateComponentsupdateDataModeldeleteSurface 這類動作,本質是執行時狀態和元件樹描述的變化

你需要引入 GenUI SDK,提前註冊 Catalog,之後 LLM 生成結構化 UI 描述,這些描述進入 SurfaceController 更新內部狀態,然後透過 Flutter rebuild 去渲染,也就是:

執行時讀取 JSON 資料,然後用你 App 裡已經 AOT 編譯好的 Dart 程式碼去建立 Widget 物件,Catalog 本質就是一張「字串 - 已編譯 builder」的註冊表

簡單來說就是,GenUI 的 Catalog 可以簡化理解成這樣:

javascript 体验AI代码助手 代码解读复制代码final catalog = {
  'text': (props) => Text(props['value']),
  'button': (props) => ElevatedButton(
        onPressed: () {},
        child: Text(props['label']),
      ),
  'slider': (props) => Slider(
        value: props['value'],
        min: props['min'],
        max: props['max'],
        onChanged: (_) {},
      ),
  'chart': (props) => MyChart(data: props['data']),
};

然後伺服器回傳:

json 体验AI代码助手 代码解读复制代码{
  "type": "slider",
  "props": {
    "value": 50,
    "min": 0,
    "max": 100
  }
}

最後客戶端做:

ini 体验AI代码助手 代码解读复制代码final builder = catalog['slider'];
return builder(props);

大概就是這樣的一個流程,所以也不違反上架要求。

DataModel

如果說前面的 Catalog 是 UI 核心,那麼 DataModel 層的實作就是互動核心,DataModel 的作用就是提供生成 UI 的互動能力,使用者可以透過按鍵、進度條和表單,把狀態變成下一輪 Agent 推理的一部分:

這也是 GenUI 和傳統 chatbot 場景的差別,傳統 chatbot 只能等使用者輸入,而 GenUI 可以讓使用者透過圖形介面修改狀態,然後把狀態回流給 Agent,所以可以在操作過程裡即時更新和建立新的 UI

genui_core

最後 genui_core 就是整個 GenUI 的基礎實作,而這次 0.9 也明確了 genui_core 的長期方向:把協議處理、狀態樹維護、JSON Pointer、表示式求值等能力放到更純粹的 genui_core 中,而 Flutter package 只負責 Flutter 渲染,大概類似:

目的其實也很簡單,就是減少 Flutter 渲染層和 A2UI 協議層的耦合,讓不同端的實作更一致,因為 Web 端已經有 shared web-core,Flutter 如果也能把 core 層抽出來,協議行為就更容易統一。

所以客戶端也許真的不需要開發一個完整的頁面功能,開發者在 App 裡可能更多是在維護元件庫,然後剩下的就是 AI 負責渲染和組合維護,例如:

  • AI 助手裡的動態卡片和動態表單
  • 內部工具和營運後台
  • 資料分析結果的互動式展示
  • 理財、旅行、健康、裝置設定等規劃類場景
  • IoT / 硬體控制面板的動態生成
  • 開發者工具裡的診斷、配置、修復精靈
  • 教育類、問答類場景

這些都可以在 A2UI 場景下得到能力提升,如果你要說問題是什麼??問題肯定是 Token,有人說生成速度太慢,那是因為你沒上 AI 滿倍率速度,只要捨得上,你看效果怎麼樣?

所以核心其實還是 Token 消耗會很高,使用者的操作都會變成企業的 Token 支出。

當然,GenUI 也明確,開發者可以在自己的 LLM/Agent 接入層快取 A2UI 輸出或業務狀態,而對於已經得到的 JSON,你也可以自己管理快取,什麼時候需要生成,什麼時候沿用既有的,具體就看業務設計了。

那麼,你覺得 A2UI 對你來說有用嗎?

連結

docs.flutter.dev/ai/genui/ge…


原文出處:https://juejin.cn/post/7640409934489010230


精選技術文章翻譯,幫助開發者持續吸收新知。

共有 0 則留言


精選技術文章翻譯,幫助開發者持續吸收新知。
🏆 本月排行榜
🥇
站長阿川
📝12   💬4   ❤️1
464
🥈
alicec
📝1   ❤️2
87
#4
我愛JS
💬1  
3
評分標準:發文×10 + 留言×3 + 獲讚×5 + 點讚×1 + 瀏覽數÷10
本數據每小時更新一次
📢 贊助商廣告 · 我要刊登