- 루트의 IMPROVEMENT-PHASE-*.md, PHASE-*.md 등 45개 → docs/history/로 이동 - docs/block-tests/ 오래된 블록 테스트 HTML 삭제 (figma_to_html_agent로 대체) - docs/figma-analysis/, docs/figma-assets/, docs/figma-screenshots/ 정리 - docs/test-*.html 등 초기 테스트 파일 정리 - 참고 페이지/ 스크린샷 정리 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
451 lines
18 KiB
Markdown
451 lines
18 KiB
Markdown
# Phase R': 접근 C 기반 — 블록 CSS 참고 + AI 구조 결정
|
|
|
|
> 작성일: 2026-03-30
|
|
> 상태: 설계
|
|
> 선행: Phase P(20점), Q(블록 선택 개선), R(실패 — 기존 구조 위에 패치)
|
|
> 근거: C_reference.png + hybrid_simulation.png 시뮬레이션 검증
|
|
|
|
---
|
|
|
|
## 1. Phase P, Q, R에서 무엇이 문제였는가
|
|
|
|
**P, Q, R 전부 같은 구조:**
|
|
```
|
|
블록을 선택한다 → 그 블록의 슬롯에 텍스트를 채운다
|
|
```
|
|
|
|
이 구조의 근본 한계:
|
|
- **블록이 구조를 결정한다.** 콘텐츠가 아니라 블록 템플릿이 HTML 구조를 고정.
|
|
- topic 1개 = 블록 1개. 합침/분리 불가.
|
|
- 38개 고정 템플릿에 없는 구조(포함 관계, Before→After 등)는 표현 불가.
|
|
- 콘텐츠 전달 의도(expression_hint)가 HTML 구조에 반영되지 않음.
|
|
|
|
Phase Q에서 블록 선택 정확도를 올렸고, Phase R에서 variant를 추가했지만,
|
|
**근본 구조("블록 선택 → 슬롯 채우기")는 P = Q = R 동일.**
|
|
결과물도 동일 수준.
|
|
|
|
---
|
|
|
|
## 2. 접근 C: 무엇이 달라지는가
|
|
|
|
### 핵심 전환
|
|
|
|
```
|
|
현재 (P=Q=R):
|
|
블록이 구조를 결정 → 콘텐츠를 슬롯에 채움
|
|
(블록 중심)
|
|
|
|
접근 C:
|
|
콘텐츠가 구조를 결정 → 블록 CSS를 참고하여 HTML 생성
|
|
(콘텐츠 중심)
|
|
```
|
|
|
|
### "블록을 참고하여 만든다"의 정확한 의미
|
|
|
|
블록을 버리는 것이 아니다. 블록을 "선택"하는 것도 아니다.
|
|
|
|
| | 현재 (블록 선택) | 접근 C (블록 참고) |
|
|
|---|---|---|
|
|
| 블록의 역할 | HTML 구조를 결정하는 템플릿 | CSS 스타일(색상, 폰트, 배경, radius)의 참고 자료 |
|
|
| 누가 구조를 결정 | 블록 템플릿 (Jinja2) | AI가 콘텐츠 전달 의도를 보고 결정 |
|
|
| topic 합침/분리 | 불가 (1 topic = 1 블록) | 가능 (AI가 판단) |
|
|
| 포함 관계 시각화 | 해당 블록이 없으면 불가 | AI가 큰 박스 안에 카드를 넣는 구조를 직접 생성 |
|
|
| CSS 일관성 | 블록 템플릿이 보장 | 디자인 토큰 + 블록 CSS 참고로 보장 |
|
|
|
|
### C_reference.png에서 증명된 것
|
|
|
|
제가 수동으로 했던 판단:
|
|
1. topic 1(문제제기) + topic 2(사례) → **1영역에 통합**, dark-bullet-list의 CSS 색상 사용
|
|
2. 사례 2건 → **가로 2열 카드**, 같은 구조로 나란히
|
|
3. topic 3(핵심) → **DX 큰 박스 안에 GIS/BIM/DT 카드** = 포함 관계 시각화
|
|
4. "BIM ≠ DX" → **별도 강조 박스** (topic에 없는 요소를 추가)
|
|
5. sidebar 용어 → **풀 정의 + 출처**, card-numbered의 CSS 스타일 참고
|
|
|
|
**이 판단들을 AI가 하는 것이 접근 C.**
|
|
|
|
---
|
|
|
|
## 3. 프로세스 설계
|
|
|
|
### 기존 프로세스 (P=Q=R)
|
|
|
|
```
|
|
1단계: Kei 분석 (topics, relation_type, expression_hint, page_structure)
|
|
1.5단계: Kei 컨셉 구체화 (source_data)
|
|
컨테이너 계산 (비중 → px)
|
|
프리셋 선택 (sidebar-right 등)
|
|
|
|
2단계: 블록 선택 (block_selector → catalog → Kei 선택) ← 여기가 문제
|
|
3단계: 텍스트 채우기 (fill_candidates → 슬롯에 텍스트) ← 여기가 문제
|
|
|
|
4단계: CSS 조정 + 렌더링
|
|
검증: Selenium 측정
|
|
품질 게이트: 비전 모델
|
|
```
|
|
|
|
### 접근 C 프로세스
|
|
|
|
```
|
|
1단계: Kei 분석 (동일)
|
|
1.5단계: Kei 컨셉 구체화 (동일)
|
|
컨테이너 계산 (동일)
|
|
프리셋 선택 (동일)
|
|
|
|
2-3단계 통합: AI가 HTML 구조를 직접 생성 ← 여기가 바뀜
|
|
입력: Kei 분석 결과 + 원본 텍스트 + 디자인 토큰 + 블록 CSS 참고 + 컨테이너 스펙
|
|
출력: 각 컨테이너 영역의 HTML (슬라이드 body, sidebar, footer)
|
|
|
|
AI가 결정하는 것:
|
|
- 각 topic을 어떤 구조로 보여줄지 (불릿? 비교? 포함관계? 카드?)
|
|
- topic을 합칠지 분리할지
|
|
- 핵심 메시지를 별도 강조할지
|
|
- 텍스트를 어떻게 배치할지
|
|
|
|
AI가 참고하는 것:
|
|
- 디자인 토큰 (CSS 변수 — 색상, 폰트, 간격)
|
|
- 기존 블록의 CSS 패턴 (다크 배경, 카드 스타일, 배너 스타일 등)
|
|
- 컨테이너 크기 (px)
|
|
- expression_hint ("포함 관계 시각화", "프로세스 변화")
|
|
- 예시 슬라이드 (few-shot)
|
|
|
|
4단계: 렌더링 (AI가 생성한 HTML을 슬라이드 프레임에 삽입)
|
|
검증: Selenium 측정 (동일)
|
|
품질 게이트: 비전 모델 (동일)
|
|
```
|
|
|
|
### 변경되는 것 / 변경되지 않는 것
|
|
|
|
| 항목 | 변경 여부 |
|
|
|------|----------|
|
|
| 1단계 Kei 분석 | 변경 없음 |
|
|
| 1.5단계 컨셉 구체화 | 변경 없음 |
|
|
| 컨테이너 계산 (space_allocator) | 변경 없음 |
|
|
| 프리셋 선택 | 변경 없음 |
|
|
| **2단계 블록 선택 (block_selector)** | **제거** — AI가 직접 구조 결정 |
|
|
| **3단계 슬롯 채우기 (fill_candidates)** | **제거** — AI가 HTML에 텍스트 직접 포함 |
|
|
| 4단계 CSS 조정 | 변경 — AI 생성 HTML을 프레임에 삽입 |
|
|
| Selenium 측정 | 변경 없음 |
|
|
| 비전 모델 품질 게이트 | 변경 없음 |
|
|
| slide-base.html | 변경 없음 |
|
|
| tokens.css, base.css | 변경 없음 |
|
|
|
|
---
|
|
|
|
## 4. AI HTML 생성의 구체적 설계
|
|
|
|
### 4-1. AI에게 주는 입력
|
|
|
|
```
|
|
1. 원본 콘텐츠 (MDX 텍스트 전체)
|
|
2. Kei 분석 결과:
|
|
- topics[] (id, title, purpose, relation_type, expression_hint, source_data)
|
|
- page_structure (본심/배경/첨부/결론 비중)
|
|
- core_message
|
|
3. 컨테이너 스펙:
|
|
- 각 역할별 높이(px), 너비(px)
|
|
- 프리셋 (sidebar-right, two-column 등)
|
|
4. 디자인 토큰 (tokens.css 전문)
|
|
5. 블록 CSS 패턴 참고 (주요 블록의 CSS만 발췌):
|
|
- 다크 배경 패턴 (.block-dark-bullets의 색상/배경)
|
|
- 카드 패턴 (.cid-card의 border/radius/padding)
|
|
- 배너 패턴 (.block-banner-grad의 gradient)
|
|
- 비교 패턴 (.block-comparison의 좌우 분할)
|
|
- 테이블 패턴 (.block-table-striped의 헤더/행)
|
|
6. 예시 슬라이드 2-3개 (few-shot):
|
|
- C_reference.png의 HTML
|
|
- hybrid_simulation의 HTML
|
|
- (다른 콘텐츠 예시)
|
|
```
|
|
|
|
### 4-2. AI에게 요구하는 출력
|
|
|
|
```
|
|
각 영역(body, sidebar, footer)의 HTML 조각.
|
|
슬라이드 프레임(slide-base.html)에 삽입할 수 있는 형태.
|
|
|
|
{
|
|
"body_html": "<div class=\"container-배경\">...</div><div class=\"container-본심\">...</div>",
|
|
"sidebar_html": "<div class=\"sidebar-label\">용어 정의</div><div class=\"def-item\">...</div>...",
|
|
"footer_html": "<div class=\"block-banner-grad\"><div class=\"bg-text\">...</div></div>"
|
|
}
|
|
```
|
|
|
|
### 4-3. AI HTML 생성 규칙 (프롬프트에 포함)
|
|
|
|
```
|
|
## 규칙
|
|
|
|
1. 원본 텍스트를 그대로 사용한다 (자유도 15-20). 축약은 공간 부족 시에만.
|
|
2. 디자인 토큰(CSS 변수)만 사용한다. 하드코딩 색상/폰트 금지.
|
|
3. 블록 CSS 패턴을 참고하되, 구조는 콘텐츠에 맞게 자유롭게 구성한다.
|
|
4. 컨테이너 높이를 초과하지 않는다.
|
|
5. expression_hint를 반드시 반영한다:
|
|
- "포함 관계" → 큰 박스 안에 작은 카드
|
|
- "프로세스 변화" → Before→After 구조
|
|
- "독립 사례 나열" → 가로 카드 비교
|
|
6. topic을 합치거나 분리할 수 있다 (page_structure의 역할 기준).
|
|
7. 핵심 메시지(core_message)는 별도 강조 요소로 만들 수 있다.
|
|
```
|
|
|
|
### 4-4. 품질 보장 (5중 방어)
|
|
|
|
```
|
|
Layer 1: 디자인 토큰 제약 (CSS 변수만 사용)
|
|
Layer 2: 컨테이너 크기 제약 (px 명시)
|
|
Layer 3: HTML 정화 (nh3 — script 태그 등 제거)
|
|
Layer 4: Selenium 측정 (overflow 감지)
|
|
Layer 5: 비전 모델 품질 게이트 (시각적 평가)
|
|
```
|
|
|
|
---
|
|
|
|
## 5. 구현 스텝
|
|
|
|
| 스텝 | 내용 | 파일 | 비고 |
|
|
|------|------|------|------|
|
|
| R'-1 | 디자인 토큰 + 블록 CSS 패턴을 프롬프트용 텍스트로 추출 | 신규 `src/design_tokens.py` | tokens.css + 주요 블록 CSS 발췌 |
|
|
| R'-2 | few-shot 예시 슬라이드 정리 (2-3개) | `data/examples/` | C_reference.html, hybrid_simulation.html |
|
|
| R'-3 | AI HTML 생성 함수 구현 | 신규 `src/html_generator.py` | Kei 분석 + 토큰 + 예시 → HTML 생성 |
|
|
| R'-4 | pipeline.py 2-3단계를 html_generator로 교체 | `src/pipeline.py` | block_selector, fill_candidates 호출 제거 |
|
|
| R'-5 | 렌더러에 AI 생성 HTML 삽입 함수 추가 | `src/renderer.py` | 기존 render_slide와 별도로 render_slide_from_html 추가 |
|
|
| R'-6 | HTML 정화 + 토큰 위반 검증 | 신규 `src/html_validator.py` | nh3 + tinycss2 |
|
|
| R'-7 | 테스트 (2개 콘텐츠로 검증) | `scripts/test_phase_r_prime.py` | DX 이해 + DX 목표 |
|
|
|
|
### 의존 관계
|
|
|
|
```
|
|
R'-1 (토큰 추출) ──→ R'-3 (HTML 생성)
|
|
R'-2 (예시 정리) ──→ R'-3
|
|
R'-3 ──→ R'-4 (파이프라인 교체) ──→ R'-7 (테스트)
|
|
R'-3 ──→ R'-5 (렌더러 추가)
|
|
R'-6 (검증) ←── 독립, R'-4와 병렬
|
|
```
|
|
|
|
---
|
|
|
|
## 6. pipeline.py 변경 상세 — 정확히 어디가 교체되는가
|
|
|
|
### 유지되는 코드 (1단계 ~ 컨테이너 계산: 줄 96~165)
|
|
|
|
```python
|
|
# 줄 96~109: 1단계 Kei 분석 — 유지
|
|
analysis = await _retry_kei(classify_content, content)
|
|
_save_step(run_dir, "step1_analysis.json", analysis)
|
|
|
|
# 줄 111~120: 1.5단계 컨셉 구체화 — 유지
|
|
analysis = await refine_concepts(content, analysis)
|
|
_save_step(run_dir, "step1b_concepts.json", ...)
|
|
|
|
# 줄 122~140: 제목 중복 검증, 이미지 측정 — 유지
|
|
|
|
# 줄 142~164: 컨테이너 스펙 계산 — 유지
|
|
preset_name = select_preset(analysis)
|
|
preset = LAYOUT_PRESETS.get(preset_name, {})
|
|
container_specs = calculate_container_specs(...)
|
|
_save_step(run_dir, "step1c_containers.json", ...)
|
|
```
|
|
|
|
### 제거되는 코드 (2-3단계: 줄 166~339)
|
|
|
|
```python
|
|
# 줄 166~207: Phase Q 블록 선택 — 전체 제거
|
|
# block_selector.select_block_candidates()
|
|
# select_fallback_candidates()
|
|
# calculate_budgets_for_candidates()
|
|
|
|
# 줄 209~257: Kei 블록 선택 — 전체 제거
|
|
# select_block_for_topics()
|
|
# selected_blocks 딕셔너리 생성
|
|
# finalize_block_specs()
|
|
|
|
# 줄 259~298: layout_concept 조립 — 전체 제거
|
|
# final_blocks 리스트, sidebar label, 역할 순서 배치
|
|
|
|
# 줄 300~339: fill_candidates 호출 — 전체 제거
|
|
# topic별 fill_candidates()
|
|
# 결과 검증
|
|
```
|
|
|
|
### 교체되는 코드 (R'-4에서 신규 작성)
|
|
|
|
```python
|
|
# 2-3단계 통합: AI HTML 생성 (줄 166~ 교체)
|
|
yield {"event": "progress", "data": "2/5 슬라이드 HTML 생성 중..."}
|
|
|
|
from src.html_generator import generate_slide_html
|
|
from src.html_validator import validate_html
|
|
|
|
# AI가 HTML 직접 생성
|
|
generated = await generate_slide_html(
|
|
content=content,
|
|
analysis=analysis,
|
|
container_specs=container_specs,
|
|
preset=preset,
|
|
)
|
|
|
|
# HTML 정화 + 토큰 위반 검증
|
|
validated_html = validate_html(generated)
|
|
|
|
_save_step(run_dir, "step2_generated.json", {
|
|
"body_html_length": len(generated.get("body_html", "")),
|
|
"sidebar_html_length": len(generated.get("sidebar_html", "")),
|
|
"footer_html_length": len(generated.get("footer_html", "")),
|
|
})
|
|
```
|
|
|
|
### 유지되는 코드 (4단계 이후: 줄 341~)
|
|
|
|
```python
|
|
# 줄 341~350: 4단계 렌더링 — 유지하되 render_slide → render_slide_from_html로 변경
|
|
html = render_slide_from_html(generated, analysis, preset)
|
|
_save_step(run_dir, "step4_rendered.html", html)
|
|
|
|
# 줄 352~446: Selenium 측정, overflow 감지, 수학적 조정 — 유지
|
|
# 단, overflow 시 텍스트 압축(fill_content 호출, 줄 442)은 제거
|
|
# 대신 AI HTML 재생성 요청
|
|
|
|
# 줄 448~474: 비전 모델 품질 게이트 — 유지
|
|
|
|
# 줄 476~483: 이미지 삽입, final.html 저장 — 유지
|
|
```
|
|
|
|
### _adjust_design (줄 490~589) — 제거 또는 변경
|
|
|
|
```
|
|
현재: layout_concept의 블록별 텍스트 양을 보고 CSS 변수 조정
|
|
R': AI가 HTML 생성 시 이미 CSS를 포함하므로, 별도 CSS 조정 단계 불필요
|
|
→ 제거하거나, AI 생성 HTML에 대한 보조 조정으로 역할 축소
|
|
```
|
|
|
|
### _review_balance, _apply_adjustments (줄 592~730) — 변경
|
|
|
|
```
|
|
현재: 블록 기반 layout_concept를 검수/조정
|
|
R': AI 생성 HTML을 검수. 조정 시 block_selector/fill_candidates가 아닌 html_generator 재호출
|
|
줄 729의 fill_content() 호출 → 제거
|
|
```
|
|
|
|
### _build_overflow_context, _convert_kei_judgment (줄 733~800) — 변경
|
|
|
|
```
|
|
현재: layout_concept의 블록 데이터에서 overflow 컨텍스트 추출
|
|
R': AI 생성 HTML에서 직접 추출하도록 변경
|
|
```
|
|
|
|
---
|
|
|
|
## 7. 다른 파일에 대한 영향 (충돌/회귀 체크)
|
|
|
|
### 영향 없음 (건드리지 않음)
|
|
|
|
| 파일 | 이유 |
|
|
|------|------|
|
|
| `src/kei_client.py` — classify_content, refine_concepts | 1단계에서 호출. R'에서 변경 없음 |
|
|
| `src/kei_client.py` — vision_quality_gate | 품질 게이트. R'에서 변경 없음 |
|
|
| `src/space_allocator.py` — calculate_container_specs | 컨테이너 계산. R'에서 변경 없음 |
|
|
| `src/design_director.py` — select_preset, LAYOUT_PRESETS | 프리셋 선택. R'에서 변경 없음 |
|
|
| `src/slide_measurer.py` | Selenium 측정. R'에서 변경 없음 |
|
|
| `src/config.py` | 설정. 변경 없음 |
|
|
| `src/sse_utils.py` | SSE 스트리밍. 변경 없음 |
|
|
| `src/image_utils.py` | 이미지 크기 측정. 변경 없음 |
|
|
| `src/main.py` | FastAPI 엔드포인트. generate_slide 호출은 동일 |
|
|
| `static/index.html` | 프론트엔드. 변경 없음 |
|
|
| `templates/slide-base.html` | 슬라이드 프레임. 변경 없음 |
|
|
| `static/tokens.css`, `static/base.css` | 디자인 토큰. 변경 없음 (프롬프트에서 읽기만 함) |
|
|
| `templates/blocks/*.html` | 38개 블록. 변경 없음 (CSS 참고용으로만 유지) |
|
|
| `templates/catalog.yaml` | 변경 없음 (프롬프트에서 CSS 패턴 인덱스로 참고만) |
|
|
|
|
### 변경되는 파일
|
|
|
|
| 파일 | 변경 내용 | 기존 코드 영향 |
|
|
|------|----------|-------------|
|
|
| `src/pipeline.py` | 줄 166~339 교체 (블록 선택+채우기 → html_generator 호출) | 2-3단계만 교체, 나머지 유지 |
|
|
| `src/pipeline.py` | _adjust_design 제거 또는 축소 | 4단계 CSS 조정 불필요 |
|
|
| `src/pipeline.py` | _apply_adjustments에서 fill_content 호출 제거 | overflow 시 html_generator 재호출 |
|
|
| `src/renderer.py` | `render_slide_from_html()` 신규 함수 추가 | 기존 `render_slide()` 변경 없음 (하위 호환) |
|
|
|
|
### 신규 파일
|
|
|
|
| 파일 | 역할 |
|
|
|------|------|
|
|
| `src/html_generator.py` | 핵심 — Kei 분석 + 토큰 + 예시 → AI HTML 생성 |
|
|
| `src/design_tokens.py` | tokens.css + 블록 CSS 패턴을 프롬프트용 텍스트로 추출 |
|
|
| `src/html_validator.py` | nh3 정화 + CSS 토큰 위반 검증 |
|
|
| `data/examples/C_reference.html` | few-shot 예시 1 |
|
|
| `data/examples/hybrid_simulation.html` | few-shot 예시 2 |
|
|
| `scripts/test_phase_r_prime.py` | R' 테스트 스크립트 |
|
|
|
|
### 호출하면 안 되는 것 (자기 검증)
|
|
|
|
| 함수 | 위치 | 이유 |
|
|
|------|------|------|
|
|
| `select_block_candidates()` | `block_selector.py` | 블록 선택 시스템 — R'에서 제거 |
|
|
| `select_fallback_candidates()` | `block_selector.py` | 동일 |
|
|
| `select_block_for_topics()` | `kei_client.py` | 블록 선택 AI — R'에서 제거 |
|
|
| `fill_candidates()` | `content_editor.py` | 슬롯 채우기 — R'에서 제거 |
|
|
| `fill_content()` | `content_editor.py` | 동일 |
|
|
| `finalize_block_specs()` | `space_allocator.py` | 블록 스펙 — 블록 없으므로 불필요 |
|
|
| `calculate_budgets_for_candidates()` | `space_allocator.py` | 블록 예산 — 블록 없으므로 불필요 |
|
|
|
|
### 호출해야 하는 것 (유지)
|
|
|
|
| 함수 | 위치 | 이유 |
|
|
|------|------|------|
|
|
| `classify_content()` | `kei_client.py` | 1단계 Kei 분석 |
|
|
| `refine_concepts()` | `kei_client.py` | 1.5단계 컨셉 구체화 |
|
|
| `calculate_container_specs()` | `space_allocator.py` | 컨테이너 px 계산 |
|
|
| `select_preset()` | `design_director.py` | 프리셋 선택 |
|
|
| `measure_rendered_heights()` | `slide_measurer.py` | Selenium 측정 |
|
|
| `capture_slide_screenshot()` | `slide_measurer.py` | 스크린샷 캡처 |
|
|
| `vision_quality_gate()` | `kei_client.py` | 비전 모델 품질 게이트 |
|
|
| `generate_slide_html()` | `html_generator.py` (신규) | AI HTML 생성 |
|
|
| `validate_html()` | `html_validator.py` (신규) | HTML 정화+검증 |
|
|
| `render_slide_from_html()` | `renderer.py` (신규 함수) | AI HTML → 슬라이드 프레임 삽입 |
|
|
|
|
---
|
|
|
|
## 8. 자기 검증 체크리스트
|
|
|
|
구현 시작 전 반드시 확인:
|
|
|
|
- [ ] **block_selector.py에서 블록을 "선택"하는 코드를 호출하고 있는가?** → 호출하면 안 됨
|
|
- [ ] **fill_candidates/fill_content로 "슬롯에 텍스트를 채우는" 코드를 호출하고 있는가?** → 호출하면 안 됨
|
|
- [ ] **finalize_block_specs/calculate_budgets_for_candidates를 호출하고 있는가?** → 호출하면 안 됨
|
|
- [ ] **AI가 HTML 구조를 결정하고 있는가, 블록 템플릿이 구조를 결정하고 있는가?** → AI가 결정해야 함
|
|
- [ ] **기존 코드를 "수정"하는 것인가, "교체"하는 것인가?** → 2-3단계는 교체
|
|
- [ ] **C_reference.png 수준의 결과가 나올 수 있는 구조인가?** → topic 합침, 포함 관계, 핵심 메시지 분리가 가능해야 함
|
|
- [ ] **_adjust_design에서 블록 기반 로직을 사용하고 있는가?** → 사용하면 안 됨
|
|
- [ ] **_apply_adjustments에서 fill_content를 호출하고 있는가?** → 호출하면 안 됨
|
|
|
|
---
|
|
|
|
## 9. 기대 효과
|
|
|
|
| 지표 | Phase R (실패) | Phase R' (목표) |
|
|
|------|---------------|----------------|
|
|
| 결과물 수준 | 34점 (블록 선택+슬롯 한계) | C_reference.png 수준 (70점+) |
|
|
| 구조 결정 주체 | 블록 템플릿 | AI (콘텐츠 기반) |
|
|
| topic 합침/분리 | 불가 | 가능 |
|
|
| 포함 관계 시각화 | 해당 블록 없으면 불가 | AI가 직접 구성 |
|
|
| 원본 텍스트 보존 | 편집자 의존 (축약됨) | AI가 원본 직접 삽입 |
|
|
| CSS 일관성 | 블록 템플릿 보장 | 디자인 토큰 + 블록 CSS 참고 + 검증 |
|
|
|
|
---
|
|
|
|
## 10. 회귀 방지 — Phase P=Q=R 반복 금지
|
|
|
|
### 이 Phase에서 절대 하면 안 되는 것
|
|
|
|
1. **block_selector.py의 select_block_candidates를 호출하면 안 됨** — 블록 "선택" 시스템 회귀
|
|
2. **content_editor.py의 fill_candidates/fill_content를 호출하면 안 됨** — "슬롯 채우기" 회귀
|
|
3. **catalog.yaml에서 블록을 매칭하면 안 됨** — 블록 매칭 회귀
|
|
4. **variant를 추가하면 안 됨** — Phase R의 실패 패턴 회귀
|
|
5. **"최소 변경"으로 기존 코드 위에 패치하면 안 됨** — P=Q=R 반복의 원인
|
|
|
|
### 이 Phase에서 반드시 해야 하는 것
|
|
|
|
1. **html_generator.py에서 AI가 HTML 구조를 직접 생성** — 콘텐츠가 구조를 결정
|
|
2. **블록 CSS는 참고만** — "선택"이 아닌 "참고"
|
|
3. **pipeline.py 줄 166~339를 교체** — 패치가 아닌 교체
|
|
4. **C_reference.png와 동일 수준의 결과를 자동으로 생성** — 이것이 합격 기준
|