AI가 UI를 대량 생성할 때, 무엇을 잠그고 무엇을 풀어야 하는가

AI가 UI를 대량 생성할 때, 무엇을 잠그고 무엇을 풀어야 하는가

JSON으로 모든 것을 통제하면 스프레드시트가 나오고, 아무것도 통제하지 않으면 브랜드가 무너진다—대규모 UI 생성에서 '잠금의 단위'를 어디에 둘지가 품질의 전부다.

디자인 토큰 AI UI 생성 Claude Code subagents JSON 스키마 디자인 시스템 UI 자동화 프롬프트 엔지니어링
광고

600개의 툴을 만들다 발견한 것

5개 로케일에 걸쳐 600개 이상의 웹 툴 UI를 AI로 대량 생성하는 프로젝트를 상상해보자. 같은 프롬프트를 써도 생성할 때마다 색상이 미묘하게 달라지고, 컴포넌트 간격이 조금씩 틀어지고, 버튼 모양이 바뀐다. 이 '드리프트(drift)' 문제를 해결하기 위해 개발자는 세 번의 전략 전환을 거쳤다. dev.to에 공개된 이 실험의 궤적은, AI로 프론트엔드 산출물을 대규모로 찍어낼 때 품질을 어떻게 구조적으로 통제해야 하는지에 대한 가장 솔직한 기록 중 하나다.

1단계: JSON으로 전부 잠갔더니 스프레드시트가 나왔다

첫 번째 전략은 직관적으로 매력적이다. 각 툴의 UI 구조를 JSON으로 정의하고, 고정된 렌더링 파이프라인으로 출력한다. 드리프트는 완벽하게 사라졌다. JSON에 있는 것만 렌더된다. 그런데 결과물은 죄다 생명력 없는 격자 화면이었다. 직선만 있고, 곡선 하나 없고, 모든 값이 제 칸 안에 갇혀 있었다. 한마디로 스프레드시트였다.

이 실패의 원인은 구조적이다. JSON 정의 방식에서 표현의 천장은 렌더러가 구현한 것까지다. 둥근 모서리, 그라디언트, 예외적 패딩을 추가하려면 스키마와 렌더러를 계속 비대하게 만들어야 하는데, 그 끝은 HTML과 CSS를 다시 발명하는 일이다. 드리프트를 잡은 메커니즘이 표현력도 함께 잡아버린 것이다.

2단계: 레이아웃이 아니라 토큰만 잠근다

두 번째 전략은 잠금의 단위를 바꾸는 것이다. 구조(레이아웃)를 잠그는 대신, 아이덴티티(색상·타이포그래피·반경·간격)만 잠근다. CSS 변수 파일이 정식 소스(canonical source)가 되고, 모든 툴은 이 변수만 사용한다. 여기에 더해 실제 브라우저에서 열 수 있는 살아있는 UI 킷을 레퍼런스로 제공한다. AI에게 전달하는 지시는 이렇게 바뀐다: "이 JSON대로 렌더해"에서 "이 킷의 파츠와 변수를 써서 레이아웃은 네가 자유롭게 구성해"로.

결과는 달랐다. 레이아웃은 각 툴에 최적화되고, 브랜드는 일관성을 유지했다. 1단계가 모든 것을 잠가 표현력을 죽였다면, 2단계는 토큰만 잠가 조합의 자유를 살렸다. 여기서 중요한 변수가 하나 더 있다. 모델의 디자인 능력 자체가 릴리스마다 좋아지고 있었다는 점이다. '자유 구성 = 드리프트'라는 전제는 특정 시점에는 사실이었지만, 모델이 진화하면서 그 전제 자체가 무너졌다.

잠금의 세 가지 원칙

이 실험이 남긴 교훈은 세 문장으로 압축된다.

첫째, "잠겼다"는 것과 "성공했다"는 것은 다르다. 잠금 메커니즘은 항상 부작용을 포함해서 평가해야 한다. 1단계는 목표를 달성하면서 실패했다.

둘째, 잠금의 단위를 선택하라. 레이아웃까지 잠그면 스프레드시트가 나온다. 토큰만 잠그면 브랜드 일관성과 조합의 자유가 공존한다.

셋째, 전제에 유통기한을 붙여라. '자유 구성은 드리프트를 만든다'는 사실이었고, 그다음엔 사실이 아니었다. 메커니즘의 전제가 무너지면 메커니즘을 버려야 한다.

Claude Code subagents: 위임의 구조를 이해해야 품질이 보인다

대규모 UI 생성의 다른 축은 에이전트 시스템 자체의 작동 원리다. Claude Code의 subagents 구조를 분석한 dev.to 글은, AI 워크플로우에서 '내 에이전트가 왜 안 쓰이는가'라는 가장 흔한 실무 질문에 구조적으로 답한다.

Claude Code에서 서브에이전트는 YAML 프론트매터를 가진 마크다운 파일 하나다. 위치는 두 곳이다. .claude/agents/에 두면 프로젝트 전용(팀 공유 가능), ~/.claude/agents/에 두면 머신 전체에 적용된다. 핵심은 라우팅 메커니즘이 전적으로 description 필드에 달려 있다는 점이다. Claude는 모든 서브에이전트의 description을 읽고 태스크가 매칭되면 위임한다. 등록 단계도, 설정 토글도 없다.

description이 라우터다: 제목이 아니라 트리거 조건을 써라

이 구조에서 가장 많이 발생하는 실패는 description을 직함처럼 쓰는 것이다. "Database expert"는 절대 쓰이지 않는다. "SQL 쿼리와 스키마 변경을 느린 패턴, 누락된 인덱스, 마이그레이션 리스크 관점에서 검토한다. SQL 또는 마이그레이션 파일이 변경될 때 사용하라."는 쓰인다. 차이는 명확하다. 전자는 '무엇인가'를 설명하고, 후자는 '언제 쓰는가'를 설명한다.

tools 필드에는 실제로 존재하는 툴 이름만 써야 한다. 오타 하나로 서브에이전트 전체가 실행되지 않는다. name 필드에 콜론이 들어가면 파일 자체가 로드되지 않고, 에러 메시지도 런타임에 나타나지 않아 디버그 로그를 직접 봐야 한다. 같은 트리 안에 name이 중복되면 파일시스템 읽기 순서로 하나만 로드되는데, 어떤 버전이 실행되는지 런타임에서 알 수 없다. /doctor 명령이 이를 감지해주므로 서브에이전트가 이전 버전처럼 동작할 때는 가장 먼저 실행해볼 것.

두 논문이 가리키는 하나의 실무 질문

두 글을 함께 읽으면 하나의 질문으로 수렴한다. AI로 프론트엔드 산출물을 대규모로 생성할 때, 품질을 구조적으로 통제하려면 무엇을 설계해야 하는가.

첫 번째 답은 잠금의 단위다. 디자인 토큰(CSS 변수)과 살아있는 UI 킷을 정식 소스로 삼고, 레이아웃 조합은 모델에게 위임한다. 모든 것을 잠그는 순간 표현력이 죽는다.

두 번째 답은 위임 구조의 명확성이다. 서브에이전트를 정의할 때 description은 직함이 아니라 실행 조건이어야 한다. 에이전트가 언제 개입하는지를 명시하지 않으면 아무도 위임하지 않는다.

전망: '무엇을 설계할지'가 점점 더 중요해진다

흥미로운 것은 두 글 모두 '지금 자동화할 수 있는 범위'가 계속 넓어지고 있다고 말한다는 점이다. Claude Code의 공식 디자인 시스템 통합이 확장될수록, 직접 구축해야 할 부분은 진짜 프로젝트 고유의 것—당신의 토큰, 당신의 UI 킷—으로 좁아진다.

이 변화는 프론트엔드 개발자의 역할이 '코드를 잘 짜는 것'에서 '어떤 구조 위에서 AI가 잘 동작하게 설계하는 것'으로 이동하고 있음을 다시 한번 확인시킨다. 잠금의 단위를 결정하고, 위임 조건을 언어로 정의하고, 전제의 유통기한을 모니터링하는 일—이것이 AI 시대 프론트엔드 엔지니어의 실질적인 설계 역량이 되고 있다.

출처

더 많은 AI 트렌드를 Seedora 앱에서 확인하세요