AI 숏폼 자동화 파이프라인 v1 — 4단계 아키텍처와 프롬프트 변수화 (1편)
1. 문제 정의
검증하려는 가설은 두 가지였다. AI 영상 생성 모델을 활용해 YouTube와 TikTok 숏폼 콘텐츠의 생성부터 업로드까지 자동화할 수 있는가? 그 결과물이 알고리즘 추천을 받을 만큼 자연스러운가?
콘텐츠 콘셉트로 "Satisfying 청소 ASMR" 장르를 선택했다. 컴퓨터 부품을 고압수로 세척하는 30~60초 길이의 무음 숏폼이다.
이 장르를 선택한 근거 5가지:
- Satisfying 카테고리는 시청 완료율이 높아 알고리즘 친화적
- 정적 물체 중심이라 현재 영상 생성 모델의 강점 영역
- 물 표현은 Veo 3 / Kling이 잘 처리하는 도메인
- 과장된 연출이 가능해 실사 영상과의 직접 비교가 어려움 (= AI 흔적이 톤으로 흡수됨)
- 무음 ASMR이라 음성 합성 모듈이 불필요 — 시스템 복잡도 감소
다섯 가지 중 결정에 가장 큰 영향을 준 항목은 4번이었다. 현재 영상 생성 모델은 물리적으로 비현실적인 동작에서 가장 자주 실패한다. 과장된 연출이 허용되는 장르에서는 그 실패가 콘텐츠 톤으로 흡수된다는 점이 핵심 근거였다.
2. 접근
방법론 — BMAD V6
5일 안에 v1 파이프라인을 완성하기 위해 BMAD V6(정해진 단계를 따르도록 하는 워크플로 방법론)를 적용했다. BMAD V6는 PRD(제품 요구사항 문서) → 아키텍처 설계 → 모듈 구현 순서를 따르도록 하며, 각 단계에서 sequential-thinking 패턴으로 대안의 장단점을 따져 선택을 명시한다.
5일 안에 4단계 모듈을 구현할 수 있었던 이유는 문서 작성 단계에서 내린 결정이 구현 시간을 줄였기 때문이다. PRD에서 시스템 경계를 잡고 아키텍처 설계에서 모듈 책임을 분리하면, 구현은 그 결정을 코드로 옮기는 작업이 된다. Claude Code는 이 결정을 코드로 옮기는 단계에서 가장 빨랐다.
세션 핸드오프(인수인계) 파일이 30개 넘게 쌓였다. 하루 평균 6개로, 단계별 결정의 흔적이다.
도구 선택
| 항목 | 선택 | 대안 | 근거 |
|---|---|---|---|
| 영상 생성 모델 | Vertex AI Veo 3 (veo-3.1-generate-preview) |
Kling 2.5 | Google Cloud 신규 가입 $300 무료 크레딧 활용 — 초기 검증 단계 비용 0 |
| 영상 편집 | FFmpeg | moviepy | 단순 concat에 재인코딩 불필요. 라이브러리 추상화 비용 회피 |
| 업로드 | YouTube Data API v3 + TikTok API | 수동 업로드 | 자동화 가설 검증에 필수 |
| 런타임 | Python 3.11 + uv | (Node.js 등) | google-cloud-aiplatform / ffmpeg-python / google-api-python-client 표준 스택 |
초기 설계에서는 Veo 3의 생성 단가를 1초당 $0.50로 잡았다. 이 단가로 계산하면 영상 1편(8초 × 4클립 = 32초)에 $16, 월 30편에 $480이 든다. 이는 재생성 비용과 무료 크레딧 차감을 반영하지 않은 예상 생성 비용이다.
3. 구현
4단계 모듈 파이프라인
모듈 간에는 데이터 클래스로 데이터를 주고받아 결합도를 최소화했다. 데이터는 Prompt → VideoClip → FinalVideo → UploadResult의 네 단계를 거쳐 전달된다. 도표의 각 단계 아래에는 출력 타입을 적었다. 실선은 데이터 전달을, 점선은 외부 API 호출과 로컬 처리 의존성을 표시한다.
핵심 결정 — 프롬프트 변수화
구현 과정에서 가장 어려웠던 부분은 코드가 아닌 프롬프트 설계였다. 단일 자연어 프롬프트("먼지 낀 GPU를 수압으로 청소하는 영상")는 출력 품질의 일관성을 보장하지 못했다. 클립마다 노즐이 사라지거나 먼지가 역류하거나 부품이 튀어 오르는 등 물리적으로 비현실적인 현상이 빈번하게 나타났다.
이를 해결하기 위해 프롬프트를 청소 대상, 청소 방식, 동작, 시각 표현, 오디오 묘사의 5개 변수로 분해했다. 아래는 선택지를 줄인 예시다.
templates:
satisfying_clean:
base: |
Extreme close-up of extremely dusty {part} being {cleaning_method},
{motion_style}, {visual_style}.
Audio: {audio_description}
variables:
part: # 청소 대상
- "RGB gaming GPU with dust caked between fan blades"
- "mechanical keyboard with debris between keys"
- "CPU cooler with thick dust buildup"
cleaning_method: # 청소 방식
- "pressure washed with powerful water jet"
- "blasted with compressed air"
motion_style: # 모션 스타일
- "slow motion water droplets flying"
- "dramatic dust particles dispersing"
visual_style: # 시각 스타일
- "4K cinematic, dramatic lighting"
- "macro lens detail, studio lighting"
audio_description: # 오디오 묘사
- "realistic high-pressure water spray, ASMR quality"
변수화의 가치는 두 가지다. 첫째, 조합 가능한 콘텐츠 풀이 생긴다. 위 예시에서 변수별 값을 하나씩 고르면 3 × 2 × 2 × 2 × 1 = 24가지 프롬프트 조합을 만들 수 있다. 둘째, 어느 변수가 품질에 큰 영향을 주는지 측정할 수 있다. 예를 들어 motion_style 변수에 "slow motion water droplets flying" 값을 넣었을 때 일관되게 자연스러운 출력이 나오는 것을 관찰했다.
Veo 3 호출
Vertex AI 표준 비동기 호출 패턴을 따랐다.
operation = await client.models.generate_videos(
model="veo-3.1-generate-preview",
prompt=prompt.text,
config={
"aspect_ratio": "9:16", # 숏폼 세로
"duration_seconds": 8, # Veo 3 단일 클립 최대
"number_of_videos": 1,
},
)
while not operation.done:
await asyncio.sleep(10)
operation = await client.operations.get(operation.name)
video_url = operation.response.generated_videos[0].video.uri
operation ID를 받아 10초 간격으로 폴링했다. 클립 1개를 생성하는 데 평균 60~90초가 걸렸다.
FFmpeg 무재인코딩 병합
4개 클립을 이어 붙여 30~60초 영상으로 만드는 단계다. 이 단계에서는 재인코딩을 하지 않기로 결정했다.
ffmpeg.input(list_file, format="concat", safe=0).output(
str(output_path),
c="copy", # 재인코딩 없음
movflags="faststart", # 스트리밍 최적화
).overwrite_output().run()
-c copy로 영상·오디오 스트림을 직접 복사하면 병합이 1~2초 안에 끝난다. 재인코딩하면 30초 이상 걸리고 화질이 손상된다. Veo 3 클립은 H.264 규격이라 호환 문제가 없었다.
업로드 — VideoMetadata와 OAuth
YouTube Data API v3에서는 OAuth 2.0(권한 부여 표준) 인증을 한 번 마치면 메타데이터 객체를 사용해 업로드를 완료할 수 있다.
@dataclass
class VideoMetadata:
title: str
description: str
tags: list[str]
category_id: str = "24" # Entertainment
privacy_status: str = "public"
made_for_kids: bool = False
shorts: bool = True
TikTok은 OAuth만으로는 부족했다. TikTok for Developers에 앱을 등록하고 video.upload와 video.publish 권한을 신청한 뒤 콘텐츠 정책 검토를 통과해야 한다. 권한을 승인받는 데 2주가량 걸렸다. 자동화 가설 검증의 외부 의존성 중 가장 큰 변수였다.
AI 흔적 판정 기준
구현 과정에서 어떤 클립을 폐기하고 어떤 클립을 발행할지 판정 기준이 필요했다. 세 가지로 좁혔다.
- 클립 사이 점프 — 4개 클립을 이어 붙일 때 시각적 불연속이 보이는가
- 클립 내부 끊김 — 단일 8초 클립 안에서 객체가 사라지거나 갑자기 나타나는가
- 물리적 비현실성 — 액체·중력·접촉이 물리 법칙에 어긋나는가
이 셋 중 하나라도 보이면 클립을 다시 생성했다. 초기 설계 단가를 적용하면 8초 클립을 한 번 다시 생성할 때마다 $4가 추가된다. 비용이 늘더라도 발행 품질이 채널 신뢰도에 미치는 영향이 더 크다고 판단했다.
4. 결과
5일간의 구현을 마친 뒤 한 달간 영상 100편 이상을 자동 생성하고 업로드했다. output/ 디렉터리에 영상 1편당 폴더 1개가 쌓였다.

| 지표 | 값 |
|---|---|
| 영상당 평균 조회수 | 700~900회 |
| 1000회를 넘긴 영상 | 0편 |
| 영상 1편당 예상 생성 비용 (8초 × 4클립, 재생성·크레딧 차감 제외) | $16 |
수익화 가설은 검증되지 않았다. 알고리즘 추천이 의미 있게 작동하려면 수만 회 이상 노출되어야 하는데, 영상이 100편 쌓인 뒤에도 그 기준에 도달하지 못했다. 자동화 가설은 검증되었다 — 4단계 파이프라인이 사람의 개입 없이 영상 생성부터 병합, 업로드까지 마쳤다.
5. 학습
이 시도에서 세 가지를 배웠다.
첫째, 영상 생성 모델의 결과는 프롬프트가 90%다. 모델 선택보다 프롬프트 변수화·체계화가 출력 품질의 일관성을 만든다. 변수 5종으로 분해한 결정이 가장 큰 자산으로 남았다. 다음 영상 파이프라인 프로젝트에서도 프롬프트를 변수 단위로 먼저 설계한다는 원칙은 그대로 가져갈 만하다.
둘째, BMAD V6 + Claude Code 조합은 5일 단위 사이드 프로젝트에 유효했다. BMAD가 결정 단계를 강제하고 Claude Code가 구현 단계를 단축한다. 핵심은 문서 작성에 시간을 들여 코드 구현 시간을 줄이는 것이다. PRD 작성에 1일, 아키텍처 설계에 1일, 구현에 3일을 쓰는 편이 5일 내내 구현에만 매달리는 것보다 빨랐다.
셋째, 자동화 가설과 시장 가설은 분리해서 측정해야 한다. AI만으로 콘텐츠를 자동 생성할 수 있는가라는 질문에는 그렇다고 답할 수 있었다. 그 콘텐츠가 시장에서 통하는가라는 질문에는 아니라고 답했다. 두 가설을 같은 영상에서 동시에 검증하려 하면 어느 가설이 어디서 실패했는지 구분하기 어렵다. 다음 단계에서는 자동화 파이프라인을 고정한 상태로 시장 가설만 다양화하는 실험이 필요하다.
다음 단계에서는 같은 파이프라인에서 프롬프트를 다양화하고 메타데이터를 최적화해 시장 가설을 다시 검증한다. 이 과정은 2편에서 다룬다.