- 영상 아카이브의 병목은 편집 도구보다 검색 불가능성이었고, 라벨 없는 클립을 영어로 질의 가능한 인덱스로 바꾸는 데 초점을 맞춤
- 로컬 우선 설계로 각 클립 옆에
.description.md사이드카 파일을 만들고, rating·조명·위치·전사·키워드·산문 설명을 한 번의 비전 호출에서 추출함 - 파이프라인은
ffprobe,exiftool, Nominatim,ffmpeg, WhisperX,insightface, 비전 모델을 묶어 메타데이터·GPS·프레임·전사·얼굴 임베딩을 생성함 - 2021년 16인치 MacBook Pro M1 Max 64GB가 LM Studio에서 Gemma 4 31B Q4를 실행했고, 대량 처리 중 스왑은 최고 50.89GB까지 올라감
- 구조화 스키마와 enum 제약은 환각을 줄였고, 대량 색인은 로컬 31B로 처리한 뒤 어려운 10~20%만 클라우드 모델로 재평가하는 구성이 가능했음
문제의 출발점: 편집보다 검색
- Maasai Mara에서 반년 가까이 머무는 동안 iPhone, DJI Pocket, 드론, Nikon Z8, Ray-Ban Meta로 촬영한 영상이 계속 쌓였지만, 대부분 다시 열어보지 못한 채 남아 있었음
- Mara Hilltop의 소셜 채널은 콘텐츠 부족이 아니라 편집 시간 부족 때문에 3개월 동안 멈춰 있었음
- Claude Code와 Opus 4.5/4.6으로 개발 작업은 장시간 에이전트 실행과 병렬 작업이 가능해졌고, KaribuKit의 첫 유료 숙소 출시와 겹치면서 영상 편집 시간은 더 줄어듦
- 처음 떠올린 해법은 Eddie AI, Higgsfield MCP, Submagic, Buffer를 조합한 월 $140 SaaS 스택이었지만, 실제 병목과 맞지 않았음
- 생성형 AI 영상은 실제 여행 브랜드와 맞지 않았고, 투숙객이 실제 장소를 기대하는 상황에서 잘못 표시된 AI 장면은 신뢰를 해칠 수 있었음
- 현실적인 게시 빈도는 주 3~5개가 아니라 주 2~3개에 가까워, 초기 계획은 두 번째 주부터 실패할 가능성이 컸음
- 이미 보유한 DaVinci Resolve Studio와 Resolve 21의 IntelliSearch, Smart Bins, Voice to Subtitle은 Eddie가 제공하는 기능의 약 70%를 커버함
- 남은 구성은 Claude Code가 오픈소스 DaVinci Resolve MCP로 Resolve를 제어하고, 정보성 클립에 한해 ElevenLabs로 보이스오버를 처리하는 구조였으며, 비용은 월 $22로 줄어듦
진짜 병목: AI 편집기보다 먼저 필요한 인덱스
- 시중 AI 영상 편집기는 영상이 이미 라벨링되어 있다고 가정하지만, 실제 아카이브는
IMG_*.mov,DJI_*.mp4,Mara june 2024 backup final FINAL같은 이름으로 흩어져 있었음 - Eddie는 전사 검색은 가능하지만, 라벨 없는 아카이브에서 “황금빛 시간대 언덕 위 코끼리” 같은 장면을 찾을 수 없었음
- 파일명, 부모 폴더, GPS 좌표, 전사 텍스트만으로는 “프레임 안에 기린이 있는 일출 와이드샷” 같은 시각적 내용을 알 수 없음
- 실제 지렛대는 편집기 위가 아니라 그 앞단에 있었고, 먼저 아카이브를 영어로 질의 가능한 형태로 만드는 인덱스가 필요했음
로컬 우선 인덱서 설계
- 전체 구조는 SimbaStack에서 클라이언트용으로 만드는 AI 네이티브 빌드와 비슷했지만, 직접 클라이언트이자 엔지니어였기 때문에 의사결정이 빨랐음
-
네 가지 제약
- 로컬 우선이어야 했음
- Mara Hilltop 아카이브는 물리 SSD에 있고 개인 영상은 노트북에 있었으며, 수천 개의 멀티 GB 클립을 클라우드에 올리는 것은 비용과 프라이버시 양쪽에서 맞지 않았음
- 중앙 DB보다 사이드카 파일을 원했음
- 각 클립 옆에
.description.md를 두고 일반 텍스트로 grep 가능하게 만듦 - 인덱서가 나중에 망가져도 파일은 남고, 드라이브 사이를 이동해도 데이터와 함께 이동함
- 각 클립 옆에
- 비전 호출 한 번에 필요한 정보를 모두 뽑아야 했음
- 추출 프레임에 대한 비전 패스가 비싼 작업이므로, 나중에 알고 싶은 정보까지 첫 호출에서 얻도록 스키마를 처음부터 넓게 잡았음
- 포함 항목은 rating, technical quality, lighting, time of day, color palette, audio quality, people count, keywords, faces, location, transcript, prose description 등이었음
- 세 가지 비전 백엔드를 선택할 수 있게 했음
- 기본값은 Claude Max 구독의 CLI로, 한계 비용이 없었음
- 속도가 필요할 때는 Anthropic API를 사용함
- 대량 처리에는 LM Studio를 향한 로컬 백엔드를 사용했고, 이 로컬 백엔드가 핵심이었음
- 로컬 우선이어야 했음
클립별 처리 파이프라인
ffprobe로 메타데이터를 읽음exiftool로 GPS 위도, 경도, 고도를 읽었고, iPhone, DJI Pocket, 드론 영상에서 동일하게 동작함- Nominatim으로 역지오코딩을 수행했으며, 무료이고 속도 제한이 있고 API 키가 필요 없었음
ffmpeg로 1920px 크기의 프레임 5장을 균등 간격으로 추출함- WhisperX로 단어 단위 정렬과 pyannote 화자 분리를 포함한 전사를 수행했으며, Hindi, English, Swahili 등 97개 언어를 지원함
insightface로 얼굴을 감지하고, 나중에 아카이브 전체에서 인물 검색을 할 수 있도록 512차원 ArcFace 임베딩을 중앙 SQLite 얼굴 DB에 저장함- 비전 모델은 프레임, 전사 일부, 폴더 맥락을 읽고 YAML frontmatter와 산문 설명을 반환함
- 최종 결과는 클립 옆에
.description.md사이드카로 기록됨 - Mara Hilltop의 실제 클립
IMG_1103.MOV는 파일명만으로 맥락을 알 수 없었지만, Gemma가 생성한 사이드카에는 사파리 텐트 설정, 실내에서 사바나로 이어지는 카메라 팬, 샷 타입, 마케팅 릴과 여행 브이로그 B-roll 같은 사용처가 포함됐음 - 폴더 단위로는 각 클립 옆 사이드카뿐 아니라 상단의
_INDEX.json과_INDEX.md가 생성되어 빠른 grep과 LLM 전달에 쓰였음 - 전체 구현은 약 1,400줄 Python으로 된 Claude Code skill이며, Claude Code가 대부분 작성했고 사람의 역할은 아키텍처, 프롬프트, 스키마 설계, 버그 triage였음
오래된 MacBook에서 돌린 로컬 31B 모델
- 2021년에 구입한 16인치 MacBook Pro M1 Max 64GB RAM은 원래 LLM용이 아니라 Chrome 탭, DaVinci Resolve, Slack, Discord, Drive를 동시에 돌리기 위한 선택이었음
- 5년 뒤 같은 노트북이 LM Studio에서 Gemma 4 31B Q4를 띄우고 1년치 영상 아카이브를 처리함
- LM Studio에는 28.40GB 모델이 메모리에 올라갔고, REST API는
127.0.0.1:1234에서 동작함 - 대량 처리 중에는 64GB RAM만으로는 부족해졌고, Activity Monitor 기준 스왑 사용량이 최고 50.89GB까지 올라감
- 이 상태는 평범한 작업일에 계속 유지할 만한 상태는 아니었지만, 주말 동안 강하게 밀어붙이는 수준에서는 허용 범위로 봤음
- 노트북은 뜨거워지고 팬은 크게 돌았지만, 다른 작업을 하는 동안 계속 사이드카를 생성함
- M1 Max 16인치는 5년 된 하드웨어에서도 31B 파라미터 모델을 사용 가능한 속도로 돌릴 여유를 보여줬고, 로컬 LLM이 더 효율적으로 바뀌면 앞으로 3~5년은 더 쓸 수 있을 것으로 봤음
네 가지 버그와 교훈
-
WhisperX 3.8의 화자 분리 API 변경
- WhisperX 3.8에서
whisperx.DiarizationPipeline이whisperx.diarize서브모듈로 이동함 - 생성자 인자
use_auth_token은 pyannote 3.x를 따라token으로 바뀜 - 해결책은 시그니처 introspection이었음
- 스크립트가 먼저
token=을 시도하고, 생성자가TypeError를 내면use_auth_token=으로 폴백함 - 빠르게 바뀌는 AI 라이브러리를 호출할 때는 방어적 생성자 호출이 저렴한 보험이 됨
- WhisperX 3.8에서
-
Claude CLI가 권한 오류를 성공 응답처럼 반환
- CLI 백엔드 첫 테스트에서 4개 사이드카가 모두 “I need permission to read the image frames...”라는 동일한 텍스트로 돌아옴
- exit code가 0이고 출력이 비어 있지 않아 스크립트의 성공 체크를 통과함
- 비대화형 모드에서
--permission-mode bypassPermissions가 없으면 Claude CLI는 프롬프트 대신 권한 거부 텍스트를 응답 본문으로 반환함 - 해결책은 해당 플래그를 추가하고, “I need permission”이 들어간 짧은 응답을 설명이 아니라 오류로 처리하는 방어 체크였음
- AI 도구를 스크립트로 다룰 때 비대화형 권한 흐름에 조용한 실패가 숨어 있음
-
Gemma가
people_count: "many"를 반환- 비전 프롬프트가
integer or the string "many" if >10이라고 지시했기 때문에 Gemma는 지시를 제대로 따른 셈이었음 - 버그는 모델이 아니라 스키마 설계였음
- 수정 후에는 0~99 정수로 추정하라고 명시하고, 기존
"many"응답은 파서에서 강제로 변환함 - 스키마 필드는
int 또는 특정 string처럼 union으로 만들지 말고, 항상 정수 또는 항상 문자열 중 하나로 고정해야 downstream 소비자가 단순해짐
- 비전 프롬프트가
-
손떨림 있는 오토바이 클립이 잘못 폐기됨
- 초기 cull 프롬프트는 사진 포트폴리오 기준에 가까워서 심한 모션 블러, 소프트 포커스, 흔들림을
cull로 평가함 - 스페인 여행 중 찍은 야간 핸드헬드 오토바이 클립도 폐기 대상이 됐지만, 그 흐림 자체가 기억의 분위기였음
- cull 기준을 “완벽하지 않은 촬영”이 아니라 “실제 기록이 아닌 것”으로 바꿈
- 폐기 대상은 렌즈 캡, 주머니 속 영상, 2초짜리 테스트 클립, 완전히 날아간 노출 같은 클립으로 좁힘
- 사진 아카이브는 공격적으로 cull하고, 영상 추억은 관대하게 cull해야 하며, 같은 스키마라도 모드를 명확히 해야 함
- 초기 cull 프롬프트는 사진 포트폴리오 기준에 가까워서 심한 모션 블러, 소프트 포커스, 흔들림을
구조화 스키마와 로컬 모델에서 얻은 결론
-
열거형 제약은 환각을 줄임
- Gemma 4 E4B는 밤에 찍은 coworking-space 사진을 “brightly lit, abundant natural light, floor-to-ceiling windows”라고 묘사했지만, 창밖은 완전히 어두운 밤이었음
- 31B에 구조화된 스키마를 주고
golden_hour | bright_daylight | overcast | dim_interior | nighttime | mixed | unclear중 하나를 고르게 하자, thinking-off와 thinking-on 모두nighttime을 회복함 - 모델은 열린 산문에서는 거짓 설명을 만들 수 있지만, enum에서는 새 값을 발명할 수 없고 잘못 고를 수 있을 뿐임
- 지시보다 스키마가 더 안전했음
-
로컬 31B와 구조화 프롬프트는 클라우드와의 격차를 줄임
- Gemma 4 31B Q4 thinking-off는 구조화된 스키마를 사용할 때 많은 테스트 클립에서 Sonnet 4.6과 구분하기 어려운 출력을 냄
- 클라우드 모델의 프리미엄은 어려운 10~20% 클립에서 가치가 있었음
- 수천 개 클립을 밤새 색인하는 대량 작업은 로컬에서 돌리고, 로컬이
review로 표시한 클립만 클라우드로 재평가하는 2단 구조가 확장 가능했음
-
AI 영상 편집기는 너무 위쪽 레이어에서 경쟁함
- 가치 있는 레이어는 편집기가 아니라 검색 가능한 인덱스였음
- “Mara의 핸드헬드 실내 클립, 황금빛 시간대, 사람이 있고, 8초보다 긴 것”처럼 자연어로 질의할 수 있으면 그 위의 편집기는 단순해짐
- AI 편집기 시장은 존재하지 않는 인덱스 위의 표면 레이어를 두고 경쟁하고 있으며, 전제 조건인 인덱스를 건너뛰고 있음
다음 단계와 한계
- 다음 작업은 Claude Code를 오케스트레이터로 쓰고, DaVinci Resolve MCP로 컷을 만들며, 정보성 클립에는 ElevenLabs 보이스오버를 붙이는 편집기를 만드는 것임
- 보이스 클론에는 명확한 제한이 있음
- 방향 안내, 객실 설명, 다국어 버전, 직접 말할 만한 사실 정보 같은 유틸리티 콘텐츠에만 사용함
- 후기나 창업자 메시지에는 사용하지 않음
- 2026년에는 공개 의무 관련 법이 현실이고, hospitality 브랜드의 신뢰는 쉽게 잃을 수 있음
- 인덱스가 있으면 47GB DJI Pocket 영상에서 일출 와이드샷을 직접 스크러빙하는 일을 피할 수 있음
- 현재 5년 된 노트북에서 Mara Hilltop 1년치 영상은 영어로 질의 가능해졌고, 비용은 주말 시간과 50GB 스왑이었음
- 오래된 SSD들에 남아 있는 나머지 연도들이 다음 처리 대상임
- Mara Hilltop의 소셜 채널은 아직 다시 살아나지 않았음
- 인덱서는 적절한 클립을 찾는 문제만 해결함
- 완성된 릴로 만드는 편집기가 나머지 절반이며, 성공하면 후속 글을 쓰고 실패하면 실패 이유를 다룰 예정임
- 올바른 해답은 사람을 고용하는 것일 수도 있음
- Mara Hilltop에 맞는 따뜻하고 관찰적인 감각을 가진 편집자를 찾는 일이 또 다른 skill을 작성하는 것보다 어려울 수 있음
- 과도하게 잘라낸 MTV식 릴은 원하는 방향이 아님
- 코드는 github.com/Simbastack-hq/framedex에 공개됐고, PR과 이슈를 받고 있음