본문으로 건너뛰기

Figma 퍼블리싱 파이프라인 03. 병렬화 시도와 토큰 폭발 악몽

·11 min read·3 / 5

V02의 스킬 시스템을 프로덕션에 투입했다. 처음엔 괜찮았다. 하지만 복잡한 페이지를 처리하다가 갑자기 토큰 게이지가 폭주했다. 원인을 추적해보니 서브에이전트가 66개나 동시에 실행되고 있었다.

병렬화 아이디어: 순차에서 병렬로

V02에서 기본 구조는 잘 작동했다. 하지만 성능이 문제였다. 섹션 5개를 처리하는 데 순차로 5배 시간이 걸린다. 병렬로 처리할 수 있으면 가장 느린 1개 섹션만큼만 걸린다.

Figma MCP의 get_design_context는 한 번에 반환할 수 있는 데이터량에 한계가 있다. 큰 프레임을 통째로 조회하면 하위 레이어가 조용히 잘린다.

get_metadata를 먼저 호출하면 전체 노드 트리를 XML 형태로 받을 수 있다. 이 트리를 보고 기능 단위로 분리한 뒤, 각 영역을 개별 get_design_context로 조회하면 누락이 거의 없어진다.

실제 노드 트리 예시

병렬 퍼블리싱 구조

각 서브에이전트는 자기 파일만 생성하고, 최종 조립은 메인 세션이 순차적으로 한다.

기존 방식과 비교

항목기존 (순차)병렬
디자인 조회1회 통째로 → 잘림 발생영역별 개별 조회 → 누락 없음
구현 속도순차 합산 시간가장 느린 1개 시간 (2~3배 빠름)
누락 대응완성 후 발견 → 재작업사전에 노드 트리로 전수 확인
컨텍스트 소모메인 세션에 모든 코드 누적서브에이전트가 분산 처리

악몽: 66개 에이전트 폭발

평소처럼 Figma 시안 퍼블리싱을 맡기고 자리를 비웠다가 돌아오니 토큰 게이지가 37%를 가리키고 있었다. 페이지 하나 퍼블리싱하는 동안 거의 1분에 3%씩 오르고 있었다.

원인을 추적해보니 백그라운드에서 claude -p 프로세스가 66개 동시에 돌고 있었다.

아키텍처 이해

PHASE 0~1.5는 Python + Figma API만 사용해 LLM 토큰이 0이다. 모든 토큰 소비는 PHASE 2에서 발생한다.

근본 원인: 섹션 분할 로직의 절벽

figma_publish.pysplit_sections() 함수를 보니 이런 로직이 있었다.

MAX_SECTION_TOKENS = 8000  # child JSON 토큰 예산
 
if n <= 3:
    return [단일 에이전트]
elif n <= 7:
    return [2개 그룹]
else:
    return [n개 개별 에이전트]  # ← 문제

절벽 현상: 섹션이 7개면 에이전트 2개, 8개면 에이전트 8개. 복잡한 페이지는 필연적으로 n >= 8에 걸려 섹션 수만큼 에이전트가 생성된다.

이 페이지는 MAX_SECTION_TOKENS = 8000 기준으로 분할하니 66개 섹션이 나왔고, 결국 66개 에이전트가 실행됐다.

토큰 낭비 구조 분석

서브에이전트 1개가 실제로 받는 컨텍스트를 측정했다.

시스템 프롬프트        ~8K 토큰
스킬 프롬프트          ~4K 토큰
빌드 프롬프트          ~2K 토큰
shared.json           ~25K 토큰
section 파일          ~36K 토큰
  └─ specCache 포함   ~30K 토큰  ← 전체 section 파일의 83%
  └─ 실제 노드 데이터  ~6K 토큰
────────────────────────────────
에이전트당 총 입력     ~75K 토큰

Claude Sonnet의 컨텍스트 창은 200K인데, 에이전트가 75K만 쓰고 125K를 비워두고 있었다.

더 심각한 문제는 specCache(~30K 토큰)66개 섹션 파일 전부에 중복 복사되고 있었다는 점이다.

실제 Figma 노드 데이터: 6K × 66 = 396K
specCache 중복:        30K × 66 = 1,980K  ← 낭비

해결책 1: MAX_SECTION_TOKENS 상향 + 병합 패스

MAX_SECTION_TOKENS를 8K에서 30K로 올리고, 분할 후 인접 섹션을 다시 묶는 merge_by_budget() 함수를 추가했다.

결과: 66개 → 4개 에이전트

그룹 1: frame-1261172071  (6개 섹션,  49K 토큰)
그룹 2: dropdown          (11개 섹션, 59K 토큰)
그룹 3: frame-1437265828  (10개 섹션, 55K 토큰)
그룹 4: table_cpa         (7개 섹션,  42K 토큰)

해결책 2~6: specCache 중복 제거, 토큰 슬리밍, 모델 교체, QA 수동화, 스킬 통합

specCache 중복 제거 specCache를 각 섹션 파일에서 제거하고 shared.json으로 이동.

tokenIndex 슬리밍 전체 토큰이 아니라 이 페이지에서 실제 참조하는 토큰만 필터링.

PHASE 2 모델 교체 서브에이전트에서 Haiku 사용 (비용 절감).

자동 QA 파이프라인 전면 수동화 필요한 것만 선택해서 실행.

스킬 통합 (4개 → 2개) chakra/tailwind 변형을 단일 스킬로 통합, 프레임워크 자동감지.

최종 결과

항목BeforeAfter절감
PHASE 2 입력4,950K484K-90%
PHASE 2 출력528K170K-68%
QA 파이프라인230K75K-67%
총계5,748K769K-87%
처음  ████████████████████████████████████░░░░░░░░░░░░░░░░░░░░░░░  37%
지금  ████░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░   5%

핵심 교훈

  1. 절벽 로직을 주의하라: n <= 7 → 2개, n >= 8 → n개 같은 분기는 입력 크기에 따라 비용이 선형이 아닌 계단식으로 폭발한다.

  2. 공유 데이터는 1회만: 여러 에이전트가 읽는 공통 데이터는 반드시 공유 파일에 1번만 두고 참조하게 해야 한다.

  3. 컨텍스트 창 활용률을 측정하라: 200K 창에 75K만 쓰고 있다면, 에이전트를 더 줄일 수 있다는 신호다.

  4. 분할과 병합을 분리하라: 분할은 트리 구조를 보존하며 분해하고, 병합이 토큰 예산 내에서 재조립한다.

  5. API truncation과 LLM context는 다른 문제다: API 응답 크기 제한과 LLM 컨텍스트 관리는 다른 파라미터로 풀어야 한다.

이 버전에서 배운 것

  1. 병렬화는 속도는 올리지만 복잡도도 올린다 — 순차 실행이 간단하다. 병렬화하기 전에 정말 필요한지 검토해야 한다.

  2. 토큰 낭비는 구조 문제다 — 모델을 바꾸는 것보다 설계를 바꾸는 게 훨씬 효과적이다.

  3. 절벽은 예측 불가능성을 만든다 — 선형이 아닌 계단식 증가는 입력 크기를 조금만 늘려도 폭발한다.

  4. 병렬 실행의 기숨은 안전성 — 66개 에이전트가 동시에 실행되면 뭔가 하나라도 실패하면 전체 실패한다.

다음 버전에서는 이 경험을 바탕으로 구조를 완전히 재설계했다. 덜 하게 만들기로 방향을 꺾었다.