# Pipeline v3 — 전체 리팩토링 설계서

> 현재 파이프라인의 구조적 문제를 해결하고, 17개 분석 + 4개 이미지 + 2개 보조 단계로 재설계한다.

## 현재 문제점

1. visible_entities를 LLM에 의존 → 빈 배열, 캐릭터 누락
2. 소품 과다 추출 (1회 등장 번호판까지)
3. 에피소드/프로젝트 요약 부재
4. 요소 추출이 한 번에 전체 → 타입별 분리 필요
5. 아웃룩 추출이 1단계 → 2단계 분리 필요
6. 교차 검증 미흡 (같은 모델만 사용)
7. scene_dependency가 배경/인물 구분 없음
8. scene_verify에 앞 씬 컨텍스트 없음
9. 프롬프트 하드코딩 잔존
10. 코드 패치 누적으로 구조 복잡

## 설계 원칙

- **모든 단계**: resume + force 재실행 + 단독 API/UI 실행
- **모든 프롬프트**: 외부 파일(prompts/_base/) + DB(prompt_template), 하드코딩 금지
- **각 단계**: 최소 1개 독립 모듈, 버전 관리
- **LiteLLM + Opik**: 텍스트 LLM 전부 (이미지는 직접 API + ImageTracer)
- **DB**: 진행상황 카운트, step_run 테이블
- **권한**: 오너만 실행, 나머지 read only
- **enum**: short_id (C01/L01/P01/O01) 기반 JSON schema 강제
- **visible_entities**: LLM 의존 X, 확정 데이터에서 코드 자동 구축

---

## 단계 정의 (총 23단계)

### 분석 Phase (17단계)

| # | step_id | 이름 | 모델 | 병렬 | Input | Output |
|---|---------|------|------|------|-------|--------|
| 1 | text_cleanup | 텍스트 정리 | nano | 단일 | PDF 추출 텍스트 | 정리된 텍스트 (불필요 제거) |
| 2 | scene_segmentation | 씬 분할 (1차) | nano | 단일 | 정리된 텍스트 | 씬 목록 (헤딩 기반) |
| 3 | episode_summary | 에피소드 요약 | mini | 단일 | 전문 | 500자 요약 (env 설정) |
| 4 | visual_world_rules | 시각적 세계관 규칙 | pro | 단일 | 전문 + 요약 | 규칙 목록 (비히클, 변신, 영혼 등) |
| 5 | scene_split | 씬 재분할 | mini | 병렬 | 긴 씬 | 분할된 씬 (크기 기반) |
| 6 | scene_save | 씬 저장 | - | - | 분할 결과 | DB + JSON 저장 (씬 번호) |
| 7 | scene_summary | 씬별 요약 | mini | **ThreadPool** | 씬 + 앞3씬 + 요약 + rules | 200자 요약 (env 설정) |
| 8 | entity_extract | 요소 추출 (3턴) | pro | 3회 순차 | 씬별 JSON + rules | 인물→배경→소품 (2회+ 등장만) |
| 9 | entity_review | 요소 교차 검증 | **다른 모델** | 단일 | 추출 결과 | gemini↔gpt 교차 |
| 10 | entity_detail | 요소 상세 + enum | pro | 타입별 | 요소 목록 | 상세 + short_id 확정 |
| 11 | entity_t2i | T2I 프롬프트 | mini | **ThreadPool** | 개별 요소 | T2I 프롬프트 (영어) |
| 12 | scene_director | 씬 감독 (V/A/H) | pro | 단일 일괄 | 전체 씬 + 엔티티 | V(물리)/A(소리)/H(비물리표현) |
| 13 | scene_cinematography | 촬영 감독 | pro | 단일 일괄 | 전체 씬 + shot_type DB | 씬당 2개 기법 |
| 14 | scene_dependency | 씬 연관 (확장) | pro | 단일 일괄 | 전체 씬 + 배경/인물 목록 | 배경 앞2씬 + 인물 앞2씬 |
| 15 | outlook_extraction | 아웃룩 (2단계) | pro | 2회 순차 | 전체 씬 + 캐릭터 | 1단계: 아웃룩 목록, 2단계: 씬별 C+O enum |
| 16 | scene_detail | 씬 상세 분석 | pro | **ThreadPool** | 씬 + 확정 요소 + 촬영기법 | T2I variations + 대표 순간 |
| 17 | scene_verify | 교차 검증 | pro | **ThreadPool** | 씬 + 앞2씬 + visible | 물리적 존재 재확인 |

### 이미지 Phase (4단계)

| # | step_id | 이름 | 모델 | 병렬 |
|---|---------|------|------|------|
| 20 | world_guide | 월드 가이드 | pro | 단일 |
| 21 | ref_image_gen | 참조 이미지 | Gemini Image + GPT Vision | **ThreadPool** |
| 22 | composite_image_gen | 합성 이미지 | Gemini Image | **ThreadPool** |
| 23 | scene_image_pipeline | 씬 이미지 (compound) | Mixed | **ThreadPool** |

### 보조 (on-demand)

| # | step_id | 이름 |
|---|---------|------|
| 100 | outlook_dedup | 아웃룩 중복 판별 |
| 101 | project_summary | 프로젝트 요약 (에피소드 요약들 종합) |

---

## 주요 변경사항 상세

### 1. text_cleanup (신규)
- 낮은 LLM (nano)으로 PDF 텍스트 정리
- 페이지 번호, 구분선, 헤더/푸터 제거
- 순수 시나리오 텍스트만 추출

### 3. episode_summary (신규)
- 에피소드 전문 → 500자 요약 (MAX_EPISODE_SUMMARY_LENGTH env)
- 프로젝트 내 모든 에피소드 요약 → 프로젝트 요약 500자 (MAX_PROJECT_SUMMARY_LENGTH env)

### 4. visual_world_rules (강화)
- 시각적 특이사항: 비히클, 몸 변형, 영혼 이동, 변신, 초능력 등
- **LLM 가이드 필수**: "이 시나리오에서 A가 B의 몸에 탑승하면, A의 외모가 아닌 B의 외모로 그려야 한다" 등

### 7. scene_summary (신규)
- 씬별 200자 요약 (MAX_SCENE_SUMMARY_LENGTH env)
- Input: 해당 씬 + 앞 3개 씬 + 에피소드 요약 + visual_world_rules
- ThreadPool 병렬 (씬당 1회)

### 8. entity_extract (3턴 분리)
- **1턴**: 인물만 (+ 몇 번째 씬에 나오는지)
- **2턴**: 배경만 (+ 몇 번째 씬에 나오는지)
- **3턴**: 소품만 (+ 몇 번째 씬에 나오는지)
- **필터**: 2회 이상 다른 씬에 등장하는 것만
- **조건**: 시각적 일관성 유지에 필요한 것만 (엑스트라, 일반 소품 제외)
- visual_world_rules 기반 판단

### 9. entity_review (교차 검증)
- entity_extract가 GPT → entity_review는 Gemini (또는 반대)
- 다른 모델로 교차 확인

### 12. scene_director (V/A/H 3분류)
- **V (Visual)**: 물리적으로 씬에 존재하고 보임
- **A (Audio)**: 소리만 들림 (V.O., 전화, 방송)
- **H (Hallucination)**: 보이지만 물리적 존재 아님 (귀신, 투영체, 회상 인물)

### 14. scene_dependency (확장)
- **배경 중심**: 같은/유사 장소의 앞 2개 씬
- **인물 중심**: 같은 인물이 등장하는 앞 2개 씬
- 이미지 첨부: 배경 씬만 참조 이미지로 (인물은 참조이미지 불필요)
- UI: 앞쪽 배경 씬만 표시

### 15. outlook_extraction (2단계)
- **1단계**: 전체 씬에서 아웃룩 목록 추출 (이름 + 설명)
- **2단계**: 캐릭터 + 아웃룩 목록 → 씬별 인물+아웃룩 매핑 (enum 기반)
  - 임시 아웃룩 enum 생성 → LLM에 전달
  - 결과로 실제 아웃룩 enum 확정
  - 인물+아웃룩 복합 enum (C01O02) 생성

### 17. scene_verify (컨텍스트 확장)
- 앞 2개 씬 텍스트를 함께 전달 → 문맥 파악
- 소울라이드/빙의 상태 추적 가능

---

## DB 스키마 변경

### 신규 컬럼
```sql
-- scene_still에 씬 요약 추가
ALTER TABLE scene_still ADD COLUMN IF NOT EXISTS scene_summary TEXT;

-- episode에 요약 길이 설정
-- (env: MAX_EPISODE_SUMMARY_LENGTH=500, MAX_SCENE_SUMMARY_LENGTH=200)

-- scene_director V/A/H 분류
-- present_entity_ids → 기존 유지
-- audio_entity_ids: [short_id] (소리만)
-- hallucination_entity_ids: [short_id] (비물리적 표현)
```

### 기존 유지
- entity_canon (short_id 포함)
- scene_still
- image_asset
- character_outlook
- step_run
- 체크포인트 파일

---

## 파일 구조

```
backend/app/
├── core/
│   ├── step_runner.py          # StepRunner 베이스 (기존 유지)
│   ├── step_manifest.py        # 단계 정의 (업데이트)
│   └── steps/
│       ├── text_steps.py       # text_cleanup
│       ├── summary_steps.py    # episode_summary, scene_summary, project_summary
│       ├── entity_steps.py     # entity_extract, entity_review, entity_detail, entity_t2i
│       ├── scene_steps.py      # scene_segmentation, scene_split, scene_save
│       ├── director_steps.py   # scene_director, scene_cinematography, scene_dependency
│       ├── outlook_steps.py    # outlook_extraction (2단계), outlook_dedup
│       ├── detail_steps.py     # scene_detail, scene_verify
│       └── image_steps.py      # world_guide, ref_image_gen, composite_image_gen, scene_image_pipeline
├── modules/
│   ├── llm/
│   │   ├── llm_client.py       # LiteLLM Router (기존)
│   │   ├── image_tracer.py     # Opik 수동 span (기존)
│   │   └── gemini_image_client.py  # Gemini Image (기존)
│   ├── short_id.py             # short_id 발급 (기존)
│   └── pipeline/
│       ├── text_cleaner.py     # 텍스트 정리 모듈 (신규)
│       ├── scene_segmenter.py  # 씬 분할 모듈
│       ├── scene_summarizer.py # 씬 요약 모듈 (신규)
│       ├── entity_extractor.py # 요소 추출 (3턴)
│       ├── entity_reviewer.py  # 교차 검증 (신규)
│       ├── scene_director.py   # V/A/H 분류 (확장)
│       ├── scene_dependency.py # 배경+인물 연관 (확장)
│       ├── outlook_extractor.py # 2단계 아웃룩
│       ├── scene_detail.py     # 씬 상세
│       ├── scene_validator.py  # 교차 검증
│       └── ...
└── prompts/_base/
    ├── text_cleanup/           # (신규)
    ├── episode_summary/        # (신규)
    ├── visual_world_rules/     # (신규/확장)
    ├── scene_summary/          # (신규)
    ├── entity_extract/         # (재설계)
    ├── entity_review/          # (신규)
    ├── scene_director/         # (V/A/H 확장)
    ├── scene_dependency/       # (확장)
    ├── outlook_extractor/      # (2단계)
    └── ...
```

---

## 구현 순서

### Phase 0: 준비
- [ ] 새 브랜치 생성
- [ ] DB 마이그레이션 (신규 컬럼)
- [ ] env 설정 추가

### Phase 1: 기반 (1-6)
- [ ] text_cleanup
- [ ] scene_segmentation (정리)
- [ ] episode_summary
- [ ] visual_world_rules
- [ ] scene_split (정리)
- [ ] scene_save

### Phase 2: 요소 (7-11)
- [ ] scene_summary
- [ ] entity_extract (3턴)
- [ ] entity_review (교차)
- [ ] entity_detail + enum
- [ ] entity_t2i

### Phase 3: 씬 분석 (12-17)
- [ ] scene_director (V/A/H)
- [ ] scene_cinematography
- [ ] scene_dependency (확장)
- [ ] outlook_extraction (2단계)
- [ ] scene_detail
- [ ] scene_verify (앞2씬)

### Phase 4: 이미지 (20-23)
- [ ] world_guide (씬 요약 입력)
- [ ] ref_image_gen
- [ ] composite_image_gen
- [ ] scene_image_pipeline

### Phase 5: 통합
- [ ] E2E 테스트
- [ ] 전체 Codex 코드 리뷰
- [ ] 문서 업데이트
