디자인 시스템이 코딩 에이전트가 작성하는 코드에 변화를 줄까?
요약
본 글은 디자인 시스템(Design System)의 구조적 중요성을 코딩 에이전트 시대에 검증하려는 시도입니다. 저자는 토큰을 데이터로 관리하고 컴포넌트를 API처럼 버전화한 실제 시스템을 구축했으며, 이 시스템이 에이전트가 추측 대신 의미론적 토큰과 계약서 기반의 정확한 결과물을 생성하는 데 필수적임을 보여줍니다.
핵심 포인트
- 디자인 시스템은 단순한 가이드가 아닌, 물리적인 '계약'으로 작동해야 한다.
- 토큰을 데이터로 관리하고 Figma 파일도 이 소스에서 파생되어야 한다.
- 컴포넌트 라이브러리는 독립적으로 패키징되고 모든 계층에서 테스트되어야 한다.
얼마 전, 저는 제가 생각하기에 디자인 시스템이 구축되어야 하는 방식으로 하나의 결과물을 완성했습니다. 토큰을 데이터로 사용하고, 컴포넌트를 버전 관리되는 공개 API처럼 만들었습니다. 모든 것을 npm에 게시하고 CI에서 검증했죠. 완벽하지는 않지만, 기반으로 삼기에 탄탄한 엔지니어링 작업이었고 잊을 수 없는 전문적인 경험이었습니다.
저는 에이전트들이 저희 UI를 작성하기 전에 이것을 구축했습니다.
그러던 어느 날, 문득 제가 스스로에게 질문했습니다. 이 모든 것이 코딩 에이전트가 만들어내는 결과물에 실제로 차이를 만드는지 말입니다. '어떻게 해야 하는지'가 아니라, '실제로 그러한지'를요.
저는 좋은 답을 준비하고 있었습니다. 물론 그렇습니다. 에이전트는 임의로 헥스 값(hex values)을 추측하는 대신 의미론적 토큰(semantic tokens)을 얻고, 테이블을 재창조하는 대신 타입이 지정된 컴포넌트 API를 사용하며, 제 소스를 스크래핑하는 대신 작성된 계약서(written contract)를 받기 때문입니다. 저는 여러 회의에서 이 문장을 반복해서 말해왔습니다. 그리고 그것을 믿었습니다.
다만, 그 근거가 되는 단 하나의 수치가 없었을 뿐입니다.
그것이 저에게는 생각보다 더 큰 고민거리였습니다. 저는 제 직업 생활 내내 팀들에게 증거를 요청하며 살아왔는데, 바로 그 자리에 제가 에이전트 코딩 시대에 디자인 시스템의 역할에 대한 일련의 믿음만을 가지고 서 있었던 것입니다.
그래서 저는 저 자신에게 답을 줄 무언가를 만들기로 했습니다.
실제로 구축한 것들
여기에 있는 모든 것은 공개되어 있습니다 — design-system-blueprint — 그리고 이것은 데모처럼 보이는 실제 시스템이 아니라, 진짜 시스템입니다.
토큰을 세 단계로 나누고 강제 적용했습니다. 1단계는 옵션(options): 원본 팔레트, 스케일, 기본 요소(primitives)입니다. 2단계는 결정 사항(decisions) — --ds-decisions-*이며, 의미론적 레이어(semantic layer)로서 애플리케이션이 건드릴 수 있는 유일한 단계입니다. 3단계는 컴포넌트 내부용으로 비공개이며, 주요 버전 업데이트 없이 변경됩니다. Style Dictionary가 이 모든 것을 구축하며, 게시된 CSS 진입점(entry point)은 오직 2단계만 노출합니다. 경계는 위키의 관습이 아니라, 패키지를 설치했을 때 물리적으로 얻게 되는 것입니다.
Figma 파일은 토큰에서 생성되며, 그 반대가 아니다. 값들은 tokens.json에 존재합니다. 디자인 파일의 변수 컬렉션은 이 파일로부터 만들어지며, 내보내기(export)가 소스(source)를 따라가지 못할 때 테스트가 실패합니다. 이전에는 두 가지를 일치시키는 것이 누군가의 기억에 의존했습니다. 감사 결과, 디자인 파일이 100개 이상의 변수만큼 뒤처져 있었고, 아무것도 확인하지 않았기 때문에 그 격차는 몇 달 동안 벌어지고 있었습니다.
해당 토큰을 사용하는 컴포넌트 라이브러리. 아코디언(accordion), 아바타(avatar), 브레드크럼(breadcrumbs), 버튼(button), 체크박스, 드롭다운(dropdown), 푸터(footer), 헤더(header), 입력(input), 리스트(list), 모달(modal), 라디오(radio), 테이블(table), 태그(tag) 등 14개의 Angular 컴포넌트가 있습니다. 이들은 독립적이며 ng-packagr로 패키징되었고, Storybook에서 개발 및 문서화되었습니다. 토큰 계약(token contracts), 단위 테스트(unit), 상호작용(interaction), 접근성(accessibility), 시각적 회귀(visual regression) 등 모든 계층에 걸쳐 테스트가 이루어집니다.
사람이 아닌 에이전트를 위해 작성된 계약. 제가 가장 궁금했던 부분입니다. 패키지 안에 포함되는 타입 선언(Type declarations) 덕분에, 이 패키지를 설치하는 에이전트는 소스 코드를 건드리지 않고도 실제 속성 표면(prop surface)을 읽을 수 있습니다. 리포지토리 루트의 AGENTS.md에는 시스템에서 작동하는 모든 것에 대한 내용이 담겨 있고, npm 패키지 안에 포함된 약 3KB 크기의 llms.client.txt에는 그것과 함께 작동하는 모든 것(어떤 선택자(selector)가 존재하는지, 그 동작이 스타일 일치보다 우선하는지, 티어 2가 참조할 수 있는 유일한 티어인지, 그리고 의미론적 토큰이 의도에 맞지 않을 경우 가장 가까운 색상을 가져오는 대신 '커버리지 없음(no-coverage)'을 보고해야 하는지 등)에 대한 내용이 담겨 있습니다.
MCP를 위한 토큰 리졸버. @jablonowski/dsb-tokens-mcp는 에이전트가 호출할 수 있는 도구로, 의도(
실험 개요
코딩 에이전트는 컴파일러가 아닙니다. 같은 프롬프트를 두 번 주면 서로 다른 두 개의 애플리케이션을 얻게 되며, 둘 다 그럴듯하고 빌드 가능합니다. 따라서 한 출력만으로는 아무것도 알 수 없으며, 정확히 한 가지가 다른 반복 실행(repeats)이 필요합니다.
또한 시각적으로 판단할 수도 없습니다. 모델들은 아무것도 없는 상태에서 유능해 보이는 UI를 만들어냅니다. 디자인 시스템을 제공했는지 여부와 관계없이 의도적인 것처럼 보이는 결과물을 건네줄 것입니다. 측정할 가치가 있는 차이는 스크린샷 아래에 있습니다. 즉, 애플리케이션이 얼마나 많은 CSS를 소유하게 되었는지, 몇 개의 컴포넌트를 재구현했는지, 토큰이 있어야 할 자리에 원시 헥스 값(raw hex values)이 얼마나 놓여 있는지, 그리고 실행 비용(run cost)입니다.
따라서 다음과 같습니다. 하나의 명세와 빌드할 애플리케이션 — 로그인, 대시보드, 사용자 테이블을 가진 작은 Angular 대시보드. 매번 바이트 단위로 동일한 프롬프트, 어떤 저장소 외부의 빈 디렉토리에서 새로운 에이전트 세션, 그리고 녹화된 것에서 제공되는 동일한 Figma 프레임으로 모든 실행이 정확히 같은 바이트를 보도록 합니다.
실행 간에 변하는 것은 단 한 가지입니다. 바로 에이전트가 보유하고 있는 디자인 시스템의 양입니다.
| 팔(Arm) | 에이전트가 가진 것 |
|---|---|
| A | 명세와 Figma 프레임, 그 외 아무것도 없음 |
| ... | |
| 각 단계는 정확히 한 가지를 추가하며, 이것이 격차를 읽을 수 있게 만듭니다. A→B는 시스템을 설치 가능한 패키지로 배포하는 것이 무엇을 사주는지 분리합니다. B→C는 그 위에 에이전트가 접하게 되는 문서를 분리합니다. C→D는 리졸버(resolver)를 분리합니다. 그리고 **A′**은 불편한 경우입니다. 즉, 문서화되었지만 아직 배포되지 않은 디자인 시스템 — 솔직히 말해서 많은 조직들이 실제로 있는 곳이 바로 여기입니다. Figma 파일, Confluence 페이지, 그리고 온보딩 문서의 한 단락입니다. |
점수 측정자(Scorers)들은 첫 번째 실행 전에 이미 확정되었고, 반증자들(falsifiers)도 그러했습니다. 즉, 내가 틀렸다고 말해줄 결과물들이었습니다. 이것이 중요합니다. 왜냐하면 디자인 시스템의 저자가 평가의 저자이기도 하기 때문에, 저는 그것이 중립적인 입장이라고 가장하지 않을 것이기 때문입니다.
결과는 어땠나
30회 실행 결과: 기본 모델에서 5개 팔(arm)에 각각 5회씩 실행되었고, 추가 검증을 위해 두 번째 모델에서도 각각 1회씩 실행되었습니다.
지금 당장 말하고 싶은 다섯 가지가 있습니다. 메커니즘이 흥미로운 부분이며, 각 메커니즘은 별도의 게시물이 필요하므로 그 구조를 소개합니다.
시스템을 배포하는 것은 계단식 함수(step function)입니다. 글로 작성하는 것은 그렇지 않습니다. 조건 간에 중복되는 부분이 전혀 없습니다. 패키지 없이 에이전트는 라이브러리 컴포넌트가 자연스럽게 위치할 수 있는 13곳 중 12곳을 직접 코딩하고, 애플리케이션은 이제 관리하게 된 약 90개의 사용자 정의 속성(custom properties)을 조용히 습득합니다. 패키지 사용 시: 0개, 그리고 0개입니다. 가장 많은 팀이 실제로 있는 것처럼 보이는 산문 스타일 가이드(prose-styleguide) 팔은 그 어느 곳에도 배치되지 않았습니다.
시스템이 하는 가장 유용한 일은 일관성(consistency)이 아니라 접근성(accessibility)이었습니다. 에이전트는 Figma에서 색상 팔레트를 읽어와 정확한 색상을 얻습니다. 하지만 두 모델 모두에서 반복적으로 심각한 명암 대비 실패(contrast failures)를 발생시킵니다. 값 자체는 한 가지 문제이지만, 어떤 값이 어떤 표면에 속해야 하는지는 또 다른 문제입니다. 그리고 디자인 파일은 이 후자(second one)를 담고 있지 않습니다. 이것이 제가 예상하지 못했던 결과이자 가장 강력하게 주장하고 싶은 부분입니다.
에이전트가 제 컴포넌트 API를 환각(hallucinate)시키지 않았습니다. 30회 실행 동안 단 한 번도 그렇지 않았습니다. — 라이브러리가 전혀 없는 팔을 포함해서도 마찬가지였습니다. 업계에서 가장 좋아하는 공포 이야기는 제가 관찰한 것이 아닙니다. 에이전트는 존재한다고 의심하지 않는 컴포넌트를 발명하지 않습니다. 대신 자체적으로 코드를 작성하며, diff(차이점)에서 오류처럼 보이는 부분은 아무것도 없습니다. 이것이 최악의 실패 모드입니다. 왜냐하면 검토 과정에서 눈에 보이지 않기 때문입니다.
비용이 적게 들지 않고 더 많이 듭니다. 저는 라이브러리가 생성당 비용이 저렴할 것이라고 가정했습니다. 에이전트가 바퀴를 재발명하는 것을 멈출 것이라고요. 그 반대가 사실입니다. 라이브러리를 사용한다는 것은 그것을 읽는다는 의미이며, 한번 읽은 모든 내용은 컨텍스트에 남아 있고 매번의 작업에서 다시 비용을 지불해야 합니다. 어떤 이점도 리워크(rework), 검토(review), 유지보수(maintenance)에서 나와야 하는데, 이는 제가 아직 측정하지 않았고 측정하게 되면 주장할 수 있는 부분입니다.
내가 가장 자랑스러워했던 레이어는 측정 가능한 성과를 전혀 내지 못했습니다. MCP 리졸버(resolver)는 그 앞에 있는 일반 텍스트 파일과 비교했을 때, 제가 감지할 수 있는 개선점을 추가하지 않았습니다. 이 비교가 결정적인 것으로 사전 등록되었기 때문에, 제가 마음에 들었던 결과와 똑같은 비중으로 발표되었습니다.
이 모든 것을 한 문장으로 압축하자면 다음과 같습니다: 디자인 시스템은 에이전트를 더 똑똑하거나 더 정확하게 만들지 않습니다. 단지 그 에이전트가 작성한 코드를 누가 소유할지를 결정할 뿐입니다 — 그리고 이 과정에서 아무도 기록하지 않은, 에이전트가 읽을 수 있는 곳에 적어둔 결정을 담고 있습니다.
이 모든 것은 하나의 애플리케이션, 하나의 프레임워크, 하나의 모델 공급업체에 관한 것입니다: 벤치마크(benchmark)가 아니라 커밋된 점수표를 가진 사례 연구입니다. 제가 원하는 두 가지 측정 지표—드리프트(drift), 그리고 승인된 화면당 비용(cost per accepted screen)—는 아직 실행되지 않았습니다. 모든 실행 기록, 세부 사항이 담긴 모든 점수, 생성된 애플리케이션과 제가 연구 도중에 변경했던 모든 규칙을 기록하는 프로토콜은 demo-blueprint에 포함되어 있으며, 여기에는 제가 발견하기 직전에 위의 결론 중 하나를 거의 뒤집었던 변경 사항도 포함되어 있습니다.
이제 당신 차례입니다
어떻게 생각하시는지 알려주세요. 그리고 디자인 시스템과 관련하여 제 생각이 바뀌도록 만들 측정 지표가 있고 제가 그것을 고려하지 않았다면, 말씀해 주세요 — 아직 추가하기에 저렴한 것들이 있습니다.
저는 IT 분야에서 18년 경력의 엔지니어링 매니저입니다. 저는 제가 주장하는 것을 직접 구축하고, 그 주장이 살아남는지 측정합니다. 이번 사례도 살아남았습니다—다만 제가 예상했던 형태와는 다르게 말이죠.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기