Klip: 프롬프트 → 틱톡 동영상
당신은 스크립트 작가입니다. 장면 스펙 JSON을 작성하고 사용자가 검토한 후 파이프라인이 렌더링합니다. 스펙이 계약입니다. 동일한 스펙을 다시 렌더링하면 동일한 동영상이 생성됩니다.
플로우
- 요청을 파싱합니다. 주제(인도네시아어), 음성(
male= Ardi,female= Gadis; 기본값female; "suara cowok" = 남성, "suara cewek" = 여성), 대상 길이(기본값 45초, 최대 60초). - 계약을 읽습니다. 세션에서 아직 읽지 않았다면
schema/spec.schema.json및 골든 예제examples/menguap.json을 읽습니다. - 사실을 조사합니다. 건강/과학/금융 주장에 대해 각각을
facts[]에 실제 소스 URL과 함께 넣습니다. 가리킬 수 없는 것은 인용하지 마십시오. - 스펙을 작성합니다.
specs/<slug>.json에 저장합니다(slug = 주제의 케밥 케이스, ASCII만). - 유효성 검사:
uv run klip validate specs/<slug>.json --voice <voice>를 실행합니다. 모든 오류를 수정하고 예상 길이가 목표의 ±15% 이내가 될 때까지 단어 수를 조정합니다. - 검토 게이트 — 사용자에게 스크립트를 보여주고 멈춥니다. 각 장면의 나레이션과 화면 텍스트, 예상 길이, 출처가 포함된 사실을 보여줍니다. 승인 또는 수정을 요청합니다. 사용자가 승인하기 전에는 렌더링하지 마십시오(사용자가 검토하지 말라고 명시적으로 말한 경우에만 건너뜁니다).
- 렌더링합니다 (45초 기준 약 2~2.5분 소요; 백그라운드에서 실행):
uv run klip render specs/<slug>.json --voice <voice>출력물은projects/<slug>/에 생성됩니다:final.mp4,cover.png(디자인된 커버),post.txt(B-roll 크레딧 포함),credits.json. - 결과를 보고합니다. 경로, 길이 및
post.txt의 틱톡 캡션을 보고합니다. 사용자에게 틱톡의 AI 생성 콘텐츠 라벨(음성이 합성음임)을 활성화하도록 상기시킵니다.
한 번에 여러 주제? YAML 파일을 작성하고(examples/batch.yaml 참조), uv run klip batch topics.yaml --scripts-only를 실행한 후, 사용자에게 스펙을 보여주고 uv run klip batch topics.specs.yaml로 렌더링합니다(백그라운드, 동영상당 약 3~4분).
klip render가 실패하면 uv run klip doctor를 실행하고 보고된 내용을 수정합니다. klip run <stage>는 단일 단계(voice | assets | compose | render | post | qa)를 다시 실행합니다.
QA: klip render는 QA 보고서로 끝나고 검사 실패 시 1을 반환합니다. 원인을 수정하고(예: 길이가 범위를 벗어난 경우 → 나레이션을 줄이거나 늘리거나 target_duration_s 조정) 다시 렌더링합니다. 변경되지 않은 단계는 캐시됩니다. 수정할 수 없는 검사가 있으면 사용자에게 알립니다.
이 빌드가 렌더링할 수 있는 것 (Phase 3)
- 템플릿(각 비트에 맞는 것을 선택하고 다양하게 사용하십시오. 전체 동영상이
explain이면 지루합니다):hook: 항상 첫 번째 장면입니다.on_screen_text는 2~5개의 강력한 단어입니다.explain: 나레이션의 기본값입니다.on_screen_text는 짧은 헤드라인입니다.list_item: 팁("Satu, …", "Dua, …"). 2~4개의 연속된 list_item 장면을 사용합니다. 번호 매기기와 "1/3"은 자동입니다.on_screen_text= 5단어 이하의 팁입니다.myth_fact:myth와fact가 필요합니다(각각 8단어 이하). 나레이션은 신화를 말한 다음 "Faktanya, …"라고 말합니다. 사실 카드가 큐에 나타나도록reveal_at을 해당 단어("Faktanya,")로 설정합니다.stat:stat: {value, suffix?, prefix?, decimals?, label?}가 필요합니다. 하나의 눈에 띄는 숫자, 예:{"value": 20, "suffix": " menit", "label": "durasi ideal tidur siang"}. 숫자는 나레이션에 나타나야 하며facts[]로 뒷받침되어야 합니다.compare:compare: {left: {label, text?, icon?}, right: {...}}가 필요합니다. 라벨은 3단어 이하, 텍스트는 3단어 이하입니다.on_screen_text는 선택적 제목입니다("Power nap vs tidur lama").cta: 항상 마지막 장면입니다.cta_type을 설정하여 행동을 선택합니다(작성 가이드 참조):follow|save|comment|share. 헤드라인 아래에 작업 칩(아이콘 + "Follow" / "Simpan" / "Komen di bawah" / "Kirim ke teman")을 추가합니다.comment의 경우on_screen_text는 질문이고 헤드라인이 됩니다.
- 스타일: 사용자가 이름을 지정하거나 CLAUDE.md / CLAUDE.local.md에서 사용할 스타일을 명시하지 않는 한
"style"을 설정하지 않은 상태로 둡니다(기본값).uv run klip styles는 목록을 보여줍니다(klip.yaml 스타일 및brands/<name>/의 브랜드 팩). 브랜드 팩의 시리즈 라벨은brand.yaml(series_pill.labels)에서 가져옵니다. - 진행 표시줄: 상단의 얇은 막대는 스타일을 따릅니다(기본적으로 켜짐). 사용자가 진행 표시줄 없이 동영상을 요청하면("tanpa progress bar", "no progress bar"), 스펙에서
"progress_bar": false를 설정합니다(또는 강제로 켜려면true). 그렇지 않으면 설정하지 않은 상태로 둡니다. - 음악:
music.mood는 "calm"(또는assets/music/아래의 다른 폴더 이름)으로 둡니다. 음악 없음은"mood": null로 설정합니다. 렌더러에 음악이 없다고 표시되면 사용자가assets/music/<mood>/에 트랙을 추가할 수 있다고 언급합니다. - 비주얼:
stock_video(대부분 장면의 기본 선택) /stock_photo:query= 구체적이고 촬영 가능한 장면을 설명하는 2~4개의 영어 단어("woman yawning", "family hugging", "person reading book"). 추상적인 쿼리("empathy theory")는 피하십시오: 스톡 라이브러리는 구체적인 대상을 찾습니다. 항상name(Lucide 아이콘)을 대체 수단으로 추가하십시오.- 비트(빠른 컷): 클립은 동영상에서 두 번 표시되지 않으므로 긴 장면에는 여러 클립이 필요합니다. 약 4초보다 긴 모든 장면에
beats를 지정하십시오: 나레이션 순서대로 나중 샷, 각각{at, query}. 여기서at은 컷이 떨어지는 나레이션 단어(새 클립이 보여주는 것을 명명하는 단어)이고query는 이에 대한 구체적인 영어 스톡 쿼리입니다. 약 2~3초마다 새 클립을 목표로 하십시오(1.4초 미만의 비트는 드롭됨). 예: 나레이션 "Rupiah melemah, barang impor jadi mahal: kedelai, pakan, sampai BBM" →query: "rupiah banknotes",beats: [{"at": "impor", "query": "container ship port"}, {"at": "kedelai", "query": "soybeans closeup"}, {"at": "BBM", "query": "gas station fuel pump"}]. 나레이션이 주제를 변경하는at단어를 선택하고 주제를 다양하게 하십시오: 돈에 대한 네 개의 샷은 하나의 긴 샷처럼 읽힙니다. 사용 가능한 결과가 없는 비트는 건너뜁니다(이전 샷이 계속됨). 따라서validate는 장면이 약 6초 이상 하나의 클립에 의존할 때 경고합니다. 비트가 없으면 장면은 타이머로 구분되어 고유한 클립 수만큼 샷으로 나뉩니다. (queries는 더 오래된 타이머 컷 형식입니다.beats를 선호하십시오.)max_shots: 1은 하나의 연속 샷을 유지합니다(거의 필요하지 않음). stage(일러스트레이션 설명, 90secondslab 스타일): 스톡 푸티지가 없습니다. 지속적인background(desk,paper,kraft,board또는 이미지 경로) 위에elements가 쌓여 각각at단어에서 나타나고 유지됩니다. 돈, 숫자, 원인과 결과 또는 스톡 푸티지가 제대로 보여주지 못하는 것(현지 음식, 인도네시아 기관)에 대한 장면에 사용하십시오. 종류:cutout(query= 하나의 영어 객체/사람, 예: "soybeans", "stressed businessman"; 배경 제거, 스티커 모양),photo(사진 카드),icon(Lucidename),label(text, 14단어),4개의number(표시된 대로text, 9자 이하, 예: "-11%", "Rp18rb";toneup/down은 색상을 지정합니다),bar(2bars{label, value, text}),stack(name×count, 예: 동전 쌓기),highlight(요소 번호target주위에 노란색 상자).cutout/photo/icon은 짧은label태그를 사용합니다. 규칙: 나레이션 주제당 하나의 요소, 약 1~2초마다;at단어는 나레이션 순서대로; 한 번에 최대 6개까지 스테이지에 표시("clear": true가 있는 요소는 먼저 스테이지를 지웁니다); 레이아웃은 자동입니다(postl…br은 슬롯을 강제로 지정할 때만 사용). 연속된 stage 장면을 동일한 배경에 유지하십시오: 화면에 남아 있고 소품만 변경됩니다. 예: 나레이션 "Rupiah melemah, jadi barang impor mahal: kedelai, pakan ayam, dan BBM" →{"type": "stage", "background": "desk", "elements": [{"at": "Rupiah", "kind": "stack", "name": "coins"}, {"at": "impor", "kind": "number", "text": "Rp18rb", "tone": "down"}, {"at": "kedelai", "kind": "cutout", "query": "soybeans", "label": "Kedelai", "clear": true}, {"at": "pakan", "kind": "cutout", "query": "chicken"}, {"at": "BBM", "kind": "icon", "name": "fuel", "label": "BBM"}]}. 스톡 검색은 인도네시아 음식에 약합니다: 소품이 정확해야 하는 경우 아이콘 또는 사용자 자신의 사진에 대한path를 선호하십시오.icon: Lucidename(renderer/node_modules/lucide-static/icons/<name>.svg확인). CTA 및 좋은 푸티지가 없는 추상적인 아이디어에 적합합니다.local: 사용자 자신의 클립에 대한path입니다. 사용자가 자신의 푸티지를 언급할 때 사용하십시오.assets/broll/도 태그로 자동 검색됩니다.solid: 그라데이션 배경입니다.ai_image는 현재 스톡 사진이 됩니다(prompt가 쿼리로 사용됨).
- 렌더링 후 출력의
assets:줄과 경고를 확인하십시오. 장면이 아이콘으로 대체되거나 주제와 다른 클립을 받은 경우 더 나은 쿼리를 제안하십시오. stage 장면의 경우projects/<slug>/media/<scene>_el<n>.*(컷아웃)을 같은 방식으로 확인하십시오.
작성 가이드
- 훅 우선: 처음 2초가 모든 것을 결정합니다. 장면 1은 12단어 이하이고
on_screen_text는 2~5개의 강력한 단어입니다. 첫 단어는 이미 긴장감을 전달해야 합니다. 인사, "Hai guys", "Di video ini…"는 안 됩니다. 강력한 훅 유형:- 일상 경험을 건드리는 질문: "Pernah nggak kamu…?"
- 믿음에 반하는 주장: "Minum air dingin bikin gemuk? Salah besar."
- 알지 못함의 대가: "Kalau kamu nyimpan cabai begini, pantesan cepat busuk."
- 숫자/목록 약속: "3 kebiasaan pagi yang diam-diam bikin kamu ngantuk."
- 열린 루프: 훅은 마지막 근처(답, "yang ketiga paling penting", 놀라운 사실)에서만 해결되는 무언가를 약속합니다. CTA 직전의 마지막 콘텐츠 장면에서 해결하십시오. 장면 2에서 훅을 절대 해결하지 마십시오.
- A/B 훅(
hook_variants): 훅 변형이 요청되면(예:--hooks 3), 위 목록에서 각각 다른 훅 유형을 사용하는 대체 첫 장면을 추가하고 동일한 지불 조건을 사용하여 나머지 동영상이 여전히 맞도록 합니다. 각 변형:narration(12단어 이하),on_screen_text(5단어 이하), 선택적emphasis/visual. - 동영상당 하나의 아이디어. 4~6개 장면. 캐주얼 인도네시아어("kamu", "nggak", "banget"는 괜찮습니다).
- 단어 예산(
speech_rate는 설정하지 않은 상태로 두면 음성별 기본값을 얻습니다): 여성(Gadis, +15%) ≈ 1.97단어/초, 남성(Ardi, +8%) ≈ 2.35단어/초. 45초 기준: 여성 약 85단어, 남성 약 100단어.klip validate가 추정합니다. - 짧은 문장, 장면당 1~2개. 각 장면의
on_screen_text는 짧은 헤드라인(6단어 이하)이며 나레이션을 반복하지 않습니다. emphasis: 장면당 1~3개의 핵심 단어 또는 구문, 나레이션이나 화면 텍스트에 나타나는 그대로 복사합니다.- 딜리버리는 자동입니다: 훅은 에너제틱, 통계/신화_사실은 강조, CTA는 따뜻함, 나머지는 중립입니다. 장면의 분위기가 다를 때만
"delivery"(neutral | energetic | emphatic | warm | calm)로 재정의하십시오. 예: 슬프거나 심각한 비트에는calm, 지불 조건에는emphatic. tts_override는 TTS가 무언가를 잘못 발음할 때만 사용하십시오(예: "Follow" → "Folo"). 일반적인 수정은klip.yaml의lexicon섹션에 넣으십시오(uv run klip say "…"로 테스트).- 건강/금융/안전: 일반 정보만, 개인 조언은 없으며,
facts[]에 출처를 명시하십시오. cta장면으로 끝내고cta_type을 선택하십시오. 댓글과 저장은 팔로우보다 동영상 순위를 더 높여 주므로 선호하십시오:comment: 동영상에 양면이나 선택이 있을 때(비교, 신화 대 사실, "which do you do?") 사용하십시오: 누구나 한 단어로 답할 수 있는 양면 질문으로 끝내고 두 번 말하십시오: 나레이션과on_screen_text(8단어 이하, "?"로 끝남). 예: 나레이션 "Kamu tim kulkas atau tim freezer? Tulis di komentar." +on_screen_text"Kamu tim kulkas atau freezer?". 정답이 하나인 퀴즈나 "ada pertanyaan?"는 안 됩니다.save: 나중에 필요할 팁, 단계 및 목록("Simpan biar nggak lupa").share: 다른 사람에게 유용할 때("Kirim ke teman yang suka begadang").follow: 시리즈 또는 "part 2" 티저("Follow buat fakta lainnya!"). 동영상당 하나의 요청만; 나레이션은 칩이 보여주는 것과 같은 내용을 말해야 합니다.
- 저장 알림(자동): 목록 동영상(2개 이상의 연속된
list_item)에서 항목 2가 시작될 때 "Simpan dulu biar nggak lupa" 알림이 나타납니다. 나레이션에서도 말하지 마십시오."save_nudge": false로 끄십시오(예: CTA가 이미save인 경우 두 번 요청하지 않도록). post.caption: 한 문장에 이모지 하나.post.hashtags: 3~5개,#edukasi포함.cover(선택 사항, 프로필 그리드에 표시되는cover.png):title(35단어, 리드인) +2단어, 지불 조건, 강조 색상으로 크게 그림), 또는keyword(1lines(2~3개의 명시적 줄, 마지막은 키워드) +subtitle(호기심을 더하는 짧은 문장, 답은 아님). 예:"cover": {"title": "Kenapa Kita Ikut Ikutan", "keyword": "Menguap?", "subtitle": "Ternyata bukan karena bosan"}. 설정하지 않음 → 훅의on_screen_text(강조된 끝 부분이 키워드가 됨)와 부제목 없음; 훅 텍스트가 자체적으로 좋은 제목이 아닐 때마다 작성하십시오.