파이프라인 현황 문서 신규 작성: - Stage 0~4 전체 흐름, Type A/B/B'/B'' 구분, MDX↔유형 매핑 - 단계별 파일/함수 맵, 데이터 흐름, 현재 구현 상태 - ARCHITECTURE_OVERVIEW.md는 3/27 스냅샷으로 archived 처리 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
614 lines
24 KiB
Markdown
614 lines
24 KiB
Markdown
# ⚠ DEPRECATED — 이 문서는 2026-03-27 기준 스냅샷입니다
|
||
|
||
> **최신 파이프라인 문서는 [`PIPELINE.md`](PIPELINE.md)를 참조하세요.**
|
||
> 이 문서는 Type A/B 분기, B'/B'' 변형, Stage 1.7/1.8 등 현재 구조를 반영하지 않습니다.
|
||
> 히스토리 참고용으로만 유지합니다.
|
||
|
||
---
|
||
|
||
# Design Agent 전체 구조 파악 리포트 (archived)
|
||
|
||
**작성일:** 2026-03-27
|
||
**목표:** design_agent의 아키텍처, 파이프라인, 코드 구조를 체계적으로 이해
|
||
|
||
---
|
||
|
||
## 📌 Design Agent란?
|
||
|
||
**목적:** 텍스트/MDX 콘텐츠를 **시각적으로 구조화된 슬라이드 HTML**(1280×720px, 16:9)로 변환하는 독립 AI 에이전트.
|
||
|
||
**핵심 특징:**
|
||
- ✅ **콘텐츠 기반 동적 비중** — Kei가 매번 콘텐츠마다 본심/배경/첨부/결론의 비중을 판단 (고정값 없음)
|
||
- ✅ **텍스트 우선 설계** — 디자인이 텍스트에 맞춤 (텍스트를 자르거나 비틀지 않음)
|
||
- ✅ **전문가 판단** — Kei 실장이 꼭지 추출, 디자인 팀장이 레이아웃, 편집자가 텍스트 정리, 실무자가 디자인 조정
|
||
- ✅ **Kei API 필수** — 하드코딩 없음. 모든 판단은 AI의 사고. fallback 없음. 성공할 때까지 무한 재시도.
|
||
- ✅ **블록 라이브러리** — 38개 블록, 6개 카테고리 (headers, cards, tables, visuals, emphasis, media)
|
||
- ✅ **중간 산출물 추적** — 각 단계별 결과가 JSON으로 저장 (`data/runs/{timestamp}/`)
|
||
|
||
---
|
||
|
||
## 🏗️ 파이프라인: 5단계 + 중간 단계
|
||
|
||
```
|
||
┌─────────────────────────────────────────────────────────────┐
|
||
│ [입력] 텍스트 콘텐츠 (텍스트 붙여넣기 또는 파일 업로드) │
|
||
└────────────────────┬────────────────────────────────────────┘
|
||
↓
|
||
┌────────────────────────────┐
|
||
│ [1단계] Kei 실장 │ (Kei API / Opus)
|
||
│ 꼭지 추출 + 정보구조 분석 │
|
||
│ ───────────────────────── │
|
||
│ 1A: 핵심 메시지, 꼭지 5개 │
|
||
│ 1B: 컨셉 구체화 │
|
||
│ 출력: step1_analysis.json │
|
||
│ step1b_concepts.json │
|
||
└────────┬───────────────────┘
|
||
↓
|
||
┌────────────────────────────┐
|
||
│ [O-1] 컨테이너 계산 │ (코드 / 결정론적)
|
||
│ 비중 → px 확정 │
|
||
│ ───────────────────────── │
|
||
│ 출력: step1c_containers... │
|
||
└────────┬───────────────────┘
|
||
↓
|
||
┌────────────────────────────┐
|
||
│ [2단계] 디자인 팀장 │
|
||
│ 레이아웃 설계 + 블록 배치 │
|
||
│ ───────────────────────── │
|
||
│ Step A: 프리셋 선택 (규칙) │
|
||
│ reference 있음 │
|
||
│ → sidebar-right │
|
||
│ Step B: 블록 매핑 (Sonnet) │
|
||
│ 각 블록에 텍스트 │
|
||
│ 글자수 가이드 │
|
||
│ 출력: step2_layout.json │
|
||
└────────┬───────────────────┘
|
||
↓
|
||
┌────────────────────────────┐
|
||
│ [O-3] 블록 스펙 확정 │ (코드 / 결정론적)
|
||
│ 항목수, 글자수, 폰트 │
|
||
│ ───────────────────────── │
|
||
│ 출력: step2c_block_specs.. │
|
||
└────────┬───────────────────┘
|
||
↓
|
||
┌────────────────────────────┐
|
||
│ [3단계] 텍스트 편집자 │ (Kei API / Opus)
|
||
│ 각 슬롯에 텍스트 정리 │
|
||
│ ───────────────────────── │
|
||
│ • 팀장의 글자 수 가이드 │
|
||
│ • 의미 우선 │
|
||
│ • 원본 보존 + 편집 │
|
||
│ 출력: step3_filled_blocks. │
|
||
└────────┬───────────────────┘
|
||
↓
|
||
┌────────────────────────────┐
|
||
│ [4단계] 디자인 실무자 │ (Sonnet + Jinja2)
|
||
│ CSS 조정 + HTML 조립 │
|
||
│ ───────────────────────── │
|
||
│ • 텍스트에 맞게 디자인 │
|
||
│ • 이미지/표 처리 │
|
||
│ • HTML 렌더링 │
|
||
│ 출력: step4_rendered.html │
|
||
└────────┬───────────────────┘
|
||
↓
|
||
┌────────────────────────────┐
|
||
│ [Phase L] 렌더링 측정 │ (Selenium)
|
||
│ 실제 높이 측정 │
|
||
│ ───────────────────────── │
|
||
│ • overflow 감지 │
|
||
│ • 피드백 루프 (미완성) │
|
||
│ 출력: step4_measurement_.. │
|
||
└────────┬───────────────────┘
|
||
↓
|
||
┌────────────────────────────┐
|
||
│ [5단계] Kei 최종 검수 │ (Opus 멀티모달)
|
||
│ 스크린샷 보고 검증 │
|
||
│ ───────────────────────── │
|
||
│ 출력: step5_screenshot.txt │
|
||
└────────┬───────────────────┘
|
||
↓
|
||
┌─────────────────────────────────────────────────────────────┐
|
||
│ [출력] 완성 슬라이드 HTML (final.html) │
|
||
│ + 시각화 리포트 (report.html) │
|
||
└─────────────────────────────────────────────────────────────┘
|
||
```
|
||
|
||
---
|
||
|
||
## 👥 5가지 역할 (Role)
|
||
|
||
### 1️⃣ Kei 실장 (Opus)
|
||
**역할:** 전략과 콘텐츠 분석
|
||
**소유 단계:** 1A, 1B, 3, 5
|
||
|
||
| 단계 | 하는 일 | 출력 |
|
||
|------|--------|------|
|
||
| **1A** | 꼭지 5개 추출, 핵심 메시지, 본심/배경/첨부/결론 비중 판단 | `step1_analysis.json` |
|
||
| **1B** | 각 꼭지의 relation_type, expression_hint, source_data | `step1b_concepts.json` |
|
||
| **3** | 팀장의 글자 수 가이드를 참고하며 원본 보존하며 텍스트 정리 | `step3_filled_blocks.json` |
|
||
| **5** | 최종 슬라이드의 스크린샷로 보고 최종 검수 | `step5_screenshot.txt` |
|
||
|
||
**원칙:**
|
||
- 비중이 모든 것을 결정 (본심 60%, 배경 20%, 첨부 10%, 결론 10% 등)
|
||
- 콘텐츠마다 비중은 달라짐 (고정값 없음)
|
||
- 하드코딩 없음 - 매번 사고하여 판단
|
||
|
||
---
|
||
|
||
### 2️⃣ 디자인 팀장 (Sonnet)
|
||
**역할:** 레이아웃과 공간 배분
|
||
**소유 단계:** 2 (Step B), 2 (Step A는 코드)
|
||
|
||
| 단계 | 하는 일 | 출력 |
|
||
|------|--------|------|
|
||
| **2A** | 규칙 기반 프리셋 선택 (코드가 수행) | 프리셋 CSS grid |
|
||
| **2B** | 프리셋 내에서 블록 매핑, 글자 수 가이드 (Sonnet) | `step2_layout.json` |
|
||
|
||
**원칙:**
|
||
- 블록 타입 변경 불가 (Kei가 선택한 것 유지)
|
||
- zone 배치만 담당 (body/sidebar/footer)
|
||
- 텍스트 내용 건드리지 않음
|
||
|
||
---
|
||
|
||
### 3️⃣ 텍스트 편집자 (Opus)
|
||
**역할:** 콘텐츠 정리 및 편집
|
||
**소유 단계:** 3 (별도 호출)
|
||
|
||
**원칙:**
|
||
- 팀장의 글자 수 가이드 참고 (하지만 의미가 우선)
|
||
- 원본 텍스트 최대 보존
|
||
- 개조식(불릿, 번호) 사용
|
||
- 슬롯 빈칸 금지
|
||
|
||
---
|
||
|
||
### 4️⃣ 디자인 실무자 (Sonnet + 코드)
|
||
**역할:** 디자인 조정 및 HTML 조립
|
||
**소유 단계:** 4 (O-3 스펙 확정 후)
|
||
|
||
**원칙:**
|
||
- 텍스트를 자르지 않음. 디자인으로 텍스트 맞추기
|
||
- 이미지는 원본 그대로, 크기만 조절
|
||
- 표는 표로 유지 (다른 형태 전환 X)
|
||
|
||
---
|
||
|
||
### 5️⃣ Code (결정론적 알고리즘)
|
||
**역할:** 계산 및 측정
|
||
**소유 단계:** O-1 컨테이너 계산, O-3 블록 스펙, Phase L 측정
|
||
|
||
| 단계 | 하는 일 |
|
||
|------|--------|
|
||
| **O-1** | Kei 비중 → px 확정. 고정식 계산. |
|
||
| **O-3** | 컨테이너 크기 → 블록별 항목수/글자수/폰트 계산. 결정론적. |
|
||
| **Phase L** | Selenium으로 실제 렌더링 높이 측정. 브라우저 엔진 기반. |
|
||
|
||
---
|
||
|
||
## 📂 소스 코드 구조
|
||
|
||
```
|
||
src/
|
||
├── main.py ← FastAPI 서버, /api/generate 엔드포인트
|
||
├── config.py ← 설정 (API key, Kei API URL, 슬라이드 크기)
|
||
│
|
||
├── ─ 파이프라인 핵심 ─
|
||
├── pipeline.py ← 메인 파이프라인 (5단계 + 중간 단계)
|
||
│ • generate_slide() — 비동기 제너레이터, SSE 이벤트 방출
|
||
│ • _retry_kei() — Kei API 무한 재시도
|
||
│
|
||
├── ─ 단계별 모듈 ─
|
||
├── kei_client.py ← 1단계: Kei API 호출
|
||
│ • classify_content() — 꼭지 추출 + 분석 (1A)
|
||
│ • refine_concepts() — 컨셉 구체화 (1B)
|
||
│ • call_kei_overflow_judgment() — Phase L 피드백
|
||
│ • call_kei_final_review() — 최종 검수 (5)
|
||
│
|
||
├── space_allocator.py ← O-1, O-3: 컨테이너 & 블록 스펙 계산
|
||
│ • calculate_container_specs() — 비중 → px
|
||
│ • finalize_block_specs() — 항목수/글자수/폰트
|
||
│ • calculate_trim_chars() — overflow px → 삭제 글자
|
||
│
|
||
├── design_director.py ← 2단계: 레이아웃 설계
|
||
│ • select_preset() — 프리셋 규칙 선택 (Step A)
|
||
│ • create_layout_concept() — 블록 매핑 (Step B, Sonnet)
|
||
│ • LAYOUT_PRESETS — 4개 프리셋 (sidebar-right, two-column, hero-detail)
|
||
│ • BLOCK_SLOTS — 모든 블록의 슬롯 정의
|
||
│
|
||
├── content_editor.py ← 3단계: 텍스트 편집
|
||
│ • fill_content() — 각 슬롯에 텍스트 정리 (Kei API)
|
||
│
|
||
├── renderer.py ← 4단계: HTML 렌더링
|
||
│ • render_slide() — Jinja2로 HTML 생성
|
||
│ • _load_catalog_map() — catalog.yaml 블록 매핑
|
||
│
|
||
├── ─ 보조 모듈 ─
|
||
├── block_search.py ← FAISS 기반 블록 검색
|
||
│ • search_blocks_for_topics() — 콘텐츠 적합 블록 후보
|
||
│
|
||
├── slide_measurer.py ← Phase L: Selenium 렌더링 측정
|
||
│ • measure_rendered_heights() — 실제 높이 측정
|
||
│ • format_measurement_for_kei() — 측정값 → 피드백 포맷
|
||
│ • capture_slide_screenshot() — 멀티모달용 스크린샷
|
||
│
|
||
├── image_utils.py ← 이미지 처리
|
||
│ • get_image_sizes() — 이미지 크기 측정
|
||
│ • embed_images() — 이미지 데이터 URI 변환
|
||
│
|
||
├── svg_calculator.py ← SVG 다이어그램 계산
|
||
│
|
||
└── sse_utils.py ← SSE 스트리밍 유틸
|
||
• stream_sse_tokens() — 토큰 스트리밍 처리
|
||
```
|
||
|
||
---
|
||
|
||
## 📊 데이터 흐름
|
||
|
||
### 입력: SlideRequest
|
||
```json
|
||
{
|
||
"content": "텍스트/MDX 콘텐츠 (붙여넣기 또는 파일 업로드)",
|
||
"base_path": "/path/to/images" (선택, 이미지 폴더 경로)
|
||
}
|
||
```
|
||
|
||
### 1단계 출력: step1_analysis.json
|
||
```json
|
||
{
|
||
"title": "슬라이드 제목",
|
||
"core_message": "핵심 메시지 한 줄",
|
||
"total_pages": 1,
|
||
"info_structure": "정보 구조 설명",
|
||
"page_structure": {
|
||
"본심": {"topic_ids": [3], "weight": 0.60},
|
||
"배경": {"topic_ids": [1, 2], "weight": 0.20},
|
||
"첨부": {"topic_ids": [4], "weight": 0.10},
|
||
"결론": {"topic_ids": [5], "weight": 0.10}
|
||
},
|
||
"topics": [
|
||
{
|
||
"id": 1,
|
||
"title": "개념 혼용의 현실",
|
||
"purpose": "문제제기",
|
||
"role": "flow",
|
||
"emphasis": false,
|
||
"layer": "intro"
|
||
}
|
||
]
|
||
}
|
||
```
|
||
|
||
### 2단계 출력: step2_layout.json
|
||
```json
|
||
{
|
||
"preset": "'header header' 'body sidebar' 'footer footer'",
|
||
"blocks": [
|
||
{
|
||
"area": "body",
|
||
"type": "callout-warning",
|
||
"topic_id": 1,
|
||
"purpose": "문제제기",
|
||
"reason": "..."
|
||
}
|
||
],
|
||
"overflow": [
|
||
{
|
||
"area": "body",
|
||
"overflow_px": 100,
|
||
"budget_px": 490
|
||
}
|
||
]
|
||
}
|
||
```
|
||
|
||
### 3단계 출력: step3_filled_blocks.json
|
||
```json
|
||
{
|
||
"blocks": [
|
||
{
|
||
"type": "callout-warning",
|
||
"topic_id": 1,
|
||
"data": {
|
||
"icon": "⚠️",
|
||
"title": "DX와 BIM의 개념적 혼용 문제",
|
||
"description": "건설산업에서 DX와 BIM이 명확히 정립되지 않은 채 혼용..."
|
||
},
|
||
"char_count": 124
|
||
}
|
||
]
|
||
}
|
||
```
|
||
|
||
### 최종 출력: final.html
|
||
완성된 슬라이드 HTML (1280×720px, 16:9 비율)
|
||
|
||
---
|
||
|
||
## 🎨 프리셋 시스템 (2단계 Step A)
|
||
|
||
규칙 기반 자동 선택:
|
||
|
||
| 프리셋 | 조건 | CSS Grid | 사용 |
|
||
|--------|------|---------|------|
|
||
| **sidebar-right** | reference 꼭지 1개 이상 | `"title title" "body sidebar" "footer"` (65fr 35fr) | 용어 정의, 참조 정보가 있을 때 |
|
||
| **two-column** | 모든 flow 꼭지가 대등한 비교 | `"title title" "left right" "footer"` (1fr 1fr) | 좌우 비교 구조 |
|
||
| **hero-detail** | 고강조 꼭지 1개 + 나머지 보조 | `"title" "hero" "detail" "footer"` | 하나의 큰 내용 + 상세 |
|
||
| **single-column** | 모든 꼭지가 flow, 순차적 | `"title" "body" "footer"` (1fr) | 일반적인 순차 흐름 |
|
||
|
||
---
|
||
|
||
## 🏷️ 블록 라이브러리 (38개)
|
||
|
||
| 카테고리 | 개수 | 용도 | 예시 |
|
||
|---------|------|------|------|
|
||
| **headers** | 5 | 타이틀, 꼭지 헤더 | section-title-with-bg, topic-left-right |
|
||
| **cards** | 10 | 항목 나열, 카드 그리드 | card-image-3col, card-compare-3col |
|
||
| **tables** | 3 | 비교표, 데이터 테이블 | data-table, comparison-table |
|
||
| **visuals** | 6 | SVG 다이어그램 | venn-diagram, flow-process, relationship |
|
||
| **emphasis** | 10 | 강조, 인용, 결론 | callout-warning, quote-block, banner-gradient |
|
||
| **media** | 5 | 이미지/사진 | image-frame, full-width-image |
|
||
|
||
각 블록은 `catalog.yaml`에 정의됨:
|
||
- `id`: 블록 ID
|
||
- `template`: HTML 템플릿 경로
|
||
- `height_cost`: 크기 등급 (compact/medium/large/xlarge)
|
||
- `slots`: 필수/선택 슬롯
|
||
- `when`: 사용 조건
|
||
- `not_for`: 금지 조건
|
||
|
||
---
|
||
|
||
## 🔧 기술 스택
|
||
|
||
### Backend (Python)
|
||
```
|
||
FastAPI ≥0.115 — 웹 서버
|
||
uvicorn ≥0.30 — ASGI 서버
|
||
Jinja2 ≥3.1 — HTML 템플릿
|
||
Pydantic ≥2.0 — 데이터 검증
|
||
Anthropic ≥0.40 — Claude API
|
||
httpx ≥0.27 — HTTP 클라이언트
|
||
sse-starlette ≥2.0 — SSE 스트리밍
|
||
Selenium — Headless Chrome 제어 (Phase L)
|
||
Pillow ≥10.0 — 이미지 처리
|
||
PyYAML ≥6.0 — YAML 파싱 (catalog.yaml)
|
||
```
|
||
|
||
### Frontend (React + Vite)
|
||
```javascript
|
||
React 18 — UI 프레임워크
|
||
Vite — 번들러
|
||
Tailwind CSS — 스타일링
|
||
```
|
||
|
||
### Design Assets
|
||
```
|
||
static/
|
||
├── base.css — 슬라이드 기본 스타일
|
||
├── tokens.css — 디자인 토큰 (색상, 폰트, 간격)
|
||
├── index.html — 프론트엔드 UI
|
||
|
||
templates/
|
||
├── catalog.yaml — 블록 라이브러리 정의
|
||
├── slide-base.html — 슬라이드 기본 템플릿
|
||
└── blocks/ — 6개 카테고리 × 38개 블록 HTML
|
||
├── headers/ — 5개
|
||
├── cards/ — 10개
|
||
├── tables/ — 3개
|
||
├── visuals/ — 6개
|
||
├── emphasis/ — 10개
|
||
└── media/ — 5개
|
||
```
|
||
|
||
---
|
||
|
||
## 🔄 Kei API 연동
|
||
|
||
### 무한 재시도 메커니즘
|
||
```python
|
||
async def _retry_kei(fn, *args, **kwargs):
|
||
"""성공할 때까지 무한 재시도"""
|
||
while True:
|
||
result = await fn(*args, **kwargs)
|
||
if result is not None:
|
||
return result
|
||
await asyncio.sleep(10) # 10초 대기 후 재시도
|
||
```
|
||
|
||
**특징:**
|
||
- fallback 없음 (모든 판단을 Kei가 함)
|
||
- 타임아웃 없음 (10분이든 1시간이든 기다림)
|
||
- 성공 또는 명시적 실패만 가능
|
||
|
||
### 호출 파이프라인
|
||
```
|
||
design_agent (Sonnet)
|
||
↓ HTTP POST
|
||
persona_agent (Opus)
|
||
↓ (구조화된 프롬프트)
|
||
Kei 페르소나 (고급 OS 모델)
|
||
↓ (판단)
|
||
JSON 응답 (역직렬화)
|
||
↓
|
||
design_agent 계속 진행
|
||
```
|
||
|
||
---
|
||
|
||
## 📁 폴더 구조
|
||
|
||
```
|
||
design_agent/
|
||
├── CLAUDE.md ← 프로젝트 규칙 & 아키텍처 (이 파일)
|
||
├── README.md ← 사용자 가이드
|
||
├── PLAN.md ← 실행 계획 (태스크 목록)
|
||
├── PROGRESS.md ← 진행 상황 추적
|
||
├── pyproject.toml ← Python 의존성 정의
|
||
├── package.json ← Node.js 의존성 (프론트 관련)
|
||
│
|
||
├── src/ ← Python 소스 코드 (백엔드)
|
||
│ ├── main.py — FastAPI 서버
|
||
│ ├── pipeline.py — 파이프라인 메인 로직
|
||
│ ├── kei_client.py — Kei API 호출
|
||
│ ├── design_director.py — 2단계 레이아웃
|
||
│ ├── space_allocator.py — O-1, O-3 계산
|
||
│ ├── content_editor.py — 3단계 텍스트 정리
|
||
│ ├── renderer.py — 4단계 HTML 렌더링
|
||
│ ├── block_search.py — FAISS 블록 검색
|
||
│ ├── slide_measurer.py — Phase L 측정
|
||
│ ├── image_utils.py — 이미지 처리
|
||
│ ├── sse_utils.py — SSE 스트리밍
|
||
│ └── config.py — 설정
|
||
│
|
||
├── templates/ ← HTML 템플릿 & 블록 정의
|
||
│ ├── catalog.yaml — 38개 블록 라이브러리
|
||
│ ├── slide-base.html — 슬라이드 기본 구조
|
||
│ └── blocks/ — 블록별 HTML
|
||
│ ├── headers/ — 5개 헤더 블록
|
||
│ ├── cards/ — 10개 카드 블록
|
||
│ ├── tables/ — 3개 테이블 블록
|
||
│ ├── visuals/ — 6개 다이어그램 블록
|
||
│ ├── emphasis/ — 10개 강조 블록
|
||
│ └── media/ — 5개 미디어 블록
|
||
│
|
||
├── static/ ← CSS & 프론트엔드
|
||
│ ├── base.css — 슬라이드 스타일
|
||
│ ├── tokens.css — 디자인 토큰
|
||
│ └── index.html — 프론트엔드 UI
|
||
│
|
||
├── data/ ← 중간 산출물 & 인덱스
|
||
│ ├── runs/{timestamp}/ — 각 실행의 단계별 결과
|
||
│ │ ├── step1_analysis.json
|
||
│ │ ├── step1b_concepts.json
|
||
│ │ ├── step1c_containers.json
|
||
│ │ ├── step2_layout.json
|
||
│ │ ├── step2c_block_specs.json
|
||
│ │ ├── step3_filled_blocks.json
|
||
│ │ ├── step4_rendered.html
|
||
│ │ ├── step4_measurement_round*.json
|
||
│ │ ├── step5_screenshot.txt
|
||
│ │ └── final.html
|
||
│ ├── block_index.faiss — FAISS 인덱스
|
||
│ └── block_metadata.json — 메타데이터
|
||
│
|
||
├── docs/ ← 문서
|
||
│ ├── BLOCKS.md — 블록 라이브러리 설명
|
||
│ └── OUTPUTS.md — 산출물 구조
|
||
│
|
||
├── scripts/ ← 유틸리티 스크립트
|
||
│ ├── build_block_index.py — FAISS 인덱스 빌드
|
||
│ └── generate_run_report.py — 실행 리포트 생성
|
||
│
|
||
└── .env — 환경 변수 (API key, Kei API URL)
|
||
```
|
||
|
||
---
|
||
|
||
## 🚀 실행 흐름 (전체)
|
||
|
||
```
|
||
1. 사용자 입력
|
||
POST /api/generate
|
||
{
|
||
"content": "콘텐츠...",
|
||
"base_path": "/path/to/images"
|
||
}
|
||
|
||
2. SSE 스트리밍 시작
|
||
event: progress
|
||
data: "1/5 Kei 실장이 꼭지를 추출 중..."
|
||
|
||
3. 파이프라인 실행 (pipeline.py)
|
||
├─ [1단계] kei_client.py: classify_content()
|
||
│ → Kei API 호출, 꼭지 5개 추출
|
||
│
|
||
├─ [1B] kei_client.py: refine_concepts()
|
||
│ → Kei API, 컨셉 구체화
|
||
│
|
||
├─ [O-1] space_allocator.py: calculate_container_specs()
|
||
│ → 결정론적 계산, 비중 → px
|
||
│
|
||
├─ [2] design_director.py:
|
||
│ ├─ select_preset() — 규칙 기반 프리셋 선택
|
||
│ └─ create_layout_concept() — Sonnet: 블록 매핑
|
||
│
|
||
├─ [O-3] space_allocator.py: finalize_block_specs()
|
||
│ → 블록별 스펙 확정
|
||
│
|
||
├─ [3] content_editor.py: fill_content()
|
||
│ → Kei API: 텍스트 정리
|
||
│
|
||
├─ [4] renderer.py: render_slide()
|
||
│ → Jinja2: HTML 생성
|
||
│
|
||
├─ [Phase L] slide_measurer.py: measure_rendered_heights()
|
||
│ → Selenium: 실제 높이 측정
|
||
│
|
||
└─ [5] kei_client.py: call_kei_final_review()
|
||
→ Opus 멀티모달: 최종 검수
|
||
|
||
4. 최종 출력
|
||
event: result
|
||
data: {
|
||
"html": "<html>...</html>",
|
||
"runs_id": "1774588279782"
|
||
}
|
||
|
||
5. 프론트엔드
|
||
├─ iframe에 HTML 미리보기
|
||
├─ 다운로드 버튼 (final.html)
|
||
└─ 리포트 버튼 (report.html)
|
||
```
|
||
|
||
---
|
||
|
||
## 🔍 핵심 원칙
|
||
|
||
| 원칙 | 설명 | 구현 |
|
||
|------|------|------|
|
||
| **비중 우선** | 비중이 모든 것을 결정 | Kei가 page_structure 판단 → space_allocator 계산 |
|
||
| **텍스트 기준** | 디자인이 텍스트에 맞춤 | renderer.py에서 폰트/여백 조정 |
|
||
| **Kei API 필수** | fallback 없음, 무한 재시도 | pipeline.py _retry_kei() |
|
||
| **결정론적 계산** | 규칙 기반 자동화 | space_allocator.py, design_director.py Step A |
|
||
| **역할 분리** | 각 역할이 자신의 영역만 담당 | CLAUDE.md Table "역할 분리" |
|
||
| **원본 보존** | 콘텐츠 의미 손상 X | content_editor.py 원칙 |
|
||
| **중간 산출물** | 모든 단계를 추적 가능하게 | _save_step() 함수 |
|
||
|
||
---
|
||
|
||
## 📊 Phase별 상태
|
||
|
||
| Phase | 내용 | 상태 |
|
||
|-------|------|------|
|
||
| **A~D** | 슬라이드 품질 핵심 | ✅ 완료 |
|
||
| **G** | Kei API 통신 정상화 | ✅ 완료 |
|
||
| **H** | 스토리라인 설계 기반 전환 | ✅ 완료 |
|
||
| **I** | 정합성 복구 + 넘침 처리 | ✅ 완료 |
|
||
| **J** | 블록 선택 권한 구조 재정의 | ✅ 완료 |
|
||
| **K** | communicative role 기반 위계 | ✅ 완료 |
|
||
| **K-1** | 파이프라인 스텝별 중간 산출물 저장 | ✅ 완료 |
|
||
| **L** | Selenium 렌더링 측정 + 피드백 루프 | ⚠️ 진행 중 |
|
||
| **M** | Kei 비중 시스템 강화 | ✅ 완료 |
|
||
| **N** | 4대 핵심 문제 해결 | ✅ 완료 |
|
||
| **O** | 컨테이너 기반 레이아웃 시스템 | 🔄 진행 중 |
|
||
|
||
---
|
||
|
||
## 🎯 결론
|
||
|
||
**Design Agent는:**
|
||
- ✅ 전문가 사고 기반 (Kei 실장, 디자인 팀장, 편집자, 실무자의 역할 분리)
|
||
- ✅ 결정론적 계산과 AI 판단의 조합
|
||
- ✅ 모든 단계를 추적 가능하게 설계
|
||
- ✅ 텍스트 우선, 디자인은 그에 맞춤
|
||
- ✅ 비중 기반 동적 레이아웃
|
||
- ✅ Kei API 필수, fallback 없음
|
||
|
||
현재 진행 상태:
|
||
- **Core 완성:** 1~4단계, O-1, O-3 명확히 작동
|
||
- **진행 중:** Phase L (피드백 루프), Phase O (세부 개선)
|
||
- **테스트 필요:** BF-4, BF-5, BF-6, BF-7 (렌더링 버그)
|
||
|