Files
C.E.L_Slide_test2/IMPROVEMENT-PHASE-P.md
kyeongmin 9410576e60 Phase P 계획: 블록 재구성 + 실제 렌더링 비교 선택
- 후보 3개 (FAISS 2 + Opus 1) → 컨테이너에 맞게 재구성 → 실제 렌더링 → Kei 스크린샷 판단
- 14건 문제 진단 포함 (블록 의미 왜곡, height_cost 부정확, 컨테이너 불일치 등)
- 미해결 사항 확정: 텍스트=Kei 편집, 선택=스크린샷, 전부 안맞으면=정확도 최고로

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 16:24:24 +09:00

177 lines
7.0 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Phase P: 블록 재구성 + 실제 렌더링 비교 선택
> 작성일: 2026-03-27
> 상태: 계획 수립 중 (사용자 승인 대기)
> 선행 완료: Phase O (컨테이너 기반 레이아웃)
---
## 핵심 원칙
**"블록을 컨테이너에 맞게 재구성하고, 실제 렌더링해보고, Kei가 목적에 맞는 것을 고른다."**
```
컨테이너 58px 확정 (Phase O)
후보 3개 선택 (FAISS 2개 + Opus 1개)
3개 블록을 각각 58px에 맞게 재구성
(폰트, 패딩, 항목 수, 레이아웃 변형)
재구성된 3개를 실제 렌더링 (Selenium)
Kei가 "당초 목적에 가장 적합한 것은?" 선택 → 최종 1개
```
---
## 이것이 해결하는 문제들
| 문제 | 왜 해결되나 |
|------|-----------|
| P-1: 키워드 반응으로 잘못된 블록 선택 | 3개를 실제 렌더링해서 Kei가 목적 기준으로 최종 선택. 키워드 반응으로 골라도 목적에 안 맞으면 탈락 |
| P-4: 블록이 콘텐츠 의미 왜곡 | compare-pill-pair에 "혼용 문제"를 넣어봤더니 의미가 안 맞으면 Kei가 탈락시킴 |
| P-5/6/7: height_cost 부정확 | catalog의 height_cost를 믿지 않음. 실제 렌더링으로 확인 |
| P-8: 58px에 콘텐츠 전달 불가 | 블록을 58px에 맞게 재구성하므로 어떤 블록이든 넣을 수 있음 |
| P-14: 피드백 루프 무력 | 처음부터 맞는 걸 고르니까 피드백 필요성 감소 |
---
## 단계별 상세
### P-Step 1: 후보 선택
각 topic에 대해 후보 3개를 뽑는다.
**FAISS 2개:**
- 기존 `search_blocks_for_topics()`로 검색
- topic의 purpose, relation_type, expression_hint를 쿼리에 포함 (이미 Phase M에서 구현)
- 상위 2개 선택
**Opus 1개:**
- 기존 `_opus_block_recommendation()`에서 Kei가 추천한 블록
- 도메인 지식 + 콘텐츠 성격 기반
**중복 제거:** FAISS 결과에 Opus 추천이 이미 포함되어 있으면 FAISS 3번째를 올림. 항상 서로 다른 3개.
### P-Step 2: 블록 재구성
각 후보 블록을 해당 topic의 **컨테이너 크기에 맞게 재구성**한다.
**재구성 항목:**
- 폰트 크기: 컨테이너 높이에 따라 조정 (Phase O `_determine_typography()` 사용)
- 패딩: 컨테이너 높이에 따라 조정
- 항목 수: 컨테이너에 들어가는 만큼만 (Phase O `_calculate_block_constraints()` 사용)
- 글자 수: 항목당 최대 글자 수 계산
- 레이아웃: 세로 → 가로 전환 등 (컨테이너 가로/세로 비율에 따라)
**이 단계에서 텍스트도 채운다:**
- 각 후보 블록의 슬롯에 맞게 Kei 편집자가 텍스트를 채움
- 3개 블록 × 같은 원본 텍스트 → 3개 다른 편집 결과
- 또는: 1회 편집 후 3개 블록 슬롯에 재배치 (API 호출 절약)
### P-Step 3: 실제 렌더링
재구성된 3개 블록을 각각 Selenium으로 렌더링한다.
**측정 항목:**
- 실제 높이(scrollHeight) vs 컨테이너 높이
- overflow 여부
- 렌더링 결과 스크린샷 (base64 PNG)
**렌더링 방법:**
- `render_standalone_block(block_type, data)`로 각 블록 단독 렌더링
- 컨테이너 크기를 감싼 div 안에서 렌더링
- `slide_measurer.py`의 기존 Selenium 인프라 재사용
### P-Step 4: Kei 최종 선택
렌더링된 3개 결과를 Kei(Opus)에게 보여주고 최종 선택.
**Kei에게 전달하는 정보:**
- 이 topic의 원래 목적 (purpose, relation_type, expression_hint)
- 3개 렌더링 결과 (스크린샷 이미지 또는 HTML 요약)
- 각 블록의 overflow 여부
- 원본 콘텐츠
**Kei 판단 기준:**
1. 당초 목적에 적합한가? (문제 제기인데 비교 블록이면 부적합)
2. 콘텐츠 의미가 왜곡되지 않는가?
3. 컨테이너에 맞게 렌더링되었는가?
**Kei API 호출:** 1회. 3개를 한꺼번에 보여주고 1개 선택.
---
## 파이프라인 흐름 변경
```
현재:
1A → 1B → 컨테이너 → A-2(Kei 1개 확정) → 블록 스펙 → 3(편집) → 4(렌더링) → 측정 → 5(검수)
Phase P 후:
1A → 1B → 컨테이너
→ 각 topic마다:
후보 3개 (FAISS 2 + Opus 1)
→ 3개 재구성 (컨테이너에 맞게)
→ 3개 렌더링 (Selenium)
→ Kei 최종 선택 (목적 적합성)
→ 선택된 블록으로 전체 슬라이드 조립
→ 4(CSS 조정 + 최종 렌더링)
→ 측정
→ 5(검수)
```
---
## 기존 코드 영향
| 파일 | 변경 |
|------|------|
| `pipeline.py` | Step A-2 단일 선택 → topic별 3후보 + 렌더링 + Kei 선택 루프로 변경 |
| `design_director.py` | `_opus_block_recommendation()` — 기존 유지. 추가로 단일 topic 추천 함수 필요 |
| `block_search.py` | 기존 유지. topic별 상위 2개 추출 함수 추가 |
| `renderer.py` | `render_standalone_block()` — 기존 유지. 컨테이너 감싼 렌더링 함수 추가 |
| `slide_measurer.py` | 기존 유지. 단일 블록 높이 측정 함수 추가 |
| `space_allocator.py` | `finalize_block_specs()` — 기존 유지. 후보별 스펙 계산에 재사용 |
| `content_editor.py` | 기존 유지. 후보별 텍스트 채우기에 재사용 |
| `kei_client.py` | 3후보 비교 선택 프롬프트 함수 신규 |
---
## 하드코딩 검증
| 항목 | 하드코딩? | 근거 |
|------|---------|------|
| 후보 수 3개 (FAISS 2 + Opus 1) | 구조적 설계 | 블록 추가해도 변경 불필요. 3개는 비교에 적절한 수 |
| 블록 재구성 (폰트/패딩/항목수) | 동적 계산 | Phase O `_determine_typography()`, `_calculate_block_constraints()` 사용 |
| 최종 선택 | Kei 판단 | 코드가 선택하지 않음 |
| 컨테이너 크기 | Kei 비중에서 동적 계산 | Phase O `calculate_container_specs()` |
---
## 비용 분석
| 항목 | 현재 | Phase P 후 |
|------|------|-----------|
| Kei API 호출 | 1A + 1B + A-2 + 3(편집) + 5(검수) = 5회 | + topic별 최종 선택 1회 × 5topics = +5회. 총 ~10회 |
| Selenium 렌더링 | 1회 (전체 슬라이드) | + topic별 3후보 × 5topics = +15회. 단독 블록이라 빠름 (~50ms/회) |
| Sonnet 호출 | 4단계 CSS 1회 | 변경 없음 |
| 총 시간 증가 | — | Selenium +750ms, Kei API +5회 (각 ~30초) ≈ +2.5분 |
---
## 미해결 사항 (사용자 논의 필요)
1. **3개 후보에 텍스트를 어떻게 채우나?**
- 방법 A: Kei 편집자를 3회 호출 (각 블록 슬롯에 맞게) — 정확하지만 느림
- 방법 B: 1회 편집 후 3개 블록 슬롯에 기계적 재배치 — 빠르지만 슬롯 구조가 다르면 부정확
- 방법 C: Kei 편집자 1회 호출에 "3개 블록 각각의 슬롯에 맞게" 한꺼번에 요청 — 중간
2. **Kei 최종 선택에 스크린샷을 보여줄까, HTML 요약을 보여줄까?**
- 스크린샷: Opus 멀티모달로 실제 렌더링을 보고 판단 — 정확
- HTML 요약: 텍스트 기반 — 빠르지만 시각 판단 불가
3. **3개 후보가 전부 목적에 안 맞으면?**
- Kei가 "없음"을 선택할 수 있게 할까? 그러면 추가 후보를 어디서?