Claude Code가 일관된 UI를 생성하도록 design-rules.md를 만든 과정
"예쁘게 만들어줘"의 함정
AI 코딩 도구에게 "버튼 예쁘게 만들어줘"라고 말하면 어떤 일이 벌어질까?
훈련 데이터에서 "예쁜 버튼"으로 학습된 패턴을 그대로 뱉어낸다. border-radius: 12px, box-shadow: 0 4px 6px rgba(0,0,0,0.1), 왼쪽에 border가 있는 blockquote. GitHub에서 봤던, Medium에서 봤던 그 흔한 스타일들.
문제는 그게 우리 디자인 시스템의 토큰이 아니라는 것이다.
디자인 시스템을 운영하면서 이런 일이 반복됐다:
1. Claude Code에게 "카드 컴포넌트 만들어줘"
2. border-radius: 8px, padding: 20px 같은 하드코딩 값이 나옴
3. 수동으로 var(--radius-lg), var(--spacing-5)로 수정
4. 다음 컴포넌트에서 또 같은 일 반복
매번 "토큰 써"라고 말해도 LLM은 다음 요청에서 또 잊어버린다. 컨텍스트 윈도우 밖으로 밀려나기 때문이다.
시도 1: CLAUDE.md에 규칙 적기
처음엔 단순하게 접근했다. CLAUDE.md에 "토큰 써라"고 적었다.
```markdown
## 디자인 시스템 규칙
- 하드코딩 색상 금지, var(--color-*) 사용
- 하드코딩 간격 금지, var(--spacing-*) 사용효과가 있긴 했다. 하지만 문제가 있었다:
1. 규칙이 길어지면 무시된다 - CLAUDE.md가 길어질수록 뒷부분 규칙은 적용 안 됨
2. 맥락 의존적이다 - "UI 만들어줘" 요청이 아닌 경우에도 항상 로드됨
3. 업데이트가 안 된다 - 규칙을 바꿔도 이미 설정된 프로젝트들은 그대로
근본적인 해결책이 필요했다.
시도 2: UserPromptSubmit Hook으로 규칙 주입
Claude Code에는 Hook 시스템이 있다. 사용자가 프롬프트를 제출할 때마다 특정 명령을 실행할 수 있다.
아이디어는 간단했다:
- "버튼", "카드", "UI" 같은 키워드가 프롬프트에 있으면
- design-rules.md 파일을 컨텍스트에 주입
주황색 버튼이 있는 검은색 화면
핵심은 node_modules에서 직접 읽는다는 것이다. 파일을 프로젝트에 복사하지 않고 패키지에서 바로 참조한다. npm 업데이트하면 규칙도 자동으로 최신 버전이 된다.
design-rules.md: 무엇을 담았나
단순히 "토큰 써라"가 아니라, LLM의 행동 패턴 자체를 제약하는 규칙을 설계했다.
1. 훈련 데이터 패턴 금지 (섹션 0)
이 섹션이 가장 중요하다. LLM에게 "네가 많이 본 패턴을 그대로 쓰지 마"라고 명시한다.
## 0. 훈련 데이터 패턴 사용 금지 (Anti-Pattern)
> ⚠️ 이 섹션은 모든 규칙보다 우선한다.
금지되는 행동:
- "GitHub에서 이렇게 하니까..." → ❌
- "대부분의 웹사이트가 이렇게 하니까..." → ❌
- "흔히 보는 형태"를 그대로 만드는 것 → ❌구체적인 안티패턴 목록도 포함했다:
컴포넌트
금지 패턴
이유
Blockquote
border-left: 4px solid
하드코딩 px, GitHub/Medium 편향
Alert
✓, ⚠ 텍스트 아이콘
SVG만 허용
Card
box-shadow: 0 4px 6px
Shadow 금지
Button
border-radius: 8px 이상
토큰만 사용
2. "그냥 만들어줘" 요청 대응
사용자가 구체적인 스타일 없이 요청하면 LLM이 임의로 결정하지 않고 되묻도록 했다.
❌ 잘못된 대응:
"Blockquote 컴포넌트를 만들겠습니다."
→ 훈련 데이터 기반으로 왼쪽 border 스타일 생성
✅ 올바른 대응:
"Blockquote 컴포넌트를 만들기 전에 스타일을 확인하고 싶습니다.
1. 배경색만 다른 단순한 박스 스타일?
2. 왼쪽에 아이콘이 있는 스타일?
3. 테두리가 있는 스타일?
4. 기 타 (설명해주세요)
어떤 스타일을 원하시나요?"이 규칙 하나로 LLM의 "멋대로 디자인" 문제가 상당히 줄었다.
3. 필수 제약 14가지
토큰 사용 규칙 외에도 UI 품질을 위한 제약들을 정의했다:
- 2.1 Border Radius: 기본값 4px, 8px 이상은 예외적 상황만
- 2.4 화면당 컴포넌트 수: 최대 7개 (Miller's Law)
- 2.6 컨테이너 중첩 금지: 불필요한 wrapper div 금지
- 2.7 단일 시각적 피드백: hover 시 배경색 하나만 변경
- 2.8 이모지/텍스트 아이콘 금지: SVG만 사용
- 2.9 Shadow 사용 제한: Modal/Dropdown/Toast만 허용
- 2.11 Header > Sidebar 위계: 레이아웃 구조 강제
4. Generation Protocol 4단계
LLM이 UI를 생성할 때 따라야 하는 검증 프로세스를 정의했다:
## 3. Generation Protocol
### Step 1: 목적 파악 (Purpose)
- 이 UI의 주요 사용자 액션은?
- 기존 컴포넌트로 해결 가능한가?
### Step 2: 토큰/컴포넌트 선택 (Selection)
- 사용할 색상 토큰 목록 (최대 3개)
- @design-geniefy/ui 컴포넌트 중 재사용 가능한 것
### Step 3: 검증 (Validation)
- [ ] 하드코딩 색상 없음
- [ ] 이모지/텍스트 아이콘 없음
- [ ] shadow 없음 (예외 제외)
- ...
### Step 4: 위반 시 거부 (Rejection)
❌ 제약 위반 발견
위반 항목:
1. [C-2.3] 하드코딩 색상: color: #333 → var(--color-foreground) 사용위반이 발생하면 생성을 거부하고 수정하도록 강제한다. 그냥 경고가 아니라 거부다.
자동 검증: lint-design-rules.sh
규칙을 정해도 위반을 잡아내지 못하면 무용지물이다. PostToolUse Hook으로 컴포넌트 파일 작성 후 자동 검증을 돌린다.
컴포넌트를 작성할 때마다 즉시 피드백이 온다. LLM도 이 피드백을 받고 자동으로 수정한다.
bash
#!/bin/bash
# design-rules.md 위반 탐지 스크립트
# 1. 텍스트 아이콘/이모지 탐지
TEXT_ICONS=$(grep -E '[""]|[✓✔✅⚠️❌✕]' "$FILE_PATH")
if [ -n "$TEXT_ICONS" ]; then
echo "❌ [2.8 위반] 텍스트 아이콘/이모 지 사용 금지"
fi
# 2. 하드코딩 색상 탐지
HARDCODED_COLORS=$(grep -E "#[0-9a-fA-F]{3,8}" "$FILE_PATH" | grep -v "var(--")
if [ -n "$HARDCODED_COLORS" ]; then
echo "❌ [2.3 위반] 하드코딩 색상 사용 금지"
fi
결과: 일관된 UI 생성
이 시스템을 도입한 후:
Before:
- LLM에게 "카드 만들어줘" → box-shadow, border-radius: 12px 난무
- 수동으로 토큰으로 교체
- 다음 요청에서 또 반복
After:
- LLM에게 "카드 만들어줘" → 스타일 확인 질문
- "배경과 border로 구분되는 스타일" 선택
- var(--radius-lg), var(--spacing-4), border: 1px solid var(--color-border) 자동 적용
- 위반 시 자동 거부 및 수정
배운 것
1. LLM은 명시적 제약이 필요하다
"토큰 써라"는 충분하지 않다. "GitHub 스타일 쓰지 마", "border-left: 4px 쓰지 마" 같은 구체적인 금지 목록이 필요하다. 훈련 데이터 패턴을 명시적으로 차단해야 한다.
2. 검증 자동화가 핵심이다
규칙을 정해도 지키지 않으면 의미 없다. Hook과 스크립트로 자동 검증하고, 위반 시 즉각 피드백을 주는 시스템이 필요하다.
3. 규칙도 버전 관리가 필요하다
design-rules.md를 프로젝트에 복사하지 않고 node_modules에서 참조하는 이유가 여기 있다. 규칙이 업데이트되면 npm 업데이트 한 번으로 모든 프로젝트에 반영된다.
다음 단계
현재 design-rules.md는 v1 상태다. 앞으로 추가할 것들:
- 접근성 규칙 (aria-label 필수 등)
- 반응형 검증 (고정 width 탐지)
- 컴포넌트별 세부 규칙 (Button의 variant별 토큰 매핑 등)
LLM이 일관된 UI를 생성하게 만드는 건 규칙을 잘 정의하고, 자동으로 강제하는 시스템을 만드는 일이다. "예쁘게 만들어줘"는 이제 금지어다.