AI 준비 상태를 측정하는 디자인 시스템 벤치마크
요약
본 벤치마크는 코딩 에이전트가 실제 디자인 시스템을 얼마나 잘 준수하는지 평가합니다. React + TypeScript 컴포넌트 라이브러리를 대상으로 하며, 고정 조건과 의도 수준 작업 프롬프트를 사용하여 헤드리스 코딩 에이전트로 테스트를 진행합니다. 생성된 코드는 기계적 검사와 LLM 기반 심사 기준을 통해 다각도로 평가됩니다.
핵심 포인트
- AI 코딩 에이전트의 디자인 시스템 준수도를 측정하는 벤치마크 제공
- 고정 조건 및 의도 수준 프롬프트를 활용하여 현실적인 테스트 환경 구축
- 기계적 검사와 LLM-as-judge를 결합한 다층적 평가 방식 적용
- 시스템별, 컨텍스트 레벨별 성능 매트릭스를 통해 회귀 현상 추적 가능
당신의 디자인 시스템은 AI 준비가 되어 있습니까? 컴포넌트 라이브러리를 대상으로 코딩 에이전트를 실행하고 결과를 평가하는 플러그인 벤치마크입니다. 프로덕션 디자인 시스템을 기반으로 구축되었으며 모든 React + TypeScript 컴포넌트 라이브러리에 일반화하여 사용할 수 있습니다.
"Design Systems Need Evals"의 방법론에 따라, AI 코딩 에이전트가 사용자의 디자인 시스템을 얼마나 잘 따르는지 벤치마크합니다. 이를 위해 고정된 조건(held-constant)과 의도 수준 작업 프롬프트(예상 컴포넌트를 절대 명시하지 않는 숨겨진 정답, hidden ground truth)를 격리된 피처 워크스페이스(isolated fixture workspace) 내부에서 헤드리스 코딩 에이전트(headless coding agent)를 통해 실행합니다. 그리고 생성된 코드는 시스템의 실제 컴포넌트 API 및 토큰에 대한 기계적 검사(mechanical checks)와, 파서가 판단할 수 없는 판단 영역에 대한 LLM 기반 심사 기준(LLM-as-judge rubrics)을 통해 평가됩니다.
헤드라인 출력은 매트릭스 형태입니다: 시스템 × 컨텍스트 레벨 × 모델로 구성되어 있으며, *"각 에이전트 컨텍스트 레이어(없음 → AGENTS.md → skills/docs)가 디자인 시스템 준수를 실제로 얼마나 개선하는가?"*에 대한 답을 제공합니다. 이는 시간이 지남에 따라 추적되므로, 문서, 매핑 또는 모델의 회귀 현상이 프로덕션에서의 예상치 못한 문제로 나타나기보다 점수 하락으로 나타납니다.
이 툴은 범용 스타터 설정(generic starter config)(systems.config.json, 채워 넣을 수 있는 단일 플레이스홀더 시스템)과 이를 채우는 init 위자드를 함께 제공합니다. 여기에 있는 어떤 것도 특정 디자인 시스템에 국한되지 않습니다: 사용자의 시스템을 가리키기만 하면 모든 검사, 피처, 그리고 평가기가 사용자 고유의 설정에서 해결됩니다.
에이전트가 구축한 결과물의 스크린샷 갤러리, 네 가지 선택적 하드 태스크(opt-in hard tasks), 그리고 매우 기본적인 실행 결과를 보여줍니다. 자세한 내용은 CHANGELOG.md를 참고하세요.
UI 갤러리.gallery [<runDir>...]는 모든 'OK' 셀을 빌드하고 헤드리스 크롬으로 캡처하며, 컨텍스트 레벨 및 반복(rep)별로 점수와 나란히 스크린샷을 배치합니다. 여기에는 태스크 선택기(task picker), 게이트 필터(gate filter), 그리고 크기 슬라이더가 있습니다. 점수가 81점인데 빈 페이지를 렌더링하는 셀도 마침내 그 모습 그대로 보이게 됩니다.하드 태스크, 선택적.tasks/hard/
확정적인 파괴적 액션이 있는 일괄 선택 기능, 모든 로딩 상태에서 비동기 조회(async lookup), 저장되지 않은 변경 사항 방지 기능이 있는 인플레이스 편집(in-place editing), 그리고 키보드 기반 액션 찾기 기능을 추가했습니다. --hard
또는 hard 프로필에는 이들이 포함됩니다.Bare는 순수함을 의미합니다. 셀은 더 이상 운영자의 ~/.claude/CLAUDE.md, 스킬(skills), 훅(hooks) 또는 메모리, 그리고 이 저장소 자체의 지침을 볼 수 없습니다. 이전 기준선과 비교할 때 이를 염두에 두십시오.추출 및 채점(Extraction and grading). 컴포넌트를 컴파일하는 프로젝트에는 Vite 스타일 솔루션인 tsconfig.json이 적용되며 (또는 tsconfig 설정), tokenDiscipline은 .css와 .scss를 읽습니다. 게이트웨이(Gateways). 긴 단일 샷 생성 시 타임아웃되는 게이트웨이 제공자에는 "stream": true가 사용됩니다; pricing-catalog.json은 실제 max_tokens와 가격을 공급합니다.
각 셀은 EvalResult를 생성합니다 (이는 eval-harness/의 동일한 Gate /score 계약과 같습니다):
| 차원(Dimension) | 가중치(Weight) | 확인 내용(What it checks) | 하드 게이트(Hard gate) |
|---|---|---|---|
| imports | 0.10 | 시스템 패키지, react, 로컬 파일만 가져오는지 여부 | 외부 UI 라이브러리 → 검토/실패 |
| apiFidelity | 0.25 | 환각된 컴포넌트가 없는지 (imports ⊆ extracted catalog), 발명된 prop이 없는지, 선택적 교차 시스템 오염 센티넬(예: iconStart 대 iconLeading, 여러 시스템을 나란히 벤치마킹할 때만 관련 있음) | 환각된 컴포넌트 → 실패 |
| tokenDiscipline | 0.15 | 원시 헥스/rgb 값, bg-[#…] /w-[137px]와 같은 임의 값, 하드코딩된 인라인 스타일 색상이 없는지, .css /.scss 선언에 원시 값이 없는지 | — |
| a11yStatic | 0.10 | AST 기반 서브셋: 폼 컨트롤/아이콘 버튼의 접근 가능한 이름, img-alt, 양수 tabindex, 키 입력 없이 클릭 가능 여부, 레이블 연결, 유효한 aria-*, autofocus, 앵커 유효성 | — |
| compile | 0.10 | fixture에 대한 tsc --noEmit (시스템 소스에 별칭 지정됨) | 오류 → 실패 |
| judgment | 0.30 | 개별 작업 루브릭을 별도의 모델(claude -p --json-schema, 기본 haiku)이 판단하며, 셀 설정에는 무관함 | 치명적인 루브릭 실패 → 검토 |
Ground truth는 추출되며, 절대 수동으로 작성되지 않습니다: catalogStrategy: "docgen"
runs
react-docgen-typescript over your componentsSrc
(public API = root barrel ∪ package.json subpath
exports); catalogStrategy: "catalog-json"
reads a pre-built machine-readable catalog file your
own repo already ships; catalogStrategy: "stencil"
reads the docs.json
a Stencil build emits
from its docs-json
output target. 파일 기반 전략(file-backed strategies)은 catalogFile에 파일을 지정하며,
추출 과정은 오래된(stale) 파일을 거부합니다. 토큰은 시스템의 foundations CSS(foundationsCss
, 하나의 경로 또는 여러 개의 경로 목록, 선택 사항 — 이를 생략하면 토큰/오염 검사는 단순히 건너뛰고 doctor 경고가 발생합니다).
- node ≥ 20
claude
CLI를 설치하고 로그인해야 합니다 (생성 및 판단 모두 이를 통해 실행됩니다; API 키 불필요)- 디자인 시스템의 레포지토리(들)를 체크아웃하고 자체 의존성을 설치해야 하며 — 경로는 systems.config.json에 선언합니다,
시스템별로 각 항목의 rootEnv를 통해 덮어쓸 수 있습니다.
이 패키지에서 npm install을 실행하세요. npm의 기본 캐시 오류(샌드박스 환경)가 발생하면 --cache .npm-cache를 추가하세요.
또는 수동 편집을 건너뛰고 위자드를 실행합니다.npx tsx src/cli.ts init
시스템(ID, 소비 모드, 패키지 사양 또는 레포 루트, CSS 진입점, 문서 파일, 카탈로그 전략)을 조사하고, systems.config.json에 항목을 작성/병합하며,
만약 비어 있다면 tasks/에 세 가지 시작 작업을 구성(scaffold)하고, doctor 등급의 ok/warn 검사 및 다음 단계를 출력합니다. 이 과정은 설정 내 다른 시스템을 절대 덮어쓰거나 기존 작업 스위트를 덮어쓰지 않습니다. (위자드 로직은 src/init/wizard.ts에 있으며; init CLI 명령어는 플래그를 여기에 연결합니다.) -
하네스(harness)를 디자인 시스템으로 지정하세요.systems.config.json을 편집하세요.
— 이 파일은 `
's profiles'"systems" 리스트가 동기화됩니다.
npm run doctor # 구성된 시스템(system), 카탈로그, claude CLI, 태스크 스위트 확인
npm run extract # 시스템의 레포지토리에서 catalogs/ 및 tokens/ 재생성
npm run validate-tasks # 태스크 스위트 린팅 (프롬프트 누출 검사 포함): ten domain-neutral
...
아래 프로필 테이블의 셀 카운트는 기본 단일 시스템 템플릿을 가정합니다. 각 프로필의 "systems" 배열(bench.config.json 내)이 실제 승수(multiplier)를 결정하므로, 여러 시스템을 한 번에 벤치마킹하려면 여기에 더 많은 시스템을 추가하거나 (--systems a,b 를 전달) 할 수 있습니다.
| 필드 (Field) | 필수 여부 (Required) | 의미 (Meaning) |
|---|---|---|
root | 예 (yes) | 시스템 레포지토리 체크아웃의 절대 경로 (Absolute path to the system's repo checkout) |
rootEnv | 예 (yes) | root를 재정의할 수 있는 환경 변수 이름 (예: CI용) |
componentsSrc | 예 (yes) | 컴포넌트 소스 디렉터리 경로 (root 기준 상대 경로) |
componentsPkg / foundationsPkg | 예 (yes) | 시스템의 컴포넌트/토큰이 가져오는 npm 패키지 이름 |
foundationsCss | 아니요 (no) | foundations CSS 토큰을 파싱하는 경로, 또는 시스템이 카테고리별로 파일을 분할하는 경우의 경로 목록 (하나의 연결된 문서로 읽음); 없음은 생략 가능 |
catalogStrategy | 예 (yes) | "docgen" (react-docgen-typescript를 통해 추출), "catalog-json" (미리 구축된 카탈로그 파일 읽기), 또는 "stencil" (Stencil 빌드가 내보내는 docs.json 읽기) |
catalogFile | catalog-json 및 stencil | 미리 구축된 카탈로그 JSON의 경로, 또는 Stencil의 docs.json 경로 |
tsconfig | 아니요 (no) | tsconfig가 컴파일되는 경로 |
agentContext.agentsMd: componentsSrc 위에 있는 가장 가까운 tsconfig.json을 기본값으로 사용합니다. 솔루션 스타일(Vite의 "files": []와 references를 결합한 방식)은 componentsSrc를 포함하는 참조를 따르며, 이름이 지정된 경고가 발생합니다 |
agentContext.skillDirs / agentContext.extraDocs: 예 | 파일은 컨텍스트 레벨 agents-md에서 AGENTS.md /CLAUDE.md로 복사됩니다 |
contamination: 아니요 | 크로스 시스템 센티넬 속성(sentinel props) + 타이포그래피 케이싱 — 2개 이상의 시스템을 구성했을 때만 의미가 있습니다 |
fixtureTemplate: 아니요 | 이 시스템의 피처(fixture) 템플릿 앱 경로. 소스 모드는 fixtures/<systemId>-app으로 폴백하고, 그 다음 일반적인 fixtures/source-app을 사용합니다. npm 모드는 fixtures/npm-app을 사용합니다 |
consume: 아니요 | "source" (기본값) 또는 "npm" — 아래 npm-consume 모드를 참조하십시오 |
componentModel: 아니요 | "react" (기본값) 또는 웹 컴포넌트를 배포하는 시스템용 "custom-elements" (Stencil, Lit, 사용자 정의 요소 레지스트리 등) — 아래 웹 컴포넌트 시스템을 참조하십시오 |
packageSpec: npm 전용 | npm install spec, 예: "@acme/ui" 또는 "@acme/ui@^2.0.0" ; 기본값은 componentsPkg입니다 |
cssEntry: 아니요 | 시스템의 스타일시트 임포트 지정자, 예: "@acme/ui/styles.css" ; 선택 사항이며, npm 모드에서만 사용 가능합니다 |
fixturePins: 아니요 | 피어 의존성 충돌을 위해 packageSpec과 함께 설치되는 추가 npm spec (예: 템플릿이 React 19를 사용하는 경우, 여전히 React 18에 있는 라이브러리는 ["react@^18.3.1", …]가 필요합니다) |
a11y: 아니요 | a11yStatic grader용 접근성 이름 어휘집 (controls, iconOnly, labels, formContext, placeholderNamed). 기존 기본값과 병합되므로, 차이가 있는 것만 선언하십시오 |
consume: "npm"은 로컬에서 체크아웃(또는 할 수 없는) 디자인 시스템, 즉 게시된 패키지만 가지고 있는 경우를 위한 것입니다. 픽스처를 소스 트리("source" 기본값)에 별칭 지정하는 대신, prepareTemplate이 일반적인 fixtures/npm-app을 복사합니다.
템플릿을 시스템별 준비된 작업 공간(fixtures/.prepared/<systemId>-app, gitignore됨)으로 구성하고 두 번의 npm install을 실행합니다. 첫 번째는 템플릿 자체 의존성(react, vite 등)에 대한 설치이며, 다음은 packageSpec(또는 packageSpec이 생략된 경우 componentsPkg)에 대한 설치입니다. 그 이후부터 provisionWorkspace는 "source" 모드에서와 정확히 동일하게 이 준비된 디렉터리에서 작동합니다. 가져오기(import) 경로는 실제 node_modules를 통해 해결되므로, __SYSTEM_ROOT__ 치환이 필요 없습니다. 만약 cssEntry가 설정되어 있다면, src/main.tsx가 이를 가져옵니다. 이 값이 생략된 경우, 해당 자리 표시자(placeholder) import 라인은 남아있지 않고 제거됩니다.
패키지의 피어 의존성(peer dependencies)이 템플릿의 React 버전과 충돌하는 경우, fixturePins를 설정하여 패키지와 함께 해결되는 추가 설치 사양을 지정할 수 있습니다. 여전히 React 18에 있는 라이브러리가 있다면, 다음과 같이 템플릿의 React 19와 연결(pinning)해야 합니다:
"fixturePins": ["react@^18.3.1", "react-dom@^18.3.1", "@types/react@^18.3.12", "@types/react-dom@^18.3.1"]
{
"systems": {
"acme": {
...
npm 모드에서는 여전히 root가 중요합니다. 이는 agentContext.agentsMd/skillDirs/extraDocs를 읽어오는 위치이기 때문입니다. 이제 이 경로는 더 이상 디자인 시스템 자체의 저장소일 필요는 없습니다. 이 시스템에 대한 AGENTS.md/README.md 스타일의 가이드를 보관하는 곳이라면 어디든 지정할 수 있습니다 (init 위자드는 기본값으로 현재 디렉터리를 사용합니다). catalogStrategy는 여전히 "docgen", "catalog-json" 또는 "stencil" 중 하나여야 합니다 (스키마에 "none"은 없습니다). 아직 추출 전략을 결정하지 못했다면, init은 스키마 유효성(schema-valid) 자리 표시자로 "docgen"을 유지하고, extract가 유용한 작업을 수행하기 전에 편집이 필요하다는 경고를 크게 띄웁니다.
시스템이 React 컴포넌트 대신 웹 컴포넌트를 배포하는 경우 (Stencil, Lit, 수동으로 작성된 커스텀 요소 레지스트리 등), "componentModel": "custom-elements"로 설정합니다. 이러한 시스템의 소비자들은 번들을 한 번 등록한 다음 <ds-button>과 같이 사용합니다.
태그로 사용하며, 컴포넌트별 임포트는 필요 없음
어디서든, 그리고 이 하네스(harness)는 다음과 같이 알려줘야 합니다: 사용 감지(usage detection)가 그렇지 않으면 componentsPkg에서 가져온 임포트에 고정되어 있다는 것을
따라서 완벽한 답변은 "design-system 컴포넌트를 사용하지 않음"으로 인해 apiFidelity에서 0점을 받게 됩니다.
이 플래그는 테스트 환경(fixture)을 일반적인 fixtures/custom-elements-app으로 전환하고, apiFidelity가 카탈로그와 대조하여 점선 JSX 태그를 해결하게 하며, 프로비저닝(provisioning)이 모든 요소와 해당 요소가 허용하는 속성을 선언하는 src/system-elements.d.ts 파일을 생성하도록 합니다. 따라서 태그는 타입 검사(typecheck)가 가능하고, 임의로 만든 속성 값은 compile 게이트를 통과하지 못합니다. 이러한 선언들이 추출된 카탈로그에서 오기 때문에, run 전에 extract를 실행해야 합니다.
이것은 catalogStrategy와 독립적입니다: `
AI 자동 생성 콘텐츠
본 콘텐츠는 GitHub Codex tools의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기