● Developer Guide

Dash Creator
Developer Guide

자연어 한 줄로 Android AI 위젯을 생성하는 플랫폼의 공식 개발자 문서. L1~L5 파이프라인, REST API, DASH.md 스펙, 스킨 시스템을 다룹니다.

✅ 안정 (v1.0.0) Python 3.11 FastAPI Kotlin / Compose 2026-04-24

01 빠른 시작

서버를 시작하고 첫 Dash를 생성하기까지 60초면 충분합니다.

bash
# 서버 시작
cd skills/dash-creator/src
uvicorn api.playground:app --reload --port 8000

# 첫 번째 Dash 생성
curl -X POST http://localhost:8000/api/creator/generate \
  -H "Content-Type: application/json" \
  -d '{"text": "매일 아침 날씨 알려줘"}'

성공하면 아래 구조의 JSON이 반환됩니다.

json · response
{
  "ok": true,
  "trace_id": "a3f2c91d",
  "intent": {
    "domain": "WEATHER",
    "size": "MEDIUM",
    "skin": "dark-ocean",
    "confidence": 0.91
  },
  "files": {
    "dash_composable_kt": "WeatherDailyDash.kt (...)  ",
    "repository_kt": "WeatherDailyRepository.kt (...)",
    "dash_md": "DASH.md (...)"
  },
  "validation": {
    "passed": true,
    "score": 8.7,
    "failed_rules": []
  },
  "stage": "ok",
  "retried": false
}
💡
LLM 키 없이 테스트하려면 /api/creator/simulate 엔드포인트를 사용하세요. 결정론적 출력이 반환됩니다.

02 아키텍처 개요

자연어 텍스트는 creator_chain.py 오케스트레이터를 거쳐 L1→L5 파이프라인을 통과합니다. 각 레이어는 독립 모듈로 분리돼 있어 단계별 교체·확장이 가능합니다.

L1
Intent Parse
creator_intent.py · LLM이 자연어를 분석해 구조화된 인텐트를 추출합니다
→ DashIntent { domain, size, skin, confidence }
L2a
Blueprint Lookup
blueprint_registry.py · 도메인에 맞는 Dash 구조 규칙을 조회합니다
→ BlueprintRule { required_features, layout_type }
L2b
Style Lookup
style_registry.py · 스킨별 디자인 토큰과 컬러를 해석합니다
→ StyleRule { skin, colors, component_tokens }
L3
Data Resolve
data_registry.py · 데이터 소스 설정과 샘플 컨텍스트를 구성합니다
→ DataContext { api_config, data_class, sample }
L4
Codegen (LLM)
creator_codegen.py · L1~L3 컨텍스트를 바탕으로 Kotlin + DASH.md 파일을 생성합니다
→ GeneratedFiles { composable_kt, repository_kt, dash_md }
L5
Validator
creator_validator.py · 생성 코드 품질을 규칙 기반으로 검증합니다. 실패 시 L4 1회 재시도
→ ValidationResult { passed, score, failed_rules }
creator_chain.py — 통합 오케스트레이터
pipeline.py / api/creator_api.py / main.py 세 파일에 복제됐던 intent → blueprint → style → data → codegen → validator 체인을 단일 함수로 통합합니다. run_text_to_dash(text) 한 줄로 전체 파이프라인이 실행됩니다.

03 API 레퍼런스

모든 엔드포인트는 http://localhost:8000/api/creator/ 아래 위치합니다. 요청/응답 모두 application/json입니다.

POST /api/creator/generate ✅ 안정

자연어 텍스트로 Dash를 생성합니다. L1~L5 파이프라인 전체를 실행하며, LLM API 키가 필요합니다.

Request Body
필드타입필수설명기본값
textstringREQUIRED자연어 요청 텍스트
sizestringoptionalTINY · SMALL · MEDIUM · LARGE · EXTRALARGEMEDIUM
skinstringoptionaldark-ocean · neon-city · warm-paper · forest-green · pure-light · sunset-warm도메인 자동 선택
domainstringoptional도메인 힌트 — L1 파싱 우선 적용L1 자동 분류
Response Fields
필드타입설명
okboolean파이프라인 성공 여부
trace_idstring8자 요청 추적 ID (디버깅용)
intentDashIntentL1 파싱 결과 (domain, size, skin, confidence)
filesGeneratedFiles생성된 파일 내용 (composable_kt, repository_kt, dash_md)
validationValidationResultL5 검증 결과 (passed, score, failed_rules)
stagestring실패 단계 (ok · L1 · L2a · L4 · L5)
clarification_neededbooleanL1 confidence < 0.5 — 추가 질의 필요
retriedbooleanValidator 실패로 L4 재생성 실행 여부
errorstring?실패 메시지 (ok=true 시 null)
POST /api/creator/simulate ✅ 안정

LLM 키 없이 결정론적 Dash를 생성합니다. CI 테스트 및 개발 환경 검증에 사용합니다. 인터페이스는 /generate와 동일합니다.

실제 LLM을 호출하지 않으므로 도메인별 템플릿 응답이 반환됩니다. 구조 검증 및 파이프라인 연결 테스트에 적합합니다.
POST /api/creator/validate-text 안정

텍스트의 인텐트만 파싱합니다 (L1만 실행). 사용자 입력의 즉각적인 분류 피드백에 활용합니다.

json · request
{ "text": "삼성전자 주가 5분마다 알려줘" }
json · response
{
  "domain": "FINANCE",
  "size": "SMALL",
  "skin": "dark-ocean",
  "confidence": 0.88,
  "clarification_needed": false
}
GET /api/creator/health ✅ 안정

시스템 상태, 지원 도메인, 스킨 목록을 반환합니다.

json · response
{
  "status": "ok",
  "version": "1.0.0",
  "domains": ["FINANCE", "WEATHER", "HEALTH", "PRODUCTIVITY", "COMMUTE", "MEDIA", "BUSINESS", "LIFESTYLE", "NATURE"],
  "skins": ["dark-ocean", "neon-city", "warm-paper", "forest-green", "pure-light", "sunset-warm"],
  "llm_available": true
}

04 DASH.md 스펙

각 Dash는 DASH.md 메타파일을 포함합니다. Orchestrator가 이 파일을 파싱해 트리거 조건, 권한, 데이터 소스, 스킨 진입점을 결정합니다.

DASH.md는 Dash의 SSoT(Single Source of Truth)입니다. Kotlin 파일은 렌더링만 담당하며, 모든 행동 정의는 DASH.md에서 읽어옵니다.

전체 예시 — 일일 날씨 대시

DASH.md 전체 구조 보기
yaml · DASH.md
meta:
  id: "com.theuniverse.weather-daily"
  name: "일일 날씨 대시"
  version: "1.0.0"
  category: "utility"
  keywords: ["날씨", "기온", "미세먼지", "forecast"]
  author: "creator@theuniverse.app"
  description: "매일 아침 날씨와 미세먼지를 한눈에 확인"

trigger:
  conditions:
    - type: time
      start: "07:00"
      end: "08:30"
      days: [1, 2, 3, 4, 5, 6, 7]
    - type: orchestrator_call
      keywords: ["날씨", "기온", "비 올까", "우산"]
      confidence: 0.8

skin:
  sizes: ["mini", "standard", "expanded"]
  theme_aware: true
  composable_entry: "WeatherDailyDash"
  default_size: "standard"

dash:
  entry: "WeatherDailyDash"
  description: "실시간 날씨 정보. 기온·체감온도·습도·미세먼지 제공."
  capabilities: [current_weather, air_quality, hourly_forecast]
  intents: ["날씨 알려줘", "오늘 기온", "미세먼지 어때"]
  data_sources:
    - type: web_api
      name: "kma_weather"
      update_interval: "1hour"
  permissions: [network, notifications, location_coarse]
  local_state: false
  quota:
    memory_mb: 24
    network_kb_per_min: 256
    cpu_percent: 5

protocol:
  fusible_with: ["travel", "schedule_management", "environmental"]

05 Spec Roles (8개)

Dash의 행동은 8개 Role의 조합으로 정의됩니다. 하나의 Dash는 여러 Role을 가질 수 있으며, display는 항상 필수입니다.

display 40%
최종 화면 렌더링. 항상 존재해야 합니다.
role: display
layout: card_metric
media_type: text
priority: 1
source 20%
외부 데이터 수집. REST API, RSS, DB 등을 지원합니다.
role: source
source_type: web_api
topic: stock_price
location: KR
notify 11%
알림 발송. 조건 충족 시 푸시·인앱 알림을 전송합니다.
role: notify
channel: push
target: user
timing: on_threshold
trigger 7%
이벤트 감지. 조건 달성 시 파이프라인을 시작합니다.
role: trigger
event: price_change
condition: gt
threshold: 0.1
schedule 6%
주기 설정. cron 형식으로 반복 실행을 정의합니다.
role: schedule
cron: "0 7 * * *"
timezone: Asia/Seoul
generate 5%
AI 콘텐츠 생성. 이미지·텍스트를 LLM으로 동적 생성합니다.
role: generate
prompt: "오늘의 격언 생성"
media_type: text
filter 5%
조건 선별. 수집된 데이터에서 관련 항목만 추출합니다.
role: filter
criteria: category_match
threshold: 0.7
summarize 4%
데이터 요약. 긴 콘텐츠를 Dash 크기에 맞게 압축합니다.
role: summarize
prompt: "핵심 3줄 요약"
max_length: 120

06 카테고리 & 도메인

9개 도메인 (L1 자동 분류)

L1 Intent Parse가 자연어를 분석해 자동으로 도메인을 할당합니다.

FINANCE WEATHER HEALTH PRODUCTIVITY COMMUTE MEDIA BUSINESS LIFESTYLE NATURE

22개 카테고리

DASH.md의 meta.category에 기록됩니다.

finance crypto weather environment fitness health news calendar utility productivity commute transport music video social business food travel lifestyle education memory nature

자연어 → 도메인 → 카테고리 매핑 예시

자연어 예시도메인카테고리기본 스킨
"삼성전자 주가 5분마다 알려줘"FINANCEfinancedark-ocean
"오늘 미세먼지 어때"WEATHERenvironmentforest-green
"매일 만보 걷기 기록"HEALTHfitnessforest-green
"오늘 할일 알려줘"PRODUCTIVITYcalendarpure-light
"지하철 막차 시간"COMMUTEtransportneon-city
"요즘 핫한 유튜브 트렌드"MEDIAvideoneon-city
"오늘 점심 뭐 먹을까"LIFESTYLEfoodsunset-warm

07 코드 예제

Python — creator_chain.py 직접 호출

python
from engine.creator_chain import run_text_to_dash, ChainHints

# ── 기본 생성 ──────────────────────────────────────────────
result = run_text_to_dash("매일 아침 삼성전자 주가 알려줘")

if result.ok:
    print(result.files.dash_composable_kt)
    print(f"검증 점수: {result.validation.score}/10")
elif result.clarification_needed:
    print("명확히 해주세요:", result.error)
else:
    print(f"실패 단계 {result.stage}:", result.error)

# ── 힌트 지정 ───────────────────────────────────────────────
result = run_text_to_dash(
    "주가 대시",
    hints=ChainHints(
        size="LARGE",
        skin="dark-ocean",
        domain="FINANCE"
    )
)

# ── 다중 후보 생성 ──────────────────────────────────────────
from engine.creator_chain import run_text_to_dash_variants

variants = run_text_to_dash_variants("날씨 대시", n=3)
best = max(
    (v for v in variants if v.ok),
    key=lambda v: v.validation.score
)
print(f"최고 점수: {best.validation.score} / skin: {best.intent.skin}")

cURL

bash
# 생성 (LLM 호출)
curl -X POST http://localhost:8000/api/creator/generate \
  -H "Content-Type: application/json" \
  -d '{"text": "주가 10% 떨어지면 알려줘", "size": "MEDIUM"}'

# 시뮬레이션 (LLM 없이)
curl -X POST http://localhost:8000/api/creator/simulate \
  -H "Content-Type: application/json" \
  -d '{"text": "날씨 대시"}'

# 인텐트만 확인
curl -X POST http://localhost:8000/api/creator/validate-text \
  -H "Content-Type: application/json" \
  -d '{"text": "내일 미세먼지 알려줘"}'

# 헬스체크
curl http://localhost:8000/api/creator/health

08 스킨 (6종)

스킨은 Dash의 시각적 정체성을 정의합니다. L1이 도메인 기반으로 자동 선택하며, 사용자가 skin 파라미터로 명시 지정할 수 있습니다.

dark-ocean
딥블루 그라데이션. 데이터 중심의 금융·실시간 대시에 적합합니다.
financerealtime_alerts
neon-city
형광+다크. 엔터테인먼트·소셜 콘텐츠에 강렬한 존재감을 부여합니다.
entertainmentsocial
warm-paper
크림+세피아. 기억·교육 콘텐츠에 아날로그 감성을 더합니다.
memoryeducation
forest-green
자연+초록. 건강·환경 지표 대시에서 신뢰감을 줍니다.
healthenvironmental
pure-light
화이트+미니멀. 생산성·일정 대시에서 집중력을 높입니다.
productivityschedule
sunset-warm
오렌지+핑크. 라이프스타일·여행 대시에 감성적 온기를 더합니다.
lifestyletravel

09 인텐트 처리

L1이 자연어에서 추출하는 인텐트 유형과 각 처리 방식입니다.

인텐트설명처리 방식상태
create새 Dash 생성L1~L5 전체 파이프라인 실행✅ 안정
conditionif-then 조건 설정condition_branch 반환 → 런타임 처리🔧 Phase 2
edit기존 Dash 수정Dash 조회 후 변경 부분 재생성🔧 Phase 2
schedule주기 실행 설정schedule Role 삽입 후 재생성✅ 안정
notify알림 조건 설정notify Role 삽입 후 재생성✅ 안정
summarize요약 요청summarize Role 추가 후 재생성✅ 안정
generateAI 콘텐츠 생성 요청generate Role 추가 후 재생성📋 실험적
filter데이터 필터링filter Role + 조건 추가✅ 안정
query단순 정보 조회clarification 없이 L1 결과만 반환✅ 안정
unknown분류 불가clarification_needed=true 반환✅ 안정

10 오류 처리 & 트러블슈팅

ChainResult.stage로 실패 단계를 특정하고 error 필드로 원인을 확인합니다.

단계원인해결 방법
L1 confidence 낮음 텍스트가 너무 짧거나 모호합니다 (예: "대시 만들어줘") clarification_needed=true 확인 후 사용자에게 추가 입력 요청. domain 힌트 명시
L2a 도메인 없음 BlueprintRegistry에 해당 도메인 항목이 없습니다 blueprint_registry.py에 도메인 BlueprintRule 추가
L2b 스킨 없음 요청한 skin 값이 등록되지 않았습니다 /api/creator/healthskins 목록으로 유효값 확인
L4 codegen 실패 LLM API 오류 또는 키 누락 ANTHROPIC_API_KEY / GEMINI_API_KEY 환경변수 확인. /simulate로 우선 검증
L5 검증 실패 생성 코드가 필수 규칙을 위반합니다 (score < 6.0) failed_rules 배열로 위반 규칙 확인. retry_on_validator_fail=True로 자동 재생성 활성화

자주 겪는 문제

서버 시작 후 422 Unprocessable Entity 반환
요청 바디의 JSON 형식이 올바른지 확인하세요. text 필드는 필수입니다. Content-Type: application/json 헤더가 포함되어야 합니다.
Python 모듈 임포트 오류 (ModuleNotFoundError)
반드시 skills/dash-creator/src 디렉토리에서 실행하세요. 또는 PYTHONPATH를 해당 경로로 설정하세요.
export PYTHONPATH=skills/dash-creator/src
python -m pytest ../tests/ -v
L4 codegen이 항상 실패합니다
LLM 키 없이 전체 파이프라인을 테스트하려면 /simulate를 사용하세요. 실제 키가 있다면 llm_router.py의 provider 우선순위를 확인하세요 (Gemini → Claude → fallback).

11 환경 설정

설치

bash
# 의존성 설치
cd skills/dash-creator/src
pip install -r requirements.txt

환경 변수

변수설명필수
ANTHROPIC_API_KEYClaude LLM 호출용 키 (sk-ant-...)L4 필수
GEMINI_API_KEYGemini LLM 호출용 키 (AI...)선택
bash
# 환경변수 설정
export ANTHROPIC_API_KEY=sk-ant-...
export GEMINI_API_KEY=AI...

# 개발 서버 시작
uvicorn api.playground:app --reload --port 8000

# 전체 테스트 (LLM 없이)
python -m pytest ../tests/ -v

# creator_chain 테스트만
python -m pytest ../tests/test_creator_chain.py -v

# 특정 테스트 함수
python -m pytest ../tests/test_creator_chain.py::test_simulate_weather -v
API 키를 소스 코드에 하드코딩하지 마세요. .env 파일이나 시스템 환경변수를 사용하고, .gitignore.env를 반드시 추가하세요.