Phase P: 블록 재구성 + 실제 렌더링 비교 선택
작성일: 2026-03-27
상태: 계획 확정 (사용자 승인 완료, 실행 대기)
선행 완료: Phase O (컨테이너 기반 레이아웃)
핵심 원칙
"블록을 컨테이너에 맞게 재구성하고, 실제 렌더링해보고, Kei가 스크린샷을 보고 목적에 맞는 것을 고른다."
해결하는 문제 (14건)
| # |
문제 |
해결 방법 |
| P-1 |
Kei가 표면 키워드에 반응하여 블록 선택 |
후보 3개 렌더링 → Kei가 스크린샷 보고 목적 기준으로 최종 선택 |
| P-2 |
purpose_fit 위반 블록 통과 |
Kei가 스크린샷으로 판단하므로 부적합 블록 탈락 |
| P-3 |
같은 블록 반복 사용 |
같은 컨테이너 topic을 함께 보여주고 "서로 다른 블록 선택" 명시 |
| P-4 |
블록이 콘텐츠 의미 왜곡 |
왜곡된 결과를 Kei가 스크린샷으로 보고 탈락 |
| P-5 |
compare-pill-pair height_cost 부정확 |
catalog를 믿지 않음. 실제 렌더링으로 확인. 추가로 Selenium 실측 스크립트로 전체 검증 |
| P-6 |
banner-gradient height_cost 부정확 |
P-5와 동일 |
| P-7 |
38개 전체 height_cost 미검증 |
Selenium 실측 검증 스크립트 작성 → catalog 갱신 |
| P-8 |
배경 58px에 콘텐츠 전달 불가 |
① 블록을 58px에 맞게 재구성 ② Kei가 비중 판단 시 topic 수 고려 ③ 또는 Kei가 topic을 합침 |
| P-9 |
sidebar 490px에 247px만 사용 |
P-10 해결 시 공간 활용도 상승 |
| P-10 |
용어 정의 빈약 (출처 누락) |
EDITOR_PROMPT 하드코딩 제거 완료. 컨테이너 제약에 맞게 Kei가 편집 |
| P-11 |
EDITOR_PROMPT 하드코딩 분량 |
해결 완료 |
| P-12 |
블록 추천 프롬프트가 의미/논리 구조 미전달 |
후보 3개 렌더링 + Kei 스크린샷 판단으로 대체. 프롬프트 정확도에 의존하지 않음 |
| P-13 |
스크린샷 .txt로 저장 |
base64 디코딩하여 .png 파일로 저장 |
| P-14 |
피드백 루프에 블록 교체 기능 없음 |
처음부터 3개 렌더링해서 맞는 걸 고르므로 피드백 부담 감소 |
실행 파이프라인
비용
| 항목 |
횟수 |
시간 |
| Kei API (기존 1A+1B+3+5) |
4회 |
~4분 |
| Step 2: Opus 추천 배치 |
1회 |
~30초 |
| Step 3: 텍스트 편집 배치 |
5회 |
~2.5분 |
| Step 5: 최종 선택 |
3회 |
~1.5분 |
| Step 4: Selenium 렌더링 |
15회 (병렬) |
~0.8초 |
| Step 6: CSS + 검수 |
2회 |
~2분 |
| 총합 |
~15회 |
~10.5분 |
하드코딩 없음 검증
| 항목 |
하드코딩? |
근거 |
| 후보 수 3개 (FAISS 2 + Opus 1) |
구조적 설계 |
블록 추가해도 변경 불필요 |
| 블록 재구성 |
동적 계산 |
Phase O _determine_typography(), _calculate_block_constraints() |
| 텍스트 분량 |
동적 계산 |
컨테이너 제약에서 자동 산출 |
| 최종 선택 |
Kei 판단 |
코드가 선택하지 않음 |
| 컨테이너 크기 |
동적 계산 |
Kei 비중에서 자동 산출 |
| 최종 선택 묶음 (2+2+1) |
동적 그룹핑 |
컨테이너 역할별 자동 |
| 배경 topic 수 처리 |
Kei 판단 |
Kei가 비중 판단 시 topic 수 고려. 코드가 비중 덮어쓰지 않음 |
기존 코드 변경 범위
| 파일 |
변경 |
신규/수정 |
pipeline.py |
Step A-2 단일 선택 → Step 2~5 루프로 교체 |
수정 |
block_search.py |
topic별 상위 2개 반환 함수 |
추가 |
design_director.py |
전체 topic 배치 Opus 추천 함수 |
추가 |
renderer.py |
컨테이너 감싼 단독 블록 렌더링 함수 |
추가 |
slide_measurer.py |
단독 블록 스크린샷 캡처 함수 + .png 저장 |
추가 |
kei_client.py |
3후보 스크린샷 비교 선택 프롬프트 함수 |
추가 |
content_editor.py |
3블록 한꺼번에 편집 프롬프트 |
수정 |
space_allocator.py |
기존 그대로 (재사용) |
변경 없음 |
catalog.yaml |
기존 그대로 |
변경 없음 |
중간 산출물 추가
| 파일 |
내용 |
step2_candidates.json |
topic별 후보 3개 (FAISS 2 + Opus 1) |
step3_edited_variants.json |
topic별 3개 블록의 편집된 텍스트 |
step4_candidate_screenshots/ |
15개 .png 스크린샷 |
step5_selection.json |
Kei 최종 선택 결과 (topic별 선택 블록 + 이유) |
충돌/회귀 검증
| 체크 항목 |
결과 |
| 기존 함수 호환 |
✅ render_standalone_block, search_blocks, measure_rendered_heights, capture_slide_screenshot 전부 존재 |
| Phase O 컨테이너 시스템 |
✅ 그대로 사용. calculate_container_specs, finalize_block_specs 재사용 |
| Phase N fallback 제거 |
✅ 회귀 없음. fallback 코드 재도입 안 함 |
| Phase N 무한 재시도 |
✅ 유지. 모든 Kei API 호출에 적용 |
| 하드코딩 |
✅ 없음. 모든 수치가 동적 계산 또는 Kei 판단 |
| EDITOR_PROMPT |
✅ 하드코딩 분량 이미 제거됨 |