Figma 퍼블리싱 파이프라인 02. 스킬 시스템 설계와 엣지케이스
V01에서 Python + REST API로 기초를 잡았다. 이제 그것을 Claude Code 스킬 시스템으로 자동화하고, 5라운드에 걸쳐 엣지케이스들을 처리했던 과정을 기록한다.
왜 스킬을 만들었나
Figma → 코드 퍼블리싱은 반복적이면서도 실수가 잦은 작업이다:
- 토큰 매핑을 추측하면 100% 틀린다 (grey.6 vs grey.7)
- 아이콘을 수동 다운로드하면 currentColor 치환을 빼먹는다
- 대형 시안을 한 번에 처리하면 컨텍스트가 넘쳐서 뒤쪽 섹션을 추측한다
- QA를 빼먹으면 strokeDashes(dashed/solid) 같은 세부사항이 누락된다
이런 실수를 구조적으로 방지하려면, 절차를 스킬로 코드화하고 강제하는 게 맞다.
스킬 아키텍처
3계층 구조
5라운드 엣지케이스 개선 과정
처음 만든 스킬은 단순했다. "Figma URL 받아서 스펙 저장하고 에이전트 돌려라." 하지만 실제로 쓰다 보니 엣지케이스가 쏟아졌다.
Round 1: 기본 안전장치
발견된 문제 3가지:
-
오래된 캐시 값 재사용 — 이전 세션에서 사용한 Figma fileKey가 임시 파일에 남아있으면, 새 URL을 입력해도 옛날 파일을 조회한다.
-
불완전한 스펙을 통과시킴 — Figma API에서 데이터를 받아왔는데, 필수 섹션(레이아웃, 색상, 자산 목록, 컴포넌트 트리) 중 일부가 빠져있어도 다음 단계로 넘어갔다.
-
병렬 에이전트의 경쟁 조건 — 여러 에이전트가 동시에 같은 파일(shared.md)에 결과를 쓰려다 내용이 뒤섞였다.
해결:
- fileKey 검증 → URL에서 직접 파싱하고 즉시 검증
- 스펙 완전성 검증 → 필수 섹션이 모두 있는지 체크
- 경쟁 조건 → 에이전트마다 개별 결과 파일 작성, 오케스트레이터가 순차 병합
Round 2: URL 파싱 강화
발견된 문제:
Figma URL이 항상 figma.com/design/:fileKey/... 형태가 아니었다. branch URL, Make URL 등 변형이 있었다.
일반: figma.com/design/abc123/MyPage?node-id=10-20
브랜치: figma.com/design/abc123/branch/xyz789/MyPage
Make: figma.com/make/def456/MyPrototype해결: URL 패턴별 분기로 처리. 또한 타입 체크 명령어가 프로젝트마다 달라서 package.json의 scripts 필드를 확인해 자동 감지하도록 했다.
Round 3: 단계 간 상태 유실
발견된 문제:
사용자가 입력한 --page src/app/dashboard 옵션이 중간에 사라졌다. PRE 단계에서 파싱한 값을 PHASE 3에서 읽으려는데, 그 사이에 값이 전달되지 않았다.
해결: 파싱한 값을 임시 파일에 저장해서, 어느 단계에서든 읽을 수 있게 했다. React의 Context API처럼, 중간 단계를 거치지 않고 직접 접근하는 방식이다.
Round 4: 템플릿 변수 치환 문제
발견된 문제 2가지:
-
빈 파일 목록 처리 — 섹션별 스펙 파일을 순회할 때, 파일이 하나도 없으면 와일드카드 패턴(
*.md) 자체가 문자열로 처리됐다. -
플레이스홀더가 치환되지 않음 — 공유 문서에
[여기에 페이지 경로]같은 플레이스홀더를 넣었는데, 실제 값으로 치환되지 않고 그대로 에이전트에게 전달됐다.
해결: 방어적 코딩 — 순회 전에 파일 존재를 확인하고, 플레이스홀더 대신 실제 값을 미리 주입한 뒤 문서를 생성했다.
Round 5: 최종 조립 단계 명확화
발견된 문제: PHASE 3에서 page.tsx를 조립할 때, "모든 섹션 컴포넌트를 import하라"고만 지시했다. 그런데 어떤 컴포넌트가 존재하는지 목록이 없었다.
해결: PHASE 2가 끝나면 실제로 생성된 파일 목록을 수집하고, 그 목록을 기준으로 page.tsx를 조립하도록 했다.
섹션 분할 전략
디자인 크기에 따라 에이전트 수를 조절한다.
| 규모 | 루트 직계 자식 수 | 전략 |
|---|---|---|
| 소형 | 1~3개 | 단일 에이전트 |
| 중형 | 4~7개 | 2~3개 그룹 |
| 대형 | 8개+ | 섹션별 개별 에이전트 |
섹션 간 import 의존성도 분석한다. CardGrid가 Card 컴포넌트를 쓴다면, Card가 먼저 만들어져야 한다. 독립적인 섹션은 병렬로, 의존 관계가 있으면 순차 실행한다.
핵심 설계 원칙
1. 감독자 패턴 (Orchestrator Pattern)
메인 에이전트는 코드를 직접 쓰지 않는다. 서브에이전트에 위임만 한다.
이 패턴의 장점은 컨텍스트 격리다. 대형 페이지를 하나의 에이전트가 처리하면 앞부분 분석 내용을 뒷부분에서 잊어버리지만, 섹션별로 나누면 각 에이전트가 자기 스펙만 집중해서 본다.
2. 파일 기반 상태 공유
에이전트 간 데이터 전달은 임시 파일로 한다. 메모리(변수)가 아닌 파일이므로 에이전트가 교체되어도 상태가 유지된다.
/tmp/.current-filekey ← Figma 파일 식별자
/tmp/.current-page ← 출력 경로
/tmp/figma-spec-cache.md ← 전체 디자인 스펙
/tmp/figma-result-section-N.md ← 각 에이전트의 구현 결과3. 조기 실패 (Fail Fast)
잘못된 입력은 첫 단계에서 즉시 차단한다. fileKey가 없거나, nodeId 형식이 틀리거나, 스펙이 불완전하면 PHASE 0 이전에 에러를 던진다.
4. 경쟁 조건 방지
병렬 에이전트가 같은 파일에 쓰지 않는다. 각자 독립 파일에 쓰고, 오케스트레이터가 순차적으로 병합한다.
정리
5라운드에 걸쳐 수정한 항목:
| 라운드 | 문제 |
|---|---|
| R1 | 오래된 캐시, 불완전 검증, 동시 쓰기 충돌 |
| R2 | URL 변형 미대응, 프로젝트별 설정 차이 |
| R3 | 단계 간 상태 유실 |
| R4 | 빈 배열 처리, 플레이스홀더 미치환 |
| R5 | 조립 대상 목록 부재, 생성 지시 누락 |
엣지케이스는 처음부터 보이지 않는다. 워크플로우를 한 번 처음부터 끝까지 시뮬레이션하고 나서야 "이 값이 저기서 사라지는구나", "이 두 에이전트가 동시에 같은 파일에 쓰는구나"가 보인다.
재귀적으로 도출하고 수정하는 과정 자체가 시스템을 강화하는 방법이다.
이 버전에서 배운 것
-
엣지케이스는 처음부터 안 보인다 — 구조가 틀렸어도 단순한 경우는 동작한다. 복잡한 입력을 받아야 드러난다.
-
상태는 파일로 공유한다 — 에이전트 간 메모리 공유는 불가능하다. 파일 기반으로 설계해야 한다.
-
검증은 조기에 — 불완전한 데이터를 뒤늦게 발견하면 이전 단계를 다시 해야 한다. 첫 단계에서 모든 검증을 끝내야 한다.
-
병렬 실행은 경쟁 조건을 부른다 — 여러 에이전트가 같은 자원에 접근하면 안 된다. 역할을 명확히 분리해야 한다.
다음 버전에서는 이 스킬 시스템을 실제로 프로덕션에 투입하면서 겪은 새로운 문제들이 터져 나온다.