Generative UI 2026: Khi AI Tự Dựng Giao Diện
Posted on: 6/9/2026 1:11:49 AM
Table of contents
- 1. Generative UI là gì — và không phải là gì
- 2. Vì sao "chat-only" là nút thắt UX
- 3. Phổ kiểm soát: ba tầng của Generative UI
- 4. A2UI v0.9 — chuẩn declarative của Google
- 5. Streaming & render tiệm tiến: cuộc chiến với độ trễ cảm nhận
- 6. Bảo mật: vì sao "declarative" thắng "executable"
- 7. Một đặc tả declarative trông như thế nào
- 8. Khung quyết định: dùng pattern nào?
- 9. Dòng thời gian: Generative UI trưởng thành
- 10. Kết luận
Suốt hai năm qua, mọi sản phẩm AI đều quy về cùng một hình hài: một ô chat. Người dùng gõ câu hỏi, model trả về một bức tường chữ. Nhưng văn bản là định dạng tệ nhất để đặt vé máy bay, so sánh ba gói bảo hiểm, hay xác nhận một giao dịch chuyển tiền. Năm 2026, câu hỏi không còn là "model trả lời đúng không?" mà là "tại sao AI vẫn buộc tôi đọc một đoạn văn, trong khi nó hoàn toàn có thể dựng cho tôi đúng cái giao diện tôi cần ngay lúc đó?"
Đó chính là Generative UI — mô hình nơi đầu ra của LLM không phải là text, mà là giao diện sống, có thể tương tác. Thay vì mô tả "chuyến bay lúc 9h giá 2,1 triệu", AI render thẳng một thẻ chuyến bay có nút "Đặt ngay". Bài viết này mổ xẻ kiến trúc đằng sau Generative UI 2026: phổ kiểm soát ba tầng, chuẩn mới A2UI v0.9 của Google, mô hình streaming, và quan trọng nhất — khi nào nên dùng pattern nào.
1. Generative UI là gì — và không phải là gì
Định nghĩa gọn nhất: Generative UI = đầu ra LLM → giao diện sống, tương tác được. Cơ chế cốt lõi là nối kết quả của một tool call với một component giao diện. Khi agent gọi hàm searchFlights(), thay vì nhồi kết quả JSON vào prompt rồi để model "kể lại" bằng chữ, hệ thống render thẳng một <FlightCard> với dữ liệu thật.
Cần phân biệt rõ ba khái niệm hay bị gộp:
| Khái niệm | Bản chất | Ví dụ |
|---|---|---|
| AI tạo code UI | Sinh code (v0, Lovable) tại design-time, lập trình viên review rồi commit | Sinh một file Dashboard.tsx |
| Generative UI | AI chọn/soạn UI tại runtime, theo từng câu hỏi của người dùng | Render thẻ thời tiết ngay trong luồng hội thoại |
| Adaptive UI | Giao diện tự điều chỉnh theo hành vi/ngữ cảnh, không nhất thiết qua LLM | A/B layout theo segment người dùng |
Generative UI là cái ở giữa: quyết định giao diện được đẩy sang lúc chạy và do model đưa ra dựa trên ý định người dùng. Đây là khác biệt căn bản so với UI truyền thống — nơi mọi màn hình đều được lập trình viên dựng sẵn từ trước.
2. Vì sao "chat-only" là nút thắt UX
Agent chỉ-văn-bản tạo ra ba nút thắt trải nghiệm rất cụ thể:
Ba nút thắt của giao diện chỉ-chữ
- Tiến trình bị giấu: agent đang gọi 5 tool, người dùng chỉ thấy con trỏ nhấp nháy — không biết nó đang làm gì, còn bao lâu.
- Đầu vào mơ hồ: "đặt vé rẻ nhất" — rẻ theo giá, theo thời gian bay, hay theo số điểm dừng? Văn bản không ép được người dùng nhập có cấu trúc.
- Luồng nhiều bước thành hộp đen: một quy trình duyệt hoàn tiền 4 bước, nếu chỉ kể bằng chữ, người dùng không bao giờ chắc mình đang ở bước nào.
Generative UI giải quyết cả ba bằng cách bề-mặt-hoá (surface) trạng thái agent thành những giao diện chuyên biệt cho từng tác vụ: một form có validation thay cho câu hỏi mở, một progress tracker thay cho con trỏ nhấp nháy, một thẻ xác nhận có nút bấm thay cho "bạn có chắc không? (yes/no)". Đầu vào trở nên có cấu trúc, phản hồi trở nên tiệm tiến, và hành động trở nên rõ ràng.
3. Phổ kiểm soát: ba tầng của Generative UI
Không có một "cách làm Generative UI" duy nhất. Tất cả các framework 2026 đều xếp dọc theo một phổ đánh đổi giữa quyền kiểm soát của lập trình viên và tự do của agent. Hiểu phổ này là chìa khoá để chọn đúng kiến trúc.
flowchart LR
A["Static GenUI
(AG-UI / Frontend Tools)"] --> B["Declarative GenUI
(A2UI / Open-JSON-UI)"] --> C["Open-ended GenUI
(MCP Apps)"]
A -.- A1["Kiem soat CAO
Tu do agent THAP"]
B -.- B1["Kiem soat & tu do
can bang"]
C -.- C1["Kiem soat THAP
Tu do agent CAO"]
style A fill:#f8f9fa,stroke:#e94560,color:#2c3e50
style B fill:#e94560,stroke:#fff,color:#fff
style C fill:#2c3e50,stroke:#fff,color:#fff
style A1 fill:#fff,stroke:#e0e0e0,color:#555
style B1 fill:#fff,stroke:#e0e0e0,color:#555
style C1 fill:#fff,stroke:#e0e0e0,color:#555
3.1. Static GenUI — component dựng sẵn, agent quyết định "khi nào"
Lập trình viên dựng sẵn toàn bộ component. Agent chỉ quyết định khi nào hiển thị và nhồi dữ liệu gì. Cài đặt điển hình dùng hook kiểu useFrontendTool, gắn một component React vào vòng đời của một tool (loading → executing → complete):
render: ({ status, args, result }) => {
if (status === "inProgress") return <LoadingState />;
if (status === "complete") return <FlightCard data={result} />;
}
Đây là tầng an toàn và nhất quán nhất: agent không bao giờ vẽ được thứ gì ngoài bộ component bạn cho phép. Đổi lại, nó kém linh hoạt với những tình huống mới mà bạn chưa dựng component.
3.2. Declarative GenUI — agent trả về "bản vẽ" JSON
Agent trả về một đặc tả JSON có cấu trúc mô tả giao diện (card, form, list, table...). Frontend đọc đặc tả đó và render bằng chính component catalog và style của mình. Đây là vùng cân bằng nhất của phổ — và là nơi A2UI v0.9 đang định hình chuẩn chung (xem mục 4). Điểm mấu chốt: agent không gửi code, nó gửi ý định; frontend giữ toàn quyền về cách hiển thị.
3.3. Open-ended GenUI — agent trả về cả "bề mặt" UI
Agent trả về nguyên một bề mặt giao diện: HTML, iframe, hoặc một mini-app nhúng — frontend chỉ đóng vai container. Cách này được mở đường bởi MCP Apps (phần mở rộng của Model Context Protocol). Sức mạnh là tối đa cho các tool phức tạp, nhưng đánh đổi lớn: rủi ro bảo mật khi render UI tuỳ ý, style không đồng nhất, khó port ra ngoài web, và chi phí hiệu năng của app nhúng.
| Pattern | Agent trả về | Ưu | Nhược | Hợp với |
|---|---|---|---|---|
| Static | Tên tool + data | An toàn, nhất quán, dễ làm | Cứng, phải dựng sẵn mọi case | SaaS, fintech, healthcare |
| Declarative (A2UI) | Đặc tả JSON | Linh hoạt có lan can, đa nền tảng | Cần renderer cho mỗi spec | Đa số app sản xuất |
| Open-ended (MCP Apps) | HTML / iframe / app | Mạnh nhất cho tool phức tạp | Rủi ro bảo mật, khó port | Internal tool, dev platform |
AG-UI: tầng runtime nằm dưới cả ba
Đừng nhầm AG-UI với một định dạng UI. AG-UI (Agent-User Interaction Protocol) là một giao thức sự kiện & trạng thái nằm bên dưới cả ba pattern: nó phát tín hiệu vòng đời tool (started → streaming → finished/failed), định tuyến tương tác người dùng (click, submit form), và đồng bộ state agent ↔ UI ↔ ứng dụng theo thời gian thực. Chính nhờ tầng này mà một runtime như CopilotKit có thể hỗ trợ cả ba pattern cùng lúc.
4. A2UI v0.9 — chuẩn declarative của Google
Ra mắt 17/04/2026, A2UI (phiên bản 0.9) là nỗ lực biến Generative UI từ demo thành thứ chạy được ở production. Triết lý của nó nằm trong một câu: "để đi từ demo lên production, ta cần tách bạch trách nhiệm thật sạch sẽ". Agent sinh đặc tả giao diện; client render bằng catalog component của riêng mình. Agent không bao giờ cần biết bạn dùng React hay Flutter, và frontend không phải liên tục thêm component mới mỗi khi agent muốn hiển thị thứ gì đó mới.
flowchart TD
U["Nguoi dung"] --> AG["Agent (LLM)"]
AG -->|"sinh dac ta JSON"| SM["Schema Manager
(validate + versioning)"]
SM -->|"surfaceUpdate
dataModelUpdate
beginRendering"| TR["Transport
MCP / A2A / WebSocket / REST"]
TR --> CL["Client Renderer"]
CL --> CAT["Component Catalog
(Basic set hoac custom)"]
CAT --> UI["Giao dien that
React / Flutter / Angular / Lit"]
UI -->|"su kien tuong tac"| AG
style U fill:#f8f9fa,stroke:#e94560,color:#2c3e50
style AG fill:#e94560,stroke:#fff,color:#fff
style SM fill:#16213e,stroke:#fff,color:#fff
style TR fill:#2c3e50,stroke:#fff,color:#fff
style CL fill:#16213e,stroke:#fff,color:#fff
style CAT fill:#f8f9fa,stroke:#e94560,color:#2c3e50
style UI fill:#f8f9fa,stroke:#e94560,color:#2c3e50
4.1. Ba "phong bì" thông điệp
A2UI mô tả giao diện qua ba loại message envelope, cho phép cập nhật giao diện tiệm tiến thay vì gửi một khối JSON khổng lồ:
| Envelope | Vai trò |
|---|---|
surfaceUpdate | Khai báo/cập nhật cấu trúc các component trên bề mặt (cây UI) |
dataModelUpdate | Bơm dữ liệu vào các component đã khai báo (tách dữ liệu khỏi cấu trúc) |
beginRendering | Ra hiệu cho client bắt đầu vẽ — chốt một frame nhất quán |
Việc tách cấu trúc (surface) khỏi dữ liệu (data model) là một quyết định thiết kế quan trọng: nó cho phép cập nhật dữ liệu mà không phải dựng lại toàn bộ cây UI, và là nền tảng cho streaming mượt.
4.2. Transport-agnostic, renderer đa nền tảng
A2UI không trói buộc đường truyền: bạn có thể chạy "A2UI trên MCP, WebSocket, REST, AG-UI, A2A, hay bất cứ thứ gì bạn muốn". Cùng thời điểm, giao thức A2A 1.0 chính thức ra mắt như một cơ chế transport vững chắc cho giao tiếp agent-từ-xa. Phía render, v0.9 đi kèm renderer chính thức cho React, Flutter, Angular và Lit, cộng một thư viện web-core chung để cộng đồng tự viết renderer trình duyệt. SDK Python đã có (pip install a2ui-agent-sdk), Go và Kotlin đang trên đường.
5. Streaming & render tiệm tiến: cuộc chiến với độ trễ cảm nhận
Một đặc tả UI hoàn chỉnh có thể là một khối JSON lớn. Nếu client phải chờ toàn bộ khối đó trước khi vẽ, người dùng sẽ nhìn màn hình trắng trong vài giây — đúng cái cảm giác chậm chạp mà Generative UI muốn loại bỏ.
Giải pháp là parse và "chữa lành" (healing) JSON tăng dần: client render các component ngay khi chúng đang được sinh ra, không chờ khối JSON đóng lại. Khi LLM mới phun ra một nửa cây UI (JSON còn chưa hợp lệ), bộ render vẫn vá tạm phần thiếu để hiển thị khung sườn, rồi điền chi tiết khi token tiếp tục về. Kết quả: độ trễ cảm nhận giảm mạnh, dù tổng thời gian sinh không đổi.
Độ trễ cảm nhận ≠ độ trễ thực
Generative UI thắng UX không phải vì nhanh hơn về mặt tính toán, mà vì nó lấp khoảng chờ bằng phản hồi có nghĩa. Một skeleton UI hiện ra sau 200ms tạo cảm giác nhanh hơn nhiều so với một đoạn text hoàn chỉnh hiện ra sau 2 giây — dù đoạn text thực ra "xong" sớm hơn về dữ liệu.
6. Bảo mật: vì sao "declarative" thắng "executable"
Đây là lý do kiến trúc declarative (A2UI) được ưa chuộng cho production thay vì để agent phun HTML/JS tuỳ ý:
Ba lớp phòng thủ xếp chồng: (1) đầu ra của agent là dữ liệu, không phải lệnh — không có eval(), không có script nhúng; (2) agent chỉ tham chiếu được component trong catalog đã phê duyệt trước; (3) catalog có thể đổi động theo quyền — người dùng chưa xác thực thấy catalog tối giản, admin thấy catalog đầy đủ. So với pattern open-ended (MCP Apps) nơi agent trả về HTML/iframe tuỳ ý, đây là khác biệt một trời một vực về diện tích tấn công.
Khi nào tránh open-ended
Đừng để agent render UI tuỳ ý trong bất kỳ luồng nào chạm tới dữ liệu nhạy cảm hoặc hành động không thể hoàn tác (thanh toán, xoá dữ liệu, đổi quyền). HTML/iframe do model sinh là vector tự nhiên cho XSS và UI-redressing nếu nội dung đi qua tay người dùng không tin cậy. Giữ những luồng đó ở tầng Static hoặc Declarative với catalog chặt.
7. Một đặc tả declarative trông như thế nào
Ví dụ một agent du lịch muốn hiển thị thẻ chuyến bay. Thay vì trả về text hay HTML, nó phát một đặc tả tham chiếu component FlightCard trong catalog đã duyệt:
// surfaceUpdate: khai bao cau truc
{
"surfaceUpdate": {
"root": {
"component": "Stack",
"children": [
{ "component": "FlightCard", "id": "f1", "bind": "flights[0]" },
{ "component": "Button", "props": { "label": "Dat ngay" },
"action": { "tool": "bookFlight", "args": { "id": "{{flights[0].id}}" } } }
]
}
}
}
// dataModelUpdate: bom du lieu
{
"dataModelUpdate": {
"flights": [
{ "id": "VN217", "from": "SGN", "to": "HAN",
"depart": "09:15", "price": 2100000 }
]
}
}
// beginRendering: chot frame
{ "beginRendering": { "surface": "main" } }
Frontend nhận đặc tả này, tra FlightCard trong catalog của mình, áp style design-system của mình, và render. Cùng một đặc tả đó render được trên React (web) lẫn Flutter (mobile) mà agent không cần biết khác biệt. Nút "Đặt ngay" phát một sự kiện ngược về agent qua tầng AG-UI — vòng lặp khép kín.
8. Khung quyết định: dùng pattern nào?
flowchart TD
Q1{"Luong cham du lieu nhay cam
hay hanh dong khong the hoan tac?"}
Q1 -->|"Co"| S["Static GenUI
component dung san, catalog chat"]
Q1 -->|"Khong"| Q2{"Can chay da nen tang
web + mobile + desktop?"}
Q2 -->|"Co"| D["Declarative / A2UI
dac ta JSON, catalog dung chung"]
Q2 -->|"Khong"| Q3{"Tool qua phuc tap,
can UI tuy bien sau?"}
Q3 -->|"Co"| O["Open-ended / MCP Apps
chi cho internal tool"]
Q3 -->|"Khong"| D
style Q1 fill:#2c3e50,stroke:#fff,color:#fff
style Q2 fill:#2c3e50,stroke:#fff,color:#fff
style Q3 fill:#2c3e50,stroke:#fff,color:#fff
style S fill:#f8f9fa,stroke:#e94560,color:#2c3e50
style D fill:#e94560,stroke:#fff,color:#fff
style O fill:#16213e,stroke:#fff,color:#fff
Cách phối hợp được khuyến nghị nhất 2026 không phải chọn một, mà chồng tầng: dùng một runtime (như CopilotKit) cho lớp sự kiện AG-UI, A2UI cho component đa nền tảng, và MCP cho tích hợp tool. Bắt đầu Static cho các luồng quan trọng/nhạy cảm, mở dần sang Declarative khi cần linh hoạt, và chỉ chạm Open-ended trong môi trường nội bộ có kiểm soát.
9. Dòng thời gian: Generative UI trưởng thành
streamUI + React Server Components — lần đầu LLM stream thẳng component về client.useFrontendTool và giao thức AG-UI phổ biến hoá Static GenUI; CopilotKit, assistant-ui trở thành runtime chủ đạo cho React.Vì sao AI SDK RSC bị tạm dừng lại quan trọng?
Việc Vercel tạm dừng nhánh RSC không phải Generative UI "chết", mà ngược lại: nó cho thấy ngành đang hội tụ về chuẩn declarative trung lập (A2UI, Open-JSON-UI) thay vì cách tiếp cận gắn chặt một framework (RSC chỉ chạy với React/Next.js). Nếu bạn đang chọn nền tảng hôm nay, ưu tiên cách tiếp cận declarative để không bị khoá vào một stack.
10. Kết luận
Generative UI là bước chuyển từ "AI nói cho bạn nghe" sang "AI dựng cho bạn dùng". Nó không thay thế thiết kế giao diện — nó dời điểm ra quyết định về giao diện sang lúc chạy, do model đưa ra theo ý định người dùng, trong một bộ lan can do bạn định nghĩa. Ba bài học cốt lõi cho 2026:
- Chọn đúng tầng kiểm soát. Static cho an toàn, Declarative (A2UI) cho cân bằng, Open-ended chỉ cho nội bộ. Mặc định nên là Declarative.
- Declarative thắng vì bảo mật. Dữ liệu-không-phải-code + catalog phê duyệt trước là nền tảng để đưa GenUI lên production an toàn.
- Tối ưu độ trễ cảm nhận. Streaming tiệm tiến với skeleton UI quan trọng hơn tốc độ sinh thô.
Ô chat đã đưa AI đến với hàng tỷ người. Generative UI là tầng tiếp theo — nơi AI thôi bắt người dùng đọc, và bắt đầu dựng cho họ đúng công cụ họ cần, ngay lúc họ cần.
Nguồn tham khảo:
- Google Developers Blog — A2UI v0.9: The New Standard for Portable, Framework-Agnostic Generative UI
- CopilotKit — The Developer's Guide to Generative UI in 2026
- Vercel AI SDK — Generative User Interfaces (docs)
- Vercel — Introducing AI SDK 3.0 with Generative UI support
- awesome-generative-ui — curated list of AI-generated UI resources
Disclaimer: The opinions expressed in this blog are solely my own and do not reflect the views or opinions of my employer or any affiliated organizations. The content provided is for informational and educational purposes only and should not be taken as professional advice. While I strive to provide accurate and up-to-date information, I make no warranties or guarantees about the completeness, reliability, or accuracy of the content. Readers are encouraged to verify the information and seek independent advice as needed. I disclaim any liability for decisions or actions taken based on the content of this blog.