← 部落格
團隊手記閱讀約 9 分鐘

GenUI 的粒度問題:LLM 的生成應該停在哪裡?

建構 AirJelly GenUI 引擎的筆記——以及為什麼給 LLM 更多自由反而讓結果變得更糟。

Translated by AI

這篇部落格來自我們在 AirJelly 專案中對 GenUI 引擎的實作探索。我們不是從理論出發,而是從一個老實說相當令人沮喪的實驗開始:為什麼當我們給 LLM 更多生成 UI 的自由時,結果反而變得更糟?

01 · 背景

為什麼 GenUI 值得認真看待

在進入細節之前,值得先釐清為什麼 GenUI 是一個嚴肅的工程問題,而不只是展示用的花招。在Generative Interfaces for Language Models中,SALT-NLP / Stanford 團隊比較了使用者對 GenUI 與傳統文字聊天介面的偏好。結論很清楚:當 AI 系統需要傳達結構化、資訊密集的內容時,動態生成的介面可以遠勝於一大片文字。

GenUI 浪潮在 2023 到 2025 年間加速,因為兩個條件同時成熟:LLM 在程式碼生成上大幅進步,而 shadcn/ui 與 Radix 等元件生態系也變得足夠穩定,可以作為建構基礎。一旦這些條件到位,工具自然湧現——Vercel v0 是最具代表性的業界實作之一。

02 · 起點

我們讓 LLM 自由發揮,結果卻變得更糟

在feat/genui-real-content-experiment分支上,我們進行了一組比較。舊做法有固定版面與統一元件——精緻且可預期。新做法讓版面更有彈性,但視覺變得雜亂,元件樣式也不一致。

這與我們的直覺相違。我們給模型越多自由,掌控力就越低,視覺一致性也變得越差。Gen-UI-Lang 論文也提出同樣的觀點:要求 LLM 直接輸出原始 HTML 或 JSX,產出會冗長、脆弱且容易出錯。這不是提示詞品質的問題——而是我們把 LLM 推到了它並非處於最佳狀態的粒度。

03 · 核心張力

GenUI 中的結構性矛盾

透過這個實驗,我們辨識出一個幾乎適用於所有 GenUI 系統的內在矛盾。

LLM 擁有的自由越多,就越難保證視覺一致性。限制越強,GenUI 就越失去意義。

這是這個範式中的結構性張力,而不是某個實作中的錯誤。每個 GenUI 系統都必須在這兩股力量之間找到自己的立足點。於是問題變得非常具體:LLM 的生成邊界應該停在哪裡?

04 · 領域現況

既有的粒度選擇

在定下我們自己的答案之前,先看看其他人如何處理同一個問題會有所幫助。

Vercel v0——一路生成到元件程式碼

v0讓 LLM 一路向下,生成完整的 React 元件程式碼。它的視覺一致性來自shadcn/ui的語意 token 系統——它把一致性外包給該函式庫的主題。代價是:生成邏輯與元件生態系緊密耦合,因此要脫離 shadcn/ui + Next.js + Vercel 技術棧會產生實質的摩擦。

v0 風格元件程式碼的典型樣貌
<Card className={cn("flex flex-col",
  plan.recommended && "border-primary shadow-lg scale-105"
)}>

arXiv 做法——結構化中介表示

SALT-NLP / Stanford 的做法在自然語言與 UI 程式碼之間插入一層結構化中介表示,分為兩個層級:高階的互動流程(使用者路徑與任務階段的有向圖)以及低階的有限狀態機(每個元件的狀態與事件回應)。最終輸出仍是 HTML、CSS 與 JavaScript——這個表示是護欄,而不是終點。

Gen-UI-Lang——定義 UI 意圖層

Gen-UI-Lang設計了一套專用 DSL,讓 LLM 只輸出結構化的節點描述。節點結構明確、淺層且一致——正是 LLM 能可靠生成的內容。相較於直接生成 HTML,它回報token 用量減少 65.3%,同時提升穩定性,而且能從同一份描述渲染成 HTML、React JSX 或 Gradio。

一份 Gen-UI-Lang UI 意圖描述
genui(
  row(
    text("Sales Overview"),
    btn("Load", on_load=lambda: get_graph(2001, 2002))
  ),
  chart(type="line", data="sales_q4"),
)
05 · 我們的選擇

停在產品語意層

這三種做法都把 LLM 往上推,遠離渲染層。差別只在於它們停在哪裡。我們選擇停得比它們都更高:停在產品語意層。

LLM 不輸出像row或btn這類通用 UI 節點。它輸出的是產品概念——「這是一張任務摘要卡片,資訊密度高,來源是今天的行事曆。」要渲染哪個元件、如何排版,完全由元件函式庫決定——而不是 LLM。

01失敗案例帶來的直接教訓

一旦我們放鬆 LLM 的生成自由,視覺結果就變得更糟。LLM 越接近渲染層,其隨機性帶來的代價就越高。

02與瀏覽器渲染引擎的類比

瀏覽器不讓頁面 JavaScript 直接控制像素。它們接受受控的 DOM 描述,由引擎決定像素。GenUI 引擎也應該以同樣的方式運作。

03結構化 LLM 輸出的可靠性

OpenAI 在 2024 年推出 Structured Outputs,正是為了對抗格式漂移。輸出越接近渲染層,格式錯誤的代價就越高。

04對可替換元件函式庫的長期需求

停在產品語意層,元件函式庫就成為可插拔的渲染後端——明天就能換掉設計系統,而不必動到語意層。

06 · 一個尚未驗證的方向

兩輪生成

在除錯複雜的GenUIPager元件時,我們發現單一 LLM 回合難以同時最佳化內容品質與版面品質。這引導我們走向兩輪架構——作為一個假設。

兩輪生成假設
First-round LLM:  content orchestration + page-structure decisions
                  (product semantics layer)
      ↓
Second-round LLM / component library:  concrete rendering decisions

動機是合理的:內容編排與渲染是兩種不同的認知任務,硬把它們塞進單一回合可能會讓它們互相干擾。

但我們必須誠實:這只是一個假設,我們尚未完全驗證它。

它出現在這裡,是因為它指向一個值得探索的方向——而不是因為它是一個已定論的結論。

07 · 地圖

粒度選擇的取捨地圖

沒有哪一種粒度選擇是普遍正確的。這取決於產品對視覺不一致的容忍度、元件函式庫的預期生命週期,以及生成內容的結構化程度。

做法LLM 輸出到哪裡如何保證一致性函式庫可替換?適用情境
Vercel v0元件程式碼層shadcn/ui 語意 token否,緊密耦合Vercel 生態系內的快速原型開發
Gen-UI-Lang通用 UI 意圖層多目標渲染器是,與框架無關跨框架原型開發、效率優先的工作流程
arXiv 做法HTML / CSS / JS以結構化中介表示作為護欄視情況而定互動複雜度高的情境
AirJelly產品語意層元件函式庫完全掌控渲染是,可插拔對產品 UI 一致性要求高的應用

如果產品對視覺不一致的容忍度低,粒度就應該更高,更接近產品語意。如果元件函式庫很可能演進或被替換,同樣要更高。而如果生成內容高度結構化,就更適合在較高層級以語意方式描述它。

來源

來源與延伸閱讀

結語

粒度是 GenUI 的核心設計決策。

最大的收穫並不是我們找到了正確答案,而是我們釐清了問題:GenUI 並不是讓 LLM 來繪製介面,而是設計 LLM 與渲染系統之間明確的責任分工。

粒度的選擇決定了這條界線畫在哪裡——而界線畫在哪裡,又決定了系統的可維護性、視覺穩定性,以及長期演進的能力。

2025 年 10 月,W3C Design Tokens 社群小組發布了穩定的 Design Tokens 2025.10 規範——這顯示將語意與視覺分離正逐漸成為工程標準。GenUI 中的粒度問題,正是這股趨勢在 AI 生成介面中的體現。

我們還在路上。如果你也在探索類似的事情,我很樂意聊聊。

更多來自 AirJelly 團隊的內容 →