Figma 퍼블리싱 파이프라인 04. 일관성 해결과 아키텍처 재정의
V03에서 66개 에이전트 폭발로 토큰을 87% 절감했다. 하지만 또 다른 문제가 터져 나왔다. 같은 Figma 디자인인데 AI가 매번 다른 코드를 만들었다. 동시에 파이프라인 전체 구조를 다시 설계해야 한다는 깨달음도 생겼다.
문제: 일관성 부족
같은 Figma 시안을 AI에게 "이거 코드로 만들어줘"라고 하면 겪는 문제가 있다.
같은 UI를 줬는데 매번 다른 코드가 나온다.
// 첫 번째 시도 — AI가 프로젝트 컴포넌트를 모름
<Badge colorScheme="blue">소진</Badge>
// 두 번째 시도 — 컴포넌트는 찾았는데 색상을 추측
<StatusBadge color="green" label="소진" />
// 세 번째 시도 — 드디어 맞음
<StatusBadge color="blue" label="소진" />왜 이런 일이 생길까?
AI는 매 요청마다 처음부터 판단한다. "이 Figma 노드에 어떤 컴포넌트를 쓸까?", "배경색 #e9f2ff는 blue야 green이야?", "import는 어디서 하지?" — 이 질문들을 매번 새로 답한다.
해결: 판단 자체를 없앤다
"AI야, 잘 판단해"가 아니라 판단할 필요가 없는 구조를 만들면 된다.
핵심 발상은 이것이다:
사람이 읽는 마크다운 규칙 문서 대신, 스크립트가 읽는 JSON 매핑 파일을 만들자.
AI가 "이 색이 뭘까?" 고민하는 대신, 스크립트가 미리 답을 정해놓는 것이다.
design-system-map.json
모든 매핑 규칙을 하나의 JSON 파일에 모았다. 프로젝트 루트의 .claude/design-system-map.json이다.
instanceMap — "이 Figma 컴포넌트 → 이 코드 컴포넌트"
Figma에서는 재사용 가능한 UI 조각을 "컴포넌트 인스턴스(INSTANCE)"라고 부른다. React의 컴포넌트와 같은 개념이다.
{
"instanceMap": {
"Status Badge": {
"component": "StatusBadge",
"import": "@/components/status-badge",
"defaultProps": {},
"colorResolve": "fillsToStatusBadge"
}
}
}Figma에서 "Status Badge"를 만나면 → StatusBadge 컴포넌트를 쓰고, import 경로는 @/components/status-badge다. 고민 끝.
fillsToStatusBadge — "이 배경색 → 이 color prop"
StatusBadge 같은 컴포넌트는 color prop으로 색상을 정한다. 그런데 Figma에서 넘어오는 건 #eff7ff 같은 hex 값이다.
{
"fillsToStatusBadge": {
"#eff7ff": "blue",
"#e0ffeb": "green",
"#fef2e3": "yellow"
}
}AI가 #eff7ff를 보고 "이게 blue일까?"라고 추측하는 대신, 미리 정해놓는다.
hexContextMap — "같은 색인데 쓰이는 곳이 다르면?"
같은 #e5e7eb라도 배경에 쓰이면 grey.3이고, 테두리에 쓰이면 border.basic.2다.
{
"hexContextMap": {
"background": { "#e5e7eb": "background.basic.4" },
"border": { "#e5e7eb": "border.basic.2" }
}
}importPaths — "import 경로 추측 금지"
AI가 가장 자주 틀리는 것 중 하나가 import 경로다.
{
"importPaths": {
"StatusBadge": "@/components/status-badge",
"Select": "@/components/select"
}
}pageTemplates — "이 페이지는 어떤 유형?"
Figma 화면을 보고 "이건 테이블 페이지다", "이건 대시보드다"를 판별하는 것도 자동화했다.
{
"pageTemplates": {
"table": {
"structure": "Header → Layout → Controls + Table",
"requiredImports": [
{ "component": "PageHeader", "from": "@/components/page-header" }
],
"indicators": ["Table", "Header Row", "Row", "Pagination"]
}
}
}맵 자동 생성
이 맵을 직접 작성할 필요는 없다. token.json과 src/components/를 스캔하면 전부 자동 생성된다.
python3 ~/.claude/scripts/init_design_system_map.py --project-root /path/to/project이 스크립트는:
- token.json에서 색상 패턴 추출
- 시맨틱 토큰 이름으로 용도 분류
- 컴포넌트 파일 스캔
- Figma 이름 ↔ 코드 컴포넌트 매칭
파이프라인 재설계: 덜 하기
V03의 토큰 폭발을 해결하고 나니 더 근본적인 문제가 보였다.
파이프라인이 너무 많은 일을 한 번에 하고 있다.
한 요청에서 처리한 것:
- Figma 분석
- 자산 추출
- 섹션 분할
- 코드 생성
- 스타일 적용
- 기존 코드 수정
- 검증
- 재수정
결과: 20~30분 소요, 토큰 증가, 결과 불안정.
핵심 깨달음
❌ 잘못된 방향: 더 똑똑하게 만들기
✅ 올바른 방향: 덜 하게 만들기
생성과 수정은 완전히 다른 문제다. 이 둘을 섞으면 안 된다.
구조 변경
추가 변화:
- 페이지 전체 → 컴포넌트 단위
- 탐색 제거
- 자동 수정 루프 제거
- 복잡한 검증 단계 제거
최종 구조
~/.claude/
├── CLAUDE.md
├── commands/
│ ├── publish-init.md
│ └── publish.md
└── tools/
└── figma-extract.js| 구성 | 역할 |
|---|---|
| CLAUDE.md | 환경 정의 |
| publish-init | 프로젝트 분석 |
| publish | 퍼블리싱 실행 |
| script | 데이터 처리 |
핵심 설계 전략
1. 컨텍스트 캐싱
/publish-init → 1회
/publish → 반복반복 작업 제거.
2. IR 중심 설계
모든 단계는:
- IR 생성
- IR 소비
- IR 검증
구조 안정화.
3. 조건문 제거
분기로 해결하지 말고, 레이어로 분리.
이 버전에서 배운 것
-
프로덕션에서 진짜 문제가 나온다 — V02까지는 잘 동작했다. V03에서 비로소 구조 문제가 드러났다.
-
일관성은 자동화를 통해 확보한다 — 규칙 문서로는 부족하다. 스크립트가 강제해야 한다.
-
덜 하는 게 더 강하다 — 모든 기능을 다 할 수 있는 시스템보다, 한 가지를 잘하는 시스템이 더 신뢰할 수 있다.
-
생성과 수정은 분리해야 한다 — 이 둘을 섞으면 복잡도가 폭발한다.
-
구조 문제는 코드로 해결 불가능하다 — 구조 자체를 다시 짜야 한다.
다음?
이 경험들은 모두 새로운 프로젝트에서도 반복된다. V05, V06, ... 계속 개선될 것이다.
하지만 지금까지의 교훈은 명확하다:
- 정확도 > 편리성
- 자동화 > 규칙 문서
- 덜 하기 > 더 하기
- 구조 > 기능