Khác với các phần mềm truyền thống (nơi phản hồi diễn ra trong vòng vài chục mili-giây), hệ thống AI luôn đi kèm với một bóng ma ám ảnh: Độ trễ (Latency).

Bên cạnh đó, vì AI có tính xác suất (non-deterministic), nó luôn có nguy cơ thực hiện sai ý đồ của người dùng. Nếu bạn để AI tự động thực thi một lệnh nguy hiểm (như Xóa Database hay Chuyển tiền) mà không có sự kiểm duyệt của con người, đó là một thảm họa.

Phần 5 này sẽ giải quyết hai vấn đề cốt lõi trên thông qua thiết kế UX: Che giấu độ trễTrao quyền kiểm soát (Human-in-the-loop).

5.1. Che giấu độ trễ bằng Skeleton Streaming và Optimistic UI

Khi một Agent nhận được lệnh, nó phải mất từ 1 đến 5 giây để suy nghĩ, sinh ra chuỗi JSON và gửi xuống Frontend. Trải nghiệm nhìn chằm chằm vào một màn hình trắng hoặc vòng xoay (Spinner) trong 5 giây là quá tệ.

Skeleton Streaming

Đừng chờ LLM sinh xong toàn bộ cục JSON rồi mới render. Ngay khi WebSocket Backend phát ra một sự kiện (Event) thông báo: "Agent đang chuẩn bị Component X", Frontend phải ngay lập tức vẽ ra một Skeleton Loading của Component đó.

<!-- Khi aiState.status === 'generating' -->
<div class="skeleton-card">
  <div class="skeleton-title animate-pulse"></div>
  <div class="skeleton-body animate-pulse"></div>
</div>

Người dùng sẽ cảm thấy hệ thống phản hồi ngay lập tức. Họ thấy được “hình hài” của kết quả trước cả khi dữ liệu thật (Data) được đẩy vào.

Optimistic UI (Giao diện Lạc quan)

Khi người dùng bấm nút “Xác nhận” trên Component GenUI, đừng đợi Backend trả về kết quả mới cập nhật màn hình. Hãy giả định (Optimistic) rằng thao tác đó sẽ thành công và cập nhật UI lập tức.

  • Ví dụ: Bấm “Xóa đơn hàng”. Component “Đơn hàng” lập tức biến mất khỏi màn hình, hiển thị thông báo “Đã xóa”. Ở dưới nền, hệ thống mới gửi request Xóa lên Backend. Nếu Backend báo lỗi, UI sẽ khôi phục lại trạng thái cũ (Rollback) và báo đỏ.

5.2. Human-In-The-Loop: Chặn AI khỏi các tác vụ nguy hiểm

“Human-in-the-loop” (HITL) có nghĩa là đặt con người vào giữa quy trình tự động hóa của AI.

Trong kiến trúc Generative UI, HITL không phải là một tính năng, mà là một nguyên tắc bảo mật. Khi AI quyết định thực thi một hành động có ảnh hưởng đến dữ liệu (Mutation), nó không được phép gọi API Backend. Thay vào đó, nó phải sinh ra một Component cho phép người dùng Approve (Chấp nhận), Reject (Từ chối), hoặc Modify (Chỉnh sửa).

Ví dụ: Hệ thống Nhân sự (HR)

  • Tình huống: Người quản lý ra lệnh: “Tăng lương cho nhân viên A lên 2000$”.
  • Cách làm SAI (Tự động hoàn toàn): Agent tự động gọi API POST /api/salary và cập nhật Database. Nếu AI nghe nhầm “A” thành “B” hoặc “2000” thành “20000”, hậu quả sẽ rất nghiêm trọng.
  • Cách làm ĐÚNG (Generative UI HITL):
    1. Agent sinh ra JSON yêu cầu gọi tool: RenderSalaryAdjustmentForm.
    2. Frontend render Component Form có chứa: Tên nhân viên (A), Mức lương cũ (1500$), Mức lương mới dự kiến (2000$).
    3. Form này có 2 nút: [Xác nhận][Hủy]. Các input có thể tự do Chỉnh sửa (Modify).
    4. Người quản lý nhìn thấy Form, sửa số 2000$ thành 1800$, rồi tự tay bấm [Xác nhận].
    5. Lúc này, Form trên Frontend mới là người gọi API thực sự (hoặc gửi lại tín hiệu xác nhận qua WebSocket cho Agent).

5.3. Fallback UI: Graceful Degradation (Suy thoái nhẹ nhàng)

Generative UI phụ thuộc vào LLM và WebSockets. Nếu OpenAI/Anthropic sập mạng, hoặc người dùng đi vào vùng mất sóng (3G/4G chập chờn), hệ thống của bạn sẽ ứng xử ra sao?

Nguyên tắc thiết kế Graceful Degradation (Suy thoái nhẹ nhàng) yêu cầu hệ thống phải lùi về một chế độ an toàn, thay vì sập hoàn toàn (Crash).

  1. Fallback về Traditional GUI: Nếu LLM trả về JSON lỗi quá 3 lần (vượt quá số lần Auto-Correction của Zod), Frontend tự động hiển thị một Form tĩnh bình thường để người dùng tự nhập tay bằng cơm.
  2. Offline Mode: Nếu WebSocket mất kết nối dài hạn, khóa (Disable) toàn bộ khu vực “Chat / Generative AI”, hiện cảnh báo “Mất kết nối với Trợ lý thông minh”, nhưng vẫn cho phép người dùng sử dụng các tính năng cơ bản của App qua REST API thông thường.

Bằng cách thiết kế đường lui (Fallback) này, bạn đảm bảo rằng AI chỉ là một lớp “Tăng cường” (Enhancement) chứ không phải là gót chân Achilles của hệ thống.


🔗 Bước tiếp theo: Hệ thống GenUI với vô vàn Component biến đổi không ngừng là một cơn ác mộng đối với đội ngũ QA (Kiểm thử). Làm sao bạn có thể test tự động một giao diện mà bạn không biết trước nó sẽ trông như thế nào? Mời bạn đón đọc Phần 6 — E2E Testing & Tối Ưu Hiệu Năng Tại Edge.