
AI가 만든 UI, 보여주기 전에 채점시켜라 — 게이트를 만들고 내 랜딩부터 떨어진 이야기
요약
AI가 생성한 UI의 완성도를 높이기 위해 단순 룰셋 제공을 넘어 '강제 루프(Loop)'와 '게이트(Gate)' 시스템 도입이 필요했습니다. StyleSeed는 이제 디자인 결정 고정, 빌드, 채점, 그리고 최종적으로 이미지 기반의 비주얼 게이트를 거치는 복합적인 프로세스를 강제합니다.
핵심 포인트
- AI UI 제작은 룰셋보다 루프와 규율이 중요함.
- StyleSeed는 `/ss-score`로 기능적/논리적 채점(80점 기준)을 수행함.
- 최종적으로 이미지 기반의 비주얼 게이트(`/ss-verify`)를 추가하여 픽셀 레벨 오류까지 검증함.
_전편: AI가 만든 UI가 어딘가 '어색한' 이유 — 그리고 그걸 고치는 한 가지 원칙에서 "축마다 값 하나"라는 정합성 원칙을 다뤘습니다. 이번 글은 그 다음 이야기 — *_원칙만으론 부족했고, 강제 장치가 필요했다*는 걸 배운 과정입니다.
룰을 줘도 안 지키더라
전편을 쓰고 나서 저는 그 원칙들을 74개 룰로 정리해 오픈소스(StyleSeed)로 공개했습니다. Claude Code·Cursor·Codex가 UI를 만들기 전에 읽는 디자인 룰셋이죠.
그런데 이상한 일이 생겼습니다. 제가 만들면 잘 나오는데, 룰만 받아간 사람들 결과물은 여전히 "AI 티"가 났어요. 같은 74개 룰인데요.
몇 주를 파고든 결론: 격차는 룰이 아니라 루프에 있었습니다. 저는 무의식적으로 이 순서를 돌고 있었어요.
디자인 결정 고정(락) → 빌드 → 채점 → 80점 미만이면 수정 → 재채점 → 통과 후에만 확인
반면 룰만 받은 에이전트는 읽고, 끄덕이고, 첫 초안을 그대로 보여줍니다. 사람으로 치면 코드리뷰 체크리스트를 벽에 붙여두고 리뷰 없이 머지하는 격이죠. 룰은 지식이고, 루프는 규율입니다. 지식은 전달됐는데 규율이 전달되지 않았던 겁니다.
그래서 루프를 강제했습니다
v2.7부터 StyleSeed의 정문은 룰 문서가 아니라 강제 루프입니다.
/ss-build inventory dashboard
/ss-build는 이렇게 동작합니다:
- 락 먼저 — 프로젝트에
STYLESEED.md(키컬러·폰트·모서리·모션이 적힌 디자인 락 파일)가 없으면 UI 코드를 쓰기를 거부하고 락부터 만듭니다. "AI가 만든 티"의 1등 원인이 매 프롬프트마다 결정이 초기화되는 드리프트거든요. - 빌드 — 락과 74개 룰 기준으로 만듭니다.
- 게이트 —
/ss-score가 8개 카테고리(색 규율·위계·레이아웃·카드·상태·모션·정합성·독창성)로 0~100 채점하고, 80점 미만이면 사용자에게 보여주지 않고 감점 항목을 스스로 고친 뒤 재채점합니다. - 통과한 것만 최종 점수와 함께 보여줍니다.
핵심 설계는 "80점은 천장이 아니라 바닥"이라는 것. 100점을 쫓느라 출시가 늦어지는 것도 실패 모드라서, 게이트는 명백히-제네릭한 초안이 사용자에게 도달하는 것만 막습니다.
코드는 통과했는데 픽셀이 어색하다면
게이트를 몇 달 돌리면서 알게 된 것: 최악의 "AI 티" 몇 개는 코드에 존재하지 않습니다. 픽셀에만 존재해요.
- 웹폰트가 조용히 실패해서 Times New Roman으로 렌더된 히어로
- 코드상 문제없는데 화면 아래 1/3이 죽은 여백
- 각각 정당한 두 색이 렌더되니 "강조색 2개"로 읽히는 화면
- 포컬 포인트 없이 균일하게 나열된 카드 그리드
그래서 v2.10에 비주얼 게이트(/ss-verify)를 추가했습니다. 화면을 실제로 렌더 → 스크린샷 → 에이전트가 이미지를 직접 보고 채점합니다. 코드 게이트(ss-score)와 픽셀 게이트(ss-verify), 두 단계 통과가 기본 루프가 됐습니다.
첫 희생자: 제 랜딩페이지 (58/100)
게이트를 만들었으면 자기한테 먼저 돌려야죠. 게이트 도입 전에 만들었던 저희 랜딩 초기 버전을 넣었더니:
| 카테고리 | 점수 | 잡힌 것 |
|---|---|---|
| 색 규율 | 7/16 | 언락 상태의 기본 인디고 + 그라디언트 히어로 텍스트 |
| 독창성 | 3/10 | 기능마다 반복되는 아이콘칩 클리셰, 목업 화면, 포컬 없음 |
| 정합성 | 5/12 | 반짝이 배지 + 그라디언트 헤드라인 + 플랫 버튼 — 언어 3개 혼재 |
| 위계·타이포 | 12/16 | 숫자/단위 2:1 미적용 |
| 상태·접근성 | 12/18 | 포커스 링 누락, 대비 미달 |
| 나머지 3개 | 19/28 | 오프그리드 간격, 1px 테두리 분리, 임의 페이드 |
| 합계 | 58/100 (F) |
만든 사람 입장에서 꽤 굴욕적인데, 동시에 이 도구를 계속 만들 이유이기도 했습니다. 게이트가 잡은 건 전부 기계적으로 고칠 수 있는 것들이었거든요. 강조색 하나로 고정, 목업 대신 실제 제품 화면을 포컬로, 아이콘칩 카드를 넘버링 플로우로 — 58 → 86. 감점 내역 전체는 채점표 페이지에 공개해뒀습니다.
커버 이미지가 그 비포/애프터입니다. 같은 제품, 같은 프롬프트 — 룰만 바꿨습니다.
Hacker News에서 또 한 번 (96→100)
이 글을 쓰기 몇 시간 전, Show HN에 올렸다가 이런 댓글을 받았습니다.
"Lighthouse 접근성 감사에서 떨어지는 요소가 꽤 있는데요."
돌려보니 사실이었습니다. 96점, 실패 요소 19개 — 다크 섹션의 11px 라벨 대비 미달 16개, aria-label이 보이는 텍스트를 포함하지 않는 버튼 3개. 접근성 채점 기준을 가진 도구의 홈페이지가, 최근 수정 후 게이트를 다시 안 돌려서 드리프트한 겁니다.
두 시간 안에 고쳐서 100점으로 만들고 답글로 보고했습니다. 교훈은 58점 때와 같습니다:
게이트는 한 번 통과하는 시험이 아니라, 수정할 때마다 다시 돌리는 루프다.
자기 도구의 규칙을 자기가 어기는 건 부끄러운 일이 아니라 — 게이트가 없으면 누구나(만든 사람조차) 드리프트한다는 증거에 가깝습니다.
정합성 다음 단계: 프리셋
전편의 반론 중 이런 게 있었습니다. "정합성을 지켜도 여전히 제네릭해 보이면?" 맞는 말입니다. 일관된 화면도 얼마든지 밋밋할 수 있어요. 정합성은 필요조건이지 충분조건이 아닙니다.
그래서 v2.8에 프리셋(/ss-restyle)을 넣었습니다 — swiss · editorial · technical · warm-dtc · minimal-mono · brutalist-lite. 각각이 모서리·타입·밀도·시그니처 무브까지 통째로 맞춰진 "하나의 좌표"라, 정합성을 깨지 않고 룩 전체를 갈아탑니다.
같은 제품이 구조부터 다른 6가지 화면이 됩니다. 각각 일관되고, 서로 다르고, 어느 것도 "기본값" 냄새가 나지 않는 것이 목표였습니다.
정리
- 룰만 주면 에이전트는 루프를 건너뛴다. 지식이 아니라 규율을 전달해야 한다 — 게이트를 강제하는 커맨드로.
- 코드 게이트 + 픽셀 게이트, 두 단계. 최악의 티는 렌더된 화면에만 존재한다.
- 게이트는 만든 사람부터 계속 통과해야 한다. 내 랜딩 58점, HN 지적 후 접근성 96점 — 두 번 다 게이트를 건너뛴 내 잘못이었다.
전부 오픈소스(MIT)입니다: github.com/bitjaru/styleseed — npx skills add bitjaru/styleseed 한 줄이면 Claude Code·Cursor·Codex에 붙습니다. 룰이 틀렸거나 너무 경직된 곳을 찾으시면 이슈로 알려주세요. 그게 이 룰셋이 자라는 방식입니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기