# Phase K: communicative role 기반 시각적 위계 + 콘텐츠 시퀀싱

> 상태: ✅ 완료 — purpose별 분량 원칙은 Phase O에서 동적 계산(_max_chars_total)으로 발전.
>
> Phase I(코드 정합성) + Phase J(블록 선택 권한) 이후에도 결과물 품질이 개선되지 않은 근본 원인.
> **핵심: purpose(communicative role)를 분류하고도, 시각적 결과에 반영하지 않았음.**
> 사용자가 반복 요청한 콘텐츠 구조 흐름이 Phase J에서 누락됨. 이번에 전부 반영.
>
> **후속 변경 (Phase O):**
> - purpose별 분량 제약(문제제기 100자 등) → 컨테이너 크기 기반 동적 계산으로 대체
> - catalog.yaml schema의 body/sidebar 글자수 → ref_chars(참고값) + max_lines/font_size(디자인 스펙)으로 분리

---

## 사용자 반복 요청 (Phase I 이전부터)

```
"상단에 오해하고 잘못되었다.
→ 그래서 보니 혼용하는 사례들이 있더라.
→ 여기랑 여기 등을 구체적 사례들을 봐라.
→ 사실은 이런것이다!! (이게 구조화가 되어야 하는것 아닌가?) ← 이게 핵심
→ 그리고 해당하는 내용에 대한 개념 정의
→ 마지막 핵심 문장 딱 하나!"

"관련 용어들의 정의만 시각적으로 오른쪽에 배치되고,
위에서부터
배경 & 증빙 사례 → 그래서 이거다! (더 자세히 보러가기) → 이 슬라이드의 핵심 키워드!!
우측에 관련 용어에 대한 정의가 구조화되어 시각적으로 잘되어야지."
```

---

## 참고 연구

| 프로젝트 | 핵심 접근 | 우리 적용점 |
|---------|----------|-----------|
| Presenton | 블록별 JSON 스키마(min/maxLength)로 overflow 원천 차단 | purpose별 분량 제약 (K-4) |
| PPTAgent | communicative role 분류 후 레이아웃 매칭 | purpose → 시각적 위계 매핑 (K-1) |
| Auto-Slides | 인지 부하 이론 기반 콘텐츠 시퀀싱 | purpose 기반 인지 흐름 순서 (K-2) |

공통 결론: **"communicative role을 먼저 분류하지 않고 레이아웃부터 선택하는 것이 실패의 근본 원인"**

우리 파이프라인은 role(purpose)을 분류하지만, **그것이 시각적 결과에 반영되지 않는 것**이 문제.

---

## 스크린샷에서 확인된 실제 문제

1. "용어간 상호관계" 4줄 불릿이 body에서 가장 크게 차지 — 핵심이 아닌데 주인공
2. DX vs BIM 비교표가 **화면 밖으로 잘림** — 헤더만 보이고 내용 행 안 보임
3. sidebar 혼용 사례 3열 카드가 파랑/초록/주황으로 과도하게 강조
4. sidebar 용어 정의가 장황하게 나열
5. 비교표에 "왜 비교하는지" 맥락 안내 없음

---

## 변경 항목 (8건)

### K-1: purpose → 시각적 위계 매핑

**지금:** 모든 purpose가 동일한 크기의 블록으로 렌더링. 핵심전달이든 근거사례든 같은 medium 블록.
**변경:** purpose별 시각적 비중 정의.

| purpose | 시각적 비중 | body 내 공간 비율 |
|---------|-----------|----------------|
| 핵심전달 | **최대** — body의 주인공 | 40-60% |
| 문제제기 | 간결 — compact 블록 | 15-20% |
| 근거사례 | 보조 — 간결 요약 또는 sidebar | 10-15% |
| 용어정의 | sidebar 참조 — body에서 빠짐 | sidebar 전용 |
| 결론강조 | footer 1줄 | footer 전용 |

**반영 위치:**
- KEI_PROMPT (kei_client.py): Kei가 꼭지 설계 시 비중 명시
- STEP_B_PROMPT (design_director.py): 팀장이 블록 크기를 purpose 비중에 맞춤

---

### K-2: purpose 기반 인지 흐름 순서

**지금:** Kei가 꼭지를 추출하지만 body 내 배치 순서를 Sonnet이 자유 결정.
**변경:** purpose가 인지 흐름 순서를 결정. Kei가 순서를 명시하고 팀장은 존중.

**인지 흐름 원칙 (하드코딩 아닌 원칙):**
- 문제/배경이 먼저 → 왜 이걸 봐야 하는지
- 근거/사례가 다음 → 그 문제의 증거
- 핵심 내용이 가장 크게 → 그래서 이거다!
- 결론이 마지막 → 기억할 한 줄

**반영 위치:**
- KEI_PROMPT: "핵심전달이 body의 중심에 오도록 순서를 설계하라. 문제제기와 근거사례는 핵심전달을 위한 도입부이다."
- 콘텐츠 유형에 따라 Kei가 판단 — 모든 콘텐츠에 동일 순서 강제 아님

---

### K-3: purpose별 허용/금지 블록

**지금:** purpose 가이드가 부적절한 블록을 추천하거나, Sonnet이 purpose와 무관하게 선택.
**변경:** purpose별 허용 블록 + 금지 블록을 명확히 정의.

| purpose | 허용 블록 | 금지 블록 |
|---------|----------|----------|
| 문제제기 | quote-big-mark, callout-warning, quote-question | 비교 블록, 카드 블록 |
| 근거사례 | card-tag-image(sidebar), card-numbered, dark-bullet-list | 비교표 (근거에 비교표 쓰면 핵심과 혼동) |
| 핵심전달 | compare-2col-split, comparison-2col, compare-3col-badge, topic-left-right | card-icon-desc (이모지), quote 계열 |
| 용어정의 | card-numbered, dark-bullet-list (sidebar 전용) | 비교 블록, 시각화 블록 |
| 결론강조 | banner-gradient | 나머지 전부 |

**반영 위치:**
- STEP_B_PROMPT purpose 가이드 (design_director.py)
- catalog.yaml when/not_for 보강

---

### K-4: purpose별 분량 제약 (min/max)

**지금:** slot_desc에 슬롯 의미만 있고 분량 제약 없음. 편집자가 자유롭게 분량 결정.
**변경:** purpose별 분량 가이드.

| purpose | 분량 가이드 | 이유 |
|---------|-----------|------|
| 문제제기 | max 100자 (2-3줄) | 간결하게. 도입부. |
| 근거사례 | max 150자 (핵심만) | 상세는 자세히보기 또는 sidebar. |
| 핵심전달 | 200-400자 (충분히 구조화) | 주인공이니 충분한 공간. |
| 용어정의 | 각 용어 max 50자 | sidebar에서 짧게. |
| 결론강조 | max 40자 (1문장) | 기억할 한 줄. |

**반영 위치:**
- EDITOR_PROMPT (content_editor.py): purpose별 분량 원칙
- char_guide: Kei가 꼭지 설계 시 purpose에 따라 char_guide 제안

---

### K-5: sidebar column_override 보존

**지금:** Stage 3(fill_content)에서 data를 통째로 덮어쓰면서 column_override 소실.
**변경:** data 덮어쓸 때 column_override 등 메타 키 보존.

**반영 위치:** content_editor.py fill_content() 내 data 매칭 로직

---

### K-6: sidebar 시각적 무게 조절

**지금:** card-tag-image가 파랑/초록/주황 태그로 본문보다 눈에 띔. 배경 증빙인데 주인공처럼 보임.
**변경:**
- sidebar용 블록은 compact + 저채도로 시각적 무게 낮춤
- Kei가 "보조 참조"로 분류한 꼭지는 편집자가 분량을 줄이고 팀장이 compact 블록 선택
- card-tag-image 대신 card-numbered(세로 리스트)를 sidebar 기본으로

**반영 위치:**
- STEP_B_PROMPT: "sidebar 블록은 본문보다 시각적 무게가 낮아야 한다"
- KEI_PROMPT: sidebar 꼭지는 분량을 간결하게

---

### K-7: Kei 검수에 구조 흐름 검증 추가

**지금:** Kei 검수가 높이 초과/채움 균형만 봄. "핵심전달이 주인공인가?"를 안 봄.
**변경:** KEI_REVIEW_PROMPT에 추가 검수 항목:

- 핵심전달 purpose의 꼭지가 body에서 가장 큰 시각적 비중을 차지하는가?
- 문제제기가 간결한가? (100자 이내)
- 용어정의가 sidebar에 있는가? body를 차지하고 있지 않은가?
- 핵심전달 블록이 화면 안에 보이는가? (잘리지 않는가?)

**반영 위치:** KEI_REVIEW_PROMPT (kei_client.py)

---

### K-8: 비교 블록 맥락 안내

**지금:** 비교표가 "DX 구분 BIM" 헤더만으로 등장 → 왜 비교하는지 모름.
**변경:**
- 핵심전달로 비교표를 사용할 때, Kei가 "비교 목적"을 summary로 제공
- 편집자가 비교표 위에 1줄 안내 텍스트를 배치하거나, compare-pill-pair를 헤더로 선행

**반영 위치:**
- KEI_PROMPT: 핵심전달이 비교 구조일 때 "비교 목적"을 명시하라
- EDITOR_PROMPT: 비교 블록의 첫 행에 비교 목적 요약 포함

---

## 반영 파일 총괄

| 파일 | 항목 | 변경 성격 |
|------|------|----------|
| `src/kei_client.py` KEI_PROMPT | K-1, K-2, K-6, K-8 | purpose별 비중 + 인지 흐름 원칙 + sidebar 간결 + 비교 목적 |
| `src/kei_client.py` KEI_REVIEW_PROMPT | K-7 | 구조 흐름 검수 항목 추가 |
| `src/design_director.py` STEP_B_PROMPT | K-1, K-3, K-6 | purpose별 시각적 위계 + 허용/금지 블록 + sidebar 무게 |
| `src/content_editor.py` EDITOR_PROMPT | K-4, K-8 | purpose별 분량 원칙 + 비교 맥락 안내 |
| `src/content_editor.py` fill_content() | K-5 | column_override 보존 |
| `templates/catalog.yaml` | K-3 | when/not_for 보강 (선택적) |

---

## 실행 순서

### K-Step 1: 콘텐츠 설계 (가장 중요 — 이것만 되면 비교표 잘림 해결)

1. K-1: KEI_PROMPT에 purpose별 시각적 비중 원칙
2. K-2: KEI_PROMPT에 인지 흐름 순서 원칙
3. K-4: EDITOR_PROMPT에 purpose별 분량 제약

### K-Step 2: 블록 선택 정확성

4. K-3: STEP_B_PROMPT purpose별 허용/금지 블록
5. K-6: STEP_B_PROMPT + KEI_PROMPT sidebar 시각적 무게
6. K-8: KEI_PROMPT + EDITOR_PROMPT 비교 맥락 안내

### K-Step 3: 코드 + 검수

7. K-5: content_editor.py column_override 보존
8. K-7: KEI_REVIEW_PROMPT 구조 흐름 검수

---

## 이것이 하드코딩이 아닌 이유

- "문제제기 → 근거 → 핵심 → 결론" 순서를 **강제하지 않음**
- Kei에게 **원칙**을 줌: "핵심전달이 주인공이어야 한다", "문제제기는 도입부이므로 간결하게"
- 콘텐츠에 따라 Kei가 **순서와 비중을 판단** — 프로세스 설명이면 프로세스 흐름, 비교면 비교 중심
- purpose별 분량도 **가이드라인** (절대값 아닌 참고)
- Presenton 연구의 min/maxLength처럼 **생성 단계에서 overflow를 예방**하는 원칙

---

## 예상 효과

| 문제 | K 적용 후 |
|------|----------|
| 비교표 화면 밖 잘림 | 문제제기 간결(compact) → 비교표에 공간 확보 |
| 용어간 상호관계가 주인공 | 핵심전달이 주인공, 상호관계는 축약 또는 sidebar |
| sidebar 과도한 강조 | 시각적 무게 낮춤 + 분량 간결 |
| 비교표 맥락 없음 | 비교 목적 안내 선행 |
| 콘텐츠 흐름 반복 무시 | KEI_PROMPT에 원칙 반영 + Kei 검수에서 확인 |

---

## 실행 방안 상세

### K-Step 1: 콘텐츠 설계 — KEI_PROMPT + EDITOR_PROMPT

**대상 파일:** `src/kei_client.py` KEI_PROMPT (20~70행), `src/content_editor.py` EDITOR_PROMPT (26~63행)

#### K-1 + K-2: KEI_PROMPT 3단계(스토리라인 설계) 수정

**현재:** purpose 목록만 나열. 비중/순서 원칙 없음.
**변경:** purpose별 시각적 비중 원칙 + 인지 흐름 원칙 추가.

```
변경할 프롬프트 내용:

## 3단계: 슬라이드 스토리라인 설계

핵심 메시지를 전달하기 위한 흐름을 설계해줘.

### purpose별 시각적 비중 원칙
- 핵심전달: body의 **주인공**. 가장 큰 공간(40-60%). 구조화된 블록으로.
- 문제제기: **도입부**. 간결하게(compact). 2-3줄이면 충분.
- 근거사례: **보조**. 핵심만 짧게. 상세는 sidebar 참조 또는 자세히보기.
- 용어정의: **sidebar 참조**. body에 넣지 마라. 각 용어 1-2줄.
- 결론강조: **footer 1줄**. core_message를 짧고 강하게.

### 인지 흐름 원칙
- 핵심전달이 body의 중심에 오도록 설계하라.
- 문제제기와 근거사례는 핵심전달을 위한 도입부이다.
- 콘텐츠 유형에 따라 순서를 판단하되,
  핵심전달이 항상 가장 큰 시각적 비중을 가져야 한다.
```

**충돌:** 없음. KEI_PROMPT 3단계 섹션 교체. 기존 purpose 목록은 위 내용으로 대체.
**회귀:** Phase J에서 수정한 KEI_PROMPT를 다시 수정. 방향이 같으므로 회귀 아님.
**하드코딩:** 아님. 순서 강제가 아닌 원칙 제공. Kei가 콘텐츠에 맞게 판단.

#### K-8: KEI_PROMPT에 비교 맥락 원칙 추가

**변경:** 배치 규칙 섹션에 1줄 추가.

```
- 핵심전달이 비교 구조일 때, 비교 목적(왜 비교하는가)을 summary에 명시하라.
```

#### K-4: EDITOR_PROMPT에 purpose별 분량 가이드 추가

**현재:** 분량 제약 없음. "글자 수 가이드는 참고"만.
**변경:** purpose별 분량 원칙 추가.

```
## purpose별 분량 원칙 (가이드라인)
- 문제제기: max 100자 (2-3줄). 간결하게. 도입부.
- 근거사례: max 150자. 핵심만 짧게. 상세는 자세히보기.
- 핵심전달: 200-400자. 충분히 구조화. 이것이 주인공.
- 용어정의: 각 용어 max 50자. sidebar에서 짧게 정의.
- 결론강조: max 40자. 기억할 1문장.
```

**충돌:** 없음. EDITOR_PROMPT에 섹션 추가만.
**회귀:** Phase J의 source 규칙(J-4)은 유지됨.

---

### K-Step 2: 블록 선택 — STEP_B_PROMPT + catalog

**대상 파일:** `src/design_director.py` STEP_B_PROMPT (501~508행), `templates/catalog.yaml`

#### K-3: STEP_B_PROMPT purpose 가이드를 허용/금지로 재구성

**현재:** (Phase J에서 수정한 상태)
```
- 문제제기 → callout-warning, quote-big-mark, quote-question
- 근거사례 → quote-big-mark (출처 포함), card-numbered (항목 나열)
- 핵심전달 → comparison-2col, compare-pill-pair, compare-2col-split
- 용어정의 → card-numbered (정의 나열), dark-bullet-list (핵심 포인트)
- 결론강조 → banner-gradient (footer)
- 구조시각화 → venn-diagram (단독 배치)
```

**변경:**
```
## purpose별 블록 선택 규칙

### 문제제기 (간결한 도입부)
- 허용: callout-warning, quote-big-mark, quote-question
- 금지: 비교 블록, 카드 블록, 시각화 블록
- 크기: compact (70px 이하)

### 근거사례 (보조 증빙)
- 허용: card-numbered, dark-bullet-list, card-tag-image(sidebar)
- 금지: 비교표 (핵심전달과 혼동), quote 계열
- 크기: compact~medium

### 핵심전달 (★ 주인공 — body에서 가장 크게)
- 허용: compare-2col-split, comparison-2col, compare-3col-badge, topic-left-right
- 금지: card-icon-desc, quote 계열 (주인공에 부적합)
- 크기: large 권장

### 용어정의 (sidebar 전용)
- 허용: card-numbered, dark-bullet-list
- 금지: 비교 블록, 시각화 블록, card-icon-desc
- 배치: 반드시 sidebar. body에 넣지 마라.

### 결론강조 (footer 1줄)
- 허용: banner-gradient
- 배치: 반드시 footer.
```

**충돌:** Phase J의 J-3a 수정을 대체. 방향 동일(card-icon-desc 제거), 더 구체화.
**회귀:** J-3a보다 상세해진 것이므로 회귀 아님.

#### K-6: STEP_B_PROMPT에 sidebar 원칙 추가

**변경:** 블록 선택 규칙 섹션에 추가.

```
- sidebar 블록은 본문보다 시각적 무게가 낮아야 한다.
- sidebar에는 compact 블록 우선. large 블록 금지.
- sidebar의 카드는 1열 세로 배치. 3열 가로 금지.
```

---

### K-Step 3: 코드 + 검수

**대상 파일:** `src/content_editor.py` fill_content(), `src/kei_client.py` KEI_REVIEW_PROMPT

#### K-5: column_override 보존

**현재:** `orig_block["data"] = filled_block.get("data", {})` — 통째 덮어쓰기.
**변경:** column_override 키를 보존하고 나머지만 덮어쓰기.

```python
new_data = filled_block.get("data", {})
preserved = {}
if "data" in orig_block:
    for k in ("column_override",):
        if k in orig_block["data"]:
            preserved[k] = orig_block["data"][k]
orig_block["data"] = {**new_data, **preserved}
```

**주의:** fill_content()에서 data를 덮어쓰는 곳이 2곳 (topic_id 매칭 + area+type 매칭). 둘 다 수정.
**충돌:** 없음. 기존 data 덮어쓰기 로직에 보존 로직 추가.

#### K-7: KEI_REVIEW_PROMPT 구조 흐름 검수

**현재:** 높이 초과, 채움 균형, 빈 블록만 검수.
**변경:** 검수 항목에 추가.

```
6. 핵심전달이 body에서 가장 큰 시각적 비중을 차지하는가?
   - 핵심전달 블록이 다른 블록보다 작거나 같으면 → rewrite로 비중 조정
7. 문제제기가 간결한가? (100자 이내)
   - 초과 시 → shrink
8. 용어정의가 sidebar에 있는가?
   - body에 있으면 → 구조 문제 지적
9. 핵심전달 블록이 화면 안에 보이는가?
   - 잘리면 → overflow_detected
```

**충돌:** Phase J의 J-7에서 추가한 KEI_REVIEW_PROMPT에 항목 추가. 기존 항목 변경 없음.

---

## 실행 프로세스

```
K-Step 1 (콘텐츠 설계)
├── K-1 + K-2: KEI_PROMPT 3단계 수정 (purpose 비중 + 인지 흐름)
├── K-4: EDITOR_PROMPT 분량 가이드 추가
└── K-8: KEI_PROMPT 비교 맥락 원칙 추가
    ↓
K-Step 2 (블록 선택)
├── K-3: STEP_B_PROMPT purpose별 허용/금지 재구성
└── K-6: STEP_B_PROMPT sidebar 원칙 추가
    ↓
K-Step 3 (코드 + 검수)
├── K-5: content_editor.py column_override 보존
└── K-7: KEI_REVIEW_PROMPT 구조 흐름 검수 추가
    ↓
검증: import + 서버 기동 + 결과물 비교
```

---

## 충돌/회귀 검토

| 항목 | Phase I 영향 | Phase J 영향 | 하드코딩 |
|------|:----------:|:----------:|:------:|
| K-1 | 없음 | 없음 | 아님 (원칙) |
| K-2 | 없음 | 없음 | 아님 (원칙) |
| K-3 | I-1 purpose 가이드 → K-3이 대체 | J-3a → K-3이 대체 (더 상세) | 아님 (허용/금지 분류) |
| K-4 | 없음 | 없음 | 아님 (가이드라인) |
| K-5 | 없음 | J-6 column_override와 연동 | 없음 |
| K-6 | 없음 | J-6과 보완 | 아님 (원칙) |
| K-7 | 없음 | J-7 KEI_REVIEW_PROMPT에 추가 | 없음 |
| K-8 | 없음 | 없음 | 아님 (원칙) |

---

## 이력

| 날짜 | 내용 |
|------|------|
| 2026-03-26 | Phase J 완료 후 결과물 확인. 사용자 반복 요청(콘텐츠 구조 흐름)이 미반영 확인. 연구 참고(Presenton/PPTAgent/Auto-Slides). Phase K 계획 수립. |
| 2026-03-26 | 실행 방안 상세 정리. Step별 변경 내용 + 적용 위치 + 충돌 검토 확정. |
