Add Type B slide pipeline and recipe rendering updates
This commit is contained in:
431
README.md
431
README.md
@@ -1,303 +1,248 @@
|
||||
# Kei Design Agent
|
||||
|
||||
콘텐츠를 시각적으로 구조화된 슬라이드 HTML(1280×720px, 16:9)로 변환하는 AI 파이프라인.
|
||||
MDX 콘텐츠를 분석해 1280x720 슬라이드 HTML로 변환하는 파이프라인입니다.
|
||||
|
||||
## 개요
|
||||
이 문서는 "지금 실제 코드 기준으로 파이프라인이 어떻게 동작하는지"를 빠르게 파악하기 위한 개요 문서입니다. 과거 Phase 문서와 일부 legacy 경로는 남아 있지만, 아래 설명은 현재 메인 경로를 기준으로 정리했습니다.
|
||||
|
||||
텍스트/MDX 콘텐츠를 입력하면:
|
||||
1. Kei 실장(Opus)이 정보 구조와 비중을 판단하고
|
||||
2. 코드가 컨테이너 크기를 계산하고
|
||||
3. 블록을 선택하고
|
||||
4. 콘텐츠-컨테이너 적합성을 검증하고
|
||||
5. AI(Sonnet)가 블록 디자인을 참고하여 HTML을 생성하고
|
||||
6. 코드가 슬라이드 프레임에 조립하고
|
||||
7. 측정+비전 모델로 검증합니다
|
||||
## 한눈에 보기
|
||||
|
||||
---
|
||||
파이프라인의 큰 흐름은 아래와 같습니다.
|
||||
|
||||
## 파이프라인 (10단계)
|
||||
1. MDX를 코드가 정규화한다.
|
||||
2. Kei가 문서의 의미와 topic을 읽는다.
|
||||
3. 코드는 `normalized.sections`를 기준으로 실제 슬라이드 구조를 다시 만든다.
|
||||
4. 코드는 schema, recipe, tag를 바탕으로 블록을 고른다.
|
||||
5. Type B는 코드가 템플릿을 조립해 `final.html`을 만든다.
|
||||
6. Type A는 아직 AI/renderer 비중이 더 크다.
|
||||
7. Selenium과 vision gate로 측정/검증한 뒤 run 산출물을 저장한다.
|
||||
|
||||
```
|
||||
MDX 원본
|
||||
↓
|
||||
[Stage 0] MDX 정규화 (코드)
|
||||
↓
|
||||
[Stage 1A] 꼭지 추출 + 영역 배정 (Kei API / Opus)
|
||||
↓
|
||||
[Stage 1B] 컨셉 구체화 (Kei API / Opus)
|
||||
↓
|
||||
[Stage 1.5a] 컨테이너 초기 계산 (코드)
|
||||
↓
|
||||
[Stage 1.7] 블록 선택 (코드)
|
||||
↓
|
||||
[Stage 1.8] 적합성 검증 + 재배분 + 보강 (코드 + Kei 에스컬레이션)
|
||||
↓
|
||||
[Stage 1.5b] 디자인 예산 재계산 (코드)
|
||||
↓
|
||||
[Stage 2] HTML 생성 (영역별 개별 호출) (Claude Sonnet)
|
||||
↓
|
||||
[Stage 3] 렌더링 조립 + 후처리 (코드)
|
||||
↓
|
||||
[Stage 4] 측정 + 품질 검증 (Selenium + Opus Vision)
|
||||
↓
|
||||
검증 통과 시 → final.html 저장 + 팝업 분리 (파일 출력)
|
||||
```
|
||||
핵심 원칙은 다음과 같습니다.
|
||||
|
||||
※ Stage 4 이후의 파일 저장은 별도 Stage가 아닌 후처리입니다.
|
||||
- source of truth는 `normalized.sections`
|
||||
- block 선택은 문서명 하드코딩이 아니라 shape, schema, tag 기반
|
||||
- 흐름의 우선순위는 `구조 -> payload -> layout -> fit`
|
||||
- popup/detail은 overflow를 덮는 임시 장치가 아니라 `메인 요약 + 상세 보기`의 2단 표현 계약
|
||||
|
||||
---
|
||||
## 타입 구조
|
||||
|
||||
## 단계별 상세
|
||||
현재 메인 타입 선택은 사실상 `A`와 `B`입니다.
|
||||
|
||||
### Stage 0: MDX 정규화
|
||||
### Type A
|
||||
|
||||
| 항목 | 내용 |
|
||||
|------|------|
|
||||
| **목적** | 원본 MDX에서 JSX/frontmatter를 제거하고, 섹션/팝업/이미지/테이블로 분리 |
|
||||
| **적용기술** | 코드 (`normalize_mdx_content()`) |
|
||||
| **인풋** | 원본 MDX 문자열 |
|
||||
| **아웃풋** | `normalized` — clean_text, title, sections[], popups[], images[], tables[] |
|
||||
| **연계** | → Stage 1A가 clean_text를 Kei에게 전달 |
|
||||
- 본문 외에 sidebar, reference, 부록성 영역이 함께 필요한 슬라이드
|
||||
- 현재는 Type B보다 덜 닫혀 있고, AI 생성 + renderer 경로 비중이 큽니다
|
||||
|
||||
### Stage 1A: 꼭지 추출 + 영역 배정
|
||||
### Type B
|
||||
|
||||
| 항목 | 내용 |
|
||||
|------|------|
|
||||
| **목적** | 콘텐츠에서 핵심 파트(꼭지)를 식별하고, 슬라이드의 어떤 영역(배경/본심/첨부/결론)에 배치할지 결정 |
|
||||
| **적용기술** | Kei API (`classify_content()`) |
|
||||
| **인풋** | normalized.clean_text |
|
||||
| **아웃풋** | `topics[]` (id, title, purpose, layer, relation_type, expression_hint), `page_structure` (role별 topic_ids, weight) |
|
||||
| **연계** | → Stage 1B가 각 꼭지를 구체화 |
|
||||
- top, bottom 같은 본문 zone 조합으로 해결되는 슬라이드
|
||||
- 현재 가장 안정적인 메인 경로입니다
|
||||
- 최근 구조화 작업은 대부분 이 Type B 경로를 중심으로 진행되었습니다
|
||||
|
||||
### Stage 1B: 컨셉 구체화
|
||||
### Type B' / B''
|
||||
|
||||
| 항목 | 내용 |
|
||||
|------|------|
|
||||
| **목적** | 각 꼭지에 실제 원본 텍스트(source_data)와 요약(summary)을 매핑 |
|
||||
| **적용기술** | Kei API (`refine_concepts()`) |
|
||||
| **인풋** | topics + clean_text |
|
||||
| **아웃풋** | `topics` 업데이트 — source_data, summary 추가 |
|
||||
| **연계** | → Stage 1.5a가 텍스트 양을 기반으로 컨테이너 비율 계산 |
|
||||
- 역사적으로 실험/호환 경로에서 나온 변형입니다
|
||||
- 문서와 일부 legacy 코드에 흔적이 남아 있습니다
|
||||
- 현재 메인 개념의 1급 타입으로 보기보다, 과거 흐름과 호환 레이어로 이해하는 편이 맞습니다
|
||||
|
||||
### Stage 1.5a: 컨테이너 초기 계산
|
||||
## 단계별 파이프라인
|
||||
|
||||
| 항목 | 내용 |
|
||||
|------|------|
|
||||
| **목적** | 폰트 위계 확정 + 슬라이드 내 영역별 컨테이너 크기(px) 계산 + 프리셋 선택 |
|
||||
| **적용기술** | 코드 (`calculate_font_hierarchy()`, `calculate_dynamic_ratio()`, `calculate_container_specs()`) |
|
||||
| **인풋** | topics, page_structure (weight), preset |
|
||||
| **아웃풋** | `font_hierarchy` (key_msg/core/bg/sidebar px), `container_ratio` (71:29 등), `containers` (role별 width_px, height_px), `preset` |
|
||||
| **연계** | → Stage 1.7이 컨테이너 크기를 보고 블록 선택 |
|
||||
아래는 현재 기준의 실질적인 단계입니다.
|
||||
|
||||
### Stage 1.7: 블록 선택
|
||||
| 단계 | 담당 | 주요 파일 | 하는 일 | 주요 산출물 |
|
||||
|---|---|---|---|---|
|
||||
| Stage 0 | 코드 | `src/mdx_normalizer.py` | MDX를 정규화하고 sections, tables, images, popups로 분리 | `NormalizedContent` |
|
||||
| Stage 1A | AI (Kei/Opus) | `src/kei_client.py` | title, core message, topic, 초기 layout 힌트 추출 | `Analysis`, `Topic[]` |
|
||||
| Phase Y | 코드 | `src/pipeline.py`, `src/section_parser.py` | `normalized.sections` 기반으로 group schema, recipe, zone/page_structure 결정 | `PageStructure`, `mdx_sections` |
|
||||
| Stage 1B | AI (Kei/Opus) | `src/kei_client.py` | topic별 relation, source_data, 표현 힌트 보강 | 보강된 `Topic[]` |
|
||||
| Stage 1B-ST | AI (Kei/Opus) | `src/kei_client.py` | structured_text 생성 | `Topic.structured_text` |
|
||||
| Stage 1.5a | 코드 | `src/space_allocator.py` | zone/container 크기, preset, font hierarchy 계산 | `containers`, `font_hierarchy` |
|
||||
| Stage 1.7 | 코드 | `src/block_reference.py`, `templates/catalog.yaml` | tag_match, schema_match, fallback 기준으로 block 선택 | `references` |
|
||||
| Stage 1.8 | 코드 + Selenium + 일부 AI | `src/pipeline.py`, `src/slide_measurer.py` | fit 측정, overflow 확인, 재배분, 보정 | `fit_result`, `measurement` |
|
||||
| Stage 2 | 코드 중심 | `src/block_assembler.py` | Type B 기준 slide-base + block template + payload 조립 | `generated_html` |
|
||||
| Stage 3 | 코드 | `src/renderer.py` | Type A 쪽 Jinja/renderer 조립, Type B는 대체로 생략 | `rendered_html` |
|
||||
| Stage 4 | 코드 + Vision AI | `src/slide_measurer.py`, `src/kei_client.py` | Selenium overflow 측정, screenshot, vision quality 평가 | `measurement`, `quality_score` |
|
||||
| Stage 5 | 코드 | `src/pipeline.py` | `final.html`, `final_context.json`, popup/detail html 저장 | run 산출물 |
|
||||
|
||||
| 항목 | 내용 |
|
||||
|------|------|
|
||||
| **목적** | 각 꼭지의 relation_type + expression_hint + 컨테이너 크기로 적합한 블록 결정. 같은 영역 꼭지들의 layer가 다르면 주종관계 판단 (블록 1개로 합침) |
|
||||
| **적용기술** | 코드 (`select_and_generate_references()`) — catalog.yaml 기반 결정론적 매칭 |
|
||||
| **인풋** | topics, containers, page_structure |
|
||||
| **아웃풋** | `references` — role별 block_id, variant, design_reference_html, topic_id, is_hierarchical, supporting_topic_ids |
|
||||
| **연계** | → Stage 1.8이 선택된 블록+콘텐츠가 컨테이너에 맞는지 검증 |
|
||||
## 현재 메인 실행 경로
|
||||
|
||||
### Stage 1.8: 적합성 검증 + 재배분 + 보강 + 서브 컨테이너
|
||||
### Type B 메인 경로
|
||||
|
||||
| 항목 | 내용 |
|
||||
|------|------|
|
||||
| **목적** | 콘텐츠가 컨테이너에 들어가는지 검증 → 안 맞으면 재배분 → 여전히 안 되면 Kei 에스컬레이션 → 여유 공간에 보충 콘텐츠 → 서브 컨테이너 배치 계산 |
|
||||
| **적용기술** | 코드 (`calculate_fit()`, `redistribute()`, `analyze_enhancements()`, `apply_enhancements()`, `calculate_sub_layout()`) + Kei API (에스컬레이션 시 `call_kei_fit_escalation()`) |
|
||||
| **인풋** | topics, containers, references, font_hierarchy, normalized, core_message |
|
||||
| **아웃풋** | `containers` (재배분된 height_px), `fit_result` (role별 fit_status, redistribution), `enhancement_result` (V-7 subordinate_treatments, V-8 supplement_blocks, V-9 emphasis_blocks, V-10 bold_keywords, V-4 kei_decisions), `sub_layouts` (role별 서브 컨테이너 name/width/height, table_rows) |
|
||||
| **내부 흐름** | Step 1: 필요 높이 계산 → Step 2: 재배분 → Step 3: Kei 에스컬레이션 → Step 4-5: 보강 분석+적용 → Step 6: fit 재검증 → Step 7: 서브 컨테이너 배치 → Step 8: 확정 |
|
||||
| **연계** | → Stage 1.5b가 재배분된 크기로 디자인 예산 재계산, → Stage 2가 sub_layouts + enhancements를 프롬프트에 반영 |
|
||||
지금 실전에서 가장 중요한 경로는 아래입니다.
|
||||
|
||||
### Stage 1.5b: 디자인 예산 재계산
|
||||
1. Stage 0에서 MDX를 정규화
|
||||
2. Stage 1A/1B에서 Kei가 의미와 topic 추출
|
||||
3. Phase Y에서 코드가 `normalized.sections`를 읽고 page_structure를 다시 생성
|
||||
4. Stage 1.7에서 block 선택
|
||||
5. Stage 1.8에서 fit/overflow 검증
|
||||
6. Stage 2에서 `assemble_slide_html_final()`로 최종 HTML 조립
|
||||
7. Stage 4/5에서 측정과 산출물 저장
|
||||
|
||||
| 항목 | 내용 |
|
||||
|------|------|
|
||||
| **목적** | 재배분된 컨테이너 크기 + 선택된 블록 schema 기준으로 영역별 가용 공간 계산 |
|
||||
| **적용기술** | 코드 (`calculate_design_budget()`) |
|
||||
| **인풋** | containers (재배분 후), references (블록 schema) |
|
||||
| **아웃풋** | `containers` 업데이트 — design_budget (available_height_px, available_width_px, fits) |
|
||||
| **연계** | → Stage 2가 design_budgets를 프롬프트에 포함 |
|
||||
Type B의 핵심 파일은 아래입니다.
|
||||
|
||||
### Stage 2: HTML 생성 (영역별 개별 호출)
|
||||
- `src/pipeline.py`
|
||||
- `src/section_parser.py`
|
||||
- `src/block_reference.py`
|
||||
- `src/block_assembler.py`
|
||||
- `src/space_allocator.py`
|
||||
- `templates/catalog.yaml`
|
||||
|
||||
| 항목 | 내용 |
|
||||
|------|------|
|
||||
| **목적** | page_structure에 존재하는 각 역할(배경/본심/첨부/결론)의 HTML을 **영역별 개별 Sonnet 호출**로 생성. 블록 디자인을 참고하되 콘텐츠가 구조를 결정 (Phase R' 방식) |
|
||||
| **적용기술** | Claude Sonnet API — 영역당 1회 호출 (`build_area_prompt()` → `_call_claude()`) |
|
||||
| **인풋** | raw_content, topics, containers, font_hierarchy, references (design_reference_html), sub_layouts (서브 컨테이너 치수), enhancements (V-4~V-10 지시), design_budgets |
|
||||
| **호출 흐름** | Sonnet(배경) → bg_html, Sonnet(본심) → core_html, Sonnet(첨부) → sidebar_html, Sonnet(결론) → footer_html. 해당 역할에 꼭지가 없으면 스킵. body_html = bg_html + spacer + core_html |
|
||||
| **아웃풋** | `generated_html` — body_html, sidebar_html, footer_html |
|
||||
| **프롬프트에 포함되는 것** | 서브 컨테이너 레이아웃 제약, 디자인 레퍼런스 HTML (블록 CSS 참고), Kei 에스컬레이션 결정, 종속 꼭지 처리 지시, 보충 블록 지시, 강조 문장, bold 키워드, 폰트/컨테이너 크기 제약 |
|
||||
| **연계** | → Stage 3이 영역별 HTML을 슬라이드 프레임에 배치 |
|
||||
### Type A 경로
|
||||
|
||||
### Stage 3: 렌더링 조립 + 후처리
|
||||
Type A는 현재도 살아 있지만, Type B만큼 단단하게 닫힌 상태는 아닙니다.
|
||||
|
||||
| 항목 | 내용 |
|
||||
|------|------|
|
||||
| **목적** | 생성된 HTML 조각을 CSS Grid 슬라이드 프레임에 삽입 + 후처리 (폰트 캡핑, overflow 제거, sidebar width 조정, bold 변환) |
|
||||
| **적용기술** | 코드 (`render_slide_from_html()`) |
|
||||
| **인풋** | generated_html, preset (grid_areas, grid_columns), font_hierarchy, container_ratio |
|
||||
| **아웃풋** | `rendered_html` → `final.html` 파일 저장 |
|
||||
| **연계** | → Stage 4가 렌더링 결과를 측정+검증 |
|
||||
- AI 생성 비중이 더 큼
|
||||
- `src/renderer.py` 의존도가 더 큼
|
||||
- sidebar/reference 구조를 포함하는 쪽에서 의미가 큼
|
||||
|
||||
### Stage 4: 품질 검증
|
||||
## schema -> recipe -> block
|
||||
|
||||
| 항목 | 내용 |
|
||||
|------|------|
|
||||
| **목적** | Selenium으로 실제 브라우저 렌더링 후 overflow 측정 + Opus Vision으로 시각적 품질 평가 |
|
||||
| **적용기술** | Selenium (`measure_rendered_heights()`) + Claude Opus Vision (`vision_quality_gate()`) |
|
||||
| **인풋** | rendered_html |
|
||||
| **아웃풋** | `measurement` (zone별 clientHeight, scrollHeight, overflow, excess_px), `quality_score` |
|
||||
| **연계** | 파이프라인 완료. overflow 시 경고 포함하여 진행 |
|
||||
최근 구조화에서 가장 중요한 변화 중 하나는 `schema -> recipe -> block` 레이어입니다.
|
||||
|
||||
---
|
||||
### schema
|
||||
|
||||
## 중간 산출물
|
||||
콘텐츠의 의미 구조입니다.
|
||||
|
||||
파이프라인 실행마다 `data/runs/{timestamp}/`에 단계별 결과가 저장된다.
|
||||
예:
|
||||
|
||||
### JSON Context (Stage별 누적 상태)
|
||||
| 파일 | Stage | 내용 |
|
||||
|------|-------|------|
|
||||
| `stage_0_context.json` | 0 | normalized (섹션, 팝업, 이미지) |
|
||||
| `stage_1a_context.json` | 1A | topics, page_structure |
|
||||
| `stage_1b_context.json` | 1B | topics (source_data 추가) |
|
||||
| `stage_1_5a_context.json` | 1.5a | font_hierarchy, containers, ratio |
|
||||
| `stage_1_7_context.json` | 1.7 | references (블록 선택 결과) |
|
||||
| `stage_1_8_context.json` | 1.8 | fit_result, enhancements, sub_layouts |
|
||||
| `stage_1_5b_context.json` | 1.5b | containers (design_budget 추가) |
|
||||
| `stage_2_context.json` | 2 | generated_html |
|
||||
| `stage_3_context.json` | 3 | (rendered_html은 final.html로 별도 저장) |
|
||||
| `stage_4_context.json` | 4 | measurement, quality_score |
|
||||
| `final_context.json` | 최종 | 전체 context |
|
||||
- `parallel_cluster`
|
||||
- `parallel_cluster_plus_visual`
|
||||
- `compare_asymmetric_paired`
|
||||
- `sequence_plus_visual`
|
||||
- `single_block`
|
||||
|
||||
### HTML 시각화 (`steps/` 폴더)
|
||||
| 파일 | Stage | 내용 |
|
||||
|------|-------|------|
|
||||
| `stage_0.html` | 0 | 섹션/팝업/이미지 목록 |
|
||||
| `stage_1a.html` | 1A | 꼭지 테이블 (purpose, layer, 영역) |
|
||||
| `stage_1b.html` | 1B | 꼭지 + source_data + summary |
|
||||
| `stage_1_5a.html` | 1.5a | 빈 컨테이너 (1280×720) |
|
||||
| `stage_1_5a_content.html` | 1.5a | 컨테이너에 콘텐츠 배치 |
|
||||
| `stage_1_5b.html` | 1.5b | 디자인 예산 (available height/width) |
|
||||
| `stage_1_7.html` | 1.7 | 블록 선택 표시 |
|
||||
| `stage_1_8_fit_before.html` | 1.8 | 적합성 (재배분 전) |
|
||||
| `stage_1_8_fit_after.html` | 1.8 | 재배분 후 + 보강 |
|
||||
| `stage_1_8_blocks.html` | 1.8 | SLOT 구조 + 블록 디자인 + 주종관계 (1280×720) |
|
||||
| `stage_2.html` | 2 | 영역별 Sonnet 출력을 실제 렌더링 (역할별 개별 확인) |
|
||||
| `stage_3.html` | 3 | 영역을 합쳐 슬라이드 프레임에 배치한 결과 (1280×720 실제 렌더링) |
|
||||
| `stage_4.html` | 4 | 측정 결과 + 품질 점수 |
|
||||
### recipe
|
||||
|
||||
---
|
||||
block 이름이 아니라 표현 규칙입니다.
|
||||
|
||||
## 핵심 원칙
|
||||
예:
|
||||
|
||||
1. **콘텐츠가 구조를 결정** — 블록 CSS는 참고만. AI가 콘텐츠 전달 의도를 보고 HTML 구조 결정 (Phase R')
|
||||
2. **하드코딩 금지** — font-size 외 모든 수치는 동적 계산. 어떤 MDX가 들어와도 동일하게 동작
|
||||
3. **스크롤 절대 금지** — overflow:auto/scroll 어떤 영역에서도 불허
|
||||
4. **Kei API 필수** — fallback 없음. 성공할 때까지 무한 재시도
|
||||
5. **AI가 옵션 생성, Kei가 결정** — 공간 부족 시 하드코딩 대응이 아니라 Kei 판단 요청
|
||||
6. **계산 먼저, AI 판단 나중에, 렌더링은 검증만**
|
||||
7. **overflow 상태에서 출력 금지** — Vision 모델 품질 게이트 통과 필수
|
||||
- `single_block`
|
||||
- `two_col_text_visual`
|
||||
- `stacked_summary_detail`
|
||||
|
||||
---
|
||||
recipe는 이런 계약을 가질 수 있습니다.
|
||||
|
||||
## 블록 라이브러리 (38개)
|
||||
- left/right kind
|
||||
- top/bottom kind
|
||||
- ratio
|
||||
- vertical align
|
||||
|
||||
6개 카테고리, 38개 블록. 각 블록은 `catalog.yaml`에 용도(when), 금지(not_for), purpose_fit, schema(슬롯 정의)가 있음.
|
||||
### block
|
||||
|
||||
| 카테고리 | 개수 | 용도 |
|
||||
|---------|------|------|
|
||||
| **headers** | 5 | 타이틀, 꼭지 헤더 |
|
||||
| **cards** | 9 | 항목 나열, 카드 그리드 |
|
||||
| **tables** | 3 | 비교표, 데이터 테이블 |
|
||||
| **visuals** | 6 | SVG 다이어그램, 관계도 |
|
||||
| **emphasis** | 10 | 강조, 인용, 결론, 불릿 |
|
||||
| **media** | 5 | 이미지/사진 |
|
||||
실제 구현 템플릿 후보입니다.
|
||||
|
||||
---
|
||||
예:
|
||||
|
||||
## 기술 스택
|
||||
- `prerequisites-3col`
|
||||
- `process-product-2col`
|
||||
- `compare-detail-gradient`
|
||||
- `card-icon-desc`
|
||||
|
||||
| 역할 | 도구 |
|
||||
|------|------|
|
||||
| 서버 | FastAPI + uvicorn (포트 8001) |
|
||||
| AI (Kei 실장/편집자) | Kei API → Opus (localhost:8000) |
|
||||
| AI (HTML 생성) | Anthropic API → Claude Sonnet |
|
||||
| AI (품질 검증) | Anthropic API → Claude Opus Vision |
|
||||
| 블록 검색 | FAISS + bge-m3 |
|
||||
| 템플릿 | Jinja2 (블록 디자인 레퍼런스용) |
|
||||
| 렌더링 | CSS Grid + 디자인 토큰 (1280×720) |
|
||||
| 렌더링 측정 | Selenium headless Chrome |
|
||||
| SVG 시각화 | svg_calculator.py (N개 동적 배치) |
|
||||
| 이미지 | Pillow (크기 측정) + base64 인라인 |
|
||||
| 폰트 | Pretendard Variable |
|
||||
| 공간 계산 | space_allocator.py + fit_verifier.py (결정론적) |
|
||||
즉, "무슨 문서냐"가 아니라 "무슨 구조냐"를 먼저 읽고, 그 구조에 맞는 표현 규칙을 정한 뒤, 마지막에 구현 블록을 고르는 방향으로 가고 있습니다.
|
||||
|
||||
---
|
||||
## popup / detail 계약
|
||||
|
||||
## 설치 및 실행
|
||||
popup은 지금 다음 철학으로 정리되는 중입니다.
|
||||
|
||||
```bash
|
||||
# 설치
|
||||
cd design_agent
|
||||
pip install -e .
|
||||
- 메인 슬라이드에는 존 크기에 맞는 요약만 남긴다
|
||||
- 큰 표, 시각 컴포넌트, 과다한 bullet은 상세 popup으로 분리한다
|
||||
- 메인에서는 `자세히보기` 링크를 제공한다
|
||||
|
||||
# FAISS 인덱스 빌드 (블록 추가/수정 시)
|
||||
python scripts/build_block_index.py
|
||||
현재 popup 관련 핵심은 아래입니다.
|
||||
|
||||
# .env 설정
|
||||
ANTHROPIC_API_KEY=sk-ant-...
|
||||
KEI_API_URL=http://localhost:8000
|
||||
LOG_LEVEL=DEBUG
|
||||
```
|
||||
- `PopupItem` 모델이 도입되어 popup 데이터를 명시적으로 다룸
|
||||
- `popup_id`, `popup_file` 생애주기를 분리해 관리 중
|
||||
- 최종 목표는 popup 판단을 휴리스틱이 아니라 명시적 contract로 만드는 것
|
||||
|
||||
```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
|
||||
```
|
||||
## run 산출물 구조
|
||||
|
||||
접속: http://localhost:8001
|
||||
각 실행은 `data/runs/{run_id}/` 아래에 저장됩니다.
|
||||
|
||||
---
|
||||
주요 파일은 다음과 같습니다.
|
||||
|
||||
## 개선 이력
|
||||
- `final.html`
|
||||
- `final_context.json`
|
||||
- `steps/*.html`
|
||||
- popup/detail html
|
||||
|
||||
| Phase | 내용 | 상태 |
|
||||
|-------|------|------|
|
||||
| A~D | 슬라이드 품질 핵심 | 완료 |
|
||||
| G~N | Kei API, 스토리라인, 정합성, 블록 선택, 비중, 측정 | 완료 |
|
||||
| O | 컨테이너 기반 레이아웃 | 완료 |
|
||||
| P | 다후보 렌더링 비교 | 완료 (20/100점 → 방향 전환) |
|
||||
| Q | 제약 기반 블록 선택 | 완료 |
|
||||
| R | 하이브리드 블록 (실패 — P=Q=R 동일 구조) | 실패 |
|
||||
| R' | 블록 CSS 참고 + AI 구조 결정 | 설계 확정 |
|
||||
| S | 검증 합격 프롬프트 + Claude HTML 생성 | 설계 확정 |
|
||||
| T | 11-Stage 파이프라인 + 디자인 레퍼런스 | 완료 (31/31 통과) |
|
||||
| V | 적합성 검증 + Kei 에스컬레이션 + 서브 컨테이너 | 완료 |
|
||||
| W | Stage 2 출력 품질 수정 (6건) | 진행 중 |
|
||||
### `final.html`
|
||||
|
||||
---
|
||||
- 최종 렌더 결과
|
||||
- 실제 눈으로 보는 산출물
|
||||
|
||||
## Kei Persona와의 관계
|
||||
### `final_context.json`
|
||||
|
||||
```
|
||||
Kei Persona Agent (localhost:8000)
|
||||
├── Opus + RAG + 세션 컨텍스트
|
||||
├── 도메인 지식 (건설/DX/BIM)
|
||||
└── 대화/생성/피드백/실행 모드
|
||||
- 각 단계 결과를 최종 context 형태로 저장
|
||||
- block 선택, page_structure, measurement, quality_score 등을 확인할 때 가장 중요
|
||||
|
||||
### `steps/*.html`
|
||||
|
||||
- 단계별 디버그/설명용 보드
|
||||
- 현재는 검토용으로 유용하지만, 일부 인코딩/설명 품질은 더 다듬을 필요가 있습니다
|
||||
|
||||
## 자주 봐야 하는 파일
|
||||
|
||||
### 파이프라인 핵심
|
||||
|
||||
- [src/pipeline.py](src/pipeline.py)
|
||||
- [src/pipeline_context.py](src/pipeline_context.py)
|
||||
- [src/section_parser.py](src/section_parser.py)
|
||||
- [src/block_reference.py](src/block_reference.py)
|
||||
- [src/block_assembler.py](src/block_assembler.py)
|
||||
- [src/space_allocator.py](src/space_allocator.py)
|
||||
|
||||
### 템플릿 / 카탈로그
|
||||
|
||||
- [templates/catalog.yaml](templates/catalog.yaml)
|
||||
- [templates/blocks/new/prerequisites-3col.html](templates/blocks/new/prerequisites-3col.html)
|
||||
- [templates/blocks/redesign/process-product-2col.html](templates/blocks/redesign/process-product-2col.html)
|
||||
- [templates/blocks/cards/compare-detail-gradient.html](templates/blocks/cards/compare-detail-gradient.html)
|
||||
- [templates/blocks/slide-base.html](templates/blocks/slide-base.html)
|
||||
주의: 현재 삭제/legacy 정리 여부를 별도로 확인해야 하는 경로입니다.
|
||||
|
||||
### 검증 / 측정
|
||||
|
||||
- [src/slide_measurer.py](src/slide_measurer.py)
|
||||
- [src/validators.py](src/validators.py)
|
||||
|
||||
### 역사 / 계획 문서
|
||||
|
||||
- [PIPELINE.md](PIPELINE.md)
|
||||
- [docs/history/PHASE-Y-PLAN.md](docs/history/PHASE-Y-PLAN.md)
|
||||
- [ARCHITECTURE_OVERVIEW.md](ARCHITECTURE_OVERVIEW.md)
|
||||
|
||||
## 현재 상태 요약
|
||||
|
||||
### 잘 닫혀가는 것
|
||||
|
||||
- Type B 메인 경로
|
||||
- `normalized.sections` 기반 구조 해석
|
||||
- schema / recipe 기반 block selection
|
||||
- `prerequisites-3col`, `process-product-2col` 같은 redesign 블록 자산화
|
||||
- popup/detail 2단 표현 계약의 초안 연결
|
||||
|
||||
### 아직 정리 중인 것
|
||||
|
||||
- Type A 전체 안정화
|
||||
- popup을 완전한 source of truth로 정리
|
||||
- `tag_match` 와 `schema_match`의 완전한 동등 점수 비교
|
||||
- step 보드 인코딩/설명 품질
|
||||
- legacy 경로와 문서의 정리
|
||||
|
||||
## 읽는 방법 추천
|
||||
|
||||
프로세스를 빠르게 파악하려면 아래 순서가 좋습니다.
|
||||
|
||||
1. 이 `README.md`
|
||||
2. [src/pipeline.py](src/pipeline.py)
|
||||
3. [src/section_parser.py](src/section_parser.py)
|
||||
4. [src/block_assembler.py](src/block_assembler.py)
|
||||
5. 최근 run의 `final_context.json`
|
||||
|
||||
히스토리까지 보려면 아래 문서를 이어서 보면 좋습니다.
|
||||
|
||||
- [PIPELINE.md](PIPELINE.md)
|
||||
- [docs/history/PHASE-Y-PLAN.md](docs/history/PHASE-Y-PLAN.md)
|
||||
|
||||
Design Agent (localhost:8001, 이 프로젝트)
|
||||
├── 슬라이드 생성 전용
|
||||
├── Kei API로 꼭지 추출(1A) + 컨셉 구체화(1B) + 에스컬레이션(1.8) 호출
|
||||
├── Sonnet으로 HTML 생성(Stage 2)
|
||||
├── Opus Vision으로 품질 검증(Stage 4)
|
||||
└── 두 프로젝트는 독립. 코드 공유 없음. API 연동만.
|
||||
```
|
||||
|
||||
Reference in New Issue
Block a user