문서 정리: Phase 히스토리 md를 docs/history/로 이동 + 오래된 테스트/에셋 정리
- 루트의 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>
This commit is contained in:
432
docs/history/IMPROVEMENT-PHASE-H.md
Normal file
432
docs/history/IMPROVEMENT-PHASE-H.md
Normal file
@@ -0,0 +1,432 @@
|
||||
# Phase H: 스토리라인 설계 + 컨셉 구체화 기반 파이프라인 전환 — 실행 상세
|
||||
|
||||
> 1단계를 A/B로 분리하여 정확도 향상.
|
||||
> 1단계-A: 전체 스토리라인 설계 (큰 그림)
|
||||
> 1단계-B: 각 꼭지 순회하며 컨셉 구체화 (세부 판단)
|
||||
> 원칙: 하드코딩 금지. 원본 텍스트 최대 보존. 회귀 금지.
|
||||
|
||||
---
|
||||
|
||||
## 문제 진단 (Phase H 1차 실행 결과 포함)
|
||||
|
||||
### 문제 1: 1단계가 "꼭지 추출"만 함 — 스토리라인 설계 없음
|
||||
|
||||
현재 KEI_PROMPT: "본문에서 핵심 꼭지 2~5개를 추출해줘"
|
||||
- 꼭지가 개별 덩어리로 나옴
|
||||
- 각 꼭지가 슬라이드 안에서 왜 그 위치에 있어야 하는지 맥락 없음
|
||||
- 결과: 제목 중복, 빈 블록, 맥락 없는 배치
|
||||
|
||||
있어야 하는 것:
|
||||
```
|
||||
핵심 메시지: "BIM은 DX의 일부분이다"
|
||||
스토리 흐름:
|
||||
(1) 문제 제기 → (2) 근거/사례 → (3) 핵심 전달 → (4) 용어 정의 → (5) 결론
|
||||
```
|
||||
|
||||
### 문제 2: 3단계 편집자가 텍스트를 과도하게 재작성
|
||||
|
||||
현재 EDITOR_PROMPT: "세련된 표현으로 편집한다"
|
||||
- 원본이 이미 충분히 정리된 텍스트인데 2줄로 압축
|
||||
- description 슬롯을 비워둠
|
||||
- 원본 분량 수준에서는 약간의 편집만 필요
|
||||
|
||||
### 문제 3: 2단계 팀장이 블록의 "목적"을 모름
|
||||
|
||||
현재: 꼭지 제목만 보고 블록 형태 매칭
|
||||
- "용어 혼용 문제" → callout? quote? 무작위
|
||||
- 블록의 목적(문제제기? 근거? 정의?)을 모르고 형태만 매칭
|
||||
|
||||
---
|
||||
|
||||
### 문제 4: 1차 실행에서 발견 — 실장이 한 번에 너무 많이 함
|
||||
|
||||
H-1~H-4 적용 후 실행 결과:
|
||||
- 스토리 흐름은 생겼지만 **블록 선택이 여전히 잘못됨**
|
||||
- section-title-with-bg(500px)가 body에 들어감 → 아래 블록 안 보임
|
||||
- compare-pill-pair에 비교 내용 없이 라벨만 (BIM VS DX)
|
||||
- **GIS → BIM → 디지털트윈을 flow-arrow로 표현** — 이건 순서/흐름이 아니라 **기술 융합 구조**인데 잘못 판단
|
||||
- 원본의 12행 상세 비교표(DX vs BIM)를 무시
|
||||
|
||||
**근본 원인:** 실장이 한 번의 호출로 정보구조 + 스토리라인 + 꼭지 + purpose + 관계 성격을 전부 판단하려니 **대충 하거나 놓침**
|
||||
|
||||
### 문제 5: 실장이 팀장에게 넘기는 정보가 부족
|
||||
|
||||
현재 실장 → 팀장 전달:
|
||||
```
|
||||
"꼭지 4: DX와 핵심기술간 상호관계, purpose: 구조시각화"
|
||||
```
|
||||
→ 팀장: "구조시각화면... flow-arrow? layer-diagram? venn-diagram?" → 아무거나 선택
|
||||
|
||||
있어야 하는 전달:
|
||||
```
|
||||
"꼭지 4: DX와 핵심기술간 상호관계
|
||||
- 관계 성격: 기술 융합 (순서 아님, 발전 단계 아님)
|
||||
- GIS, BIM, 디지털트윈이 DX의 구성요소
|
||||
- 포함 관계 또는 융합 관계로 표현
|
||||
- flow/순서 표현 금지"
|
||||
```
|
||||
→ 팀장: "포함 관계면 venn-diagram"
|
||||
|
||||
---
|
||||
|
||||
## 개선 방향: 1단계를 A/B로 분리
|
||||
|
||||
### 현재 (1회 호출, 부담 과중)
|
||||
```
|
||||
1단계: 전부 한 번에
|
||||
정보구조 + 핵심메시지 + 스토리라인 + 꼭지추출 + purpose + role + 관계성격 + 이미지/표
|
||||
→ 정확도 낮음. 대충 처리.
|
||||
```
|
||||
|
||||
### 변경 (2회 호출, 각각 집중)
|
||||
```
|
||||
1단계-A: 전체 스토리라인 설계 (큰 그림)
|
||||
- 콘텐츠 전체를 읽고 핵심 메시지 파악
|
||||
- 스토리 흐름 설계 (문제→근거→핵심→정의→결론)
|
||||
- 꼭지 추출 + purpose + role + layer
|
||||
- 출력: topics[] (기존과 동일 구조)
|
||||
|
||||
1단계-B: 각 꼭지 컨셉 구체화 (세부 판단) — 1단계-A 결과를 순회
|
||||
- 각 꼭지의 내용을 원본에서 다시 확인
|
||||
- 관계 성격 판단: 순서? 포함? 비교? 나열? 정의?
|
||||
- 표현 방법 제안: "이건 융합 관계 → venn/포함", "이건 수단-목적 → 비교표"
|
||||
- 원본에 있는 데이터(비교표, 사례, 출처) 누락 없이 확인
|
||||
- 출력: 각 topic에 concept 필드 추가
|
||||
|
||||
→ 이 결과를 디자인 팀장에게 넘김
|
||||
```
|
||||
|
||||
### 장점
|
||||
- 각 호출의 부담 감소 → 정확도 향상
|
||||
- 1단계-B에서 **내용을 깊이 이해**하고 컨셉 판단
|
||||
- 팀장이 받는 정보가 구체적 → 블록 선택 정확도 향상
|
||||
- Kei API 호출 2회이지만, 각각의 응답 시간 단축 가능
|
||||
|
||||
### Kei API 호출 횟수
|
||||
- 현재: 1단계 1회 + 2단계 Opus 1회 + 3단계 1회 = Kei 3회
|
||||
- 변경: 1단계-A 1회 + 1단계-B 1회 + 2단계 Opus 1회 + 3단계 1회 = Kei 4회
|
||||
- 1회 추가. 하지만 각 호출이 더 정확하므로 재시도/재검토 감소.
|
||||
|
||||
---
|
||||
|
||||
## H-1 수정: KEI_PROMPT를 A/B 두 단계로 분리
|
||||
|
||||
### H-1a: 1단계-A — 전체 스토리라인 설계 (KEI_PROMPT_A)
|
||||
|
||||
기존 H-1의 KEI_PROMPT를 "스토리라인 설계" 전용으로 유지.
|
||||
핵심메시지 + 스토리흐름 + 꼭지추출 + purpose + role.
|
||||
관계 성격, 표현 방법 같은 세부 판단은 **하지 않음** (1단계-B에서).
|
||||
|
||||
### H-1b: 1단계-B — 각 꼭지 컨셉 구체화 (KEI_PROMPT_B, 신규)
|
||||
|
||||
1단계-A 결과(topics)를 받아서, 각 꼭지를 원본과 대조하며 구체화:
|
||||
|
||||
```
|
||||
각 꼭지에 대해 다음을 판단해줘:
|
||||
|
||||
1. 관계 성격 (relation_type):
|
||||
- sequence: 시간/단계 순서 (A→B→C)
|
||||
- inclusion: 포함/융합 관계 (A가 B,C를 포함)
|
||||
- comparison: 대등 비교 (A vs B)
|
||||
- hierarchy: 상위-하위 (A > B > C)
|
||||
- definition: 용어 정의 (나열)
|
||||
- cause_effect: 원인-결과
|
||||
|
||||
2. 표현 제안 (expression_hint):
|
||||
- "포함 관계이므로 venn-diagram 또는 layer-diagram"
|
||||
- "대등 비교이므로 comparison-table. 원본에 12행 비교표가 있으니 활용"
|
||||
- "용어 정의 나열이므로 card-text-grid"
|
||||
|
||||
3. 원본 데이터 확인 (source_data):
|
||||
- 원본에 비교표가 있는가? → 행/열 수, 활용 여부
|
||||
- 원본에 사례/증거가 있는가? → 출처 명시
|
||||
- 원본에 이미지가 있는가? → 크기/역할
|
||||
- 놓치면 안 되는 핵심 데이터가 있는가?
|
||||
```
|
||||
|
||||
### pipeline.py 변경
|
||||
|
||||
```python
|
||||
# 현재
|
||||
analysis = await classify_content(content)
|
||||
|
||||
# 변경
|
||||
analysis = await classify_content(content) # 1단계-A: 스토리라인
|
||||
analysis = await refine_concepts(content, analysis) # 1단계-B: 컨셉 구체화
|
||||
```
|
||||
|
||||
`refine_concepts()`는 kei_client.py에 신규 함수로 추가.
|
||||
Kei API 호출 (Sonnet fallback 없음).
|
||||
|
||||
### 수정 파일
|
||||
- `src/kei_client.py` — KEI_PROMPT_B 추가, `refine_concepts()` 함수 신규
|
||||
- `src/pipeline.py` — 1단계에 `refine_concepts()` 호출 추가
|
||||
|
||||
---
|
||||
|
||||
## H-5: 1단계-B 컨셉을 2단계 팀장에게 전달
|
||||
|
||||
### 현재 상태
|
||||
팀장이 받는 꼭지 정보: title, purpose, layer, role, emphasis
|
||||
→ 부족. "이 내용이 순서인지 포함인지 비교인지" 모름.
|
||||
|
||||
### 변경
|
||||
1단계-B에서 추가된 `relation_type`, `expression_hint`를 팀장 프롬프트에 포함:
|
||||
|
||||
```python
|
||||
# design_director.py 꼭지 요약 생성 시
|
||||
line = (
|
||||
f"꼭지 {t.get('id')}: {t.get('title')} "
|
||||
f"[{t.get('purpose')}, 관계:{t.get('relation_type', '?')}, "
|
||||
f"표현:{t.get('expression_hint', '?')}]"
|
||||
)
|
||||
```
|
||||
|
||||
### 수정 파일
|
||||
- `src/design_director.py` — 꼭지 요약 생성 부분
|
||||
|
||||
### 현재 상태
|
||||
```
|
||||
"본문에서 핵심 꼭지 2~5개를 추출해줘"
|
||||
→ topics: [{id, title, summary, layer, role, ...}]
|
||||
```
|
||||
|
||||
### 변경
|
||||
```
|
||||
"이 콘텐츠로 슬라이드 1장을 만든다면 어떤 스토리로 구성할지 설계해줘"
|
||||
```
|
||||
|
||||
프롬프트에 추가할 지시:
|
||||
- **핵심 메시지**를 먼저 파악 (이 슬라이드가 전달해야 할 한 줄)
|
||||
- **스토리 흐름**을 설계 (문제→근거→핵심→정의→결론)
|
||||
- 각 위치의 **목적(purpose)** 명시 (문제제기/근거사례/핵심전달/용어정의/결론강조)
|
||||
- 각 위치에 **원본의 어떤 부분**이 가는지 명시
|
||||
- 원본 텍스트는 최대한 보존. 슬라이드에 맞게 약간만 편집.
|
||||
|
||||
출력 형식 (기존 topics 구조 유지 + 필드 추가):
|
||||
```json
|
||||
{
|
||||
"title": "건설산업 DX의 올바른 이해",
|
||||
"core_message": "BIM은 건설산업 DX의 기초 일부분이지 전체가 아니다",
|
||||
"total_pages": 1,
|
||||
"info_structure": "...",
|
||||
"topics": [
|
||||
{
|
||||
"id": 1,
|
||||
"title": "용어 혼용 문제",
|
||||
"summary": "DX와 BIM이 혼용되어 사용",
|
||||
"purpose": "문제제기",
|
||||
"source_hint": "용어의 혼용 섹션 전체",
|
||||
"layer": "intro",
|
||||
"role": "flow",
|
||||
...
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### 하류 호환
|
||||
- topics[] 배열 구조 동일 → 2단계/3단계 파싱 깨지지 않음
|
||||
- purpose, core_message, source_hint는 새 필드 → `.get()`으로 접근하면 없어도 안전
|
||||
- 기존 필드(layer, role, emphasis 등) 유지
|
||||
|
||||
### 수정 파일
|
||||
- `src/kei_client.py` — KEI_PROMPT
|
||||
|
||||
---
|
||||
|
||||
## H-2: EDITOR_PROMPT 수정 — 원본 텍스트 최대 보존
|
||||
|
||||
### 현재 상태
|
||||
```
|
||||
"세련된 표현으로 편집한다 (원본 그대로가 아님)"
|
||||
→ 과도한 요약/재작성. description 비움.
|
||||
```
|
||||
|
||||
### 변경
|
||||
```
|
||||
"원본 텍스트를 최대한 보존한다.
|
||||
슬라이드 공간에 맞게 약간만 축약한다.
|
||||
의미를 바꾸거나 완전히 재작성하지 않는다.
|
||||
각 블록의 purpose를 보고 해당 목적에 맞는 텍스트를 원본에서 가져온다.
|
||||
모든 슬롯을 빠짐없이 채운다. 빈 슬롯 금지."
|
||||
```
|
||||
|
||||
### 핵심 변경 포인트
|
||||
- "세련된 표현으로 편집" → "원본 보존, 약간만 축약"
|
||||
- "빈 슬롯 금지" 명시
|
||||
- purpose 필드를 참고하여 "이 위치에 무엇이 들어가야 하는지" 맥락 제공
|
||||
|
||||
### 수정 파일
|
||||
- `src/content_editor.py` — EDITOR_PROMPT
|
||||
|
||||
---
|
||||
|
||||
## H-3: STEP_B_PROMPT 보강 — purpose 기반 블록 선택 + 출력에 purpose 추가
|
||||
|
||||
### 현재 상태
|
||||
```
|
||||
"꼭지에 적합한 블록을 선택해줘"
|
||||
→ 형태만 보고 매칭. 목적 모름.
|
||||
→ 출력 JSON에 purpose 필드 없음.
|
||||
```
|
||||
|
||||
### 변경 1: purpose 기반 블록 선택 가이드 추가
|
||||
STEP_B_PROMPT의 "블록 선택 규칙" 섹션 뒤에 추가:
|
||||
|
||||
```
|
||||
## purpose 기반 블록 선택 가이드 (참고, 강제 아님)
|
||||
- purpose: 문제제기 → callout-warning, quote-big-mark, quote-question 중 선택
|
||||
- purpose: 근거사례 → quote-left-border (출처 포함), card-text-grid (항목 나열)
|
||||
- purpose: 핵심전달 → comparison-2col, compare-pill-pair, compare-2col-split
|
||||
- purpose: 용어정의 → card-text-grid (정의+출처), card-numbered (순서 있으면)
|
||||
- purpose: 결론강조 → conclusion-accent-bar (footer), banner-gradient
|
||||
- purpose: 구조시각화 → venn-diagram, layer-diagram (단독 배치)
|
||||
```
|
||||
|
||||
### 변경 2: 출력 JSON에 purpose 필드 추가
|
||||
정밀 검토에서 발견: H-4에서 편집자에게 purpose를 전달하려면, Step B 출력에 purpose가 있어야 함.
|
||||
|
||||
```json
|
||||
{"blocks": [{"area": "...", "type": "...", "topic_id": 1, "purpose": "문제제기", "reason": "...", ...}]}
|
||||
```
|
||||
|
||||
### 하드코딩 점검
|
||||
- purpose 가이드는 AI 참고용 추천. 강제 아님. Sonnet이 무시해도 기존과 동일 동작.
|
||||
- purpose 값은 1단계 Kei가 결정한 것을 2단계 Sonnet이 참조. AI 판단 체인.
|
||||
|
||||
### 수정 파일
|
||||
- `src/design_director.py` — STEP_B_PROMPT (가이드 추가 + 출력 형식에 purpose 추가)
|
||||
|
||||
---
|
||||
|
||||
## H-4: 3단계 편집자에게 purpose 전달
|
||||
|
||||
### 현재 상태
|
||||
content_editor.py의 `fill_content()`에서 각 블록의 슬롯 정보는 전달하지만,
|
||||
**이 블록이 왜 여기 있는지 (purpose)** 는 전달하지 않음.
|
||||
|
||||
### 변경
|
||||
블록별 슬롯 요청 생성 시 purpose를 포함:
|
||||
|
||||
```python
|
||||
req_text = (
|
||||
f"블록 {i+1} ({block_type}, 영역: {area}, topic_id: {topic_id}):\n"
|
||||
f" 목적(purpose): {block.get('purpose', '미지정')}\n" # 추가
|
||||
f" 용도: {block.get('reason', '미지정')}\n"
|
||||
...
|
||||
)
|
||||
```
|
||||
|
||||
### 수정 파일
|
||||
- `src/content_editor.py` — `fill_content()` 내 slot_requirements 생성 부분
|
||||
|
||||
---
|
||||
|
||||
## 수정 파일 총괄
|
||||
|
||||
| 파일 | 항목 | 변경 성격 |
|
||||
|------|------|----------|
|
||||
| `src/kei_client.py` | H-1a, H-1b | KEI_PROMPT_A (스토리라인) + KEI_PROMPT_B (컨셉 구체화) + `refine_concepts()` 신규 |
|
||||
| `src/pipeline.py` | H-1b | 1단계에 `refine_concepts()` 호출 추가 |
|
||||
| `src/content_editor.py` | H-2, H-4 | EDITOR_PROMPT 수정 (원본 보존) + purpose 전달 |
|
||||
| `src/design_director.py` | H-3, H-5 | STEP_B_PROMPT purpose 가이드 + 꼭지 요약에 relation_type/expression_hint 포함 |
|
||||
|
||||
코드 구조 변경 없음. 프롬프트만 수정. persona_agent 수정 0건.
|
||||
|
||||
---
|
||||
|
||||
## 검증 체크리스트
|
||||
|
||||
- [ ] H-1: 1단계 출력에 core_message, purpose, source_hint 포함
|
||||
- [ ] H-1: 기존 topics 구조 유지 (하류 깨지지 않음)
|
||||
- [ ] H-2: 편집자가 원본 텍스트를 과도하게 축약하지 않음
|
||||
- [ ] H-2: 모든 슬롯에 텍스트 채워짐 (빈 슬롯 0건)
|
||||
- [ ] H-3: purpose에 맞는 블록 선택 (문제제기→경고계열, 정의→카드계열)
|
||||
- [ ] H-4: 편집자가 각 블록의 purpose를 인지하고 적절한 텍스트 배치
|
||||
- [ ] 전체: 슬라이드에 스토리 흐름이 있음 (문제→근거→핵심→정의→결론)
|
||||
|
||||
---
|
||||
|
||||
## 정밀 검토 결과
|
||||
|
||||
### 발견 사항
|
||||
|
||||
| # | 발견 | 대응 |
|
||||
|---|------|------|
|
||||
| 1 | H-4가 동작하려면 H-3의 JSON 출력에 purpose 필드 필요 | H-3에 출력 형식 수정 포함 (위에 반영) |
|
||||
| 2 | "약간만 축약" 시 슬라이드 초과 가능 | 기존 안전망 유지 (4단계 CSS 조정 + 5단계 재검토) |
|
||||
| 3 | core_message 현재 미활용 | Kei의 사고 과정 기록용. 향후 5단계에서 활용 가능 |
|
||||
|
||||
### 충돌/회귀/하드코딩 총괄
|
||||
|
||||
| 항목 | 충돌 | 회귀 | 하드코딩 | API | persona 수정 |
|
||||
|------|:----:|:----:|:-------:|:---:|:----------:|
|
||||
| H-1 | 없음 | 없음 | 없음 (Kei 사고) | Kei API | 없음 |
|
||||
| H-2 | 없음 | 없음 | 없음 | Kei API | 없음 |
|
||||
| H-3 | 없음 | 없음 | 가이드일 뿐 강제 아님 | Sonnet | 없음 |
|
||||
| H-4 | 없음 | 없음 | 없음 | Kei API | 없음 |
|
||||
|
||||
---
|
||||
|
||||
## 수정 이력
|
||||
|
||||
| 날짜 | 내용 |
|
||||
|------|------|
|
||||
| 2026-03-26 | 초안. 스토리라인 설계 기반 전환. 프롬프트 3개 수정. |
|
||||
| 2026-03-26 | 정밀 검토. H-3 출력 형식에 purpose 추가 필요 발견. 반영. |
|
||||
| 2026-03-26 | 1차 실행 결과 분석. 1단계 A/B 분리 결정. H-1b(컨셉 구체화) + H-5(팀장 전달) 추가. |
|
||||
| 2026-03-26 | 정밀 검토 11개 발견. 아래 보완 사항 반영. |
|
||||
|
||||
## 정밀 검토 보완 사항
|
||||
|
||||
### 필수 보완 (구현 전 반드시 반영)
|
||||
|
||||
**1. refine_concepts() 실패 처리:**
|
||||
- Kei API 실패 시 1단계-A 결과 그대로 사용 (relation_type/expression_hint 없이 진행)
|
||||
- pipeline 멈추지 않음
|
||||
```python
|
||||
analysis = await refine_concepts(content, analysis)
|
||||
# refine_concepts 내부에서 실패 시 analysis를 변경 없이 그대로 반환
|
||||
```
|
||||
|
||||
**2. source_data 하류 전달:**
|
||||
- H-5(팀장 전달)에서 relation_type + expression_hint + **source_data** 모두 포함
|
||||
```python
|
||||
line += f", 원본데이터:{t.get('source_data', '?')}"
|
||||
```
|
||||
|
||||
**3. section-title-with-bg body 배치 금지:**
|
||||
- STEP_B_PROMPT "블록 선택 규칙"에 추가:
|
||||
"section-title-with-bg는 body/sidebar/footer zone에서 사용 금지. header zone 전용."
|
||||
- 또는 `_validate_height_budget()`에서 body zone의 section-title-with-bg를 topic-center로 교체
|
||||
|
||||
**4. 1회 호출 명시:**
|
||||
- 1단계-B는 **1회 Kei API 호출로 모든 꼭지를 한꺼번에 처리**
|
||||
- 꼭지별 개별 호출 아님
|
||||
|
||||
**5. manual_classify() fallback 동기화:**
|
||||
```python
|
||||
return {
|
||||
"title": "슬라이드",
|
||||
"core_message": "",
|
||||
"total_pages": 1,
|
||||
"info_structure": "",
|
||||
"topics": [{"id": 1, ..., "purpose": "핵심전달", "source_hint": ""}],
|
||||
"images": [], "tables": [],
|
||||
}
|
||||
```
|
||||
|
||||
**6. session_id:**
|
||||
- 1단계-B: `"design-agent-refine"` (별도 session. 1단계-A 대화 맥락에 영향받지 않도록)
|
||||
|
||||
**7. 제목 중복 방지:**
|
||||
- KEI_PROMPT_A에 추가: "슬라이드 제목(title)과 첫 번째 꼭지 제목은 달라야 한다. 슬라이드 제목은 전체 주제, 꼭지 제목은 해당 위치의 구체적 내용."
|
||||
|
||||
**8. expression_hint 역할 재정의 (Opus와 역할 분리):**
|
||||
```
|
||||
expression_hint는 "관계 성격"을 기술한다. 구체 블록 이름을 지정하지 않는다.
|
||||
✅ "기술 융합/포함 관계. 순서 아님. 구성요소 간 관계 표현 필요."
|
||||
❌ "venn-diagram 추천"
|
||||
블록 이름 결정은 2단계 Opus의 역할이다.
|
||||
```
|
||||
Reference in New Issue
Block a user