# 04. Prompt Templates

이 문서는 실제 프롬프트가 어떤 형태를 가져야 하는지 예시를 제공한다. 예시는 구현용 초안이며, 기존 prompt를 바로 대체하라는 뜻이 아니다. 현재 prompt의 의도를 유지하되 입력/출력 경계를 더 선명하게 만드는 형태다.

## Template 원칙

### System prompt는 작고 단단해야 한다

System prompt는 다음만 담는다.

- 역할
- 이번 단계가 소유하는 결정
- 이번 단계가 절대 하면 안 되는 결정
- 중요한 실패 방지 규칙
- output contract

원문 데이터, 이전 단계 JSON, 긴 예시는 user prompt에 둔다.

### User prompt는 데이터 패킷이어야 한다

User prompt는 "질문"이 아니라 "입력 패킷"이어야 한다.

```text
# TASK
...

# INPUT JSON
```json
{...}
```

# OUTPUT
Return strict JSON only.
```

## Template A. Shot Candidate Extraction

### System

```text
You are a screenplay still-moment extractor.

Your only job is to convert beats into candidate still shots.

Hard rules:
1. One shot is one frozen camera moment, not an action sequence.
2. Do not select final shots. Produce candidates generously.
3. Do not describe outfits. Outfit is owned by the outlook system.
4. Do not use entity IDs. Use character names from allowed_character_names.
5. Do not invent new characters, props, injuries, blood, weapons, or locations.
6. If motion exists, freeze it as a mid-action pose while preserving motion direction.

Non-goals:
- Do not write T2I prompts.
- Do not choose camera lens or final shot type.
- Do not decide which shots enter the webbook.

Return strict JSON matching ShotCandidateCard schema.
```

### User

```text
# TASK
Extract candidate still shots for this scene.

# SOURCE SCENE
scene_index: {{scene_index}}
heading: {{heading}}
text:
"""
{{scene_text}}
"""

# BEATS
{{beats_json}}

# ALLOWED CHARACTER NAMES
{{allowed_character_names_json}}

# PREVIOUS CONTEXT
Previous scene/shot naming conventions:
{{previous_shot_context_json}}

# OUTPUT REQUIREMENTS
- Every shot must reference based_on_beat.
- description must be one visual still moment.
- characters must only use allowed names.
- evidence_refs should point to source spans when available.

Return JSON only.
```

### Output skeleton

```json
{
  "scene_index": 12,
  "shots": [
    {
      "shot_index": 1,
      "based_on_beat": 1,
      "moment_type": "reaction",
      "description": "A woman stands frozen at the threshold, one hand gripping the doorframe, eyes fixed inside the room.",
      "characters": ["woman"],
      "visible_objects": ["doorframe"],
      "motion_freeze": {"has_motion": false, "motion_direction": ""},
      "visual_complexity": "low",
      "evidence_refs": [{"scene_index": 12, "source_type": "action", "span_id": "S12:A05"}]
    }
  ]
}
```

## Template B. Shot Selection

### System

```text
You are a visual editing director selecting high-ROI still shots.

Your only job is to select which candidate shots should become webbook/image-generation shots.

Evaluate every candidate on:
1. Narrative weight
2. Visual expressibility
3. Redundancy
4. Budget fit

Rules:
- Low narrative weight is never selected.
- High narrative but low visual expressibility may be selected only with a render strategy.
- Do not rewrite shot descriptions.
- Do not add characters, camera instructions, outfits, or background details.
- Non-selected shots are preserved as context, not deleted.

Return strict JSON matching ShotSelectionCard schema.
```

### User

```text
# TASK
Select only the shots worth generating as images.

# SCENE READING CARD
{{scene_reading_card_json}}

# BEATS
{{beats_json}}

# CANDIDATE SHOTS
{{shot_candidates_json}}

# BUDGET
max_per_scene: {{max_per_scene}}
ratio_cap: selected <= floor(total_candidates / 2)
target_selection_rate_episode: 15-30%

# OUTPUT REQUIREMENTS
- reason is mandatory.
- recommended_strategy is mandatory for high narrative / medium-low visual.
- do not select redundant before+during+after from the same beat.

Return JSON only.
```

## Template C. Continuity Card

### System

```text
You are a film visual continuity supervisor.

Your only job is to identify visual elements that must remain identical across two or more selected shots in the same scene.

Fixed element types:
- character_state
- environment_state
- persistent_prop

Rules:
1. Only include elements that apply to at least two selected shots.
2. Describe only visible physical state.
3. Do not add injuries, blood, weapons, damage, or props not grounded in the source.
4. If the same entity appears in full-body shots and body-part closeups, split fixed elements by framing class and never apply both to the same shot.
5. Use bound_entity_id for identity. In description_for_prompt, use common nouns suitable for T2I.

Return strict JSON matching ContinuityCard schema.
```

### User

```text
# TASK
Create fixed visual continuity elements for the selected shots.

# SOURCE SCENE
{{scene_packet_json}}

# SELECTED SHOTS
{{selected_shots_json}}

# SHOT STAGING
{{shot_staging_json}}

# VISIBLE ENTITIES BY SHOT
{{shot_director_json}}

# ENTITY CANON
{{entity_canon_json}}

# DECISION RULES
- If a fixed element applies to only one shot, omit it.
- If exact pose is under-specified, choose the least invasive stable pose and mark confidence=medium.
- If source contradicts itself, record uncertainty instead of forcing a detail.

Return JSON only.
```

### Output skeleton

```json
{
  "scene_index": 12,
  "fixed_elements": [
    {
      "element_id": "motionless_body_full_pose",
      "element_type": "character_state",
      "bound_entity_id": "C02",
      "description_for_prompt": "an East Asian woman lying motionless on her left side, eyes closed, one arm bent near her face",
      "applies_to_shots": [1, 3],
      "framing_class": "full",
      "must_not_duplicate_with": [],
      "evidence_refs": [{"scene_index": 12, "source_type": "action", "span_id": "S12:A08"}],
      "confidence": "medium"
    }
  ],
  "uncertainties": [
    {
      "question": "Exact arm direction is not specified.",
      "resolution": "Choose one stable pose for cross-shot consistency."
    }
  ]
}
```

## Template D. Background Master Plan

### System

```text
You are a film art-direction master planner for a recurring location group.

Your only job is to decide floor plans and empty background states for selected shots.

Rules:
1. Floor plans define physical layout.
2. Backgrounds define empty location images for a specific sub_location + visual state.
3. Every background must apply to at least one selected shot.
4. Same sub_location shares the same floor plan.
5. State labels encode plot-critical visual state, not prose.
6. Use generic ASCII snake_case identifiers only.
7. Do not include people or character names.

Return strict JSON matching BackgroundMasterPlanCard schema.
```

### User

```text
# TASK
Plan floor plans and empty backgrounds for this building group.

# BUILDING GROUP
{{building_group_json}}

# SELECTED SHOTS IN GROUP
{{selected_shots_json}}

# RELATED SCENE SEGMENTS
{{scene_segments_json}}

# LOCATION CANON
{{locations_json}}

# VISUAL WORLD RULES
{{visual_world_rules_json}}

# OUTPUT REQUIREMENTS
- Every bg_id must list applies_to_shots from selected shots only.
- Generate order must be topologically sorted.
- No proper nouns.

Return JSON only.
```

## Template E. Scene Detail / Render Prompt Compile

This stage should behave more like a compiler than an author. It should not rediscover the story.

### System

```text
You are a render prompt compiler for one selected screenplay shot.

Your job:
Compile a final image prompt from upstream cards.

Decision priority:
1. shot_staging camera/person placement
2. continuity_card fixed elements
3. shot_director visible entities
4. background_binding and camera metadata
5. shot_selection render strategy
6. shot_candidate moment description

Hard rules:
1. One prompt = one still moment.
2. Never add visible entities outside shot_director.
3. Use C##O## only for real visible people whose face/body reference should be attached.
4. For body-part closeups, do not use C## or C##O##.
5. For printed/TV/mirror/reflection people, use common nouns, not C##.
6. If background reference is attached, do not regenerate large background objects.
7. If close framing skips background reference, do not mention "reference image" or "existing room".
8. Keep outfits brief; the outlook reference carries the detail.
9. Output only JSON.

Return strict JSON matching RenderPromptCard schema.
```

### User

```text
# TASK
Compile final T2I prompt variations for this selected shot.

# SHOT
{{shot_candidate_json}}

# SELECTION DECISION
{{shot_selection_json}}

# VISIBLE ENTITIES
{{shot_director_json}}

# STAGING
{{shot_staging_json}}

# CONTINUITY CARD
{{continuity_card_for_this_shot_json}}

# ENTITY CANON
{{entity_canon_json}}

# OUTLOOK ASSIGNMENTS
{{outlook_assignments_json}}

# BACKGROUND BINDING
{{background_binding_json}}

# PROVIDER RULES
{{provider_rules_json}}

# OUTPUT REQUIREMENTS
- t2i_prompt starts with "Photorealistic cinematic still."
- visible_entities must match allowed visible IDs.
- If reference_usage is skipped_close_framing, prompt must be self-contained.
- Include validation_hints for downstream LVM review.

Return JSON only.
```

### Output skeleton

```json
{
  "scene_index": 12,
  "shot_index": 4,
  "scene_type": "normal",
  "representative_moment": "The observer freezes in the doorway.",
  "render_strategy": "direct",
  "t2i_variations": [
    {
      "variant_label": "var_1",
      "camera_effect": "doorway reveal from eye level",
      "t2i_prompt": "Photorealistic cinematic still. C01O02 in a dark jacket, an East Asian woman, stands at the doorway in left profile, one hand gripping the doorframe. In the dim room beyond, a motionless figure lies on the floor as fixed in the continuity note. Cool low interior light, shallow depth, tense quiet composition.",
      "visible_entities": ["C01", "C02", "L01"],
      "outfit_assignments": [
        {"character_id": "C01", "outlook_id": "O02"},
        {"character_id": "C02", "outlook_id": "O03"}
      ],
      "background_binding": {
        "bg_id": "cb_main_room_night_normal",
        "reference_usage": "exact_background"
      },
      "continuity_elements_used": ["motionless_body_full_pose"]
    }
  ],
  "validation_hints": [
    "There must be only two people.",
    "The motionless figure must not change pose.",
    "Do not create an extra doorway or window."
  ]
}
```

## Template F. Asset Readiness Validator Prompt

이 단계는 prompt가 아니라 deterministic code여야 한다. 그래도 LLM review prompt가 필요하다면 "원인 설명" 용도로만 쓴다.

### Deterministic input

```json
{
  "render_prompt_card": {},
  "db_image_assets": [],
  "filesystem_root": "projects/{pid}",
  "path_policy": "project_relative"
}
```

### Deterministic output

```json
{
  "ready": true,
  "resolved_refs": [],
  "missing_refs": [],
  "path_errors": [],
  "db_errors": []
}
```

## Prompt anti-patterns

### Anti-pattern 1. "분석하고 프롬프트도 작성하라"

문제: 분석, 선택, 컴파일이 섞인다.

대신:

```text
This call only selects shots.
Do not rewrite descriptions.
Do not create T2I prompts.
```

### Anti-pattern 2. background를 scene prompt에 다시 길게 쓴다

문제: background reference와 중복 렌더링이 생긴다.

대신:

```text
Use background_binding as the space source.
Only describe foreground action and frame-edge visible local surfaces.
```

### Anti-pattern 3. "참조 이미지가 있을 것이다"를 prompt가 가정한다

문제: 실제로 ref가 없으면 모델이 환각으로 채운다.

대신:

```text
Asset readiness determines reference availability.
If reference is not attached, prompt must be self-contained or generation must block.
```

### Anti-pattern 4. schema description과 system rule 충돌

문제: strict JSON은 맞지만 값 정책이 흔들린다.

예: system prompt는 C##O## 직접 사용, schema description은 bare C##만 허용.

대신:

```text
The schema description must repeat the same ID policy as the system prompt.
```

