# Kei Design Agent 콘텐츠를 시각적으로 구조화된 슬라이드 HTML(1280×720px, 16:9)로 변환하는 AI 파이프라인. ## 개요 텍스트/MDX 콘텐츠를 입력하면 Kei 실장(Opus)이 정보 구조와 비중을 판단하고, 그 비중대로 컨테이너를 확정하고, 블록을 선택하고, 텍스트를 편집하여 슬라이드를 생성한다. **핵심 특징:** - 콘텐츠마다 비중이 동적으로 변한다 (본심 60% / 배경 20% 등 — Kei가 매번 판단) - 비중이 컨테이너 px를 확정 → 블록과 텍스트가 컨테이너에 맞춰진다 - Kei API 필수. fallback 없음. 성공할 때까지 무한 재시도. --- ## 파이프라인 (6단계) ``` 텍스트 입력 ↓ [1단계] Kei 실장 — 꼭지 추출 + 비중 판단 (Kei API / Opus) ↓ [1.5단계] Kei 실장 — 컨셉 구체화 (Kei API / Opus) ↓ [컨테이너 계산] 비중 → px 확정 (코드, 결정론적) ↓ [2단계] 블록 확정 + 배치 (Kei API + Sonnet) ↓ [블록 스펙 확정] 항목수/글자수/폰트 (코드, 결정론적) ↓ [3단계] Kei 편집자 — 텍스트 정리 (Kei API / Opus) ↓ [4단계] 디자인 실무자 — CSS 조정 + HTML 조립 (Sonnet + Jinja2) ↓ [Phase L] Selenium 렌더링 측정 → 피드백 루프 ↓ [5단계] Kei 실장 — 최종 검수 (스크린샷) (Opus 멀티모달) ↓ 완성 슬라이드 HTML ``` ### 단계별 상세 | 단계 | 담당 | AI | 역할 | |------|------|-----|------| | **1A** | Kei 실장 | Kei API (Opus) | 핵심 메시지, 꼭지 추출, page_structure(비중), purpose 부여 | | **1B** | Kei 실장 | Kei API (Opus) | relation_type, expression_hint, source_data | | **컨테이너** | 코드 | — | Kei 비중 → 역할별 컨테이너 px 확정, height_cost 제약, 블록 스펙 | | **2 A-2** | Kei 실장 | Kei API (Opus) | 컨테이너 제약 보고 블록 확정 (FAISS 후보 기반) | | **2 B** | 디자인 팀장 | Sonnet | zone 배치 + char_guide만 (블록 타입 변경 불가) | | **블록 스펙** | 코드 | — | 컨테이너 크기 → 항목수/글자수/폰트/패딩 확정 | | **3** | Kei 편집자 | Kei API (Opus) | 텍스트 편집 (컨테이너 제약 준수, 원본 보존) | | **4** | 디자인 실무자 | Sonnet | CSS 변수 override + Jinja2 렌더링 | | **Phase L** | 코드 | Selenium | 렌더링 측정 → overflow 감지 → 편집자 재호출 | | **5** | Kei 실장 | Opus | 스크린샷 보고 최종 검수 (멀티모달) | ### 핵심 원칙 - **비중 → 컨테이너 → 블록 → 콘텐츠** 순서. 비중이 모든 것을 결정 - **Kei API 필수.** fallback 없음. 기본값 없음. 성공할 때까지 무한 재시도 - **Sonnet은 zone 배치 + CSS 조정만.** 블록 선택/콘텐츠 판단 금지 - **블록 선택은 Kei가 확정 → 코드가 강제.** Sonnet이 변경 불가 - **텍스트가 기준.** 디자인이 텍스트에 맞춤. CSS로 사후 자르기 금지 --- ## 컨테이너 시스템 (Phase O) Kei가 판단한 비중이 시각적 레이아웃에 정확히 반영되는 구조. ``` 슬라이드 1280×720px ├── header: 제목 (~60px 고정) ├── body (65%): 490px │ ├── 배경 컨테이너: 490 × 20% = 98px ← Kei 비중으로 확정 │ │ └── 문제제기 + 근거사례 (compact 블록만) │ └── 본심 컨테이너: 490 × 60% = 294px ← Kei 비중으로 확정 │ └── 핵심전달 (large/xlarge 블록 가능) ├── sidebar (35%): 490px │ └── 첨부 컨테이너: 490px 전체 │ └── 용어 정의 (여유 있게) └── footer: 결론 (~60px 고정) └── banner-gradient (핵심 메시지 한 줄) ``` - 컨테이너 높이(px)가 블록의 height_cost를 제약 - 컨테이너 크기에서 항목수/글자수/폰트/패딩이 자동 계산 - 편집자에게 컨테이너 제약이 전달되어 텍스트 분량이 맞춰짐 --- ## 개선 이력 | Phase | 내용 | 상태 | |-------|------|------| | **A~D** | 슬라이드 품질 핵심 (디자인 조정, overflow 방지, 이미지 처리) | 완료 | | **G** | Kei API 통신 정상화 (SSE 스트리밍, Sonnet fallback 제거, GPU 분리) | 완료 | | **H** | 스토리라인 설계 기반 전환 (core_message, purpose, source_hint) | 완료 | | **I** | 전수 정합성 복구 + 넘침 처리 패러다임 전환 (14건) | 완료 | | **J** | 블록 선택 권한 구조 재정의 + 최종 검토 Kei 전환 | 완료 | | **K** | communicative role 기반 시각적 위계 + purpose별 분량 제약 | 완료 | | **K-1** | 파이프라인 스텝별 중간 산출물 로컬 저장 (`data/runs/`) | 완료 | | **L** | 렌더링 측정 에이전트 (Selenium headless) + 피드백 루프 | 완료 | | **M** | Kei 비중 시스템 (page_structure weight) + 원본 보존 강화 | 완료 | | **N** | 4대 핵심 문제 해결 — catalog 개선, fallback 전면 제거, topic_id 버그 수정, 무한 재시도 | 완료 | | **O** | 컨테이너 기반 레이아웃 시스템 — 비중→px→블록제약→콘텐츠제약 | **진행 중** | --- ## 중간 산출물 파이프라인 실행마다 `data/runs/{timestamp}/`에 단계별 결과가 저장된다. | 파일 | 단계 | 내용 | |------|------|------| | `step1_analysis.json` | 1A | 꼭지 추출, page_structure(비중), core_message | | `step1b_concepts.json` | 1B | relation_type, expression_hint, source_data | | `step1c_containers.json` | O-1 | 역할별 컨테이너 스펙 (height_px, width_px, max_height_cost) | | `step2_layout.json` | 2 | 블록 배치 (area, type, purpose, reason) | | `step2c_block_specs.json` | O-3 | 블록별 스펙 (_max_items, _max_chars, _font_size_px) | | `step3_filled_blocks.json` | 3 | 텍스트 편집 결과 (data, char_count) | | `step4_css_adjustment.json` | 4 | CSS 변수 override | | `step4_rendered.html` | 4 | 렌더링된 HTML | | `step4_measurement_round*.json` | Phase L | Selenium 측정 (scrollHeight, overflow) | | `step5_review_round*.json` | 5 | Kei 검수 결과 | | `final.html` | 최종 | 완성 슬라이드 | | `report.html` | 리포트 | 전 단계 시각화 리포트 | 리포트 생성: `python scripts/generate_run_report.py` --- ## 블록 라이브러리 (38개) 6개 카테고리, 38개 블록. 각 블록은 `catalog.yaml`에 용도(when), 금지(not_for), purpose_fit이 정의됨. | 카테고리 | 개수 | 용도 | |---------|------|------| | **headers** | 5 | 타이틀, 꼭지 헤더 | | **cards** | 9 | 항목 나열, 카드 그리드 | | **tables** | 3 | 비교표, 데이터 테이블 | | **visuals** | 6 | SVG 다이어그램, 관계도 | | **emphasis** | 10 | 강조, 인용, 결론, 불릿 | | **media** | 5 | 이미지/사진 | FAISS 블록 검색: bge-m3 1024차원 임베딩 → 꼭지별 관련 블록 후보 추출 --- ## 기술 스택 | 역할 | 도구 | |------|------| | 서버 | FastAPI + uvicorn (포트 8001) | | AI (Kei 실장/편집자) | Kei API → Opus (localhost:8000) | | AI (디자인 팀장/실무자) | Anthropic API → Sonnet | | AI (최종 검수) | Anthropic API → Opus (멀티모달) | | 블록 검색 | FAISS + bge-m3 | | 템플릿 | Jinja2 | | 렌더링 | CSS Grid + 디자인 토큰 (1280×720) | | 렌더링 측정 | Selenium headless Chrome | | SVG 시각화 | svg_calculator.py (N개 동적 배치) | | 이미지 | Pillow (크기 측정) + base64 인라인 | | 폰트 | Pretendard Variable | | 공간 계산 | space_allocator.py (결정론적) | --- ## 설치 및 실행 ```bash # 설치 cd design_agent pip install -e . # FAISS 인덱스 빌드 (블록 추가/수정 시) python scripts/build_block_index.py # .env 설정 ANTHROPIC_API_KEY=sk-ant-... KEI_API_URL=http://localhost:8000 LOG_LEVEL=DEBUG ``` ```bash # 터미널 1: Kei API (필수) cd D:\ad-hoc\kei\persona_agent python -m uvicorn backend.main:app --host 127.0.0.1 --port 8000 # 터미널 2: Design Agent cd D:\ad-hoc\kei\design_agent python -m uvicorn src.main:app --host 127.0.0.1 --port 8001 --reload ``` 접속: http://localhost:8001 --- ## 프로젝트 구조 ``` design_agent/ ├── src/ │ ├── main.py FastAPI 서버 (포트 8001) │ ├── config.py 설정 (pydantic-settings) │ ├── pipeline.py 파이프라인 오케스트레이션 (6단계) │ ├── kei_client.py Kei API 클라이언트 (1A, 1B, 검수, 넘침 판단) │ ├── design_director.py 2단계: 프리셋 + Kei 블록 확정 + Sonnet zone 배치 │ ├── content_editor.py 3단계: Kei API 텍스트 편집 │ ├── renderer.py 4단계: HTML 조립 (컨테이너 grid + Jinja2) │ ├── space_allocator.py 컨테이너 스펙 계산 + 블록 스펙 확정 (Phase O) │ ├── slide_measurer.py Selenium 렌더링 측정 + 스크린샷 (Phase L/N) │ ├── block_search.py FAISS 블록 검색 │ ├── svg_calculator.py SVG 좌표 계산 (N개 동적 배치) │ ├── image_utils.py 이미지 크기 측정 + base64 삽입 │ └── sse_utils.py SSE 스트리밍 유틸 │ ├── templates/ │ ├── slide-base.html 슬라이드 베이스 │ ├── catalog.yaml 블록 카탈로그 (38개, when/not_for/purpose_fit) │ └── blocks/ 블록 라이브러리 (6 카테고리) │ ├── scripts/ │ ├── build_block_index.py FAISS 인덱스 빌드 │ └── generate_run_report.py 실행 리포트 생성 │ ├── static/ 프론트엔드 (index.html, CSS) ├── data/ 로컬 데이터 (runs/, FAISS 인덱스) ├── docs/ 기술 조사, Figma 분석 │ ├── IMPROVEMENT.md 개선 계획 총괄 (Phase A~O) ├── IMPROVEMENT-PHASE-*.md 각 Phase 상세 └── PROGRESS.md 진행 상황 추적 ``` --- ## Kei Persona와의 관계 ``` Kei Persona Agent (localhost:8000) ├── Opus + RAG + 세션 컨텍스트 ├── 도메인 지식 (건설/DX/BIM) └── 대화/생성/피드백/실행 모드 Design Agent (localhost:8001, 이 프로젝트) ├── 슬라이드 생성 전용 ├── Kei API로 실장(1단계) + 편집자(3단계) + 블록 확정(2단계) 호출 ├── 최종 검수(5단계)는 Opus 직접 호출 (멀티모달 스크린샷) └── 두 프로젝트는 독립. 코드 공유 없음. API 연동만. ```