# 이미지 파이프라인 기술 설계 v4

> Updated: 2026-03-22

---

## 1. 파이프라인 DAG

```
entity_style ──→ entity_review ──→ entity_detail_batch ──→ entity_t2i ─┐
                                                                        │
scene_segmentation ──→ scene_split ──┬──→ scene_director ──┬──→ scene_cinematography
                                     │                     │            │
                                     │                     │            │
                                     └──→ scene_dependency  │   outlook_extraction
                                                    │       │            │
                                                    └───────┴────────────┤
                                                                         ↓
                                                                  scene_detail
                                                                         │
                                                                    scene_verify
                                                                         │
                                              world_guide ──→ ref_image_gen ──→ composite_image_gen
                                                                                        │
                                                                             scene_image_pipeline
```

## 2. 신규: scene_cinematography

### DB: shot_type 테이블
```sql
CREATE TABLE shot_type (
    id SERIAL PRIMARY KEY,
    name VARCHAR(50) NOT NULL UNIQUE,    -- emotional_close_up
    category VARCHAR(30) NOT NULL,       -- emotion/dialogue/tension/action/environment
    intent VARCHAR(30) NOT NULL,         -- emotion/detail/power/action/establish
    description TEXT NOT NULL,           -- 한국어 설명 (UI/LLM 선택용)
    llm_description TEXT NOT NULL,       -- 영어 카메라 구도 설명 (T2I 프롬프트용)
    is_active BOOLEAN DEFAULT true,
    sort_order INTEGER DEFAULT 0
);
```

30개 시드 데이터: 5개 카테고리 × 5~8개 기법

### DB: scene_still 확장
```sql
ALTER TABLE scene_still ADD COLUMN shot_type_1 TEXT;  -- 촬영 기법 1
ALTER TABLE scene_still ADD COLUMN shot_type_2 TEXT;  -- 촬영 기법 2
```

### StepRunner: SceneCinematographyStep
- 입력: 전체 씬 JSON (200자 발췌) + shot_type DB 목록
- 1회 LLM 호출 (GPT)
- 출력: 씬별 `{shot_1, shot_1_reason, shot_1_focus, shot_2, shot_2_reason, shot_2_focus}`
- DB 저장: `scene_still.shot_type_1/2` UPDATE

### scene_detail 연동
```python
# SceneDetailStep에서:
shot_desc_map = {name: llm_description for name, llm_description in shot_type_rows}
scene_shot_map[si] = {
    "shot_1": {"name": "...", "description": llm_description, "focus": "동녘"},
    "shot_2": {"name": "...", "description": llm_description, "focus": "폐창고 전경"},
}

# scene_extractor_v2에서:
cinematography_block = f"""
## 촬영 기법 지시 (촬영 감독 결정)
변형 1: {shot_1.name} — {shot_1.llm_description} (초점: {shot_1.focus})
변형 2: {shot_2.name} — {shot_2.llm_description} (초점: {shot_2.focus})
"""
# 기존 카메라 자유선택 지시 제거 후 append
```

## 3. scene_director (전체 씬 일괄)

- 1회 LLM 호출로 전체 씬 분석
- 앞쪽 씬 맥락 추적 (접속/빙의 상태)
- 출력: `scene_present_characters` → outlook_extraction에 전달
- 모델: Gemini Pro

## 4. 참조 이미지 3단계

| Phase | 비율 | 저장 | 프롬프트 |
|-------|------|------|---------|
| 얼굴 | 1:1 | entity_id=char, primary=1 | character_ref.md |
| 아웃룩 단독 | 1:1 | entity_id=outlook, primary=1, `[outfit:id]` | character_outlook_ref.md |
| 합성 | 16:9 | entity_id=char, primary=0, `[composite:char:outlook]` | character_composite_ref.md |

## 5. 씬 참조 매칭 (_resolve_refs_for_prompt)

```
composite 우선 → "character in outfit" (1장)
fallback → "character identity" + "outfit appearance" (2장)
이전 씬 → "previous scene for visual continuity"
소품 → "object appearance"

_used_ref_ids에 composite_key + char_id + outlook_id 모두 등록 (중복 방지)
```

## 6. 프롬프트 번역 (_build_final_scene_prompt)

| 라벨 | 우선순위 | 지시 |
|------|---------|------|
| `"outfit appearance"` | 1 (exact) | dress in outfit |
| `"character in outfit"` | 2 | keep face + use outfit |
| `"character identity"` | 3 | keep face/hair/identity |
| `"object appearance"` | 4 | include object |
| `"previous scene..."` | 5 | maintain continuity |

## 7. pipeline_gate

```python
or_(
    ImageAsset.prompt_used.like("%composite:%"),
    ImageAsset.prompt_used.like("%outlook_id:%"),
)
```

## 8. 이미지 크기 + fal.ai

- Gemini: `imageSize: "1K"` (1376×768 / 1024×1024)
- fal.ai: 4.5MB 초과 시 1536px 리사이즈
- 503/timeout: Gemini 키 로테이션

## 9. order 체계

| 범위 | Phase | 단계 |
|------|-------|------|
| 1~12 | 분석 | entity(1~4) + scene(5~12) |
| 20~23 | 이미지 | world_guide(20) + ref(21) + composite(22) + scene(23) |
| 100~101 | 보조 | summary(100) + dedup(101) |

## 10. 앞쪽 씬 맥락

| 단계 | 전달 방식 |
|------|----------|
| scene_detail (T2I) | 헤딩 + 텍스트 300자 |
| 앵글 추천 (Vision) | 제목 + 설명 (텍스트만) |
| 씬 이미지 생성 | labeled_refs에 이전 씬 이미지 포함 |

## 11. DB 키 일관성

```python
eid = v.get("id") or v.get("entity_id", "")  # 모든 코드에서 통일
```
