$

케이스 03 · 자동화

서로 다른 유형의 AI를 하나의 흐름으로

Whisper(STT)·Hyperframe(결정론적 HTML 렌더)·Claude(메타데이터)·YouTube API를 엮은 숏폼 반자동 파이프라인. 서로 다른 유형의 AI 도구를 각자 잘하는 일에 맞춰 골라 엮었다. 그리고 '자막 생성'이라는 한 가지 일을 같은 영상으로 다섯 방식(클라우드·로컬 STT·비전·수동) 실측 비교했다.

  • Automation
  • Orchestration
  • Tool Comparison

$

엮은 도구와 왜 그 조합인지

Whisper의 word_timestamps가 자막 데이터 구조를 정한다. Hyperframe은 결정론적이라 같은 입력이면 같은 출력이 나오고, 그래서 LLM이 HTML을 직접 작성해도 안전하다. Claude는 프롬프트 엔지니어링으로 구조화된 메타데이터를 맡고, YouTube API는 멱등 업로드를 담당한다.

파이프라인

  1. Upload

    영상

  2. Whisper

    단어 단위 자막

  3. Claude

    메타·후크

  4. Hyperframe

    결정론적 렌더

  5. Review

    사람 검수

  6. YouTube

    멱등 업로드

자막 — 한 가지 일을 다섯 방식으로 실측

자막은 파이프라인의 핵심이라, 같은 26초 클립(한국어 강아지 쇼츠)을 다섯 가지 자막 소스로 돌려 한국어 고유명사 정확도·속도·비용·오디오 데이터 경로로 판정했다. 그중 넷(whisper-1·faster-whisper large-v3·ElevenLabs Scribe·Claude 비전)은 실제로 끝까지 돌렸고, manual은 사람이 직접 입력한 기준선이다.

자막 엔진 비교 (같은 클립)

클립 실제 발화: “시루 … 궁예에요 궁예? 누가 그랬어 누가?”. 아래 네 엔진을 모두 직접 돌렸는데, 고유명사가 어떻게 갈리는지 보면 흥미롭다.

엔진방식한국어 결과 (고유명사)측정값판정
whisper-1 (OpenAI API)✓ 클라우드 STT · 단어 타임스탬프“시루 … 궁예” ✓ (audio_hint 덕)~$0.006/분 · 클라우드기본값 — 고유명사 교정에 강함
faster-whisper large-v3✓ 로컬 STT (int8/CPU)“지루 … 궁이” ✗ (hint 없음)추론 8.2s · RTF 0.31 · $0 · 로컬무비용·프라이버시, 단 고유명사 약점
Claude vision✓ 멀티모달 · 음성 미사용프레임 보고 “견주야 빨리 좀” 창작4.6s · 프레임 4장BGM·무음 영상 전용 경로
ElevenLabs Scribe✓ 클라우드 STT · 화자분리“티로 … 궁해” ✗ (hint 없음)2.2s · 43단어 · ~$0.40/시간빠름·촘촘, 단 고유명사는 여전히 hint 필요
manual사람 입력 baseline정확$0 · 느림환경음만 있는 영상용

같은 오디오가 보여준 것

같은 오디오를 STT 엔진 셋에 넣었다. audio_hint를 준 whisper-1만 “시루 … 궁예”를 맞췄다. hint 없이 돌린 로컬 large-v3는 “지루 … 궁이”, ElevenLabs Scribe는 “티로 … 궁해”가 나왔다. 일반 한국어는 비슷했고 고유명사에서만 갈렸다. 진짜 변수는 모델의 원시 성능이 아니라 프롬프트 바이어싱이었던 셈이다. API가 강아지 이름을 미리 알려주기 때문이다. 파이프라인이 한 모델을 박지 않고 'STT 엔진 선택 + audio_hint 필드'를 둔 이유가 여기에 있다. 비전은 아예 축이 다르다. 음성을 안 쓰니 경쟁자가 아니라 무음 영상용 fallback이다.

렌더 결과

실제 파이프라인 출력 프레임이다. Whisper 받아쓰기가 단어 타이밍 자막 pill이 되고 Claude가 쓴 훅이 얹힌다. “시루”·“궁예”가 맞은 건 audio_hint 덕분이다.

  • hook + 시루

    hook + 시루

    Claude 훅 + STT 고유명사

  • 산책가요

    산책가요

    단어 타이밍 자막 pill

  • 궁예

    궁예

    audio_hint 로 교정된 고유명사

  • 누가

    누가

    결정론적 Hyperframe 렌더

나레이션 — 강아지 속마음에 목소리를

자막을 넘어 나레이션도 오디오 레이어로 실험했다. 같은 한국어 대사(“견주야, 빨리 좀… 나 혼자라도 간다”)를 OpenAI TTS 보이스들과 ElevenLabs 멀티링궐로 읽혔다. OpenAI 보이스는 영문 학습이라 한국어 억양이 들리고, 마지막(ElevenLabs multilingual_v2)이 자연스러운 한국어 대조군이다. 보이스만이 아니라 어떤 제작사를 쓰느냐가 한국어 나레이션의 실사용 가능 여부를 가른다.

  • OpenAI tts-1 · nova (밝음)

  • OpenAI tts-1 · onyx (저음)

  • OpenAI tts-1 · shimmer (부드러움)

  • gpt-4o-mini-tts · “장난스러운 강아지” 지시

  • ElevenLabs multilingual_v2 · Laura (자연스러운 한국어)

반복 · 실패 · 전환

  1. Streamlit → Next.js (ADR 0003)

    4주 MVP라 Streamlit으로 시작했는데, 매일 보는 도구는 디자인이 중요하다는 생각이 들어 FastAPI와 Next.js로 분리했다. 이어 다크에서 라이트+그린(Tasko 레퍼런스)으로 이틀 만에 바꿨다.

  2. 한글 폰트 결정론

    시스템 폰트가 OS에 의존해서, @font-face를 CDN으로 임베드해 결정론적 렌더링을 확보했다.

  3. 자막 pill 겹침 — 발견하고 수정

    갤러리 렌더에서 노란 자막 pill이 겹쳐 쌓이는 게 드러났다(뒤로 갈수록 심했다). 렌더러가 GSAP 타임라인을 seek하는데 단어 pill에 페이드-인만 있어서, 한 번 뜨면 사라지지 않고 계속 쌓였다. 단어마다 윈도 끝에 페이드-아웃을 명시적으로 넣고 다시 렌더하니, 한 번에 깨끗한 pill 하나씩 나왔다.

  4. 단계 재배치

    원래 순서는 받아쓰기, 렌더, 메타데이터였는데, 렌더 시점에 후크 텍스트가 아직 없었다. 그래서 메타데이터를 렌더 앞으로 옮겨 후크를 얹을 수 있게 했다.

  5. 교체성·안전

    STT 엔진 세 개 중 선택, 고유명사를 잡아주는 audio_hint, 재실행해도 중복 업로드되지 않는 멱등성, 비용 0으로 개발하는 MOCK 환경변수, 그리고 YAML 설정 기반 카테고리.

발견

모듈을 따로 떼어 두니 실패하고 방향을 바꾸는 속도가 빨랐다. 도구마다 뭘 잘하는지 파악하고 나면, 엮는 일 자체는 어렵지 않았다.

어디서 멈췄나 — 무엇을 만들지 않을지

다음 단계는 자연스레 '풀 에디터'(자막 편집·음악·트림·효과)로 보였다. 하지만 그건 캡컷의 영역 — 자동 자막·라이선스 음원·즉각 프리뷰를 갖춘 성숙한 무료 도구다. 더 느리고 빈약한 캡컷을 만드는 건 잘못된 투자다. 그래서 의도적으로 'AI 오케스트레이션 탐구'로 스코핑했다 — 자동 초안(자막·메타·훅) + 검수·발행 플로우, 수작업 편집은 캡컷에 맡긴다. 가장 쓸모 있는 발견은 마지막에 왔다: 자동화를 깊이 판 끝에, 가장 강한 결정은 '에디터를 재발명하지 않는 것'이었다. AI가 강한 곳(초안·메타·배치·발행)과 아닌 곳(손으로 하는 craft)을 가르는 것 — 그리고 언제 멈출지 아는 것 — 이 엔지니어링의 일부다.

$

근거 · 깃·위키 인용

  • 위키 · ADR 0001/0003 · content-autopilot-wiki/decisions
  • 위키 · hyperframe/whisper · content-autopilot-wiki/concepts
  • 위키 · 자막 엔진 비교 · content-autopilot-wiki/concepts/caption-engine-comparison
  • 스크립트 · STT 벤치 + 비전 테스트 · content-autopilot/scripts/stt_bench.py · vision_caption_test.py
  • 커밋 936b451 · 560578d · git:936b451,560578d