
Zero to Autopilot, 파트 2: 단 한 줄의 텍스트가 7단계를 거쳐 게시된 쇼츠가 되기까지
요약
단 한 줄의 텍스트로 유튜브 쇼츠를 자동 생성하는 AI 미디어 채널 구축 아키텍처를 소개합니다. 비디오 생성을 모놀리스 방식이 아닌, Makefile과 같은 단계별 파이프라인 및 순수 함수 구조로 설계하여 효율성과 재사용성을 높였습니다.
핵심 포인트
- 비디오 생성을 단계별 파이프라인으로 설계하여 멱등성 확보
- 각 단계를 파일 기반의 순수 함수로 구현하여 디버깅 용이
- 모든 작업 결과물을 특정 디렉토리에 파일로 저장하는 구조
- 오픈 소스 프로젝트로 공개되어 직접 테스트 가능
시리즈: Zero to Autopilot — 자기 개선형 AI 미디어 채널 구축하기. 7부작 중 2부입니다. 파트 1에서는 전반적인 환경과 저의 10달러짜리 깨달음에 대해 다루었습니다. 이번 편은 아키텍처 (architecture)에 관한 내용입니다. 즉, 제가 비디오 편집기를 한 번도 열지 않고 어떻게 단 한 줄의 텍스트가 업로드된 쇼츠 (Short)가 되는지에 대한 과정입니다.
데이터 상태 (파트 2): 실시간 (real-now). 코드, 파일 레이아웃, 그리고 측정된 비용을 리포지토리 (repo)에서 직접 가져왔습니다. 시청자 지표는 포함되지 않았습니다 — 그것들은 파트 7로 미뤄두었습니다.
⭐ 전체 프로젝트는 오픈 소스입니다: github.com/dasein108/slope-studio. 함께 클론 (clone) 해보세요 — 하단에 API 키가 필요 없는 스모크 테스트 (smoke test)가 있습니다.
멘탈 모델 (mental model): 비디오는 Makefile이다
대부분의 "AI 비디오 생성기" 도구들은 하나의 거대한 모놀리스 (monolith)입니다 — 하나의 거대한 버튼, 하나의 블랙박스이며, 14번째 장면이 이상하게 나왔을 때 당신은 14개 장면 전체를 다시 생성해야 합니다. 저는 소프트웨어를 충분히 출시해 보았기에 그것이 잘못된 형태라는 것을 알고 있습니다.
그래서 저는 빌드 시스템 (build systems)에서 모델을 빌려왔습니다: 비디오는 단계(stages)로 이루어진 방향성 파이프라인 (directed pipeline)이며, 각 단계는 파일에서 파일로 이어지는 순수 함수 (pure function)이고, 전체 과정은 멱등성 (idempotent)을 가집니다. 단계를 다시 실행하면 이미 완료된 작업은 건너뜁니다. 하나의 아티팩트 (artifact)를 삭제하면, 해당 단계(및 그 의존성 항목)만 다시 빌드됩니다. 이는 마지막에 YouTube 업로드가 추가된 make와 같습니다.
다음은 위에서 아래로 이어지는 파이프라인입니다:
idea ──► [1 script] ──► 01_script.json (타이밍이 지정된 장면 + 내레이션)
│
├──► [2 visuals] ──► 02_visuals/scene_NN.png
...
모든 화살표는 파일을 작성합니다. 모든 파일은 하나의 실행 디렉토리 (run directory) 아래에 존재합니다. 이는 프로젝트 전체에서 가장 중요한 설계 결정으로 우리를 안내합니다.
모든 것은 runs/<id>/ 아래의 파일이다
데이터베이스도 없습니다. 숨겨진 상태(hidden state)도 없습니다. 하나의 실행(run)은 하나의 디렉토리이며, 그 디렉토리가 곧 상태(state)입니다:
runs/lobachevsky/
├── project.json # 매니페스트(manifest): 단계별 제공자(provider) + 비용 + 완료 플래그
├── 01_script.json # 장면(scenes), 내레이션(narration), 제목(title), 해시태그(hashtags)
...
이것은 거의 너무 단순하게 들릴 수도 있지만, 이를 통해 다음과 같은 모든 이점을 얻을 수 있습니다:
- 디버깅 가능성 (Debuggability) — 무언가 잘못되었나요? PNG 파일을 여세요. JSON을 읽으세요. "파이프라인 상태를 검사하는" 별도의 도구가 필요하지 않습니다.
ls와 이미지 뷰어만 있으면 그것이 바로 디버거입니다. - 재개 가능성 (Resumability) — 9번째 장면에서 프로세스를 종료하고 다시 시작하면, 9번째 장면부터 이어서 진행합니다.
- 멱등성 (Idempotency) — 각 단계는 자신의 출력물을 확인하고 이미 존재하면 건너뜁니다.
visuals단계를 다시 실행해도 이미 가지고 있는 15개의 이미지에 대해 비용이 중복 청구되지 않습니다 (실제로 다시 생성하고 싶을 때는--force옵션을 사용합니다). - 아티팩트(artifacts)의 버전 관리 — 저장소 내의 모든 제작된 비디오는
diff를 수행하거나, 복사하거나, 직접 편집할 수 있는 폴더입니다.
표준 경로(Canonical paths)는 정확히 한 곳(studio/paths.py)에 존재하므로, 어떤 단계에서도 파일 이름을 하드코딩하지 않습니다:
def scene_image(d: Path, sid: int) -> Path:
return visuals_dir(d) / f"scene_{sid:02d}.png"
...
각 단계는 CLI 서브커맨드입니다 (그리고 이들은 체인처럼 연결됩니다)
파이프라인은 Typer 앱입니다. 모든 단계는 각각의 서브커맨드(subcommand)이므로, 전체를 실행하거나 특정 단계만 정밀하게 건드릴 수 있습니다:
# 전체 파이프라인 실행, 하나의 아이디어를 입력하여 하나의 쇼츠(Short) 출력:
studio run "lobachevsky geometry explained in a fun way" --duration 150
...
단계 순서는 하나의 리스트이며, run은 단순히 이를 순차적으로 훑으며 진행합니다:
STAGE_ORDER = ["script", "visuals", "narrate", "clips", "stitch", "audio", "voice", "save"]
단계를 추가하는 방법은 간단합니다: stages/에 순수 함수(pure function)를 작성하고, 서브커맨드를 추가한 뒤, 해당 이름을 리스트에 넣으면 됩니다. 제공자(provider) (새로운 이미지 모델, 새로운 TTS 등)를 추가하는 것은 파이프라인을 전혀 건드리지 않습니다. 이에 대해서는 다음 섹션에서 더 자세히 다루겠습니다.
제공자 계약(provider contract): 모든 모델은 자신의 비용을 보고합니다
이것은 제가 가장 자랑스럽게 생각하는 설계 선택입니다. 왜냐하면 이것이 _시리즈의 나머지 전체_를 가능하게 만드는 핵심이기 때문입니다. 모든 미디어 생성 제공자(media-producing provider) — 모든 LLM, 이미지 모델, 비디오 모델, TTS — 는 동일한 데이터 클래스(dataclass)를 반환합니다:
@dataclass
class GenResult:
path: Path | None = None
...
그 cost_usd는 제가 스프레드시트에 대충 적어둔 추정치가 아닙니다. Nano Banana 제공자는 $0.039를 반환합니다. kling 제공자는 초(seconds) × $0.07를 계산합니다. Ken-Burns 애니메이터는 $0.00을 반환합니다. 따라서 각 단계(stage)가 실행될 때, 매니페스트(manifest)는 추측한 비용이 아닌 측정된(measured) 비용을 기록합니다:
class StageRecord(BaseModel):
done: bool = False
provider: str = ""
...
이것이 기초입니다. 측정할 수 없는 것은 최적화할 수 없으며, 추측하는 비용 위에 예산 인식 밴딧(budget-aware bandit) (파트 6)을 구축하는 것은 확실히 불가능합니다. 이 시리즈에 등장하는 모든 달러는 시스템이 스스로 보고한 실제 달러입니다.
실제로 실행되는 모습 관찰하기
다음은 Lobachevsky 실행 시의 실제 로그입니다. 각 단계가 진행되면서 자신의 제공자(provider)와 비용을 공표하는 점에 주목하세요:
» visuals
visuals 15 images via fal-nanobanana $0.585
» clips
...
15개의 정지 이미지, 15개의 애니메이션 클립, 나레이션, 자막, 믹싱 및 마스터링까지 — 단 한 줄의 텍스트로부터 완전히 자동화되어 $1.34가 소요되었습니다. (해당 실행에서는 유료 AI 비디오를 약간 사용했습니다. 동일한 쇼츠의 전체 Ken-Burns 버전은 $0.585이며, 파트 1에서 다룬 저가형 플레이북을 사용하면 유사한 비디오를 6센트에 얻을 수 있습니다. 비용 조절 노브(knobs)에 대해서는 파트 4에서 다룹니다.) 다음은 완성된 결과물의 한 프레임입니다:
그리고 각 장면 아래에 있는 데이터 구조(data shape)를 보면, 스크립트 단계(script stage)에서 생성된 시간 정보가 포함된 장면(timed scenes)을 나머지 파이프라인이 소비합니다:
// 01_script.json (한 장면)
{
"id": 1,
...
narration은 TTS (Text-to-Speech)를 구동하며, 이에 따라 클립의 길이도 결정됩니다 (오디오가 주도하고 비디오가 이를 따르므로 싱크가 어긋날 일이 없습니다). visual_prompt는 이미지 모델을 구동합니다. motion_hint는 프리 애니메이터 (free animator)를 구동합니다. 하나의 JSON 객체가 세 개의 후속 단계(downstream stages)를 이끕니다.
직접 시도해 보세요 (API 키 불필요, 비용 0원)
이 저장소(repo)는 오프라인 모드를 제공하므로, 단 하나의 키나 비용 없이 전체 파이프라인이 실행되는 과정을 지켜볼 수 있습니다. 유료 서비스 대신 스텁 프로바이더 (Stub providers)가 그 역할을 대신하며, 그 외의 모든 것은 실제 ffmpeg를 사용합니다:
git clone https://github.com/dasein108/slope-studio
cd slope-studio
uv venv && source .venv/bin/activate
...
완전히 무료인 로컬 도구들로 구축된, 편집되고 내레이션이 포함된 06_final.mp4 파일이 담긴 실제 runs/<id>/ 폴더를 얻게 될 것입니다. (주의: stub은 배선(wiring) 생성기입니다. 즉, 파이프라인의 구조를 테스트할 수 있도록 플레이스홀더 텍스트를 생성합니다. 시각 자료에 비용을 쓰기 전에 실제 LLM 키로 교체하세요. 그렇지 않으면 의미 없는 채우기용 영상(filler)을 정성스럽게 렌더링하게 될 것입니다. 제가 어떻게 아냐고요?)
다른 AI 엔지니어에게 해주고 싶은 말
핵심 요약 (Takeaway): 모놀리스 (monolith) 구조를 경계하세요. AI 파이프라인을 단일 실행 디렉토리(run directory) 상에서 파일 대 파일(file-to-file)로 작동하는 순수 함수 단계로 모델링하세요. 각 단계를 독립적으로 실행 가능한 명령어로 만들고, 모든 프로바이더가 자신의 비용을 보고하는 통일된 결과 타입 (result type)을 갖도록 하세요. 이렇게 하면 무료로 디버깅 가능성 (
ls가 당신의 인스펙터가 됩니다), 무료로 재개 가능성 (resumability), 무료로 멱등성 (idempotency)을 얻을 수 있습니다. 그리고 결정적으로, 당신이 나중에 구축할 더 똑똑한 기능들(예산 관리, 자동 전략, 밴딧 등)의 기반이 될 '측정 가능한' 비용 장부를 갖게 됩니다. 지루한 아키텍처가 곧 강력한 기능입니다.
다음 — 파트 3: 무료 모션 (Free Motion). 재미있는 부분입니다. AI 비디오는 초당 0.07달러가 들지만, 저는 단 하나의 정지 이미지를 가져와서 드리프트 (drift), 피사체 인페인팅 (inpainting)을 포함한 패럴랙스 (parallax), 키네틱 타이포그래피 (kinetic type), 분위기 있는 비와 불꽃 효과 등을 0.00달러에 구현할 것입니다. ffmpeg 필터그래프 (filtergraphs)와 그 뒤에 숨겨진 인디 게임 개발자들의 트릭을 심도 있게 다룰 예정입니다. (스포일러: 이 모든 것은 이미 **라이브 이펙트 갤러리**에서 실행되고 있습니다.)
▶ 라이브 이펙트 갤러리 (Live effects gallery): dasein108.github.io/slope-studio
⭐ 함께 따라하기 위해 리포지토리(repo)를 스타(Star) 해주세요: github.com/dasein108/slope-studio
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기