01 — Overview · TBD_PERIOD · 1인 풀스택

Iyagi AI

기획부터 시각화까지 맥락이 끊기지 않는 AI 영상 제작 도구. 7개 도메인 에이전트 오케스트레이션으로 캐릭터·장소·소품 컨텍스트가 자동으로 다음 단계로 흐릅니다.

Iyagi AI 랜딩 hero 화면

02Role & Scope

Role & Scope

본인이 의뢰받을 수 있는 전체 스택은 포트폴리오 사이트의 별도 섹션 참고 (예: Supabase 기반 풀스택 MVP도 가능).

03Problem

Problem

영상 스토리 제작 워크플로우는 도구의 단절 문제로 가득합니다. 시나리오 도구에서 만든 캐릭터 설정이 이미지 생성 도구로 매끄럽게 넘어가지 않고, 한 컷의 분위기를 영상 생성 모델에 정확히 전달하기 위해 매번 프롬프트를 손으로 다시 만들어야 합니다.

Iyagi AI는 이 흐름을 한 채팅 안으로 모았습니다. 사용자는 AI 에이전트와 대화하면서 이야기를 구상하고, 에피소드·씬·컷으로 분해하고, 각 컷의 이미지·영상까지 한 워크스페이스 안에서 생성합니다. 부모 도메인의 메타데이터는 자식 도메인의 에이전트에게 자동으로 전달돼, 동일한 캐릭터·스타일·톤이 끝까지 유지됩니다.

04Engineering Highlights

Engineering Highlights

1. 에이전트 오케스트레이션

OrchestratorAgent → character 도메인 라우팅 (응답 스트리밍)크게 보기
OrchestratorAgent → character 도메인 라우팅 (응답 스트리밍)

OrchestratorAgent가 채팅 메시지를 받아 7개의 전문 에이전트(iyagi · episode · scene · cut · character · location · prop)로 라우팅합니다. 사용자가 agentType을 명시한 경우(예: 캐릭터 탭의 "AI로 추가" 버튼) LLM 라우팅 판단을 건너뛰고 도메인 에이전트로 직접 호출하여 응답 지연과 토큰 비용을 줄였습니다. 위 캡처는 "새로운 조연 캐릭터 한 명 추천해줘" 요청에 대해 OrchestratorAgent가 character 도메인으로 라우팅하여 "인물 작업 중..." 상태로 응답을 스트리밍하는 순간입니다.

2. 4계층 도메인 모델링

이야기 목록 — 본선의 최상위크게 보기
이야기 목록 — 본선의 최상위
에피소드 목록 — 두 번째 계층크게 보기
에피소드 목록 — 두 번째 계층
씬 펼침 — 속한 컷이 갤러리로크게 보기
씬 펼침 — 속한 컷이 갤러리로

이야기(Iyagi) → 에피소드(Episode) → 씬(Scene) → 컷(Cut)의 4계층 본선과, 이 본선을 공유하는 사이드 엔티티 캐릭터·장소·소품을 함께 모델링했습니다. 부모-자식 컨텍스트는 ChatMessageReferences로 묶여 에이전트 입력으로 전달되며, Prisma 스키마에서 각 계층의 cascade 동작과 권한 경계를 명시적으로 잡아 두었습니다. 가장 아래 캡처에서 보이듯 한 씬을 펼치면 그 안에 속한 컷들이 갤러리로 노출되어, 4계층이 UI에서도 자연스럽게 드릴다운됩니다.

3. AI 멀티모달 (이미지) 파이프라인

캐릭터 상세 — 후보 이미지 갤러리크게 보기
캐릭터 상세 — 후보 이미지 갤러리
컷 이미지 모드 — *AssetAgent가 생성크게 보기
컷 이미지 모드 — *AssetAgent가 생성

CharacterAgent / CutAgent가 텍스트 응답을 만들고, 이어서 전용 *AssetAgent가 LLM 응답에서 프롬프트를 정제해 이미지 생성 모델을 호출합니다. 생성 결과는 자산 저장소에 보관되고, UI에서는 한 캐릭터·한 컷에 여러 후보 이미지를 두고 비교·재생성할 수 있는 갤러리 형태로 관리됩니다.

4. 이미지 → 영상 생성 파이프라인

컷 영상 모드 — 이미지 자산을 시드로 (Kling v2.6)크게 보기
컷 영상 모드 — 이미지 자산을 시드로 (Kling v2.6)

같은 컷의 image 모드에서 만든 자산을 시드로 영상을 생성합니다(현재는 Kling v2.6 모델 사용). 영상 생성은 LLM·이미지 생성보다 훨씬 긴 처리 시간이 필요하기 때문에 비동기 작업 큐로 분리하고, 진행 상태는 폴링과 실시간 푸시 양쪽으로 클라이언트에 전달합니다. 영상 자산도 이미지와 동일한 메타데이터 규약으로 관리해 컷 단위에서 자산 종류를 매끄럽게 전환합니다.

5. 모노레포 + 실시간 인프라

워크스페이스 — 채팅 + 본선 4계층크게 보기
워크스페이스 — 채팅 + 본선 4계층

pnpm + Turborepo로 apps/web · apps/server · packages/common을 단일 저장소에서 운영합니다. DTO는 @workspace/common에 인터페이스로 정의하고 서버에서 class-validator 데코레이터 클래스가 implements하여 타입과 검증 규칙을 한곳에서 동기화합니다. Socket.io 기반의 message:stream:delta / message:stream:end 이벤트로 채팅 응답을 스트리밍하며, 같은 패턴을 자산 생성 진행률 푸시에도 재사용합니다.

05Architecture

Architecture

시스템 구조도

시스템 구조도크게 보기
시스템 구조도

에이전트 라우팅 시퀀스

에이전트 라우팅 시퀀스 — agentType 지정 시 fast path크게 보기
에이전트 라우팅 시퀀스 — agentType 지정 시 fast path

채팅 메시지가 들어와 응답이 토큰 단위로 돌아오기까지의 흐름입니다. agentType이 지정되면 OrchestratorAgent의 LLM 라우팅을 건너뛰고 도메인 에이전트를 직접 호출하는 fast path를 탑니다.

06Key Decisions

Key Decisions

7개 도메인 에이전트를 1인 개발자가 유지 가능한 구조로 잡기

맥락: 도메인이 7종으로 늘어나면 각 에이전트가 자체 instruction · tool · output 정규화 로직을 따로 가지면서 코드가 폭발적으로 늘어납니다.

옵션: 1. 각 에이전트를 완전 독립 구현, 2. 공통 추상화로 묶고 도메인별 변하는 부분만 주입

선택: 2. apps/server/src/agents/common/에 instruction 템플릿 시스템, model settings, 가드레일, 트레이싱, output 정규화, stream 유틸을 공통화하고 각 도메인 에이전트는 그 위에서 자기 특화 부분만 정의합니다.

이유: 새 도메인 추가 비용이 일정 수준 이하로 묶여 1인 개발 페이스를 무너뜨리지 않고, 라우팅·스트리밍 동작이 도메인 간 일관성을 유지합니다.

외부 생성 모델을 안정적으로 붙이기 위한 비동기 설계

맥락: LLM 응답은 수초, 이미지 생성은 수십초, 영상 생성은 수분 단위로 처리 시간 편차가 큽니다. 단일 요청-응답으로 묶으면 클라이언트 타임아웃이나 사용자의 다른 작업 차단이 발생합니다.

옵션: 1. 단일 동기 호출 + 긴 타임아웃, 2. 작업 큐 + 폴링 + 실시간 푸시 병행

선택: 2. 영상 같은 장시간 작업은 큐로 떼고, 진행 상태를 폴링과 WebSocket 푸시 양쪽으로 전달합니다.

이유: 사용자는 영상 생성 중에도 다른 컷을 손볼 수 있고, 외부 모델의 일시적 실패에 대해 재시도 정책을 한 곳에서 적용할 수 있습니다.

`agentType` 직접 라우팅으로 LLM 라우팅 비용·지연 절감

맥락: OrchestratorAgent가 사용자의 자연어를 LLM으로 분석해 도메인 에이전트로 핸드오프하는 구조는 우아하지만, 명백히 도메인이 정해진 UI 진입점(예: 캐릭터 탭의 "AI로 추가" 버튼)에서는 LLM 분석이 낭비입니다.

옵션: 1. 모든 경로에서 LLM 라우팅을 거치게 함, 2. 도메인이 사전에 알려진 진입점은 agentType으로 명시해 LLM 라우팅을 우회

선택: 2. 클라이언트에서 보내는 메시지에 agentType 필드를 도입하고, OrchestratorAgent.streamDirect()가 이 필드를 받으면 LLM 호출 없이 도메인 에이전트로 바로 진입합니다.

이유: 첫 토큰 지연이 눈에 띄게 줄고, 라우팅용 LLM 호출이 사라지면서 메시지당 비용이 절감됩니다. 사용자 자연어로 들어오는 경우에는 기존 LLM 라우팅이 그대로 동작합니다.