← Chương trước: Phần 2 — State Management | Mục lục Series | Chương tiếp theo: Phần 4 — Bảo Mật & A11y →


Answer-first: Component Registry là từ điển ánh xạ 1-1 giữa Tool Calls của Model Context Protocol (MCP) từ AI Agent và UI components tương ứng ở Client. Kiến trúc Controlled Generative UI này đảm bảo AI không bao giờ trực tiếp viết mã HTML, giữ vững tính đồng nhất thiết kế và khả năng tái sử dụng linh hoạt.


Trong phần trước, chúng ta đã hiểu rằng Frontend Framework-Agnostic (như Astro) không nhận mã HTML từ AI, mà nhận dữ liệu JSON. Nhưng làm sao để Frontend biết cần phải render khối JSON đó thành một thẻ <Card>, một cái <Chart>, hay một <Form>?

Câu trả lời nằm ở Component Registry — bộ não phân giải giao diện của kiến trúc Generative UI.

3.1. Sự hội tụ của MCP (Model Context Protocol) và Frontend

Để hiểu Component Registry, ta cần đi ngược dòng lên Backend. Ở Backend, các hệ thống Agentic hiện đại đang chuẩn hóa việc giao tiếp với các hệ thống ngoại vi (như Database, API) thông qua chuẩn MCP (Model Context Protocol) (Xem thêm chi tiết tại Series: MCP Engineering In Production).

Khi Agent muốn lấy dữ liệu thời tiết, nó không tự gọi API. Kể từ bản cập nhật MCP lớn nhất vào tháng 7 năm 2026 (chuyển sang kiến trúc Stateless Core và Enterprise-Managed Authorization), Agent sẽ gọi một Tool Call tuân theo đặc tả mới:

{
  "name": "get_weather_mcp_tool",
  "arguments": { "location": "Hanoi" },
  "_meta": {
    "version": "2026-07-28",
    "client": "astro-genui-client"
  }
}

Trong Generative UI, chúng ta tận dụng chính xác cơ chế “Tool Call” này nhưng áp dụng cho Frontend. Thay vì gọi một tool ở Backend, Agent gọi một “UI Tool” để yêu cầu Frontend hiển thị giao diện. Chúng ta map 1-1 giữa Backend MCP Tool và Frontend UI Component, hoàn toàn không cần duy trì session state cồng kềnh nhờ cơ chế Stateless.

3.2. Khái niệm Component Registry

Component Registry đơn giản là một từ điển (Dictionary / Map) nằm ở Frontend (ví dụ như cấu hình của Astro), dùng để đối chiếu Tên_Tool mà AI gọi với Tên_Component thực tế trong mã nguồn.

Sơ đồ luồng dữ liệu (End-to-End Flow):

flowchart TD
    LLM["LLM Agent (Backend)"] -->|"1. Stream JSON Block {component, props}"| Wire["SSE Stream Transport"]
    Wire -->|"2. OnMessage Chunk"| Engine["Generative UI Engine"]
    
    subgraph Validation_Registry["Tra cứu & Xác thực Schema"]
        Engine -->|"3. Tra cứu Component Definition"| Registry["Component Registry"]
        Registry -->|"4. Trả về Zod Schema"| Engine
        Engine -->|"5. Xác thực Props"| Validator["Zod Validator"]
    end

    Validator -->|"Props Hợp Lệ"| UI["Dynamic Hydration: Render Component lên DOM"]
    Validator -->|"Lỗi Schema"| Fallback["Render Safe Fallback (Markdown / Raw Text)"]

Ví dụ mô phỏng Code Frontend (Astro/Svelte):

Đầu tiên, bạn đăng ký các Components hợp lệ trong Registry:

// src/lib/registry.js
import WeatherWidget from '../components/WeatherWidget.svelte';
import ShopeeOrderCancel from '../components/ShopeeOrderCancel.svelte';

export const ComponentRegistry = {
  "RenderWeatherWidget": WeatherWidget,
  "RenderOrderCancel": ShopeeOrderCancel,
  // Bất kỳ Component nào không có ở đây sẽ bị loại bỏ (Ignored)
};

Tại component Render chính (Dynamic Component):

<!-- src/components/DynamicRenderer.svelte -->
<script>
  import { ComponentRegistry } from '$lib/registry';
  export let aiPayload; // Ví dụ: { tool: "RenderWeatherWidget", args: { temp: 30 } }

  // Tìm component trong Registry
  $: TargetComponent = ComponentRegistry[aiPayload.tool];
</script>

{#if TargetComponent}
  <!-- ⚠️ CẢNH BÁO BẢO MẬT: Thực tế aiPayload.args phải được validate bằng Zod trước khi spread vào Props. (Xem Phần 4) -->
  <svelte:component this={TargetComponent} {...aiPayload.args} />
{:else}
  <div class="error">Agent yêu cầu giao diện không tồn tại.</div>
{/if}

3.3. Mẫu thiết kế Controlled Generative UI

Kiến trúc bên trên được gọi là Controlled Generative UI (Giao diện sinh tạo có kiểm soát).

Bạn KHÔNG cho phép AI tự suy nghĩ ra màu sắc nút bấm hay viết thẻ <div>. Bạn bắt buộc AI phải “lắp ráp” giao diện từ những khối LEGO (Components) do chính tay các lập trình viên Frontend của bạn (người hiểu rõ về UI/UX và Brand Identity nhất) tạo ra.

Lợi ích khổng lồ của Controlled GenUI:

  1. Brand Consistency (Đồng nhất thương hiệu): Component <Button> hay <ShopeeOrderCancel> là do team Design system của bạn làm. Nó sẽ có bo góc, màu cam đặc trưng, chuẩn font chữ. AI chỉ lo việc điền số liệu (Data) vào đó.
  2. Framework-Agnostic: AI không cần biết bạn dùng Svelte, Vue hay Tailwind. Nó chỉ trả JSON. Nếu năm sau công ty đổi từ Svelte sang SolidJS, AI Agent ở Backend không cần sửa dù chỉ 1 dòng code.
  3. Tính tái sử dụng: Các Component trong Registry hoàn toàn có thể là các Component đang dùng cho các màn hình tĩnh bình thường. Bạn không cần viết riêng Component cho AI.

← Chương trước: Phần 2 — State Management | Mục lục Series | Chương tiếp theo: Phần 4 — Bảo Mật & A11y →


❓ Câu Hỏi Thường Gặp (FAQ)

Q1: Component Registry & Bridging MCP to Frontend giải quyết vấn đề cốt lõi nào trong kiến trúc hệ thống?

Xây dựng Component Registry: cầu nối từ Backend MCP Agent tới Frontend Svelte. Mẫu Controlled Generative UI nguyên tắc vàng để AI không viết HTML.

Q2: Những lưu ý quan trọng nhất khi triển khai thực tế là gì?

Cần chú trọng phân tầng ranh giới trách nhiệm (bounded context), thiết lập cơ chế fallback dự phòng, và giám sát chặt chẽ qua metrics OpenTelemetry để phát hiện sớm các điểm nghẽn.

Q3: Làm sao để kiểm thử và đánh giá hiệu quả sau khi áp dụng?

Áp dụng kiểm thử tải (load test), benchmark độ trễ P95/P99 trước và sau triển khai, kết hợp tracing phân tán để xác minh tính ổn định dưới tải cao.