블록 선택 방식(Phase P/Q/R) 폐기 → Claude Sonnet이 영역별 HTML 직접 생성. 생성-검증 분리: content_verifier.py로 텍스트 보존/금지 콘텐츠/구조를 코드 검증. 주요 변경: - src/html_generator.py: 4개 프롬프트 템플릿(BG/CORE/SIDEBAR/FOOTER) + 영역별 Claude 호출 - src/content_verifier.py: L1 텍스트 보존, L2 금지 콘텐츠, L3 구조 검증 + 재시도 루프 - src/html_validator.py: 보안 검증(script/iframe 제거) - src/renderer.py: render_slide_from_html() 추가, area div overflow:hidden - scripts/test_phase_s.py: generate_with_retry() 통합, step2b_verification 결과 저장 - 배경 라이트 디자인(#f8fafc), 개조식 어미 변환, 축약 금지 규칙 다음 과제: 폰트 위계(핵심14>본문12>배경10-12>첨부9-11) + 동적 컨테이너 계산 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
13 KiB
13 KiB
Phase S 실행 결과 문제점 + 해결 방향
작성일: 2026-03-31 상태: 문제 기록. 수정 대기. 근거: 1774736083771_phaseS_20260331_024142 결과물 검토
1. 근본 원인
검증 때 성공한 것과 실제 실행에서 실패한 것의 차이:
| 항목 | 검증 (성공) | 실행 (실패) |
|---|---|---|
| 프롬프트 | 실제 텍스트를 한 글자씩 프롬프트에 포함 | "source_data를 그대로 써라"만 지시 |
| CSS | 구체적 수치까지 지정 (13px, #93c5fd 등) | 추상적 ("디자인 토큰 참고") |
| 레이아웃 | 구체적 구조 지시 (flex, float, margin-top 등) | "여백 최소화"만 지시 |
| 결과 | 합격 | 전부 불합격 |
즉, 프롬프트가 구체적이면 합격, 추상적이면 실패.
2. 문제 목록 (전체)
2-1. 텍스트
- 원본 MDX 80-95% 보존 안 됨 — 다시 축약/변형
- source_data가 프롬프트에 직접 포함되지 않고 "참고하라"만 지시
2-2. 레이아웃
- 배경과 본심 사이 간격이 없음
- 본심 가로 크기가 배경에 비해 좁음 — 같은 body인데 너비가 다름
- 전체 컨테이너 크기/간격이 검증 때와 다름
2-3. 이미지
- float으로 어우러지지 않고 본문에 붙어있음
- 검증(core_c_fix)에서는 margin-top으로 위치 조정, 텍스트 감싸기 작동 — 지금은 안 됨
- 이미지 캡션이 이상함
2-4. 들여쓰기
- 불릿(•) 다음 줄 들여쓰기 전혀 적용 안 됨
- padding-left + text-indent CSS가 생성된 HTML에 없음
2-5. 색상/강조
- 배경(다크 박스)이 너무 강해서 본심보다 배경에 시선이 감
- 배경은 "배경"이지 핵심이 아닌데, 시각적으로 가장 강조됨
2-6. 핵심 메시지
- 하단 강조 박스("BIM ≠ DX")가 잘림
2-7. 용어 정의 (sidebar)
- 텍스트 축약 — 검증(verify_v2/A_definitions)에서는 풀 텍스트였음
- overflow +15px — 490px 안에 안 맞음
2-8. 전체 균형
- 배경/본심/sidebar/footer의 시각적 비중이 안 맞음
- 배경이 가장 강조되고 본심이 약함
3. 해결 방향 — 5단계 프로세스
Step 1: 원본 텍스트 매핑
- Kei 분석 결과(topics, purpose, expression_hint)에 따라 원본 MDX에서 해당 텍스트를 매핑
- source_data의 Kei 메모("간결한 문제 제기용" 등)는 제외
- 원본 MDX 텍스트만 가져옴
- MDX를 ## 기준으로 섹션 슬라이싱 → topics의 source_hint로 섹션 매칭
Step 2: 검증 합격 프롬프트와 결합
- 검증에서 합격한 프롬프트의 디자인/구조 부분은 고정
- Step 1에서 매핑한 원본 텍스트를 동적으로 삽입
- 영역별 개별 호출 (배경/본심/sidebar/footer)
| 영역 | 검증 합격 프롬프트 | 텍스트 부분 |
|---|---|---|
| 배경 | verify_claude_1_2.py prompt_1의 디자인 지시 | Step 1에서 매핑한 혼용+사례 텍스트 |
| 본심 | core_c_fix.py의 CSS 구조 | Step 1에서 매핑한 핵심기술 텍스트 |
| sidebar | verify_definitions_v2.py prompt_a의 디자인 지시 | Step 1에서 매핑한 용어 정의 텍스트 |
| footer | 간단 프롬프트 | Step 1에서 매핑한 결론 텍스트 |
Step 3: Claude 생성 HTML 자체 검증 (제출 전)
- 원본 텍스트가 축약/변형 없이 들어갔는가
- 들여쓰기 CSS(padding-left + text-indent)가 적용되었는가
- 이미지가 정확히 배치되었는가
- 컨테이너 크기를 초과하지 않는가
- Kei 메모("간결한 문제 제기용" 등)가 슬라이드에 포함되지 않았는가
- 검증 실패 시 사용자에게 제출하지 않고 재생성
Step 4: 전체 슬라이드 조립 + 전체 균형 검증
- 각 영역 HTML을 슬라이드 프레임에 조립
- 전체 균형 검증:
- 배경이 본심보다 강조되지 않는가
- 영역 간 간격/여백이 적절한가
- 전체 720px 안에 들어가는가
- 시각적 비중이 page_structure의 비중과 맞는가
Step 5: 결과물 저장
- runs 폴더에 스텝별로 정리
- 각 스텝의 입력/출력을 JSON + PNG로 저장
- 최종 실행 환경: localhost:8001 (Design Agent 서버, pipeline.py 경유)
4. 세부 수정 사항 10개 (2026-03-31 03:30 추가)
Phase S 실행 결과에서 발견된 세부 문제 10개와 각각의 해결 방법.
1-1. 배경 다크 박스가 시각적으로 너무 강함
- 문제: linear-gradient(135deg, #1e293b, #0f172a) — 거의 검정. 본심보다 배경이 더 눈에 띔.
- 해결: 배경의 opacity를 낮추거나, 다크 대신 연한 회색 배경 사용. 또는 본심에 시각적 강조 추가하여 상대적 균형.
- 프롬프트 수정: BG_PROMPT의 배경색을 연한 톤으로 변경하거나, 본심에 배경색/border 추가.
- 충돌/회귀: 없음. 색상만 변경이고, 검증 합격 배경도 같은 다크였으므로 톤만 조정.
1-2. 배경 사례 카드가 배경 영역 안에 다 들어가는가
- 문제: height:176px + overflow:hidden이면 사례 카드가 잘릴 수 있음.
- 해결: 프롬프트에 "폰트를 줄여서라도 height 안에 맞출 것" 이미 포함. 실제 잘림 여부는 브라우저에서 확인.
- 충돌/회귀: 없음. 기존 프롬프트에 이미 있는 지시.
2-1. 본심 가로 크기가 배경과 다름
- 문제: 배경 width:100%, 본심 width:707px. 같은 body인데 너비가 다름.
- 해결: CORE_PROMPT의 CSS에서
.core { width: 707px; }→.core { width: 100%; }변경. - 충돌/회귀: 없음. 본심이 body 전체 너비를 사용하는 것이 자연스러움. 검증(core_c_fix)에서 707px이었던 것은 테스트 컨테이너 크기였을 뿐.
3-1. 본심 이미지가 텍스트와 어우러지지 않음
- 문제: float이 적용 안 되거나 이미지가 본문에 붙어있음.
- 해결: CORE_PROMPT의 참고 CSS에
.fi { float:right; margin:60px 0 8px 12px; width:250px; }이미 포함되어 있으나, Claude가 무시. → 프롬프트에 "이 CSS를 반드시 그대로 사용하라. float:right를 반드시 적용하라." 강조 추가. - 충돌/회귀: 없음. CSS 강조만 추가.
3-2. 이미지 캡션이 이상함
- 문제: 캡션 텍스트가 검증 때와 다를 수 있음.
- 해결: CORE_PROMPT의 참고 HTML에서 캡션을 명시:
<div class="cap">건설산업의 DX</div>. "이 캡션을 그대로 사용하라" 추가. - 충돌/회귀: 없음. 캡션 텍스트 고정.
4-1. 본심 우상단 "상세비교" 팝업 링크
- 문제: 검증(core_c_fix)에서는
📊 DX와 BIM의 상세 비교텍스트 링크였는데 다르게 나옴. - 해결: CORE_PROMPT의 참고 HTML에서
<span class="popup-link">📊 DX와 BIM의 상세 비교</span>명시. "이 텍스트를 그대로 사용하라" 추가. - 충돌/회귀: 없음. 텍스트 명시만 추가.
4-2. 본심 하단 핵심 메시지 박스
- 문제: "상위-하위 포함관계" 같은 임의 텍스트가 들어감.
- 해결: CORE_PROMPT에서 핵심 메시지를 명시:
<div class="key-msg"><em>BIM ≠ DX</em> — BIM은 DX를 실현하기 위한 핵심 기술 중 하나일 뿐이다</div>"이 텍스트를 그대로 사용하라. '상위개념', '하위기술', '포함관계' 같은 임의 라벨 금지." 추가. - 충돌/회귀: 없음. 텍스트 명시 + 금지어 추가.
5-1. 용어 정의 들여쓰기 안 됨
- 문제: 불릿 2줄째가 왼쪽 끝에서 시작. padding-left + text-indent 미적용.
- 해결: SIDEBAR_PROMPT에 CSS 코드를 직접 포함하고 "이 CSS를 반드시 적용하라" 명시:
.def-bullet { padding-left: 14px; text-indent: -14px; } .def-bullet::before { content: '•'; display: inline-block; width: 14px; text-indent: 0; } - 충돌/회귀: 없음. CSS 추가만.
6-1. 용어 정의에서 원본의 2줄을 1점에 합침
- 문제: BIM 정의 "형상정보와... 정보 관리 도구. 건설 정보와... 핵심 인프라 기술"이 하나의 불릿. 검증(verify_definitions_v2)에서는 2개 불릿으로 분리.
- 해결: SIDEBAR_PROMPT에 "마침표(.)로 끝나는 문장이 2개 이상이면 별도 불릿(•)으로 분리하라" 명시. 또는 프롬프트에 넣는 텍스트를 미리 줄 단위로 분리.
- 충돌/회귀: 없음. 분리 규칙 추가만. 단, 원본 MDX가 1줄에 2문장인 경우에만 적용 — 다른 MDX에서 1문장 1줄인 경우는 영향 없음.
7-1. 배경 블록이 다크 디자인 — 보조 영역인데 시각적 주인공
- 문제: BG_PROMPT가 "다크 배경 박스"로 설계. 전체 슬라이드에서 흰색 바탕에 남색 블록 하나만 있으면 거기에 시선이 먼저 감. 배경은 보조인데 시각적으로는 주인공이 되는 근본적 모순.
- 해결: BG_PROMPT 자체를 라이트 디자인으로 근본 교체. background: #f8fafc (연회색), border: 1px solid #e2e8f0. 사례 카드도 padding/gap 축소 (6px 8px, gap 8px).
- 충돌/회귀: 없음. 디자인 변경이고 기능 영향 없음.
7-2. 배경 텍스트가 개조식이 아닌 서술형 원문 그대로
- 문제: 배경 영역의 문장이 "~인식되고 있다", "~해당한다", "~빈번하다" 등 서술형으로 끝남. 슬라이드는 개조식이어야 하고, 마침표로 끝나는 2-3문장이 불릿 없이 한 덩어리로 들어감.
- 해결:
- 모든 프롬프트에 개조식 통일 규칙 추가: 서술형(~하다/~이다/~있다/~된다) → 개조식(~에 해당/~인식되는 중/~발생 등)
- 마침표(.)로 끝나는 문장이 2개 이상이면 별도 불릿(•)으로 분리 (sidebar에만 있던 규칙을 전체로 확대)
- 슬라이드 전체에서 문장 끝 형식이 통일되어야 함
- 충돌/회귀: 없음. 원본 "의미"는 보존하되 "형식"만 슬라이드에 맞게 변환. 범용적 규칙.
5. 충돌/회귀 종합 검토
| 수정 | 기존 코드 영향 | 다른 MDX 영향 | 판정 |
|---|---|---|---|
| 1-1 배경 톤 조정 | 색상 값만 변경 | 모든 MDX에 동일 적용 | ✅ 안전 |
| 1-2 사례 잘림 확인 | 프롬프트 지시 기존과 동일 | 영향 없음 | ✅ 안전 |
| 2-1 본심 width 100% | CSS 값 변경 | 모든 MDX에 동일 적용 | ✅ 안전 |
| 3-1 float 강조 | 프롬프트 강조 추가 | 영향 없음 | ✅ 안전 |
| 3-2 캡션 명시 | 프롬프트 텍스트 추가 | 다른 MDX에서는 해당 topic의 title로 동적 생성 | ✅ 안전 |
| 4-1 팝업 링크 명시 | 프롬프트 텍스트 추가 | 팝업이 없는 MDX에서는 생성 안 됨 | ✅ 안전 |
| 4-2 핵심 메시지 명시 | 프롬프트 텍스트 추가 + 금지어 | core_message에서 동적 생성 | ✅ 안전 |
| 5-1 들여쓰기 CSS | CSS 추가 | 모든 MDX에 동일 적용 | ✅ 안전 |
| 6-1 문장 분리 | 분리 규칙 추가 | 1문장 1줄인 MDX에는 영향 없음 | ✅ 안전 |
| 7-1 배경 라이트 디자인 | BG_PROMPT 전면 교체 | 모든 MDX에 동일 적용 | ✅ 안전 |
| 7-2 개조식 통일 | 전체 프롬프트에 규칙 추가 | 모든 MDX에 동일 적용 | ✅ 안전 |
회귀 위험: 없음. 충돌 위험: 없음. 하드코딩: 4-2의 핵심 메시지 텍스트는 analysis.core_message에서 동적으로 가져오도록 해야 함 — 하드코딩 아님.
6. 자기 검증 체크리스트
결과물 제출 전 반드시 확인:
- 배경이 본심보다 시각적으로 강조되지 않는가?
- 본심 가로 크기가 배경과 동일한가? (둘 다 100%)
- 본심 이미지가 float:right로 텍스트와 어우러지는가?
- 본심 이미지 캡션이 적절한가?
- 본심 우상단에 팝업 링크가 있는가?
- 본심 하단 핵심 메시지에 임의 텍스트("상위개념", "하위기술", "포함관계")가 없는가?
- 용어 정의 들여쓰기(padding-left + text-indent)가 적용되어 있는가?
- 용어 정의에서 2문장이 별도 불릿으로 분리되어 있는가?
- 텍스트가 원본 MDX의 80-95%를 보존하는가?
- Kei 메모가 슬라이드에 포함되지 않았는가?
- 배경이 라이트 디자인(연회색)인가? (다크 배경 아닌가?)
- 문장 끝이 개조식으로 통일되어 있는가? (서술형 "~하다/~이다" 혼재 없는가?)
- 마침표로 끝나는 2문장 이상이 별도 불릿으로 분리되었는가?
7. 검증 합격 결과물 참조
| 영역 | 파일 | 프롬프트 위치 |
|---|---|---|
| 배경 | data/runs/verify_claude_20260330_212019/verify1.png | scripts/verify_claude_1_2.py prompt_1 |
| 용어 정의 | data/runs/verify_v2_20260331_003421/A_definitions.png | scripts/verify_definitions_v2.py prompt_a |
| 본심 | data/runs/core_c_fix_20260331_015828/core_c_fix.png | scripts/verify_core_c_fix.py (직접 작성 HTML) |
| footer | 이전부터 OK | 간단 프롬프트 |