A2UI(Agent-Driven User Interfaces)
최근 AI를 서비스에 도입하면서 단순한 텍스트 챗봇을 넘어, AI가 상황에 맞는 화면(UI)을 직접 생성해 주는 ‘Generative UI’에 대한 관심이 뜨겁다. 하지만 AI가 직접 HTML이나 JavaScript 코드를 짜서 클라이언트에 내려보내는 것은 보안상으로도, 유지보수 측면에서도 최악의 수다.
오늘 학습한 A2UI(Agent-Driven User Interfaces)는 바로 이 지점에서 “AI의 지능”과 “프론트엔드의 렌더링”을 가장 안전하고 효율적으로 이어주는 강력한 통신 프로토콜이다.
1. A2UI의 진짜 정체: AI가 아니다, ‘파이프라인’이다
가장 먼저 짚고 넘어가야 할 오해는 “A2UI 자체는 AI 모델(LLM)이 아니다”라는 점이다. A2UI는 텍스트를 이해하고 답변을 추론하는 지능이 아니라, AI가 만들어낸 결과물을 클라이언트(React, Flutter 등)가 이해하고 화면에 그릴 수 있도록 규격화한 ‘공용 UI 통신 규격이자 렌더링 도구 모음’이다.
🔄 전체 데이터 플로우
- 사용자 요청: “평점 4점 이상 근처 식당 보여줘”
- 에이전트(AI)의 UI 생성: 모델이 응답을 분석하고 화면을 구성할 요소들을 A2UI 규격의 JSON으로 스트리밍한다.
- 클라이언트 렌더링: 프론트엔드는 이 JSON 데이터를 받아 미리 정의해둔 네이티브 UI 컴포넌트(카드, 지도 등)로 조립해 화면에 띄운다.
- 액션 피드백: 사용자가 화면에서 버튼을 누르면 이 이벤트(Action)가 다시 AI에게 전달되어 다음 대화를 이어간다.
2. 왜 코드가 아니라 JSON인가? (핵심 철학)
AI가 <div> 같은 태그나 동작 코드를 직접 보내지 않고, 컴포넌트의 타입과 데이터만 담긴 ‘JSON’을 보내는 데에는 강력한 이유가 있다.
- 보안 (Secure by Design): 외부에서 임의의 실행 코드가 주입되는(XSS 등) 위험을 원천 차단한다. 앱에 미리 정의되지 않은 비정상적인 UI나 악성 스크립트는 절대 실행될 수 없다.
- 프레임워크 독립성 (Framework-Agnostic): AI는 오직
{"type": "button"}과 같이 ‘무엇’을 그릴지만 지시한다. 이것을 React로 그릴지, iOS 네이티브로 그릴지(‘어떻게’ 그릴지)는 전적으로 클라이언트의 자유다.
3. 스트리밍 렌더링을 위한 천재적 발상: 평면적 구조 (Adjacency List Model)
대형 언어 모델(LLM)은 답변을 한 번에 주지 않고 타자를 치듯 스트리밍(Streaming)으로 내려보낸다. 점진적 렌더링(Progressive Rendering)을 통해 사용자 경험(UX)을 극대화하려면 UI 역시 도착하는 즉시 그려져야 한다.
하지만 일반적인 중첩된(Nested) 트리 구조의 JSON은 치명적인 단점이 있다.
// ❌ 일반적인 방식: 스트리밍 중 괄호가 안 닫히면 전체 에러 발생!
{
"type": "card",
"children": [ { "type": "title" } ]
}
이를 해결하기 위해 A2UI는 데이터를 트리 구조가 아닌 평면적인 인접 리스트(Flat Adjacency List) 구조로 쪼개어 전송한다.
// ✅ A2UI 방식: 레고 블록에 번호표만 붙여서 하나씩 던지기
[
{ "id": "block-1", "type": "card", "parentId": "root" },
{ "id": "block-2", "type": "title", "parentId": "block-1" }
]
AI는 괄호의 깊이를 계산할 필요 없이 리스트에 아이템을 하나씩 추가하기만 하면 되고, 프론트엔드는 조각이 도착하는 즉시 해당 parentId를 찾아 화면의 제자리에 끼워 넣는다. 스트리밍 환경에서 파싱 에러를 막고 실시간 렌더링을 가능하게 하는 핵심 기술이다.
💡 A2UI Composer의 역할 개발자가 이 평면적 JSON 문법을 모두 외워서 AI를 프롬프팅 할 필요는 없다. A2UI Composer라는 시각적 노코드 툴을 사용해 화면을 배치하면, 이 평면적 JSON 구조를 자동 생성해 준다. 이를 복사해 AI의 시스템 프롬프트(Few-Shot)에 넣기만 하면 AI 학습이 끝난다.
4. 프론트엔드에서의 실제 동작: Catalog와 Renderer
이론을 알았으니 실제 코드(React 기준)에서 어떻게 적용되는지 살펴보자. 프론트엔드 개발자가 할 일은 매우 단순해진다.
1) 카탈로그(Catalog) 만들기
AI가 내려주는 텍스트(type)와 내가 직접 만든 네이티브 UI 컴포넌트를 짝지어주는 ‘사전’을 정의한다.
import { CustomCard, ActionButton } from './components';
const myCatalog = {
"restaurant-card": CustomCard,
"button": ActionButton
};
2) A2UI Renderer 배치
복잡한 스트리밍 파싱이나 트리 구조 재조립 로직은 모두 A2UI 라이브러리(<A2uiRenderer />)가 알아서 처리한다.
import { A2uiRenderer } from '@a2ui/react';
export default function ChatScreen({ aiStreamData }) {
return (
<A2uiRenderer
catalog={myCatalog}
messages={aiStreamData} // AI가 실시간으로 쏴주는 평면적 JSON 조각들
onAction={(event) => { sendToAi(event); }}
/>
);
}
도착한 JSON의 데이터(예: label, rating 등)는 매핑된 컴포넌트의 Props로 그대로 주입된다.
5. 결론: 언제 도입해야 할까?
A2UI는 1인 개발자나 프론트엔드 리소스가 한정된 상황에서 엄청난 레버리지가 될 수 있다.
-
👍 권장되는 상황:
-
사용자 의도에 따라 화면이 계속 변하는 다이나믹 폼(Dynamic Form)이나 대화형 AI 어시스턴트를 만들 때.
-
“이 상황엔 A화면, 저 상황엔 B화면”이라는 수많은 라우팅/상태 관리 로직을 하드코딩하기 벅찰 때. (컴포넌트만 만들어두고 화면 배치는 AI에게 위임)
-
빠른 MVP 검증이 필요한 서비스.
-
👎 피해야 할 상황:
-
상호작용이 없는 정적인 블로그나 랜딩 페이지.
-
초정밀 애니메이션이나 결제/보안처럼 100% 결정론적(Deterministic)이고 엄격한 흐름 제어가 필요한 시스템.
오늘의 깨달음: A2UI는 단순한 라이브러리가 아니라 프론트엔드 아키텍처의 패러다임을 바꿀 수 있는 개념이다. 프론트엔드는 본연의 ‘컴포넌트 디자인과 퀄리티’에 집중하고, 복잡한 비즈니스 로직과 화면 분기처리는 AI 에이전트에게 넘기는 우아한 역할을 분담할 수 있게 되었다.