GitHub - chessire/shelter-puppy
Contribute to chessire/shelter-puppy development by creating an account on GitHub.
github.com
요청이 짧다고 영상까지 짧아지면 안 됩니다.
빈칸은 LLM의 저작으로 채우고,
채워진 칸은 아무도 건드리지 않습니다.
우선 작업 결과부터 보고가겠습니다.
프롬프트
우리 토리 소개 영상 만들어줘
(애견카페 장면을 집에서 쉬는 장면으로 오해한 할루시네이션이 포함됨)
프롬프트
우리 토리 소개 영상 만들어줘 뛰어노는 모습 좀 나오다가 산책하고 밤에도 달리고 마지막에 하이파이브로 끝나면 딱이겠다
'소개 영상 만들어줘' 한 줄이면 알아서 잘 나와야 하는 것 아냐?
이번 함정은 파이프라인이 아니라 요청 쪽에 있었습니다. 한 줄 요청에는 구조 정보가 없습니다. 몇 블록으로, 어떤 순서로, 자막은 뭐라고, 아무것도 없죠. 지난 편까지의 파이프라인은 이 요청에 성실하게 답했습니다. 기본값 블록 하나, 소스당 한 컷씩 26초. 하지만 "소개 영상 만들어줘"라는 요청에는 소개 영상이 아니라 영상의 나열이 나왔습니다. 번역할 문장이 없으면 번역기는 구성을 못 합니다.
유저가 정하지 않은 것만 LLM이 저작하고,
유저가 정한 것은 LLM이 마음대로 건드리지 않는다.
잠시 배경 하나를 설명드리면 지난 편 이후 남았던 수동 단계 둘은 자동화로 풀었습니다. 영상마다 기계가 "무엇이 찍혔는지" 적어두는 관찰 프로필, 그리고 강아지 사진 몇 장으로 여러 마리 중 주인공을 확정하는 프레임 앵커. 덕분에 영상과 사진만 넣으면 결과가 나옵니다. 이번 편은 고정 형태의 파이프라인을 잘 만드는 파이프라인으로 다듬은 기록입니다. 한 줄 요청을 구성으로 바꾸는 저작 모드. 요청 디테일 천차만별에 대응하는 소유권 원칙. 그리고 실사용이 낸 숙제들. 결론부터 말하면 이번 구간에서 같은 문제를 네 번 고치고 나서야 규칙 하나를 얻었습니다. 프롬프트에는 지시만 적는다. 내용은 금지.

12. 한 줄 요청을 구성으로 - 저작 모드
편집의 구조가 요청에 없다면 어떻게 만들어야 할까요. 소재와 목적. 무엇이 찍혀 있는지(관찰 프로필)와 무엇을 원하는지(요청의 느낌)를 알면 구성은 만들 수 있습니다. 그래서 번역기 앞에 LLM을 다시 세웠습니다. 간단한 요청이 들어오면 LLM이 요청 원문과 영상별 관찰 프로필, 그리고 소재 길이를 보고 블록을 직접 구성합니다. 어떤 영상을 어떤 순서로, 몇 초씩, 자막은 뭐라고 할지 말이죠.
소재 길이를 입력에 넣은 건 실측 때문입니다. 길이를 모르는 LLM의 저작은 2.3초짜리 영상을 인트로와 엔딩 두 블록에 배치하는 실수를 했습니다. LLM에게도 재료의 속성은 알려줘야 합니다.
재미있는 결정 하나가 있습니다. LLM의 저작은 이 파이프라인 전체에서 유일하게 의도된 비결정입니다. 지금까지 "같은 입력 = 같은 출력"을 그렇게 지켜놓았지만 저작은 정답이 없는 주관 축이기 때문입니다. 같은 요청에서 매번 다른 구성이 나와도 되고, 마음에 안 들면 다시 뽑으면 됩니다(빠른 재추첨 옵션 추가). 결정론은 정답이 있는 곳의 규칙이지, 창작을 막으면 안되니까요.
다만 창작에도 결정론은 붙습니다. 작가가 지어낸 소재 이름은 실제 목록과 대조해 환각을 제거하고, 블록 길이와 개수는 Clamp하고, 배속은 [요청이 명시한 경우만]이라는 가드를 유지합니다. 실측 샘플로 "문틈 사이로 빼꼼! 우리 토리 등장!" 같은 자막이 나왔는데, 해당 영상의 관찰 프로필에 실제로 문틈 장면이 기록돼 있었습니다. 창작이되, 근거 있는 창작입니다.
13. 소유권은 이진, 빈칸은 Gradient - 요청 디테일 대응
실제 요청은 한 줄만 오지 않습니다. "소개 영상 만들어줘"부터, "뛰어노는 모습 나오다가 산책하고 밤에 달리고 하이파이브로 끝" 같은 스케치, 블록별 초와 자막까지 박은 풀 스펙까지. 디테일이 천차만별입니다. 처음엔 [요청이 얼마나 구조적인가]를 점수로 재려 했습니다. 잘못된 접근이었습니다. 구조는 결국 하나로 귀결돼야 합니다. 유저가 뼈대를 줬으면 구조는 유저 것이고, 안 줬으면 LLM이 저작합니다. Gradient인 건 구조가 아니라 빈 필드의 수입니다.
| 요청 | 수준 | 결과 |
| "소개 영상 만들어줘" | 전체 저작 | 작가가 구성 창작 (4~5블록) |
| "뛰어놀다가 → 산책 → 밤 달리기 → 하이파이브 엔딩" | 부분 저작 | 유저 4박자 보존 + 빈칸(자막·초·소재)만 채움 |
| 블록별 스펙 완비 | 저작 0호출 | 빈칸 없음 → 작가 미출동 |
병합은 결정론입니다. LLM의 저작에서 유저가 명시한 필드는 아예 읽지 않습니다. "덮어쓰지 않도록 주의한다"가 아니라 읽는 코드 자체가 없는 구조적 불변입니다. 대본 스킵, 복창 사고와 같은 문제들이 재발하지 않도록 원천 차단한 겁니다.
텍스트는 한 단계 더 엄격합니다. 요청에 자막 지시가 하나라도 있으면 자막은 통째로 유저의 소유입니다. LLM은 빈 블록의 자막조차 채우지 않습니다. 절반의 자막을 유저가 썼는데 나머지 절반을 LLM이 채우면 유저의 의도가 사라질 수 있습니다. 덤으로 잠재돼있던 버그도 하나 잡았습니다. [자막 없이]라는 요청에 [자막]이라는 단어가 포함돼 있어서 오히려 자막을 채우던 것입니다. 부정 표현이 긍정 표현보다 우선한다는 원칙으로 수정했습니다.
14. 프롬프트에는 지시만 - 같은 문제만 네 번
이번 구간에서 제일 어려웠던 문제였습니다. 자막에 요청 전문을 그대로 발화하는 사고가 났습니다("…만들어줘"까지 통째로). 1차 수정은 결정론으로 필터링 했습니다. 출력에서 요청 문자열을 지우는 필터였습니다. 그런데 이건 단순히 표면적으로 문제를 지웠습니다. 실질적 문제는 프롬프트에 있었는데 말입니다. "요청의 말투를 그대로 살려서"라는 지시가 사실상 인용의 원인이었던 겁니다. 프롬프트를 "요청은 지시문이고, 자막은 시청자에게 말하는 새 문장"으로 고치자 4회 배터리에서 복창 0건(수정 전 2/4)으로 수정되었습니다.
같은 문제가 또 발생했습니다. 요청에 없는 캠페인성 문구가 자막에 붙어 나왔는데 추적해 보니 프롬프트에 박아둔 페르소나(~홍보 영상 편집기)가 요청에 없는 목적을 주입하고 있었습니다. 프롬프트 6곳을 전부 중립적인 "강아지 영상"으로 고쳤습니다. 목적과 톤은 요청에서만 옵니다.
패턴을 정리하면 네 번 모두 같은 문제였습니다. 코드나 프롬프트에 박힌 내용(어휘, 예시 문구, 프레이밍)이 출력으로 샌 것입니다. 그래서 규칙을 정리했습니다. 프롬프트에는 지시만, 내용은 금지. 결정론은 폐기하지 않고 가드로 강등했습니다.
15. 실사용이 낸 숙제들 - 폴리싱과 권한
실사용 데모를 돌리며 자잘한 숙제들이 쏟아졌습니다. 영상이 12.2초로 짧게 나오고(LLM이 길이 필드를 안 적는 습성. 스키마에서 필수로 강제), 0.8초짜리 컷이 화면에서 번쩍하고 지나가고(표시 하한 1.5초 규칙 추가), 제목과 자막이 한 자리에 겹쳐 찍혔습니다. 자막 겹침은 8방위 텍스트 영역 시스템으로 풀었습니다. 상단, 하단, 좌우의 네 구석에 텍스트 자리를 정의하였고, 상단 행은 AI 표시 배지를 침범하지 않게 그 아래에서 시작하며, 긴 자막은 자동 개행합니다. 위치와 표시 타이밍도 소유권 원칙 그대로 유지했습니다. 유저가 명시하면("왼쪽 아래에 자막") 번역기가 받아 적고, 아니면 LLM의 연출 재량입니다.
인프라 쪽에서는 무서운 버그를 하나 잡았습니다. 전처리 산출물이 깨졌을 때 파일이 존재한다는 이유로 재사용되면서 깨진 캐시가 계속 사용되는 버그였습니다. 영상 하나의 분석이 통째로 증발했습니다. 재사용 조건에 내용 검증을 추가했습니다. TTS에서도 하나, 첫 구절 앞에 "흠" 하는 발성이 붙은 걸 Whisper 왕복과 파형으로 문제를 파악하고 해당 구절만 재합성해 지웠습니다.
마지막이 이번 편의 하이라이트입니다. 사진으로 지정한 주인공이 안 나오는 장면이 렌더에 들어왔습니다. 고양이만 걸어다니는 복도 컷이었죠. 문제를 추적하니 LLM이 소스를 직접 지정하면서 시스템이 이를 확실한 선택으로 취급해 Uncertain 구간임에도 영상으로 들어왔습니다. LLM의 선택은 영상 단위일 뿐인데 그것이 주인공이 없는 구간을 선택해버렸습니다. Uncertain 구간이 영상 단위 선택을 타고 그대로 들어온 겁니다.
수정은 권한의 분리였습니다. 유저의 프롬프트는 "그 장면을 원한다"는 보증이라 Uncertain 면제 + 소스 예약을 다 받지만, LLM의 지정은 "그 영상이 어울릴 것 같다"는 판단일 뿐이라 예약만 받았습니다. 여기에 프레임 앵커에 있는 확정된 주인공 박스로 실제 존재하는 구간인지 교차해서 클립을 뽑게 했습니다. 재렌더에서 고양이 컷은 사라졌고 모든 클립에 주인공이 있는 걸 프레임 단위로 확인했습니다.
맺음말
여기까지로 파이프라인이 나오는 것을 넘어 만드는 쪽까지 넘어왔습니다.
- 저작 모드는 한 줄 요청에서 소재와 목적을 근거로 구성을 창작하고(파이프라인 유일의 의도된 비결정),
- 소유권 원칙은 구조를 하나로 귀결시켜 유저가 정한 필드는 LLM의 저작이 아예 간섭하지 못하게 하고,
- 프롬프트는 같은 문제 네 번 끝에 [지시만, 내용 금지]로 확립하고,
- 권한 분리는 유저의 보증과 LLM 저작의 보증에 다른 크기의 권한을 줬습니다.
시리즈의 문장들이 이번 편에서 하나 더 늘었습니다. 정답지로 채점하고, 측정할 수 있는 건 측정에게 맡기고, 소리도 채점하고. 이것에 더해 이번엔 하나의 구조로 귀결시켜라. 구조든 텍스트든 권한이든 구조가 나뉘어지니 문제가 많아졌습니다.
남은 것은 저작 품질의 평가입니다. 구성이 좋은지는 골든셋으로 채점할 수 없는 주관 축이라, 지금은 재추첨 복권이 UX의 전부입니다. 저작 결과를 고객이 미리 보고 고르는 카드 UI, 그리고 이 파이프라인을 제품으로 감싸는 일. 다음 편에서 이어가겠습니다.
이 글에서 다룬 고정 함수 분류층은 ProjectDavid의 일부입니다.
전체를 바닥부터 만드는 과정은 강의 3부작으로 정리하고 있고, 10월에 오픈 예정입니다.
→ 오픈 알림 받기
다음글
스레드보다 자원: Mac GPU(MPS)로 3.5배 빠르게 - Resource First AI
GitHub - chessire/shelter-puppyContribute to chessire/shelter-puppy development by creating an account on GitHub.github.com파이프라인을 빠르게 만드는 첫 질문은"스레드를 몇 개 띄울까?"가 아니라"어떤 자원이 어디서 놀고
chessire.tistory.com
이전글
로컬 TTS(mlx-audio)로 영상 타임라인 컨트롤 - Narration First AI
GitHub - chessire/shelter-puppyContribute to chessire/shelter-puppy development by creating an account on GitHub.github.com목소리를 얹는 순간,화면이 음성에 맞춰 늘어나고,타임라인은 음성이 컨트롤합니다. 우선 작업 결과
chessire.tistory.com
관련글
오픈소스 LLM vs 빅테크 LLM API: AI 사업의 비용과 리스크
모델은 커모디티가 된다.마진은 판단에 남는다. 2025년 2월, OpenAI는 당시 가장 비싼 모델 GPT-4.5를 출시했습니다. 백만 토큰당 입력 75 달러, 출력 150 달러. 그리고 다섯 달이 지나기 전, API에서 제거
chessire.tistory.com
'AI > Pipeline' 카테고리의 다른 글
| 환각을 통제하는 로컬 AI 파이프라인 만들기 (0) | 2026.08.03 |
|---|---|
| 스레드보다 자원: Mac GPU(MPS)로 3.5배 빠르게 - Resource First AI (0) | 2026.07.27 |
| 로컬 TTS(mlx-audio)로 영상 타임라인 컨트롤 - Narration First AI (0) | 2026.07.20 |
| 결정론적 AI 파이프라인 설계 - Deterministic First AI (0) | 2026.07.13 |
| YOLO11 해상도 함정: 골든셋으로 검증 - Measurement First AI (0) | 2026.07.08 |