콘텐츠를 시각적으로 구조화된 슬라이드 HTML로 변환하는 독립 에이전트. 아키텍처 (4단계 파이프라인): 1. Kei 실장 (Opus) — 콘텐츠 유형 분류 + 블록 배치 2. 디자인 팀장 (Sonnet) — 레이아웃 컨셉 (블록 배치 + 페이지 수) 3. 텍스트 편집자 (Sonnet) — 슬롯 텍스트 정리 (핵심 유지) 4. CSS Grid 렌더러 — HTML 조립 블록 템플릿 7종: comparison, card-grid, relationship, process, quote-block, conclusion-bar, comparison-table 기술 스택: FastAPI + Anthropic API + Jinja2 + CSS Grid Pretendard Variable 한국어 폰트 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
7.6 KiB
7.6 KiB
Design Agent — 실행 계획
Phase 1: 기반 구축
DA-1: 프로젝트 셋업
- 파일: pyproject.toml, .env, .gitignore
- 내용: Python 환경, 의존성 정의, 환경 변수
- 의존성: 없음
- 완료 기준:
pip install -e .성공
DA-2: FastAPI 서버 기본 구조
- 파일: src/main.py, src/config.py
- 내용: FastAPI 앱, CORS, health endpoint, 설정 관리
- 의존성: DA-1
- 완료 기준:
uvicorn src.main:app --reload정상 시작,/api/health200 반환
DA-3: 디자인 토큰 + 기본 CSS
- 파일: static/tokens.css, static/base.css
- 내용: CLAUDE.md에 정의된 디자인 토큰을 CSS 변수로 구현, Pretendard 폰트 설정, 16:9 슬라이드 컨테이너
- 의존성: 없음
- 완료 기준: 빈 슬라이드가 16:9 비율로 렌더링, Pretendard 폰트 적용 확인
Phase 2: 블록 템플릿 제작
DA-4: 블록 템플릿 — 비교 (comparison)
- 파일: templates/blocks/comparison.html
- 내용: 2단 병렬 레이아웃, Jinja2 슬롯 ({{left_title}}, {{left_content}}, {{right_title}}, {{right_content}})
- 의존성: DA-3
- 완료 기준: 더미 데이터로 렌더링 시 2단 비교 표시, 디자인 토큰 적용
DA-5: 블록 템플릿 — 카드 그리드 (card-grid)
- 파일: templates/blocks/card-grid.html
- 내용: 2~4열 카드 배열, Jinja2 슬롯 ({{cards[n].icon}}, {{cards[n].title}}, {{cards[n].description}})
- 의존성: DA-3
- 완료 기준: 3개 카드 렌더링, 카드 수에 따라 자동 배열
DA-6: 블록 템플릿 — 관계도 (relationship)
- 파일: templates/blocks/relationship.html
- 내용: 벤 다이어그램 (CSS 원형), Jinja2 슬롯 ({{center}}, {{items[n]}})
- 의존성: DA-3
- 완료 기준: 3원 벤 다이어그램 렌더링, 라벨 표시
DA-7: 블록 템플릿 — 프로세스 (process)
- 파일: templates/blocks/process.html
- 내용: 가로 단계 흐름, Jinja2 슬롯 ({{steps[n].number}}, {{steps[n].title}}, {{steps[n].description}})
- 의존성: DA-3
- 완료 기준: 4단계 프로세스 렌더링, 연결선 표시
DA-8: 블록 템플릿 — 강조 인용 (quote-block)
- 파일: templates/blocks/quote-block.html
- 내용: 배경색 + 좌측 라인 + 인용 텍스트, Jinja2 슬롯 ({{quote_text}}, {{source}})
- 의존성: DA-3
- 완료 기준: 인용 블록 렌더링, 강조 스타일 적용
DA-9: 블록 템플릿 — 결론 바 (conclusion-bar)
- 파일: templates/blocks/conclusion-bar.html
- 내용: 하단 전체 폭 강조 영역, Jinja2 슬롯 ({{conclusion_text}})
- 의존성: DA-3
- 완료 기준: 결론 바 렌더링, 강조 색상 적용
DA-10: 블록 템플릿 — 비교 테이블 (comparison-table)
- 파일: templates/blocks/comparison-table.html
- 내용: 다항목 비교 테이블, Jinja2 슬롯 ({{headers}}, {{rows}})
- 의존성: DA-3
- 완료 기준: 5행 3열 테이블 렌더링
DA-11: 슬라이드 조합 렌더러
- 파일: src/renderer.py, templates/slide-base.html
- 내용: Jinja2로 블록 조합 → HTML 생성. grid-template-areas로 블록 배치. 다중 페이지 지원.
- 다중 페이지:
.slidediv 여러 개 +page-break-after: always(인쇄 시 페이지 분리) - 의존성: DA-4 ~ DA-10
- 완료 기준: JSON 블록 배치 명세 → 완성 HTML 출력 (1페이지 또는 다중 페이지)
Phase 3: AI 파이프라인 연결
DA-12: Kei API 연동 — 콘텐츠 분류 (Opus)
- 파일: src/kei_client.py
- 내용: Kei API (
localhost:8000/api/message)에 콘텐츠 전송 → Opus 분류 결과 수신. Kei API 미연결 시 수동 분류 fallback - 의존성: DA-2
- 완료 기준: 테스트 콘텐츠 전송 → 유형 분류 JSON 반환
DA-13: 디자인 팀장 — 레이아웃 컨셉 (Sonnet)
- 파일: src/design_director.py
- 내용: Anthropic API 직접 호출. Opus 분류 결과 + 원본 콘텐츠 → 레이아웃 컨셉만 결정. 텍스트 정리 안 함.
- 출력: 블록 배치 + 페이지 수 + 슬롯 목록 (텍스트 없이 구조만)
- 기술: Anthropic API (Sonnet), JSON 반환
- 의존성: DA-12
- 완료 기준: "이 파트는 카드로, 이건 비교로, 2페이지 필요" 수준의 컨셉 JSON 반환
DA-13b: 텍스트 편집자 — 슬롯 텍스트 정리 (Kei 역할)
- 파일: src/content_editor.py (신규)
- 내용: Anthropic API 직접 호출. 디자인 팀장의 레이아웃 컨셉 + 원본 콘텐츠 → 각 슬롯에 맞는 텍스트 편집. 도메인 지식 보존, 핵심 유지.
- 역할: 도메인 전문가로서 콘텐츠를 정리하는 편집자 (Kei persona 규칙 일부 적용)
- 규칙: 핵심 내용 유지, 개조식, 출처 보존, 슬롯 분량 준수, 내용 날조 금지
- 기술: Anthropic API (Sonnet), JSON 반환
- 의존성: DA-13
- 완료 기준: 슬롯별 텍스트가 채워진 JSON 반환. 원본 핵심 내용 보존 확인.
DA-14: 전체 파이프라인 연결 (3단계)
- 파일: src/pipeline.py
- 내용: 콘텐츠 입력 → Opus 분류 → 디자인 팀장 컨셉 → 텍스트 편집자 정리 → 렌더러 조립 → HTML 출력
- 기술: 순차 호출, 다중 페이지 지원
- 의존성: DA-11, DA-12, DA-13, DA-13b
- 완료 기준: 텍스트 입력 → 완성 슬라이드 HTML 출력 (엔드투엔드, 다중 페이지 포함)
Phase 4: UI + 출력
DA-15: 프론트엔드 — 콘텐츠 입력 + 미리보기
- 파일: static/index.html (별도 HTML 파일), main.py (FileResponse로 서빙)
- 내용: 텍스트 입력 영역 + iframe 미리보기 + HTML 다운로드 버튼
- 기술: FileResponse (FastAPI 내장), fetch API + 수동 SSE 파싱
- 의존성: DA-14
- 완료 기준: 텍스트 붙여넣기 → 슬라이드 미리보기 표시 + HTML 다운로드
- 주의: HTML/JS를 Python 문자열에 넣지 않는다 (이스케이프 충돌 방지)
버그 수정
BF-2: 블록 내용 비어있음 (렌더러 Jinja2 include 문제)
- 파일: src/renderer.py, templates/slide-base.html
- 내용:
include→ 블록별 개별render()후 HTML 삽입 - 기술: Jinja2
get_template().render()(내장) - 의존성: 없음 (기존 코드 수정만)
- 완료 기준: 콘텐츠 입력 → 슬라이드에 텍스트가 표시됨
BF-3: 한글 깨짐 (다운로드 파일)
- 파일: static/index.html
- 내용: download() Blob에 UTF-8 BOM 추가
- 기술: JavaScript
'\uFEFF'1줄 - 의존성: 없음
- 완료 기준: 다운로드한 HTML 파일에서 한글 정상 표시
DA-16: 통합 테스트
- 파일: tests/test_pipeline.py, tests/test_renderer.py
- 내용: 전체 파이프라인 테스트 + 블록 렌더링 테스트
- 의존성: BF-2, BF-3
- 완료 기준: 테스트 전체 통과
의존 관계
DA-1 → DA-2 → DA-12 → DA-13 ─┐
├→ DA-14 → DA-15 → DA-16
DA-3 → DA-4~DA-10 → DA-11 ────┘
Phase 1(DA-13)과 Phase 2(DA-411)는 AI 없이 진행 가능.
Phase 3(DA-12~14)부터 Kei API + Anthropic API 필요.
기술 스택
| 역할 | 도구 | 비고 |
|---|---|---|
| 서버 | FastAPI + uvicorn | Kei와 동일 |
| 템플릿 엔진 | Jinja2 | 블록 상속 + 슬롯 변수 |
| 렌더링 | CSS Grid + 디자인 토큰 | 순수 CSS |
| 한국어 폰트 | Pretendard Variable | word-break: keep-all |
| AI (실장) | Kei API (Opus) | localhost:8000 |
| AI (팀장) | Anthropic API (Sonnet) | Structured Outputs |
| 테스트 | pytest | 렌더링 + 파이프라인 |