본문으로 건너뛰기

© 2026 Molayo

Dev.to헤드라인2026. 06. 20. 21:52

TypeScript를 이용한 AI 비디오 작업 큐(Job Queue) 구축하기

요약

TypeScript를 사용하여 AI 비디오 생성 작업을 효율적으로 관리하기 위한 작업 큐(Job Queue) 구조를 제안합니다. 제공업체별 API 차이를 격리하기 위해 어댑터 패턴을 활용하고, 작업 상태 관리 및 검증 단계를 포함한 안정적인 워크플로우 구축 방법을 다룹니다.

핵심 포인트

  • 제공업체 API가 앱 전체로 유출되지 않도록 어댑터 계층 구축
  • 작업 상태(queued, validating 등)를 정의하여 제품 계약 명확화
  • 비용 절감을 위해 작업 제출 전 사전 검증 단계 필수
  • 작업이 무한 대기 상태에 빠지지 않도록 지연(delayed) 상태 및 복구 워커 도입

AI 비디오 생성은 일반적인 HTTP 요청이 아닙니다. 사용자가 프롬프트(prompt), 모델 설정(model settings), 그리고 어쩌면 참조 이미지(reference image)를 제출하지만, 결과가 나오기까지는 몇 분이 걸릴 수 있습니다. 백엔드는 입력을 검증하고, 작업을 생성하며, 이를 제공업체(provider)에 제출하고, 완료 여부를 폴링(poll)하며, 실패를 처리하고, 사용자에게 유용한 상태를 보여주어야 합니다.

이 포스트에서는 AI 비디오 작업 큐(job queue)를 위한 작은 TypeScript 구조를 살펴봅니다. 목표는 한 편의 글로 완전한 프로덕션 시스템을 구축하는 것이 아닙니다. 목표는 제공업체별 API가 앱 전체로 유출되지 않도록 핵심 계약(contracts)을 충분히 명확하게 정의하는 것입니다.

문제점 (The Problem)

기본적인 AI 비디오 워크플로우(workflow)는 최소 6단계를 거칩니다:

  1. 프롬프트 및 모델 설정 검증.
  2. 업로드되었거나 참조된 에셋(assets) 검증.
  3. 내부 작업(job) 레코드 생성.
  4. 제공업체(provider)에 작업 제출.
  5. 출력이 준비되거나 실패할 때까지 폴링(poll).
  6. UI를 위해 결과를 정규화(normalize).

만약 앱이 하나 이상의 모델이나 제공업체를 지원한다면, 백엔드는 각 제공업체가 제품의 나머지 부분을 결정하도록 내버려 두어서는 안 됩니다. 큐(queue)와 어댑터(adapter) 계층은 시스템을 안정적으로 유지하는 데 도움이 됩니다.

작업 정의하기 (Define the Job)

내부 작업 타입(job type)부터 시작합니다:

type JobStatus =
  | "queued"
  | "validating"
...

이 타입은 제품 계약(product contract)입니다. 제공업체별 페이로드(payloads)는 이 타입으로 변환되거나 이 타입으로부터 변환되어야 합니다.

제공업체 어댑터 생성하기 (Create a Provider Adapter)

각 제공업체는 자체적인 어댑터를 가질 수 있지만, 큐(queue)는 하나의 인터페이스(interface)와 통신해야 합니다.

interface VideoProvider {
  submit(job: VideoJob): Promise<{ providerTaskId: string }>;
  poll(providerTaskId: string): Promise<
...

이렇게 하면 제공업체 간의 차이점이 큐 워커(queue worker), 결제 로직(billing logic), 그리고 UI로부터 격리됩니다.

전송 전 검증하기 (Validate Before Dispatch)

비디오 작업은 느리고 비용이 많이 들 수 있습니다. 저렴한 체크를 먼저 수행하세요.

type ValidationResult =
  | { ok: true }
  | { ok: false; code: VideoJobErrorCode; message: string };
...

실제 앱에서는 검증 단계에서 모델 가용성, 업로드 파일 제한, 종횡비(aspect ratio) 지원, 사용자 크레딧(user credits), 그리고 안전 규칙(safety rules)도 확인하게 됩니다.

작업 처리하기 (Process the Job)

다음은 간단한 워커(worker) 함수입니다:

async function processVideoJob(job: VideoJob, provider: VideoProvider) {
  await markStatus(job.id, "validating");

...

중요한 동작은 delayed 상태로의 강제 전환입니다. 작업이 영원히 running 상태로 남아있어서는 안 됩니다. 별도의 복구 워커(recovery worker)가 더 느린 주기로 지연된 작업(delayed jobs)을 계속해서 폴링(polling)할 수 있습니다.

지속성 함수 스텁(Stub) 만들기

위의 워커는 데이터베이스 계층이 있다고 가정합니다. 최소한의 데모를 위해 해당 함수들은 다음과 같이 보일 수 있습니다:

async function markStatus(jobId: string, status: JobStatus) {
  console.log("markStatus", { jobId, status });
}
...

프로덕션 환경에서 이러한 함수들은 영구 저장소(durable storage)를 업데이트해야 하며, 재시도(retry) 시에도 안전해야 합니다.

UI 상태 메시지

UI는 제공업체(provider)의 가공되지 않은 에러를 그대로 노출해서는 안 됩니다. 내부 상태와 정규화된 에러를 명확한 메시지로 매핑해야 합니다:

상태 또는 에러사용자 대상 메시지
queued비디오가 시작되기를 기다리고 있습니다.
...

예측 가능한 상태 메시지는 고객 지원 티켓(support tickets)을 줄이고 실패 상황을 덜 혼란스럽게 만듭니다.

문서화의 중요성

Seedance 스타일의 비디오 API를 사용하는 경우, 지속 시간 제한, 종횡비(aspect ratios), 폴링(polling) 동작, 입력 에셋 요구 사항 및 모더레이션(moderation) 동작을 명확하게 문서화하십시오. LumiYing의 Seedance API 가이드는 이 워크플로우에 필요한 사용자 대상 문서화의 좋은 예시입니다:

https://lumiying.com/resource/seedance-2-api

결론

AI 비디오 생성은 작업 시스템(job system)으로 취급되어야 합니다. 안정적인 큐(queue), 제공업체 어댑터 인터페이스(provider adapter interface), 폴링 전략(polling strategy), 에러 분류 체계(error taxonomy), 그리고 사용자가 읽을 수 있는 상태 계층(status layer)은 제품을 더 유지보수하기 쉽게 만듭니다.

백엔드는 모든 제공업체의 차이점을 숨겨서는 안 됩니다. 안정성이 필요한 부분은 정규화(normalize)하고, 사용자가 이해해야 하는 제약 사항(constraints)은 노출해야 합니다.

AI 자동 생성 콘텐츠

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

원문 바로가기
0

댓글

0