Vanilla JavaScript를 사용하여 결정론적인 AI 비디오 브리프 생성기 구축하기
요약
생성형 비디오 모델의 불안정한 프롬프트 입력을 해결하기 위해 Vanilla JavaScript를 사용하여 결정론적인 비디오 브리프 생성기를 구축하는 방법을 설명합니다. 창의적 결정과 프롬프트 변환 과정을 분리하여 데이터의 일관성을 유지하는 워크플로우를 제안합니다.
핵심 포인트
- 창의적 방향 결정과 프롬프트 변환 과정을 분리하여 작업 효율성 증대
- 입력값을 데이터 객체로 모델링하여 단일 진실 공급원(Source of Truth) 확보
- 정규화 도구를 통해 프롬프트의 일관성과 가독성 유지
- 결정론적(Deterministic) 방식을 통해 동일 입력에 대한 동일 출력 보장
생성형 비디오 모델(Generative video models)은 빠르게 발전하고 있지만, 놀라울 정도로 평범한 문제 하나가 여전히 많은 시간을 낭비하게 만듭니다. 바로 누군가 브리프(brief)를 다시 작성할 때마다 입력 내용이 매번 바뀐다는 점입니다.
어떤 프롬프트(prompt)에는 렌즈와 조명이 포함되어 있지만, 다음 프롬프트에서는 종횡비(aspect ratio)를 잊어버립니다. 이후의 수정 버전에서는 주인공 제품이 세라믹에서 유리로 바뀌기도 합니다. 모델은 능력이 있을지 모르지만, 제작 입력값(production input)이 불안정합니다.
반복 가능한 작업을 위해서는 두 가지 작업을 분리하는 것이 도움이 됩니다:
- 크리에이티브 방향(creative direction)을 무엇으로 할지 결정하는 것;
- 그 결정을 프롬프트와 스토리보드(storyboard)로 변환하는 것.
첫 번째 작업은 창의적인 영역입니다. 두 번째 작업은 결정론적(deterministic)일 수 있습니다.
이 튜토리얼에서는 구조화된 양식을 다음과 같이 변환하는 작은 브라우저 앱을 구축할 것입니다:
- 마스터 이미지 또는 비디오 프롬프트;
- 연속성 제약 조건(continuity constraints);
- 3~6컷의 스토리보드;
- 나머지 제작 워크플로우(production workflow)를 위한 다운로드 가능한 JSON.
이 앱은 프레임워크(framework), 빌드 단계(build step), AI API를 전혀 사용하지 않습니다.
브리프를 데이터로 모델링하기
생성 세션 동안 안정적으로 유지되어야 하는 정보부터 시작합니다:
const brief = {
projectType: "video",
subject: "a matte ceramic skincare bottle on a mirrored plinth",
...
이 객체(object)는 단순히 양식 값을 정리하는 것 이상의 역할을 합니다. 이는 모든 다운스트림 함수(downstream function)에 동일한 단일 진실 공급원(source of truth)을 제공합니다.
프롬프트를 구성하기 전에 입력값 정규화하기
양식 입력값에는 종종 의도치 않은 줄 바꿈이나 반복된 공백이 포함됩니다. 작은 정규화 도구(normalizer)가 출력물을 읽기 쉽게 유지해 줍니다:
const clean = (value) =>
String(value || "")
.trim()
...
다음으로, 선택적 필드(optional fields)를 라벨이 붙은 문장으로 변환합니다:
const sentence = (label, value) => {
const normalized = clean(value);
return normalized ? `${label}: ${normalized}.` : "";
...
이제 프롬프트 빌더(prompt builder)는 반복적이지 않으면서도 명시적으로 작성할 수 있습니다:
function buildPrompt(input) {
const subject = clean(input.subject);
if (!subject) {
...
결과는 결정론적 (deterministic)입니다. 즉, 동일한 입력은 동일한 출력을 생성합니다. 이는 모델을 비교하거나 샷 (shot)을 재생성할 때 유용한데, 브리프 (brief)가 더 이상 변하는 변수가 아니기 때문입니다.
연속성 (continuity)을 일급 객체 (first-class object)로 취급하기
스토리보드 (storyboard)는 전역 제약 조건 (global constraints)이 개별 샷과 분리되어 저장될 때 더 유용합니다.
function buildStoryboard(input) {
const requestedCount = Number.parseInt(input.shotCount, 10);
const shotCount = Math.min(
...
여기에는 두 가지 의도적인 제한이 있습니다:
- 최소 3개의 샷: 출력이 시작, 전개, 결말을 갖도록 합니다.
- 최대 6개의 샷: 단순한 컨셉이 감당할 수 없는 제작 규모로 커지는 것을 방지합니다.
이 숫자들은 보편적인 것은 아닙니다. 중요한 부분은 규칙을 가시화하고 테스트 가능하게 만드는 것입니다.
브라우저에서 JSON 내보내기
브라우저는 서버 없이도 다운로드 가능한 파일을 생성할 수 있습니다:
function downloadStoryboard(storyboard) {
const blob = new Blob([JSON.stringify(storyboard, null, 2)], {
type: "application/json"
...
해당 JSON은 프로젝트와 함께 저장하거나, 풀 리퀘스트 (pull request)에서 검토하거나, 나중에 다른 도구를 위해 변환할 수 있습니다.
불일치가 문제가 되는 곳에 작은 테스트 추가하기
프롬프트 (prompt)의 모든 단어에 대해 스냅샷 테스트 (snapshot tests)를 할 필요는 없습니다. 중요한 규칙들을 테스트하세요:
import assert from "node:assert/strict";
import test from "node:test";
...
이 정도 규모의 프로젝트에는 내장된 Node 테스트 러너 (test runner)만으로도 충분합니다.
생성 도구의 역할
이 스타터 (starter)는 이미지나 비디오 모델을 대체하는 것이 아닙니다. 모델을 위한 안정적인 지침 세트 (instruction set)를 준비하는 역할을 합니다.
실제적인 워크플로 (workflow)는 다음과 같습니다:
- 로컬 앱에서 브리프 (brief)에 합의합니다.
- JSON을 프로젝트와 함께 저장합니다.
- 첫 번째 생성을 위해 마스터 프롬프트 (master prompt)를 사용합니다.
- 연속성 객체 (continuity object)를 유지하면서 개별 샷을 생성합니다.
- 결과를 비교할 때는 한 번에 하나의 변수만 변경합니다.
통합된 생성 워크스페이스를 원한다면, 완성된 브리프를 Vynyo AI Video Generator와 함께 사용할 수 있습니다.
Repository
의존성 없는 완전한 스타터(starter), 테스트, 그리고 Replit 설정은 공개된 Vynyo Creative Brief Starter repository에서 확인할 수 있습니다.
더 큰 교훈은 간단합니다: 더 나은 생성(generation)이 항상 더 복잡한 프롬프트(prompt)에서 시작되는 것은 아닙니다. 그것은 종종 일관되게 유지되는 더 작은 결정(decision)들의 집합에서 시작됩니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기