
매일 아침 6시, AI가 알아서 뉴스 프로그램을 만들어 YouTube에 업로드하는 시스템을 구축했다
요약
Claude Code를 활용하여 매일 아침 AI가 뉴스 대본 작성부터 영상 제작, YouTube 업로드까지 전 과정을 자동화하는 파이프라인 구축 사례를 소개합니다. Manifest 방식을 도입하여 각 단계의 상태를 관리하고 오류 발생 시 특정 단계부터 재개할 수 있는 안정적인 아키텍처를 구현했습니다.
핵심 포인트
- Claude Code를 활용한 개발 프로세스 효율화
- Manifest 기반의 단계별 상태 관리 및 재개 기능 구현
- AI 에이전트를 통한 대본 작성 및 슬라이드 형식 자동 결정
- 뉴스 수집부터 YouTube 업로드까지의 엔드투엔드 자동화
서론
"Unity 상의 가상 뉴스 스튜디오에서 아바타가 해설하는 영상을 만들어서, YouTube에 업로드하는 것까지 전부 자동화하고 싶다"
그런 야망을 품고 프로젝트 폴더를 만든 것이 몇 달 전입니다. "좋은 시점에 좌절할 것 같지만(웃음)"이라고 README에 적어두었었는데, 좌절하기는커녕 지금은 매일 아침 6시 15분이 되면 제가 자는 동안 AI가 뉴스 프로그램 1편을 완성하여 YouTube에 (비공개로) 업로드하고, Telegram으로 "다 만들었어"라고 알림을 보내주는 생활이 되었습니다.
제가 하는 일은 아침에 일어나 영상을 확인하고, Telegram에서 /kokai라고 입력하는 것뿐입니다. 그러면 영상이 공개됩니다.
이 기사에서는 이 전자동 AI 뉴스 프로그램 파이프라인(통칭 yabou02)의 구조와, 만드는 과정에서 겪었던 시행착오(지뢰)를 소개합니다. 개발은 거의 대부분 Claude Code와의 대화를 통해 진행했습니다.
매일 아침 완성되는 것
먼저 실물을 보시죠. 이것이 오늘 아침, 제가 자는 동안 전자동으로 생성 및 업로드된 영상입니다 (제목, 썸네일, 설명란, 태그도 모두 AI가 설정한 것입니다).
- 약 10분의 뉴스 해설 영상 (1080p/30fps)
- 그날의 AI 테크 뉴스 중 요일별 테마에 맞춘 5편 내외 + 심층 해설
- 목소리 클로닝 (Voice Cloning)을 통한 자연스러운 나레이션
- 내용과 연동된 AI 생성 배경 + 도표(표, 그래프, 플로우차트)가 포함된 슬라이드
- 입 모양(Lip-sync), 눈깜빡임, 포즈 전환을 하는 아바타 캐스터
- 뉴스에 동기화된 자막, 슬라이드 전환, 효과음
- AI 생성 썸네일, 제목 안 2개, 타임스탬프가 포함된 설명란
전체 아키텍처 (Architecture)
파이프라인은 7개의 스테이지로 구성되어 있습니다.
설계에서 가장 신경 쓴 부분은 manifest 방식입니다. 각 스테이지는 manifest.json에 결과(생성물 경로, 실측값, 통계)를 기록하며, 다음 스테이지는 manifest만을 보고 동작합니다.
{
"stages": {"script": "done", "tts": "done", "render": "running", ...},
"tts": {"audio_path": "...", "duration_sec": 813.2, "chunks_failed": 0},
...
}
이전 프로젝트(yabou01)에서는 "최신 파일을 glob으로 가져오는" 방식을 사용했는데, 이는 실패한 잔해를 가져와 오래된 음성으로 영상을 만드는 사고가 발생할 수 있는 구조였습니다. manifest 방식을 도입한 후에는 어느 스테이지에서부터라도 재개할 수 있다(--from-stage render)는 점이 최대의 장점입니다. 후술할 "PC가 열기로 인해 꺼진 사건"에서도 이 방식 덕분에 살 수 있었습니다.
대본은 "구성 작가 AI"가 2단계로 작성
뉴스 수집은 Brave Search API, 대본 생성은 Claude (Agent SDK)를 사용합니다. 이 부분은 매일 아침 별도의 작업(Job)으로 동작하며, 영상 파이프라인과는 공통 모듈로 공유됩니다.
흥미로운 점은 2단계인 **구성 작가 패스 (Writer Pass)**입니다. 완성된 대본을 다시 한번 Claude에게 전달하여, 프로그램 디렉터로서 메타 콘텐츠를 만들게 합니다.
- YouTube 제목 안 2개 (캐치한 버전과 검색 키워드 버전)
- 설명란 (인사 + 요약 + 타임스탬프 + 해시태그)
- 썸네일 이미지 생성 지시
- 슬라이드별 최적의 표현 형식 선택
마지막 항목이 이번에 가장 마음에 드는 부분인데, 구성 작가 AI가 뉴스 내용을 보고 "이것은 수치가 임팩트가 있으니 큰 숫자 타일", "이것은 절차에 관한 이야기이니 플로우차트", "이것은 비교니까 표"와 같이 슬라이드의 형식을 선택합니다.
{"type": "stats", "stats": [{"value": "4배", "label": "공격 속도"}, ...]}
{"type": "flow", "steps": ["OSS에 트릭 삽입", "AI가 검사 실행", "멀웨어 기동"]}
{"type": "bars", "bars": [{"label": "한국", "value": 88, "display": "88조 엔"}]}
그리기 자체는 Pillow를 사용하며, 네온 사이버펑크 스타일의 디자인 시스템 (팔레트, 글로우 글자, 그래디언트 배경)을 하나의 모듈로 집약해 두었습니다.
음성: VOICEVOX에서 목소리 클로닝으로
처음에는 VOICEVOX CORE를 사용했습니다. 무료이며 로컬에서 동작하여 훌륭하지만, 뉴스 프로그램으로서 매일 듣다 보면 아무래도 기계적인 낭독 느낌이 납니다.
그래서 Irodori-TTS(Flow Matching 기반의 일본어 TTS, MIT 라이선스)로 교체했습니다. **10초의 레퍼런스 음성으로부터 제로샷 음성 클로닝 (Zero-shot Voice Cloning)**이 가능하기 때문에, VOICEVOX의 목소리를 레퍼런스로 삼아 "음질은 그대로 유지하면서 운율(Prosody)만 자연스럽게" 만드는 전환을 할 수 있었던 것이 핵심입니다.
대가로 속도를 포기했습니다. GPU가 없는 환경(WSL2)에서는 CPU 추론이 되어, 10분 분량의 영상 음성 합성(Speech Synthesis)에 약 50분이 소요됩니다. 아침 6시 15분에 시작하여 7시 30분에 완성되는 스케줄 안에 들어오므로, 실용상으로는 문제가 없습니다.
영어 단어 문제
일본어 TTS의 고질적인 고민은 영어 단어입니다. "Midjourney"를 사전 없이 읽게 하면 "엠아이디..."라며 한 글자씩 읽어버리는 비극이 발생합니다.
대책으로서, 미지의 영어 단어만을 Claude에게 물어보고 카타카나 읽기를 영구적으로 캐싱하는 학습 사전을 만들었습니다. 매일 아침의 대본에서 미지의 단어를 추출 $\rightarrow$ Claude에게 일괄적으로 읽기 방식을 질문 $\rightarrow$ english_kana.json에 저장. 같은 단어는 두 번 다시 묻지 않으므로, 사전이 나날이 성장해 나갑니다. 운용 며칠 만에 "Suno $\rightarrow$ 스노", "Midjourney $\rightarrow$ 미드저니" 등 100개 이상의 단어가 축적되었습니다.
영상: ffmpeg 한 방 렌더링
동영상 편집 소프트웨어는 사용하지 않고, ffmpeg의 filter_complex를 하나로 구성하여 한 번에 렌더링합니다.
- 슬라이드 PNG는 1프레임만 입력하여
zoompan의d=프레임 수로 프레임 복제(매 프레임 디코딩하지 않도록 하여 가속화) - Ken Burns 효과(천천히 줌),xfade로 크로스페이드(Crossfade) - 진행 바는overlay의 t 식을 사용하여 그라데이션 이미지를 슬라이드 - 입 모양 아바타는 투명 PNG를 concat demuxer로 입력하여overlay
10분 분량의 영상 렌더링이 약 4분 만에 끝납니다. 필터 그래프(Filter Graph) 구축은 순수 함수(Pure Function)로 분리해 두었으며, xfade의 offset 계산(트랜지션 분량을 연장 생성하여 총 길이를 보존하는 작업)은 유닛 테스트(Unit Test)로 검증하고 있습니다.
동기화 메커니즘
자막, 슬라이드 전환, 효과음, 아바타의 포즈 전환은 모두 TTS의 실측 타이밍에 동기화되어 있습니다. TTS는 대본을 문장 단위의 청크(Chunk)로 분할하여 합성하므로, 각 청크의 음성 길이를 기록하면 "이 문장은 영상의 몇 초부터 몇 초까지"인지 정확히 알 수 있습니다. 청크에 "어느 슬라이드에 속하는 문장인가"라는 태그를 붙여두면, 나레이션이 다음 주제로 넘어가는 순간에 슬라이드가 전환되는 방식입니다. 영상 설명란의 타임스탬프도 이 실측값으로부터 자동 생성합니다.
아바타: HeyGen을 포기하고 선택한 "윳쿠리 방식"
아바타는 당초 HeyGen과 같은 AI 아바타 서비스를 검토했으나, API는 종량제 과금이라 매일 10분 분량의 영상을 만들면 월 수백 달러가 들 판이었습니다. 대신 채택한 것이 일본 YouTube에서 친숙한 윳쿠리 실황 (Yukkuri Jikkyou) 방식입니다.
- 캐릭터 스탠딩 일러스트(1장)를 준비
- 이미지 생성 AI(Gemini의 nanobanana)로 "입 벌림", "눈 깜빡임", "손가락 가리키기", "팔짱 끼기", "인사" 등의 차분(Difference) 이미지를 생성
- 입이나 눈의 국소 영역만을 템플릿 매칭(Template Matching)으로 잘라내어 베이스 이미지에 합성(전신을 교체하면 화면이 떨리기 때문) - 나레이션의 음량 엔벨로프(Envelope)로 입 모양 타임라인을 생성
- 포즈는 슬라이드 진행에 연동(주제 시작 시 손가락 가리키기, 심층 분석 시 팔짱 끼기, 엔딩 시 인사)
런타임 비용은 제로입니다. 포즈 간의 전환은 디졸브(Dissolve) 3프레임을 모션 블러(Motion Blur)로 끼워 넣고 있습니다(이미지 생성 AI에게 "중간 포즈"를 그리게 하는 실험도 해보았으나, 확산 모델(Diffusion Model)은 "움직임의 중간 단계"를 잘 그리지 못해 채택하지 않았습니다).
운용 중 밟았던 지뢰들
완전 자동 시스템은 "만들어서 끝"이 아니라, 사람 없이 매일 아침 계속 돌아가는 것이 본게임입니다. 밟았던 지뢰들을 추모합니다.
지뢰 1: WSL2의 IPv6
YouTube 업로드가 알 수 없는 연결 타임아웃으로 실패했습니다. 원인은 WSL2의 IPv6 경로가 죽어 있어서, Python이 IPv6를 먼저 시도하다가 연결 타임아웃이 발생하는 것이었습니다. getaddrinfo를 IPv4 우선으로 정렬하는 패치로 해결했습니다.
지뢰 2: OAuth 토큰 만료와 input() 행(Hang)
YouTube API의 리프레시 토큰(Refresh Token)이 만료되었을 때, 폴백(Fallback) 재인증 흐름이 input()
인증 코드를 기다리는 구현으로 되어 있었습니다. cron 실행 시에는 stdin(표준 입력)이 없기 때문에, 타임아웃인 90분 동안 그냥 행(Hang) 상태로 머무는 최악의 방식으로 종료됩니다. 비대화형 실행을 감지하여 즉시 실패 처리하고, Telegram으로 재인증 절차를 알리도록 변경했습니다.
지뢰 3: PC가 열 때문에 꺼짐
어느 날 아침, 영상 생성 도중에 PC 전원이 통째로 꺼져 있었습니다. 범인은 TTS의 CPU 추론이었으며, 24코어를 계속 풀 가동(Full Load)시킨 결과 발생한 열 정지(Thermal Shutdown, i9-12900K)였습니다. 대책은 3단계로 준비했습니다.
- 스레드 제한 + 낮은 우선순위: torch를 6스레드로 제한 (CPU 사용률 726% → 148%)
- 온도 가드 (Temperature Guard): Windows 측에 LibreHardwareMonitor를 실행하여, WSL에서 HTTP를 통해 CPU 온도를 가져옴. 88°C를 초과하면 합성을 일시 중지하고 냉각 대기
- 재개 (Resume): 이미 합성된 청크(Chunk)의 WAV 파일을 재사용하여 중간부터 다시 시작
참고로 WSL2에서는 호스트의 온도 센서를 읽을 수 없기 때문에, 온도 취득은 Windows 측 도구의 Web 서버를 경유하는 방법이 유일한 선택지입니다.
지뢰 4: 알림이 사라지면 영상이 "존재하지 않게" 된다
완성 알림은 Telegram에 의존하고 있지만, Telegram API는 가끔 Bad Gateway를 반환합니다. 알림이 사라지면, 비공개 상태로 아무도 모르는 영상이 남게 됩니다. 지수 백오프(Exponential Backoff) 재시도에 더해, "private 상태로 남아 있는 영상"을 YouTube API로 조회하는 Telegram 명령어를 안전망으로 준비했습니다.
비용
| 항목 | 월간 |
|---|---|
| 뉴스 수집 (Brave Search API) | 무료 범위 |
| ... | 합계 |
| 약 1,500엔 + 전기세 |
HeyGen 등으로 아바타 영상을 외주 맡겼다면 월 수만~십수만 엔 코스였겠지만, "로컬에서 할 수 있는 것은 로컬에서, AI에게 맡기는 것은 판단과 생성뿐"이라는 구성이 효과를 발휘하고 있습니다.
요약
- 매일 아침 10분의 뉴스 프로그램이 완전 자동 생성되며, 인간은 공개 버튼만 누르면 됨
- 파이프라인은 manifest 방식으로 스테이지를 분할하여 어디서든 재개 가능
- TTS 실측 타이밍에 모든 것(자막, 슬라이드, 효과음, 아바타)을 동기화
- 무인 운영의 핵심은 "에러 처리, 폴백(Fallback), 열 대책"
그리고 개인적으로 가장 컸던 배움은, 이 정도 규모의 시스템(Python으로 수천 줄 + 테스트 60건 가까이)을 거의 전부 Claude Code와의 대화만으로 만들어 버렸다는 점입니다. 제가 한 것은 방향성 판단과 "이 부분을 조금 더 이렇게 해줘"라는 피드백뿐이었습니다. 설계 상담부터 심야의 버그 수정, 열 충돌(Thermal Crash)로부터의 복구까지, 마치 옆에 개발자가 앉아 있는 듯한 느낌이었습니다.
야망은 좌절되지 않았습니다. 다음은 이 프로그램의 시청자를 늘릴 차례입니다.
(이 기사에서 소개한 시스템이 매일 아침 만들고 있는 영상은, YouTube의 아크로파파 AI 테크 뉴스(@acropapa330)에서 공개하고 있습니다. 오늘의 영상은 위에 삽입된 이 링크 →
)Discussion

AI 자동 생성 콘텐츠
본 콘텐츠는 Zenn AI의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기