에이전트 사용을 위한 디자인 시스템
이 스킬은 설계 결정을 안내할 뿐, 강제하지 않습니다. 모든 권장 사항은 합법적인 프로젝트 목표(전문가의 표현력, 브랜드 요구, 플랫폼 제약, 기존 관례)에 의해 무효화될 수 있습니다. 트레이드오프를 명시하고 의도적으로 반대되는 선택을 한 경우 이를 존중하십시오. 예시는 React와 TypeScript로 제공됩니다. 이는 모델 사전이 가장 선명한 스택이기 때문이며, 원리는 모든 스택에 적용됩니다.
목표
코드 생성 모델은 샘플러입니다. 훈련에서 학습한 내용(사전)과 세션에 있는 내용(문맥)을 기반으로 가장 그럴듯한 프로그램을 방출하고, 실행 가능한 검사를 통과한 것만 유지합니다. 인간 우선 API는 "올바른 것을 표현할 수 있는가?"를 묻습니다. 에이전트 우선 API는 "올바르게 보이는 모든 것 중에서 얼마나 많은 것이 실제로 올바른가?"를 묻습니다. 따라서 목표는 두 가지입니다. 가장 그럴듯한 프로그램을 올바르게 만들고, 그렇지 않은 프로그램은 배포되기 전에 실패하게 만드는 것입니다.
이것은 두 가지 더 엄격한 가정 하에서의 일반적인 API 설계입니다(Bloch의 "올바르게 사용하기 쉽고, 잘못 사용하기 어렵게", Minsky의 "불법 상태를 표현 불가능하게", 성공의 구덩이). 소비자의 친숙도는 공개 코드에 대한 측정 가능한 분포이며, 소비자는 실행할 수 있는 것만 검증합니다.
소비자의 세 가지 속성
아래의 모든 내용은 이 세 가지 속성에서 파생됩니다. 결정에 중요하거나 로컬 측정이 필요할 때는 증거 원장을 읽으십시오. 출처, 범위 주의사항, 측정 프로토콜이 있습니다.
-
사전은 빈도 기반이고, 버전이 혼합되어 있으며, 패치할 수 없습니다. 모델은 훈련 데이터에 나타난 빈도에 비례하여 패턴을 알게 됩니다. 정확도는 코퍼스 빈도에 따라 로그-선형으로 증가합니다. 라이브러리의 모든 버전이 하나의 분포로 중첩되기 때문에, 모델은 25~38%의 확률로 더 이상 사용되지 않는 API를 방출하고 버전이 고정된 작업에서 약 50%의 정확도를 보입니다. 라이브러리가 제공하는 어떤 것으로도 이것을 수정할 수 없습니다. 일치시키거나 재정의하는 것만 가능합니다.
-
문맥은 사전을 재정의하지만, 실제로 존재하는 문맥만 재정의합니다. 오래된 코드에서 가져온 프롬프트는 70
90%의 더 이상 사용되지 않는 사용법을 생성했지만, 최신 코드에서 가져온 프롬프트는 918%에 그쳤습니다. 파일 내의 형제 코드는 라이브러리가 게시한 어떤 것보다 출력을 더 강력하게 조종합니다. 검색된 문서는 도움이 되지만, 버전 레이블만 있는 것은 거의 도움이 되지 않습니다. 에이전트가 로드하지 않는 게시된 문서는 아무 효과가 없습니다. -
실행 가능한 피드백만이 검증입니다. 타입 체커는 결정론적이고 저렴하며 항상 루프 안에 있습니다. LLM이 생성한 TypeScript의 컴파일 오류 중 94%가 타입 오류이므로 많은 것을 잡아냅니다. 렌더링은 비용이 많이 들고 설정이 필요하며, 스크린샷이 있더라도 비전-언어 레이아웃 판단은 약합니다. 타입이 인코딩하지 않은 것은 모델이 잘못 이해하면 그대로 배포됩니다.
두 가지 결과가 있습니다. 오류 비용은 비대칭입니다. 인간은 잘못된 간격을 보고 몇 초 안에 수정하지만, 에이전트의 잘못된 간격은 그대로 배포됩니다. 따라서 "수정하기 쉬운 것"은 "잘못 사용하기 어려운 것"보다 훨씬 가치가 떨어집니다. 그리고 진화는 추가적이어야 합니다. 이름 바꾸기나 의미 변경은 다음 훈련 실행까지 에이전트에게 비용이 발생하고 이전 형태는 분포에서 완전히 사라지지 않습니다. 따라서 변경이 불가피하다면, 마이그레이션을 체인지로그가 아닌 타입과 함께 위치한 문서에 넣으십시오.
세 가지 전략
모든 설계 레버는 이 중 하나입니다. 설계를 평가할 때, 어떤 전략을 사용하고 어떤 전략을 훼손하는지 물어보십시오.
전략 1: 기본 추측을 올바르게 만들기
에이전트의 첫 번째 추측은 사전과 가시적인 문맥의 조합입니다. 두 가지가 이를 형성합니다.
이름은 분포에 대한 베팅입니다. 이름의 가치는 선명도와 일치도의 곱입니다. 공개 사용에서 얼마나 단일 의미를 가지는지, 그리고 그 의미가 당신의 의미와 일치하는지입니다. 선명도는 코퍼스 크기, 연령, 안정성을 따르므로 HTML 및 CSS 사양 어휘가 ARIA 패턴 이름보다, ARIA 패턴 이름이 범-라이브러리 단어(sm/md/lg, primary/danger, solid/outline/ghost)보다, 그리고 범-라이브러리 단어가 특정 라이브러리 숙어보다 강합니다. 의미가 허용하는 한 가장 깊은 곳에 닻을 내리십시오. 일치도는 이진입니다. 익숙한 이름이 다른 동작을 가지는 것이 최악의 경우입니다. 모델은 학습된 의미를 확신하며 적용하고 코드는 컴파일됩니다. 선명한 이름이 당신의 의미와 일치하지 않으면, 학습된 문법에서 새로운 이름을 조합하십시오. Page/PageHeader/PageTitle은 주요 라이브러리에 존재하지 않지만, X/XHeader/XTitle 접합은 계층과 자식 순서를 무료로 전달하며 자동 완성과 에이전트의 자체 계획에서 발견 가능합니다. 다른 prop에 따라 의미가 달라지는 prop(direction 스위치 아래의 align)은 두 개의 결합된 베팅입니다. 이를 분리하여 축당 하나의 컴포넌트 또는 명시적인 이름으로 만드십시오. 이득은 자유도 하나를 줄이는 것이지, 사전을 구제하는 것이 아닙니다. 모델은 CSS의 자체 축 전환을 잘 처리합니다.
가시적인 코드베이스가 프롬프트입니다. 형제 사용법, 카탈로그, 표준 예제가 에이전트가 실제로 조건으로 삼는 것입니다. 규칙성은 프롬프트를 압축합니다. 모든 컴포넌트가 동일한 어휘로 동일한 축을 접합한다면, 문맥 속의 두 컴포넌트가 전체 카탈로그를 가르칩니다. 모든 동의어나 컴포넌트별 예외는 별도로 가르쳐야 하며, 대개 그렇지 않습니다. 카탈로그는 출력을 분할합니다. 에이전트는 코드를 읽기 전에 "페이지 헤더"나 "툴바"와 같은 단위로 계획하고, 존재하는 모든 것을 통해 계획을 강제합니다. 따라서 컴포넌트 이름을 해당 단위로 지정하십시오. 예제가 보여주는 것이 워크플로가 됩니다. className 재정의도 포함됩니다. 의도된 경로를 보여주고, 예제를 버전에 맞추고 에이전트가 만져야 할 코드와 함께 배치하십시오.
사전의 강점은 에이전트가 작성해야 하는 구문에 순응하는 것을 정당화합니다. 그러나 에이전트가 결정해서는 안 되는 결정을 노출하는 것을 정당화하지는 않습니다. 이것은 전략 3입니다.
전략 2: 잘못된 출력이 배포되기 전에 실패하게 만들기
렌더나 런타임이 잡았을 모든 것은 더 일찍 실패해야 합니다. 그렇지 않으면 배포됩니다.
타입이 표현할 수 있는 곳에는 타입에 넣으십시오. 아무도 설계하지 않은 boolean 조합 대신 닫힌 유니온을 사용하십시오. 모드 종속 props에는 판별 유니온을 사용하십시오. "여기서 사용하지 마세요"라고 문서화하는 대신 부품이 지원하지 않는 것을 Omit하십시오. 소비자에게 맡겨진 의미 동작 레이어(대화 상자 제목, 아이콘 버튼 레이블, 오류 텍스트; Radix와 React Aria는 에이전트가 보지 않는 콘솔에서만 경고함)에는 필수 props를 사용하십시오. asChild/as의 지원되지 않는 경우에 대한 컴파일 오류, 또는 ButtonLink와 같은 명시적인 비-다형성 변형을 만드십시오. 테스트는 매번 동일합니다. prop을 완성하는 에이전트는 합법적인 어휘를 보고, 불법적인 프로그램은 컴파일되지 않습니다.
타입이 표현할 수 없는 곳에는 코드가 작성된 곳에서 발산을 보이게 만드십시오. 이름은 타입이 인코딩하지 않는 레이아웃 기대를 전달합니다. (컨테이너는 자체 패딩을 소유하고, 블록은 부모를 채우며, 간격은 부모 갭에서 옵니다. 사례 연구에 나열되어 있습니다.) 이름이 만드는 기대를 깨는 컴포넌트는 에이전트가 볼 수 없는 한 차원에서 조용히 잘못 컴파일되고 렌더링됩니다. 호출 지점 (필수 prop, 충돌하지 않는 이름) 또는 에이전트가 신뢰성 있게 로드하는 문맥 (코드 옆의 규칙)에서 위반을 신호하십시오. 에이전트가 접하지 않을 문서는 계산하지 않습니다.
전략 3: 결정 제거하기
올바름이 렌더링되어야만 보이는 결정은 호출 지점이 아닌 라이브러리에 속합니다. 네 가지 세분성 수준에서의 한 가지 원칙입니다.
- 값. 모든 크기를 양자화하고 의미적 역할을 통해 모양을 결정하십시오. 호출 지점에서는
gap="3"과tone="danger"를 사용하고, 테마에서는 px와 hex를 사용하십시오. 모델은 flex와 grid 메커니즘을 알지만, 12와 16을 눈으로 보고 선택할 수 없습니다. 독립적인 선택은 파일 전체에 걸쳐 아무도 보지 않는 리듬으로 표류합니다. Spec 키워드 (justify="space-between")는 의미를 자유롭게 유지하면서 스케일이 추측을 제거합니다. - 구성. 위젯뿐만 아니라 레이아웃도 소유하십시오. Braid의 규칙이 깔끔한 버전입니다. 컴포넌트는 외부 공백을 제공하지 않고, 레이아웃 컴포넌트가 모든 간격을 소유합니다. 위젯 경계에서 멈추는 시스템은 모든 호출 지점이 즉흥적으로 만들게 합니다.
- 패턴. 구성이 반복되는 곳 (
FormField,EmptyState,PageHeader,ConfirmDialog)에서는 이를 제공하십시오. 기본 요소에서의 재도출은 매번 발산할 기회입니다. - 적응. 뷰포트, 콘텐츠 길이, 쓰기 방향, 모션 및 대비 선호도, 로딩/빈/오류 상태를 기본적으로 처리하거나 타입에 요구하십시오. 호출 지점의 미디어 로직은 눈먼 결정입니다.
탈출구 (className, style, CSS 변수)는 존재해야 하며, 확률적으로 기본 경로 아래에 있어야 합니다. 사용 가능하고, 순위가 매겨져 있으며, 결코 강조되지 않습니다. 이것들이 시연된 워크플로라면, 전략 1이 이를 기본 추측으로 만들었습니다.
레짐이 가독성 대 계약을 결정합니다
두 가지 일관된 철학이 존재합니다. shadcn이 첫 번째의 가장 명확한 진술입니다.
- 가독성. 소스를 저장소로 제공하십시오. 에이전트가 읽고 편집하며, 스타일링이 작성된 곳에서 보입니다. 에이전트가 컴포넌트를 소유할 때 올바릅니다. 파일을 열 것이며, 읽기 쉬운 구현 (함께 배치된 스타일링, 최소한의 간접 참조)이 필요합니다.
- 계약. 타입이 있는 API를 노출하고 구현을 숨기십시오. 에이전트가 앱 코드에서 컴포넌트를 소비할 때 올바릅니다. 임포트, 타입, 몇 가지 형제 사용법을 보고 구현을 거의 열지 않습니다. 읽기 쉬운 스타일링은 작성하기 쉬운 스타일링이며, 호출 지점 스타일링은 전략 3이 제거하는 엔트로피입니다.
대부분의 시스템은 청중에 따라 둘 다 필요합니다. components/를 유지하는 사람에게는 가독성, 그곳에서 임포트하는 모든 사람에게는 계약입니다. 전략을 적용하기 전에 파일이 어떤 레짐에 있는지 결정하십시오. 시스템이 shadcn을 기반으로 하거나 shadcn과 비교될 때는 shadcn 사례 연구를 읽으십시오. 무엇을 유지하고, 무엇을 변경하며, 그 이유를 설명합니다.
긴장 관계
두 가지이며, 각각 여러 얼굴을 가지고 있습니다. 트레이드오프를 명시하십시오. 공짜인 척 하지 마십시오.
- 집중된 확률 대 표현력. 제거된 모든 자유도는 누군가의 손실된 능력입니다. 이것은 의도 컴포넌트 대 기본 요소, 닫힌 축 대 직교 props, 축 확장 대 축 분할 (각 값이 동일한 질문에 답하는 동안 확장; shadcn의
Button변형은 의도, 처리, 요소 정체성을 융합한 표준적인 융합 축입니다)로 나타납니다. 순위가 매겨진 탈출구가 일반적인 답입니다. - 사전 정렬 대 소유권. 관례에 맞추면 무료 정확성을 얻지만, 관례의 결함과 혼란을 수입합니다. 이것은 익숙한 이름 대 독특한 이름 (독특함은 발견 가능성을 희생; 문법을 따르는 새로운 이름은 대부분 회복함)과 사전 친화적 대 더 나은 설계로 나타납니다. 발산은 한 번의 정렬 비용이 들지만, 유지된 결함은 영원히 정확성에 비용을 부과합니다.
신뢰 대신 측정하십시오
세 가지 속성은 모델 수준에서 측정됩니다. 전략은 해당 측정과 일치하는 메커니즘이지만, 어떤 UI 라이브러리에서도 측정되지 않았습니다. 증거 파일은 어떤 것이 어떤 것인지 표시합니다. 규칙을 채택하기 전에 실행하십시오. 현실적인 UI 작업 20~40개를 레짐당 여러 번 샘플링하고 (문맥 없음, 타입 + 두 형제 사용법, 전체 소스), 첫 시도 컴파일, 타입에 잡힌 오용 대 침묵 오류, 형제 호출 지점 간 토큰 분산, 접근성 린트, 짧은 시각적 검토를 점수화하고, 하나의 설계 결정을 변경하고, 다시 실행하십시오. 숫자를 움직이는 것을 유지하십시오.
리뷰 체크리스트
- 전략 1: 유사한 라이브러리에 익숙한 모델이 첫 시도에 이것을 추측할 것인가? 이름을 빌려왔다면 동일하게 동작하는가? 표준 예제가 의도된 경로를 보여주는가?
- 전략 2: 모든 현실적인 오용이 컴파일에 실패하는가? 이름의 시각적 기대가 깨졌을 때, 코드가 작성된 곳에서 깨짐이 보이는가?
- 전략 3: 어떤 값, 구성, 패턴, 적응이 호출 지점에 눈먼 결정으로 남겨졌는가?
- 레짐: 이 파일은 에이전트가 소유하는가 소비하는가? 가독성/계약 선택이 의도적인가?
- 진화: 이 변경이 작년 사전에서 작성된 코드를 깨뜨리는가? 마이그레이션이 타입과 함께 위치한 문서에 보이는가?