Phase T 적용: 폰트 위계 + 불릿 충돌 수정 + pipeline 통합
폰트 위계 적용: - key-msg: 11→14px (가장 중요, 가장 큰 폰트) - core: 12px 유지 - bg: 11px/9-10px 유지 - sidebar: 제목 14→11px, 불릿 12→10px (가장 덜 중요, 가장 작은 폰트) 불릿 충돌 수정: - BG/SIDEBAR: <style> 블록 금지, 인라인 style만 사용 - CORE의 .bp::before CSS가 BG의 .bp에 적용되는 문제 해결 pipeline.py 통합: - generate_slide_html() → generate_with_retry() 교체 - step2b_verification.json 저장 추가 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -56,13 +56,14 @@ BG_PROMPT = """다음 콘텐츠를 배경(보조) 영역 HTML로 만들어라.
|
||||
- 사례 카드: background:#ffffff, border-left: 2px solid #94a3b8, padding: 6px 8px (여백 최소화)
|
||||
- 사례 제목: 10px bold #334155, margin-bottom: 2px
|
||||
- 사례 내용: 9px #64748b, line-height: 1.3
|
||||
- 들여쓰기: 불릿 다음 줄은 불릿 옆 글자 위치에 맞춤
|
||||
CSS: .bp {{ padding-left:14px; text-indent:-14px; }}
|
||||
CSS: .bp::before {{ content:'•'; display:inline-block; width:14px; text-indent:0; }}
|
||||
- 들여쓰기: 불릿은 인라인 style만 사용. CSS class 사용 금지 (<style> 블록 금지).
|
||||
불릿 마커: 텍스트로 "• " 직접 삽입 (::before 금지)
|
||||
들여쓰기: style="padding-left:14px; text-indent:-14px;" 인라인으로.
|
||||
- 폰트를 줄여서라도 높이 안에 맞출 것. overflow:hidden이므로 넘치면 잘림.
|
||||
- 모든 텍스트가 보여야 한다. 잘리는 텍스트가 있으면 안 됨.
|
||||
- <style> 블록을 만들지 마라. 모든 스타일을 인라인 style 속성으로만 적용하라.
|
||||
|
||||
HTML + inline <style>만 반환. 설명 없이 코드만."""
|
||||
HTML만 반환. <style> 블록 금지. 설명 없이 코드만."""
|
||||
|
||||
|
||||
CORE_PROMPT = """다음 콘텐츠를 본심 영역 HTML로 만들어라.
|
||||
@@ -155,7 +156,7 @@ CORE_PROMPT = """다음 콘텐츠를 본심 영역 HTML로 만들어라.
|
||||
border-radius: 6px;
|
||||
padding: 5px 12px;
|
||||
text-align: center;
|
||||
font-size: 11px;
|
||||
font-size: 14px;
|
||||
font-weight: 700;
|
||||
color: #0c4a6e;
|
||||
margin-top: 8px;
|
||||
@@ -225,24 +226,22 @@ SIDEBAR_PROMPT = """다음 용어 정의를 sidebar 카드로 만들어라. {wid
|
||||
|
||||
## 디자인 요구사항
|
||||
1. 최상위 div: width:{width}px, height:{height}px, overflow:hidden (반드시 적용, 넘치면 잘림)
|
||||
2. 상단에 "용어 정의" 구분선 라벨 (좌우 선 + 중앙 텍스트, 13px #64748b)
|
||||
2. 상단에 "용어 정의" 라벨 (카드 좌측 시작점에 맞춰 좌측 정렬, 10px #64748b)
|
||||
3. 각 용어를 카드로:
|
||||
- 배경: #f8fafc, 테두리: 1px solid #e2e8f0, border-radius: 8px, padding: 14px
|
||||
- 용어명: 14px bold #1e293b (예: "BIM (Building Information Modeling)")
|
||||
- 용어명: 11px bold #1e293b (예: "BIM (Building Information Modeling)")
|
||||
- 부제 금지: 원본에 없는 텍스트를 만들어 넣지 마라. 용어명 아래에 임의 설명을 추가하지 마라.
|
||||
- 불릿: 12px #475569, line-height: 1.6, 불릿 마커 "•"
|
||||
- 들여쓰기 CSS (반드시 적용):
|
||||
```css
|
||||
.def-bullet {{ padding-left: 14px; text-indent: -14px; margin-bottom: 4px; }}
|
||||
.def-bullet::before {{ content: '•'; display: inline-block; width: 14px; text-indent: 0; color: #475569; }}
|
||||
```
|
||||
- 불릿: 10px #475569, line-height: 1.6, 불릿 마커 "•"
|
||||
- 들여쓰기: 인라인 style만 사용 (CSS class 사용 금지).
|
||||
각 불릿 div에 style="padding-left:14px; text-indent:-14px; margin-bottom:4px; font-size:10px; color:#475569; line-height:1.6;" 적용.
|
||||
불릿 마커는 "• " 텍스트로 직접 삽입 (::before 금지).
|
||||
- 각 불릿은 원본 텍스트 그대로. 단어를 한 글자도 빼지 마라.
|
||||
- 마침표(.)로 끝나는 문장이 2개 이상이면 별도 불릿(•)으로 분리하라.
|
||||
- 개조식 어미 변환: 문장 끝 1-2글자만 변환 ("~이다"→삭제, "~있다"→"~있음"). 그 외 단어 절대 건드리지 마라.
|
||||
4. 카드 간 간격 10px
|
||||
5. {height}px 안에 맞출 것. 넘치면 폰트를 줄여서 맞출 것.
|
||||
|
||||
HTML + inline <style>만 반환. 설명 없이 코드만."""
|
||||
HTML만 반환. <style> 블록 금지. 모든 스타일은 인라인 style 속성으로. 설명 없이 코드만."""
|
||||
|
||||
|
||||
FOOTER_PROMPT = """결론 배너 HTML.
|
||||
|
||||
@@ -165,8 +165,7 @@ async def generate_slide(
|
||||
# 블록 선택 없음. 슬롯 채우기 없음. AI가 콘텐츠에 맞는 HTML 구조를 직접 만든다.
|
||||
yield {"event": "progress", "data": "2/4 슬라이드 HTML 생성 중..."}
|
||||
|
||||
from src.html_generator import generate_slide_html
|
||||
from src.html_validator import validate_and_clean_html
|
||||
from src.content_verifier import generate_with_retry
|
||||
from src.renderer import render_slide_from_html
|
||||
from src.kei_client import vision_quality_gate
|
||||
import asyncio
|
||||
@@ -191,8 +190,8 @@ async def generate_slide(
|
||||
"b64": img_b64,
|
||||
})
|
||||
|
||||
# Claude Sonnet이 HTML 생성
|
||||
generated = await generate_slide_html(
|
||||
# Claude Sonnet HTML 생성 + 독립 검증 + 재시도 루프
|
||||
generated, verification = await generate_with_retry(
|
||||
content=content,
|
||||
analysis=analysis,
|
||||
container_specs=container_specs,
|
||||
@@ -200,8 +199,10 @@ async def generate_slide(
|
||||
images=slide_images,
|
||||
)
|
||||
|
||||
# HTML 정화 + 검증
|
||||
generated = validate_and_clean_html(generated)
|
||||
_save_step(run_dir, "step2b_verification.json", {
|
||||
area: {"passed": r.passed, "score": r.score, "errors": r.errors}
|
||||
for area, r in verification.items()
|
||||
})
|
||||
|
||||
_save_step(run_dir, "step2_generated.json", {
|
||||
"body_html_length": len(generated.get("body_html", "")),
|
||||
|
||||
Reference in New Issue
Block a user