Vercel에서 에이전트에게 제품 디자인을 가르치는 방법
요약
Vercel은 코딩 에이전트가 제품의 디자인 의도와 컨텍스트를 이해할 수 있도록 `.product-design` 시스템을 도입했습니다. 이 시스템은 디자인 결정 사항을 코드처럼 저장소에 관리하여 에이전트가 제품 스타일과 규칙을 학습하고 준수할 수 있게 합니다.
핵심 포인트
- 에이전트에게 코드 외의 디자인 컨텍스트(의도, 패턴)를 제공하는 방법 제시
- .product-design 시스템을 통한 디자인 결정 사항의 코드화 및 저장소 관리
- SKILL.md를 활용한 요청 모드(형태, 구현, 검토 등) 정의 및 작업 최적화
- 컴포넌트 API, 디자인 시스템 규칙 등을 정전 소스(canonical sources)로 라우팅
- 에이전트의 결과물이 디자인 표준을 준수하도록 추적 가능한 구조 구축
코딩 에이전트(Coding agents)는 작동하는 UI를 빠르게 만들어낼 수 있지만, 더 어려운 것은 다른 형태의 문제입니다. 에이전트는 제품의 스타일을 복제하고, 패턴을 맞추며, 컨벤션(conventions)을 따르려고 노력할 수 있습니다. 하지만 그들이 할 수 없는 것은 왜 그러한 패턴이 존재하는지 이해하는 것입니다. 코드는 에이전트에게 무엇이 출시되었는지는 보여주지만, 왜 특정 컴포넌트, 문구, 또는 상호작용(interaction)이 표준이 되었는지는 보여주지 않습니다. 그러한 추론은 디자인 리뷰(design reviews), PR 코멘트, Slack 스레드, 그리고 그 자리에 있었던 사람들에게 존재합니다. 에이전트에게 코드베이스(codebase)에 없는 컨텍스트(context)는 존재하지 않는 것과 같습니다.
Vercel은 에이전트 네이티브(agent-native) 팀입니다. 우리는 승인된 제품 결정 사항을 코드처럼 취급하여 저장소(repository)에 보관하고, 이를 기준으로 변경 사항을 검토하며, 그곳에서 작업하는 모든 에이전트가 사용할 수 있도록 합니다.
우리는 이를 .product-design을 통해 수행합니다. 이는 세 가지 부분으로 구성된 시스템입니다.
어떤 팀이든 자신들만의 표준을 바탕으로 동일한 구조를 구축할 수 있습니다.
기술(skill)은 그것이 관리하는 코드와 함께 저장소 내부에 존재합니다. 다음은 그 구조의 단순화된 모습입니다:
SKILL.md는 요청 모드(request mode)를 먼저 해결합니다: 형태(shape), 구현(implement), 검토(review), 복제(copy), 또는 강화(harden). 이를 통해 감사(audits)가 수정(edits)으로 변질되는 것을 방지하고, 복제 작업(copy passes)이 재설계(redesigns)로 확장되는 것을 막습니다. 또한 백엔드 전용 작업, 텔레메트리(telemetry), 콘솔 에러, 생성된 파일, 그리고 출시된 UI에 영향이 없는 테스트는 건너뜁니다.
기술은 정보를 중복 생성하는 대신 정전(canonical) 소스로 라우팅(routing)합니다. 컴포넌트 API(Component APIs), 디자인 시스템 규칙(design-system rules), 접근성 기준(accessibility criteria), 그리고 상호작용 가이드(interaction guidance)는 각각의 소유자와 함께 유지됩니다.
라우팅은 작업(task)과 표면(surface) 모두에 대해 구체적입니다. 실질적인 변경 사항은 제품 판단(product-judgment)과 인터페이스 품질(interface-quality)을 먼저 로드합니다. 문구(copy), 컴포넌트(component), 레이아웃(layout), 상호작용(interaction), 접근성(accessibility), 그리고 회복 탄력성(resilience)은 각 경로에 따라 집중된 참조 자료로 연결됩니다. 모달(modal)은 파괴적 작업 패턴(destructive-action patterns)과 정전 동사(canonical verbs)를 로드합니다. 설정 양식(settings form)은 레이블(labels), 유효성 검사(validation), 점진적 공개(progressive disclosure), 그리고 접근 가능한 이름(accessible-name) 가이드를 로드합니다.
이 단순화된 구조를 시작점으로 사용할 수 있으며, 경로와 표준을 여러분의 것으로 교체할 수 있습니다:
라우팅 (Routing)은 이 기술을 유용하게 만드는 요소의 일부일 뿐입니다. 다른 한 가지 요소는 기술이 결과물을 생성했을 때 그 발견 사항들이 어떻게 추적 가능하게 유지되느냐 하는 점입니다.
복사 규칙 (Copy rules)은 안정적인 ID를 가지며 정식 소스 (canonical sources)를 가리킵니다:
[IMG:1]
Vercel Agent가 패치 (patch)를 제안할 때, 제안을 게시하기 전 해당 저장소의 빌드 (builds), 테스트 (tests), 린터 (linters)가 포함된 보안 Vercel Sandbox 환경에서 변경 사항을 검증합니다.
린터 (Linter)가 규칙을 안정적으로 강제할 수 있는 경우에는 결정론적 검사 (deterministic checks)를 선호합니다. 린터는 실행 속도가 빠르고 비용이 저렴하므로, 개발자와 코딩 에이전트 (coding agents)는 나중에 리뷰를 기다리는 대신 작업하는 동안 즉각적인 피드백을 받을 수 있습니다.
코드는 두세 개의 정적 옵션을 셀 수 있으므로, 린터가 라디오 버튼 (radio buttons)을 추천할 수 있습니다. 파괴적인 작업 (destructive action)에 대해 적절한 객체와 결과를 명명하는 데는 제품 컨텍스트 (product context)가 필요하므로, 기술 (skill)이 이를 처리합니다.
코드베이스의 예시에는 다음과 같은 규칙들이 포함되어 있습니다:
[IMG:2]
각 규칙은 왜 해당 패턴이 문제인지 설명하고 구체적인 수정 방법을 제안합니다. 일부 규칙은 권장되지 않는 (deprecated) Tailwind 유틸리티 이름을 교체하는 것과 같이 안전한 마이그레이션 (migrations)을 자동으로 수정 (autofix)합니다.
수용된 결정 (Accepted decisions)은 여러 가지 형태를 취할 수 있습니다:
[IMG:3]
아래의 린트 규칙 (lint rule)은 하나의 제품 가이드라인이 어떻게 결정론적 검사로 인코딩되는지 보여줍니다:
[IMG:4]
이 각각의 규칙은 특정 유형의 실수를 자동으로 잡아내어, 실제 판단이 필요한 결정들을 위한 코드 리뷰 (code review) 시간을 확보해 줍니다.
린트 규칙은 결정론적이지만, 에이전트 (agent)의 행동은 가변적일 수 있으므로, 이전에 본 적 없는 인터페이스 (interfaces)에서 기술을 테스트합니다.
[IMG:5]
에이전트가 이전 상태 (before state)를 편집하면, 심판 (judge)이 루브릭 (rubric)에 따라 결과를 확인합니다.
평가 (Evals)는 기술에 문서화된 출시된 예시 (shipped examples)에서 가져옵니다. 홀드아웃 (Holdouts)은 예상되는 편집 내용을 숨겨서 가이드라인이 일반화될 수 있는지 테스트합니다. 또한 기술을 적용하지 않은 상태에서 픽스처 (fixtures)를 실행하여 기술이 에이전트의 행동을 변화시켰는지 측정합니다.
우리는 규칙의 정확도 (rule correctness)를 출시된 결과물과의 유사성 (similarity)과 별도로 점수를 매깁니다. 출시된 코드에는 에이전트가 그대로 재현하는 대신 개선해야 할 결함이 포함되어 있을 수 있기 때문입니다.
제품 표준은 컴포넌트 (components), 이름, 워크플로 (workflows), 실패 상태 (failure states)가 변함에 따라 변경되며, 모든 업데이트에는 증거와 인간의 검토 (human review)가 필요합니다.
우리의 주간 증거 수집 워크플로우 (evidence-intake workflow)는 제품 디자인을 개선할 수 있는 디자인 피드백을 수집합니다. 이 워크플로우는 Slack 대화를 검색하고 Figma 파일, 풀 리퀘스트 (pull requests), 리뷰 코멘트 (review comments), 프리뷰 (previews)에 대한 링크를 증거로서 보존합니다. 증거가 불완전할 경우, 검증에 필요한 코드나 커밋 (commit)을 기록합니다. product-design
이 워크플로우는 수집과 판단을 분리합니다:
모든 후보는 출처와 연결되며 대기 (pending) 상태로 유지됩니다. 숙련된 리뷰어의 코멘트는 후보의 우선순위를 높일 수 있지만, 모든 후보는 여전히 증거가 필요합니다.
자동화는 리뷰 패킷 (review packet) 단계에서 종료됩니다. 후보가 에이전트 가이드라인 (agent guidance), 린트 규칙 (lint rule), 예시 (example), 평가 (eval), 또는 변경 사항 없음 중 무엇이 될지는 사람이 결정합니다. 승인된 변경 사항은 가장 관련성이 높은 파일에 반영되며, 머지 (merging) 전 관련 체크를 통과해야 합니다.
우리의 설정은 Vercel의 제품, 컴포넌트 (components), 그리고 리뷰 이력을 반영하지만, 다른 팀들도 이 구조를 자신들의 표준에 맞게 조정할 수 있습니다.
동일한 리뷰 코멘트가 반복적으로 나타나는 하나의 제품 접점 (product surface)을 선택하세요: 파괴적인 동작 (destructive actions), 에러 상태 (error states), 설정 양식 (settings forms), 빈 상태 (empty states), 또는 네비게이션 (navigation). 출시된 코드와 실제 리뷰에서 사례를 수집하고, 결정 사항, 그것이 중요한 이유, 예외 사항, 그리고 출처를 기록하세요.
clear, polished, 또는 intuitive와 같은 광범위한 형용사로 시작하는 것을 피하세요. 에이전트에게는 관찰 가능한 결정이 필요합니다. is usable은 관찰할 수 없지만, is not은 관찰 가능합니다. Destructive actions use Verb + Noun이나 Buttons should be clear와 같이 작성하세요.
다른 영역으로 확장하기 전에 선택한 접점에 특화된 필드들을 먼저 채우세요.
지속적인 리포지토리 지침 (persistent repository instructions)에 에이전트가 언제 해당 기술 (skill)을 로드해야 하는지 명시하고, 해당 기술이 다루는 파일과 접점, 그리고 건너뛰어야 하는 영역을 정의하세요. separate Next.js evals 사례에서 에이전트는 56%의 경우에서 사용 가능한 기술을 호출하는 데 실패했습니다. 기술을 로드하는 데 실패하는 것과 규칙을 따르는 데 실패하는 것은 서로 다른 문제이므로, 트리거 (trigger)를 가이드라인과 분리하여 별도로 테스트하세요. separate Next.js evals
에이전트에게 어떤 표면(surface)과 참조(reference)를 로드했는지 보고하도록 요청한 다음, 그 결과가 해당 소스들을 인용하고 있는지 확인하세요.
짧은 진입점(entry point)을 사용하여 표면을 식별하고 집중된 참조를 로드하세요. 세부 사항은 검토자들이 이미 논의하고 있는 표면 및 결정 사항들을 중심으로 구성하세요: 폼(forms), 모달(modals), 내비게이션(navigation), 제품 어휘(product vocabulary), 워크플로 상태(workflow states), 그리고 교차 표면 패턴(cross-surface patterns) 등이 있습니다.
규칙(rules)에 안정적인 ID를 부여하고 이를 예시 및 소스와 연결하세요. 유용한 결정 사항과 알려진 결함이 모두 포함된 출시된 예시들을 기록하고, 누락된 가이드는 커버리지 격차(coverage-gap) 목록에 명시적으로 유지하세요.
커버리지 격차 목록은 누락된 가이드를 명확하게 드러내 줍니다.
린터(linter)가 문제를 안정적으로 식별할 수 있다면, 해당 위치에서 규칙을 강제하세요. 결정에 제품 또는 코드베이스의 컨텍스트(context)가 필요한 경우에는 에이전트 가이드(agent guidance)를 사용하세요. 새로운 표준, 정책 선택, 그리고 해결되지 않은 제품 결정 사항은 사람의 영역으로 남겨두세요.
문서화된 예시와, 예상되는 편집 사항이 스킬(skill)에 나타나지 않는 인터페이스의 홀드아웃(holdouts)으로부터 훈련용 피스처(training fixtures)를 구축하세요. 검색(retrieval)과 적용(application)을 분리하여 테스트하세요. 에이전트가 스킬을 로드했는지 여부와 규칙을 따랐는지 여부는 서로 다른 질문이기 때문입니다.
만약 규칙이 수많은 예외 사항 없이는 안정성을 유지할 수 없다면, 다시 에이전트 가이드로 이동시키세요.
새로운 증거를 정기적으로 검토하되, 가이드나 체크 사항을 변경하기 전에는 반드시 사람의 승인을 거치도록 하세요. 무엇이, 왜 변경되었는지, 그리고 어떤 소스가 이를 뒷받침했는지를 기록하는 결정 로그(decision log)를 유지하세요. 새로운 규칙을 제품 변경 사항으로 취급하여 각각을 검토 및 테스트하고, 더 이상 도움이 되지 않는 규칙은 제거하세요.
하나의 표면과 팀이 이미 반복하고 있는 결정 사항부터 시작하세요. 그러한 결정 사항들을 코드가 작성되고 검토되는 곳에 배치하고, 무엇이 표준이 될지에 대한 책임은 사람이 갖도록 하세요.
가장 어려운 부분은 첫 번째 표면을 선택하는 것입니다. 모든 팀에는 인코딩할 가치가 있는 결정 사항들이 있습니다. 문제는 그것들이 누군가의 머릿속에 머물러 있는지, 아니면 에이전트가 찾을 수 있는 어딘가에 있는지입니다. 이 패턴을 사용하여 무언가를 구축했거나 저희가 이를 설정한 방식에 대해 궁금한 점이 있다면 알려주세요.
-
제품 또는 코드베이스에 대한 판단이 필요한 결정의 배경 맥락을 코딩 에이전트에게 제공하는 에이전트 기술 (agent skill).
-
명확한 규칙을 자동으로 강제하는 린터 (Linters).
-
Slack, Figma, GitHub에서 증거를 수집한 다음, 검토를 위한 가이드라인 업데이트를 준비하는 검토 루프 (review loop).
-
수집기 (collector)는 규칙을 제안하지 않고 메시지, 링크 및 주변 맥락을 수집합니다.
-
별도의 판단자 (judge)가 증거를 그룹화하고, 출처를 확인하며, 미결 질문을 기록합니다.
-
작업 (job)은 후보군, 거부된 주제, 후속 요청 및 커버리지 격차 (coverage gaps)를 포함한 검토 패킷을 생성합니다.
제품 디자인 기술 (product-design skill) 내부
더 빠른 피드백을 위한 린터 (linters) 활용
평가 (evals)를 통한 가이드라인 테스트 방법
가이드라인 최신 상태 유지하기
코드베이스에 제품 디자인을 구축하는 방법
직접 구축하기
-
AGENTS.md는 리포지토리가 코딩 에이전트에게 언제 기술을 로드할지 알려줍니다.SKILL.md는 로드 순서, 검증 및 거버넌스를 정의하며, 런타임 워크플로 (runtime workflow)를 소유합니다. -
references/는 제품 판단 (product-judgment), 인터페이스 품질 (interface-quality), 회복탄력성 (resilience), 카피 (copy), 표준 제품명 (canonical product names), 상호작용 패턴 (interaction patterns) 및 특정 표면 관련 결정 사항을 저장합니다. -
exemplars/는 배포된 풀 리퀘스트 (pull requests)에서 반복할 가치가 있는 결정 사항과 피해야 할 실수를 문서화합니다.coverage-gaps.md는 아직 표준이 없는 영역을 나열합니다. -
copywriting-eval/은 카피 및 인터페이스 언어 동작을 테스트합니다. 이는 더 광범위한 제품 디자인 워크플로를 평가하지는 않습니다. -
포커스 관리 (focus management), 키보드 내비게이션 (keyboard navigation), 레이어링 (layering)을 방해하는 중첩 모달 (nested modals) 방지.
-
2~3개의 정적인 옵션이 있는 경우, 모든 선택지가 계속 보이도록 셀렉트 (select) 대신 라디오 버튼 (radio buttons) 권장.
-
아이콘 버튼 (icon buttons) 및 폼 컨트롤 (form controls)에 접근 가능한 이름 (accessible names)을 요구하며, 공유 포커스 토큰 (shared focus tokens)을 우회하는 커스텀 포커스 링 (custom focus rings) 거부.
-
레이아웃 클래스 (
className)는 허용하되, 디자인 시스템 컴포넌트 (design-system component)의 색상 (color), 반경 (radius), 또는 그림자 (shadow)를 덮어쓰는 것 방지. -
콘텐츠가 길어질 경우 올바르게 스크롤되고 헤더 (headers)와 푸터 (footers)가 스티키 (sticky) 상태를 유지할 수 있도록 요구.
Modal.Body -
가공되지 않은 그림자 (raw shadows)를 테마 인지형 (theme-aware) Material 클래스로 교체하고, Material의 내장 처리 (built-in treatment)를 중복하는 테두리 (borders) 거부.
-
4px 그리드 (4px grid)에서 벗어나는 임의의 간격 (arbitrary spacing)을 플래그 (flag)하고, 표준 유틸리티 (standard utility)가 존재하는 경우 이를 제안.
-
관련 Geist 컴포넌트 옆에 배치된 사람이 읽을 수 있는 가이드 (Human-readable guidance), 예: Checkbox best practices
-
스킬 (skill) 내의 에이전트 가이드 (Agent guidance).
product-design. -
코드가 이를 안정적으로 확인할 수 있을 때의 린트 규칙 (lint rule).
스킬이 라우팅 (routes)되는 방식
발견 사항을 추적 가능하게 만들기 (Make findings traceable)
1. 반복되는 결정부터 시작하기
2. 명시적인 트리거 (trigger)와 확고한 경계 추가하기
3. 라우팅 (routing), 규칙 (rules), 증거 (evidence) 분리하기
4. 명확한 규칙을 위해 코드 사용하기
5. 소유권 할당 및 업데이트 루프 (update loop) 구축하기
AI 자동 생성 콘텐츠
본 콘텐츠는 Vercel AI의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기