AI 可以重畫介面,但不能重寫產品的真相
想像一個已經做得很順的 demo。
使用者輸入一句「把這週的餐點換成高蛋白版本」,agent 隨即產生幾張互動卡片,列出替換前後的菜單、營養差異與套用按鈕。畫面不是設計師預先排好的,但資訊完整,操作也真的有反應。
然後使用者按下套用,關掉分頁,隔天再回來。
這時最重要的問題突然變得很樸素:產品現在相信哪一份資料?是昨天那張生成卡片、agent 留下的文字,還是應用程式原本的 store?
生成介面最吸睛的時刻,是它第一次出現。產品真正開始承擔責任,卻是使用者第二次回來的時候。
畫面可以變,作準的資料不能跟著漂移
傳統介面很容易讓人把畫面和狀態混在一起。表單裡顯示某個值,我們便直覺認為系統「就是這個狀態」。其實畫面一直都只是資料的投影,只是固定元件讓這件事不太顯眼。
Generative UI 把兩者拆開後,問題反而清楚了。
Agent 可以依照當下任務重新排列資訊,產生比較表、時間軸或一組臨時控制項。這些畫面即使每次稍有不同,也不一定會傷害產品。真正不能漂移的,是帳戶、訂單、權限、設定或工作項目等需要持久保存的資料。
CopilotKit 最近公開的 Angular 範例提供了一個很具體的做法。Agent 能提出餐點替換,也能生成互動介面,但 dashboard 的結果仍由 NgRx store 重新計算。Agent 說「已經換好了」不算完成;store 接受變更,畫面再從 store 重建,才是產品承認的結果。
我認為這條界線值得保留。模型適合負責表達、探索與提案,應用程式則要握住唯一作準、可以查詢,也能重新計算的狀態。否則每一張生成畫面,都可能悄悄變成一份新的臨時資料庫。
讓 agent 提出變更,不要讓它直接改寫世界
一個 agent 能讀取頁面內容,不代表它也該任意寫入所有資料。
比較可靠的做法,是把可修改的動作收斂成少數有型別的工具。例如「替換某一天的餐點」可以要求 dayId、oldMealId 與 newMealId;「調整專案期限」則要帶入專案識別碼與新日期。Agent 可以選擇呼叫哪個工具,卻不能自行發明一條繞過產品規則的寫入路徑。
工具 handler 收到請求後,還要回到當下的 application state 做判斷:
這個物件還存在嗎?
使用者有修改權限嗎?
前一個步驟是否已完成?
這次變更會不會讓資料進入無效狀態?
如果條件不成立,應用程式可以拒絕 mutation。拒絕機制把產品規則留在可以測試的程式邊界裡,不必寄望模型每次都做出相同判斷。
對小團隊來說,這也比在 prompt 裡堆更多警告實際。Prompt 可以幫 agent 選擇合理動作,schema 與 handler 才能限制一個動作究竟能造成什麼結果。前者改善判斷,後者決定權限。
Sandbox 與授權處理的是兩件事
生成 HTML 時,大家很自然會先想到 sandbox。這是必要的,因為不可預測的內容不該直接取得整個頁面的 DOM、cookie 或任意網路存取。
但 iframe 隔離得再完整,也沒有回答「這個使用者現在能不能取消訂單」。
Sandbox 控制生成內容能碰到哪些資源;authorization 與 state validation 決定某個變更能不能發生。CopilotKit 的 open generative UI 讓 sandbox 只能呼叫事先列出的函式,而應用程式端的 handler 仍可依目前狀態拒絕請求。兩條邊界各自負責一半,不能互相代替。
如果只有 sandbox,生成內容可能被關在小房間裡,卻仍握著一個權限過大的函式。如果只有 mutation 驗證,任意生成的內容又可能在頁面其他地方造成不必要的風險。安全隔離和產品授權都要做,而且最好由不同層處理。
使用者需要回到同一件事
Generative UI 的另一個麻煩,不一定會出現在第一次操作。
固定介面有一種常被低估的價值:人知道去哪裡找東西。昨天在「帳務設定」裡完成的工作,今天大概還在同一個入口;客服也能請使用者打開某個頁面,逐步確認問題。
生成畫面若每次都不同,單純放一個 undo 不夠。使用者還需要辨識同一個物件、查到操作紀錄、重做先前的步驟,並在 agent 沒有產生理想畫面時回到固定流程。
這不表示所有 AI 介面都得長得一樣。一次性的資料探索、低風險分析,或只在當下成立的比較畫面,本來就適合讓 agent 有較大的組合空間。付款、權限、公開發布與長期設定則不同。這些流程牽涉的後果比較難收回,也常需要稽核、客服或團隊協作,固定結構應該留得更多。
真正要選的不是「固定 UI 還是生成 UI」,而是每一段流程願意交出多少控制權。常用又高風險的操作可以採 controlled UI;允許布局變化、元件仍受控的情境可以用 declarative UI;open-ended UI 則留給邊界清楚、失敗成本低的任務。
開工前先回答四個問題
小團隊不必先建立一套龐大的 Generative UI 治理制度。做第一個功能前,先把四個答案寫進設計文件,通常就能避開最危險的模糊地帶。
第一,哪一份 state 作準?它應該能被查詢、持久保存,也能在重新整理後重建畫面。
第二,agent 能呼叫哪些 mutation?每個動作需要哪些 typed inputs,又有哪些權限與前置條件?
第三,生成內容隔離在哪裡?它能讀什麼、呼叫什麼,是否還有不必要的 DOM 或網路權限?
第四,使用者如何回到同一件事?固定入口、穩定物件名稱、歷史紀錄與替代操作路徑,至少要有一種能在生成失敗時接手。
這四題沒有要求團隊把所有介面重新設計。它們只是把責任分清楚:agent 可以決定這次怎麼呈現,產品仍要決定什麼是真的、什麼可以被改,以及改錯後怎麼回來。
介面可以是暫時的,產品承諾不能是。Agent 當然可以換一種方式顯示同一件事,但每次生成都不該把使用者帶進一個無法核對、也無法回頭的新世界。
Source notes
喜欢我的作品吗?别忘了给予支持与赞赏,让我知道在创作的路上有你陪伴,一起延续这份热忱!