Files
C.E.L_Slide_test2/PIPELINE.md

13 KiB
Raw Blame History

Design Agent 파이프라인 현황

최종 갱신: 2026-04-13 목적: 새 세션의 AI가 이 문서만 읽으면 파이프라인 전체를 이해하고 작업할 수 있도록 한다.


1. 전체 흐름 요약

MDX 입력
  ↓
[Stage 0]  MDX 정규화              (코드)
  ↓
[Stage 1A] Kei 실장 — 꼭지 추출     (AI: Opus)
           → layout_template: A 또는 B 선택
  ↓
[Stage 1B] 컨셉 구체화              (AI: Opus)
           → relation_type, expression_hint, source_data
  ↓
[Stage 1B-ST] 구조화 텍스트 생성     (AI: Opus)
           → structured_text per topic
  ↓
[Stage 1.5a] 컨테이너 계산          (코드: 결정론적)
           → FontHierarchy, ContainerSpec, Preset
  ↓
[Stage 1.7] 블록 레퍼런스 선택       (코드 + AI 1회)
           → relation_type → 카테고리 → 필터 → 블록 결정
  ↓
[Stage 1.8] 적합성 검증 + 보강       (코드 + Selenium + AI)
           → overflow 감지 → Kei 에스컬레이션 → 재배분
  ↓
[Stage 1.5b] 디자인 예산 계산        (코드)
  ↓
[Stage 2]  HTML 생성                 (Type에 따라 다름)
           → Type B/B'/B'': block_assembler (코드)
           → Type A: Sonnet 재구성 (AI, 미완성)
  ↓
[Stage 3]  렌더링 조립               (Type A만, Jinja2)
  ↓
[Stage 4]  검증                     (Selenium + Opus Vision)
           → overflow 측정 + 스크린샷 품질 평가
  ↓
최종 HTML 출력 (data/runs/{id}/final.html)

2. 레이아웃 유형 (Type A / B / B' / B'')

2.1 Kei가 선택하는 유형: A와 B

Kei 프롬프트(src/kei_client.py:34-46)에서 A 또는 B를 선택한다.

유형 조건 Zone 구조
Type A 참조자료(용어 정의, 부록 등)가 별도로 존재 body(배경+본심) + sidebar(첨부) + footer(결론)
Type B 본문 흐름만. 배경/첨부가 없거나 억지로 만들어야 하면 top + bottom_left + bottom_right + footer

2.2 Type B 변형: B'과 B''

B'과 B''은 Kei가 선택하지 않는다. 특정 MDX 테스트 과정에서 하드코딩한 변형이다.

변형 생성 경위 차이점 코드 위치
B 범용 상단(전체폭 텍스트+이미지) + 하단 2분할 + 결론 block_assembler.py:461 _assemble_slide_html_type_b()
B' 03번 MDX 테스트 중 생성 상단이 세로 카드 형태 + 하단에 표 렌더링 + 불릿 전용 block_assembler.py:885 _assemble_slide_html_type_b_prime()
B'' B'에서 스타일 변형 border/gradient 없음. 색상바+여백으로 구분 block_assembler_b2.py:9 _assemble_slide_html_type_b_double_prime()

분기 코드 (block_assembler.py:370-378):

if ctx.analysis.layout_template == "B":
    return _assemble_slide_html_type_b(ctx, title_text)
if ctx.analysis.layout_template == "B'":
    return _assemble_slide_html_type_b_prime(ctx, title_text)
if ctx.analysis.layout_template == "B''":
    return _assemble_slide_html_type_b_double_prime(ctx, title_text)

2.3 향후 방향

B'/B''은 범용화가 필요하다. 현재는 03번 콘텐츠 구조(카드형+표)를 B 조립 함수가 커버하지 못해서 만든 땜질이다. 궁극적으로는 B 하나로 다양한 콘텐츠 구조를 커버하거나, AI가 서브타입을 판단하게 해야 한다.


3. MDX 샘플 ↔ 유형 매핑

MDX 파일 콘텐츠 성격 선택 유형 상태
01번 samples/mdx/01. 건설산업 DX의 올바른 이해(0127).mdx 용어 혼용 문제 + 용어 정의(참조) Type A ⚠ Stage 2 미완성 (Sonnet 의존)
02번 samples/mdx/02. DX의 시행 목표 및 기대효과.mdx 본문 흐름 (3대 목표) Type B 동작
03번 samples/mdx/03. DX 시행을 위한 필수 요건 및 혁신 방안.mdx 카드형 구조 + 표 + 불릿 Type B' 동작 (하드코딩)

4. 단계별 상세

Stage 0: MDX 정규화

  • 파일: src/mdx_normalizer.pynormalize_mdx_content()
  • 입력: raw MDX 텍스트
  • 출력: NormalizedContent (sections, images, tables 분리)

Stage 1A: Kei 실장 — 꼭지 추출

  • 파일: src/kei_client.pyclassify_content()
  • AI: Opus (Kei API)
  • 입력: 정규화된 텍스트
  • 출력: Analysis (title, core_message, layout_template, total_pages, page_structure, topics)
  • 핵심 판단:
    • 꼭지 5개 이내 추출
    • 각 꼭지에 purpose, layer, role, emphasis, direction 부여
    • layout_template = "A" 또는 "B" 선택
    • page_structure에 역할별 weight(비중) 배정

Stage 1B: 컨셉 구체화

  • 파일: src/kei_client.pyrefine_concepts()
  • AI: Opus
  • 출력: topics에 relation_type, expression_hint, source_data 추가

Stage 1B-ST: 구조화 텍스트 생성

  • 파일: src/kei_client.pygenerate_structured_text()
  • AI: Opus
  • 출력: topic별 structured_text (마크다운 형태)

Stage 1.5a: 컨테이너 계산 (결정론적)

  • 파일: src/space_allocator.py
  • 함수:
    • Type A → calculate_container_specs()
    • Type B/B'/B'' → build_containers_type_b()
    • 공통 → calculate_font_hierarchy(), select_preset()
  • 입력: page_structure의 weight, slide 크기(1280×720)
  • 출력: 역할별 ContainerSpec (width_px, height_px, zone)
  • 로직: weight × available_px = 각 zone px 확정

Stage 1.7: 블록 레퍼런스 선택

  • 파일: src/block_reference.pyselect_and_generate_references()
  • 로직 (코드 결정론적 + AI 1회):
    1. relation_type → 블록 카테고리 매핑
    2. expression_hint 키워드 매칭
    3. 컨테이너 크기 적합성 필터
    4. role/zone 제약 (sidebar → visuals/media 제외)
    5. catalog.yaml 존재 검증 (유령 블록 차단)
    6. 후보 2-3개 → Kei 1회 호출로 최종 선택
  • 출력: 역할별 BlockReference (block_id, design_reference_html)

Stage 1.8: 적합성 검증 + 보강

  • 파일: src/fit_verifier.pycalculate_fit()
  • 로직:
    1. 텍스트 분량 vs 할당 공간 계산
    2. Selenium으로 실제 높이 측정 (3회 루프)
    3. overflow 시 → Kei 에스컬레이션 (call_kei_fit_escalation())
      • 팝업 분리 판단, zone 간 재배분
    4. 보강 제안: bold 키워드, 팝업 요약 등

Stage 2: HTML 생성

Type B/B'/B'' (코드 조립):

  • 파일: src/block_assembler.pyassemble_slide_html()
  • 역할별 assemble_role_html() 호출 → 블록 HTML 조립
  • structured_text + design_reference_html 결합
  • 이미지/팝업 embed
  • 즉시 완성 HTML 반환

Type A (AI 재구성, 미완성):

  • 파일: src/content_verifier.pygenerate_with_retry()
  • Sonnet에 phase_t_context 전달 → CSS + 레이아웃 생성
  • 현재 검증 불완전

Stage 3: 렌더링 조립 (Type A만)

  • 파일: src/renderer.pyrender_slide_from_html()
  • Type B는 Stage 2에서 완전한 HTML이므로 스킵

Stage 4: 검증

  • 파일: src/slide_measurer.py
    • measure_rendered_heights() — Selenium 실측
    • capture_slide_screenshot() — 스크린샷 캡처
  • 파일: src/kei_client.pyvision_quality_gate()
    • Opus 멀티모달: 스크린샷 보고 시각 품질 평가

5. 핵심 파일 맵

src/
├── main.py                 ← FastAPI 서버, POST /api/generate
├── pipeline.py             ← 파이프라인 오케스트레이터 (generate_slide)
├── pipeline_context.py     ← PipelineContext 데이터 클래스
├── config.py               ← 설정 (API key, 슬라이드 크기)
│
├── mdx_normalizer.py       ← Stage 0: MDX → NormalizedContent
├── kei_client.py           ← Stage 1A/1B/1B-ST: Kei API 호출 + 프롬프트
├── space_allocator.py      ← Stage 1.5a: 컨테이너 px 계산
├── block_reference.py      ← Stage 1.7: 블록 선택 (relation_type 기반)
├── fit_verifier.py         ← Stage 1.8: 적합성 검증 + Selenium 루프
├── block_assembler.py      ← Stage 2: Type B/B' HTML 조립
├── block_assembler_b2.py   ← Stage 2: Type B'' HTML 조립
├── content_verifier.py     ← Stage 2: Type A HTML (Sonnet, 미완성)
├── renderer.py             ← Stage 3: Jinja2 렌더링 (Type A만)
├── slide_measurer.py       ← Stage 4: Selenium 측정 + 스크린샷
├── validators.py           ← Kei 응답 검증 (A/B별 구조 확인)
│
├── image_utils.py          ← 이미지 크기 측정 + data URI 변환
├── svg_calculator.py       ← SVG 다이어그램 좌표 계산
└── sse_utils.py            ← SSE 스트리밍 유틸

templates/
├── slide-base.html         ← 슬라이드 기본 구조 (Jinja2, CSS Grid)
├── catalog.yaml            ← 블록 라이브러리 정의 (50+개)
└── blocks/                 ← 블록 HTML 템플릿
    ├── headers/   (8개)
    ├── cards/     (17개)
    ├── emphasis/  (12개)
    ├── tables/    (8개)
    ├── visuals/   (6개)
    ├── media/     (4개)
    └── BEPs/      (6개)

6. 데이터 흐름 (PipelineContext)

PipelineContext:
  raw_content          ← 원본 MDX
  normalized           ← NormalizedContent (sections, images, tables)
  analysis             ← Analysis (title, core_message, layout_template, page_structure, topics)
  topics               ← list[Topic] (relation_type, expression_hint, structured_text 포함)
  page_structure       ← PageStructure (roles → {topic_ids, weight, zone})
  containers           ← dict[role → ContainerSpec(width_px, height_px)]
  font_hierarchy       ← FontHierarchy (key_msg, core, bg, sidebar 폰트 크기)
  references           ← dict[role → list[BlockReference]]
  sub_layouts          ← dict[role → SubLayout]
  fit_result           ← 역할별 fit_status, 재배분값
  enhancement_result   ← bold_keywords, popup_summaries 등
  generated_html       ← Stage 2 출력
  rendered_html        ← Stage 3 출력 (완전 HTML)
  measurement          ← Selenium 측정값
  quality_score        ← 0-100

7. 현재 구현 상태 (Phase Y-11~13, 2026-04-15)

Phase Y: slide-base 기반 파이프라인 재설계. 상세: docs/history/PHASE-Y-PLAN.md

파이프라인 흐름 (현재)

[Stage 0] MDX → normalized.sections (source of truth)
[Stage 1A] Kei 꼭지 추출 (영역/zone 판단 안 함)
[Phase Y] 코드: normalized → 대목차 추출 → group schema 분류 → 블록 매칭 → 영역 확정
[Stage 1.5a] space_allocator: weight → zone px (% 기반)
[Stage 1.7] block_reference: tag_match → schema_match → fallback 순서
[Stage 1.8] assembler(measure_mode) → Selenium 측정 → fit 루프
[Stage 2] assembler(slide-base + 블록) → final HTML
[Stage 4] Selenium overflow + 비전 (-1 미평가)

MDX별 상태

MDX 상태 비고
03 동작 prerequisites-3col + pp2. 텍스트 누락 없음. 회귀 기준.
02 ⚠ schema 1차 top: parallel_3_with_image. bottom: 분류 정교화 필요.
01 미착수 Type A. 별도 작업.

핵심 원칙 (확립됨)

  • source of truth = normalized.sections (Stage 0)
  • 영역 = 코드가 결정 (Kei 아님). sub_titles 기반 + group schema.
  • 블록 CSS에 최종 고정값. slide_font_css는 공통 레이아웃 계약만.
  • zone = % 기반, block = height:100%.
  • 글씨 크기 고정. fit은 padding → 내용량 → font 1단계(responsive tier).
  • 기존 경로 삭제 금지. 새 schema 점진적 추가. MDX 03 회귀 기준.
  • 하드코딩 금지. 프로세스가 결과를 만드는 구조.
  1. 블록 글씨 크기 하드코딩 (px 고정)
    • 블록 CSS에 font-size가 Figma 원본 px로 고정
    • 컨테이너 크기에 따라 조정 불가 → overflow 원인
    • CSS 변수(var(--block-font-heading))로 전환 → assembler가 zone 크기에 따라 계산

미해결 프로세스

  1. overflow 시 font 조정 루프 — 재배분만으로 부족할 때 font/padding 줄이기 (Y-5)
  2. Sonnet redesign 경로 — tag 매칭 실패 시 블록 단위 redesign → 저장 (Y-6)

8. 검증 계획

업데이트된 템플릿이 파이프라인에서 제대로 동작하는지 확인한다.

MDX 유형 검증 포인트
01번 Type A 업데이트된 블록 + slide-base.html로 조립 정상 동작
02번 Type B 업데이트된 블록 선택 + 조립 + overflow 없음
03번 Type B' 카드/표 구조가 업데이트된 템플릿으로 정상 렌더링

검증 방법

  1. 각 MDX를 파이프라인에 투입
  2. 중간 산출물(step1_analysis.json 등) 확인 — 블록 선택이 의도대로인지
  3. 최종 HTML(final.html) 렌더링 — overflow, 시각 품질 확인
  4. 업데이트 전/후 비교