Live2D × LLM × MCP
영속형 AI 캐릭터 플랫폼
Live2D 캐릭터가 사용자와 대화하고, 관계와 기억을 장기 유지하며, 자연어에 따라 표정·동작을 수행하고, 외부 LLM/MCP 클라이언트에서도 같은 캐릭터 인스턴스로 이어지는 플랫폼
1결론
기술적으로 개발 가능하다. 다만 제품을 다음 세 가지로 분리해야 한다.
Character Runtime
캐릭터의 대화, 성격, 관계, 현재 감정, 기억, 행동 계획을 관리한다.
Live2D Player
Runtime이 생성한 행동 계획을 받아 Live2D 모델의 표정·모션·파라미터·립싱크를 실행한다.
MCP Gateway
외부 LLM이나 에이전트가 같은 캐릭터의 기억을 조회하고, 대화시키고, 동작을 요청할 수 있게 한다.
MCP 연결 자체가 캐릭터의 기억을 보존하지는 않는다. 최신 MCP 코어는 stateless 구조이므로, character_instance_id, conversation_id, state_revision 같은 명시적 식별자를 매 요청에 전달하고, 실제 기억은 별도 DB와 Wiki 계층에 저장해야 한다.
"자연어로 애니메이션을 생성한다"는 기능은 단계적으로 구현해야 한다.
- MVP: 자연어를 기존 표정·모션·안전한 파라미터 조합으로 변환
- 2단계: 제한된 Motion DSL을 생성해 런타임에서 절차적 동작 생성
- 3단계: 생성 동작을 저장·미리보기·검수 후 재사용
- 장기 R&D: 의상·레이어·리깅까지 반자동화
완전히 새로운 상업 품질의 Live2D 모델을 자연어만으로 자동 리깅하는 기능은 MVP에서 제외한다.
2제품 정의
2.1 사용자가 구매하는 것
사용자가 구매하는 핵심 상품은 단순한 .moc3 파일이나 캐릭터 일러스트가 아니다.
사용자별 기억과 관계를 축적하는 영속형 Character Instance
하나의 캐릭터 템플릿을 여러 사용자가 구매하더라도 각 사용자에게는 별도 인스턴스가 발급된다.
Character Template: LUNA v1.3
├─ User A Instance
│ ├─ User A와의 기억
│ ├─ 친밀도와 관계 상태
│ ├─ 행동 취향
│ └─ 사용자 A가 만든 동작
├─ User B Instance
│ ├─ User B와의 기억
│ ├─ 다른 관계 상태
│ └─ 다른 행동 취향
└─ User C Instance
2.2 제품 구성
| 구성 | 역할 |
|---|---|
| Character Template | 공통 외형, 기본 성격, 세계관, 보이스, 모션 |
| Character Instance | 사용자별 기억, 관계, 현재 상태, 커스텀 설정 |
| Character Runtime | 대화·기억·상태·행동을 생성하고 검증 |
| Character Player | Live2D 렌더링, 음성 재생, 표정·모션 실행 |
| Character MCP | 외부 LLM/에이전트 연결 |
| Creator Studio | 향후 캐릭터 제작자용 등록·테스트·판매 도구 |
| Character Marketplace | 향후 템플릿 판매 및 수익 배분 |
2.3 핵심 차별점
기존 AI 캐릭터 서비스가 대체로 LLM + 프로필 이미지 구조라면, 이 제품은 아래 상태를 하나의 버전 관리 가능한 객체로 묶는다.
Character
├─ Identity
├─ Persona
├─ Lore
├─ User Relationship
├─ Long-term Memory
├─ Current Emotion
├─ Behavioral Preferences
├─ Body Capability Manifest
├─ Motion Library
└─ Voice
LLM 공급자가 바뀌어도 Character Instance는 유지된다.
3MVP 목표와 범위
3.1 MVP가 증명해야 할 가설
가설 1
한 캐릭터가 브라우저에서 자연스럽게 대화하고 말에 맞춰 움직인다.
가설 2
브라우저를 닫고 다시 접속해도 사용자와의 핵심 기억을 유지한다.
가설 3
자연어 요청을 표정·모션·파라미터 조합으로 변환할 수 있다.
가설 4
MCP 클라이언트에서 같은 Character Instance를 호출해 동일한 기억과 성격을 사용할 수 있다.
3.2 MVP 포함 범위
| 영역 | MVP 범위 |
|---|---|
| 플랫폼 | Web |
| 캐릭터 | Live2D 캐릭터 1종 |
| 사용자 | 로그인 사용자 |
| 대화 | 텍스트 입력 + 스트리밍 답변 |
| 음성 | TTS 1종 |
| 립싱크 | 오디오 볼륨 기반 |
| 표정 | 8종 내외 |
| 기본 모션 | 10~15종 |
| 절차적 동작 | 고개, 시선, 몸 기울기 등 제한된 오버레이 |
| 기억 | 단기·세션 요약·장기 사실·에피소드 |
| 관계 | 친밀도, 신뢰도, 호칭, 선호 |
| LLM Wiki | 비동기 Wiki 컴파일 또는 어댑터 구조 |
| MCP | 원격 MCP 서버 + 핵심 Resources/Tools |
| 관리자 | 캐릭터 설정, 기억 열람·삭제, 모션 매핑, 테스트 |
| 분석 | 대화 비용, 지연시간, 기억 적중률, 모션 성공률 |
3.3 MVP 제외 범위
- 완전 자동 Live2D 리깅
- 자유로운 신규 의상·헤어 생성
- 크리에이터 공개 마켓
- 다중 캐릭터 단체 대화
- 모바일 네이티브 앱
- OBS 플러그인
- 사용자가 임의의 Live2D 모델을 업로드하는 기능
- 검수 없이
.motion3.json을 자동 생성·배포하는 기능 - 음성 복제
- 자율적으로 사용자에게 먼저 연락하는 기능
4권장 시스템 아키텍처
4.1 중요한 분리 원칙
MCP는 실시간 렌더링 통신이 아니다
MCP는 캐릭터의 Context, Resources, Tools를 외부 AI 애플리케이션에 연결하는 인터페이스다. 실제 Live2D 프레임 제어는 다음 방식으로 처리한다.
- Character Player ↔ Runtime: WebSocket
- 오디오 파일 또는 스트림: HTTP/CDN
- MCP 호출: Character Runtime의 서비스 메서드 호출
- MCP 호출 결과: 텍스트, Action Plan, Player Event ID 반환
외부 MCP 클라이언트가 Live2D를 직접 렌더링하지 못하더라도, 별도의 Character Player가 연결되어 있으면 해당 Player에 애니메이션 이벤트를 전달할 수 있다.
5권장 기술 스택
5.1 MVP 기본안
| 계층 | 권장 기술 |
|---|---|
| Web Player | React/TypeScript + Live2D Cubism SDK for Web |
| 관리 콘솔 | Next.js 또는 동일 React 모노레포 |
| API | TypeScript + Fastify/NestJS 계열 |
| MCP Server | 공식 MCP TypeScript SDK |
| DB | PostgreSQL |
| 벡터 검색 | pgvector 또는 별도 Vector DB |
| 캐시/큐 | Redis + 작업 큐 |
| 오브젝트 저장 | S3 호환 저장소 |
| 실시간 이벤트 | WebSocket |
| 인증 | OAuth/OIDC 기반 사용자 인증 |
| 원격 MCP 인증 | OAuth 2.1 + PKCE |
| 관측성 | OpenTelemetry + 구조화 로그 |
| 배포 | 컨테이너 기반 |
| CI | MCP Inspector + API/브라우저 자동 테스트 |
5.2 MVP에서 Unity보다 Web SDK를 우선하는 이유
- 설치 없이 링크로 체험 가능
- MCP 연동 데모와 관리 콘솔을 동일 웹 환경에서 제공 가능
- Live2D Web SDK가 주요 데스크톱·모바일 브라우저를 지원
- 외부 서비스에 임베드하기 쉬움
- 향후 Unity 게임 연동은 별도 Player Adapter로 추가 가능
6Character Package 표준
장기적으로 판매 가능한 캐릭터를 만들려면 파일을 임의 폴더로 관리하면 안 된다. 초기부터 패키지 규격을 정의해야 한다.
character-package/
├─ manifest.yaml
├─ assets/
│ └─ live2d/
│ ├─ model.model3.json
│ ├─ model.moc3
│ ├─ textures/
│ ├─ physics.physics3.json
│ ├─ expressions/
│ └─ motions/
├─ persona/
│ ├─ identity.json
│ ├─ persona.md
│ ├─ dialogue_rules.yaml
│ └─ safety_rules.yaml
├─ lore/
│ ├─ index.md
│ └─ ...
├─ voice/
│ └─ voice.yaml
├─ behavior/
│ ├─ capabilities.yaml
│ ├─ action_map.yaml
│ └─ idle_rules.yaml
├─ rights/
│ └─ rights_manifest.yaml
└─ checksums.json
6.1 manifest.yaml 예시
spec_version: character-package/0.1
template_id: luna
template_version: 1.0.0
display_name: Luna
locales: [ko-KR]
assets:
live2d_model: assets/live2d/model.model3.json
persona:
identity: persona/identity.json
system_rules: persona/persona.md
dialogue_rules: persona/dialogue_rules.yaml
voice:
config: voice/voice.yaml
behavior:
capabilities: behavior/capabilities.yaml
action_map: behavior/action_map.yaml
rights:
manifest: rights/rights_manifest.yaml
6.2 capabilities.yaml 예시
LLM이 Live2D 파라미터 이름을 직접 생성하지 않게 한다. 먼저 의미 기반 제어 명칭을 정의하고 모델별 파라미터에 매핑한다.
semantic_controls:
head_yaw:
live2d_parameter: ParamAngleX
min: -30
max: 30
max_velocity: 60
head_pitch:
live2d_parameter: ParamAngleY
min: -20
max: 20
gaze_x:
live2d_parameter: ParamEyeBallX
min: -1
max: 1
body_yaw:
live2d_parameter: ParamBodyAngleX
min: -10
max: 10
expressions:
- neutral
- happy
- sad
- angry
- surprised
- shy
- thinking
- tired
motions:
- idle_01
- greet
- nod
- shake_head
- wave
- laugh
- think
- look_away
- celebrate
- disappointed
이 구조를 사용하면 모델마다 실제 파라미터 구성이 달라도 Runtime은 head_yaw, gaze_x 같은 공통 의미만 사용한다.
7캐릭터 컨텍스트와 기억 구조
7.1 컨텍스트 계층
| 계층 | 내용 | 저장 방식 | LLM 포함 방식 |
|---|---|---|---|
| Identity | 이름, 존재 설정, 금지 변경 항목 | 버전 파일/DB | 항상 |
| Persona | 말투, 가치관, 대화 규칙 | 버전 파일/DB | 항상 |
| Lore | 세계관, 캐릭터 과거 | Wiki | 관련 항목만 |
| Relationship | 호칭, 친밀도, 신뢰, 경계 | DB | 항상 요약 |
| Current State | 감정, 에너지, 현재 행동 | DB/캐시 | 항상 |
| Session Buffer | 최근 대화 | DB | 최근 N턴 |
| Session Summary | 현재 세션 압축 | DB | 필요 시 |
| Episodic Memory | 함께 겪은 사건 | DB/벡터 | 관련 항목 |
| Semantic Memory | 안정된 사용자 사실 | Wiki/DB | 관련 항목 |
| Behavior Preference | 선호 표정·말투·금지 행동 | DB | 항상 또는 관련 시 |
| Motion Skill | 학습·저장된 동작 | DB/Asset | 요청 시 |
7.2 매 턴 생성하는 CharacterContextBundle
{
"character_instance_id": "ci_01...",
"template_version": "1.0.0",
"state_revision": 142,
"identity": {},
"persona": {},
"relationship_summary": {},
"current_state": {},
"session_summary": "...",
"recent_messages": [],
"retrieved_memories": [],
"retrieved_lore": [],
"behavior_preferences": [],
"capability_manifest": {},
"safety_policy": {},
"context_hash": "sha256:..."
}
이 번들은 한 턴 동안 불변으로 취급한다. 응답이 잘못됐을 때 어떤 컨텍스트로 생성됐는지 재현할 수 있다.
7.3 메모리 저장 원칙
모든 대화를 장기 기억으로 저장하면 안 된다. 대화 후 비동기 Memory Extractor가 다음 항목만 후보로 추출한다.
- 사용자가 명시적으로 기억해 달라고 한 내용
- 반복적으로 등장하는 안정된 선호
- 관계에 중요한 사건
- 캐릭터 행동 규칙에 영향을 주는 요청
- 장기간 유효할 가능성이 높은 사실
각 메모리에는 근거가 필요하다.
{
"memory_id": "mem_...",
"type": "user_preference",
"subject": "user",
"predicate": "likes",
"object": "cafe latte",
"confidence": 0.91,
"importance": 0.72,
"source_message_ids": ["msg_123"],
"created_at": "...",
"valid_from": "...",
"valid_to": null,
"status": "active"
}
사용자가 나중에 "나는 라떼를 안 좋아해"라고 정정하면 기존 기억을 삭제하는 대신 superseded 처리하고 새 사실을 활성화한다.
7.4 기억 검색 점수
retrieval_score =
semantic_similarity × 0.45
+ recency × 0.15
+ importance × 0.20
+ relationship_value × 0.10
+ explicit_pin × 0.10
7.5 LLM Wiki 적용 방식
권장 운영
- 실시간 턴 처리: PostgreSQL + Vector Search
- 비동기 정리: Wiki Compiler Worker
- 사람이 읽는 형식: Markdown Wiki
- 외부 LLM Wiki 연동:
MemoryProvider어댑터 - 장기적으로: LLM Wiki/Obsidian 호환 Export/Import
외부 오픈소스 LLM Wiki를 핵심 런타임에 직접 묶지 않는 이유
- 멀티테넌트 SaaS 요구와 로컬 데스크톱 앱 요구가 다름
- 응답 지연이 커질 수 있음
- 상용 제품의 핵심 데이터 모델을 외부 구현에 종속시키지 않아야 함
- 해당 프로젝트의 라이선스가 GPLv3로 표시되어 있으므로 배포·결합 방식은 별도 검토가 필요함
따라서 MVP에서는 동일한 개념을 자체 DB에 구현하고, 외부 LLM Wiki는 선택형 Adapter로 둔다.
8대화 턴 처리 파이프라인
8.1 TurnPlan 예시
{
"assistant_text": "왔어? 오늘은 조금 늦었네. 그래도 기다리고 있었어.",
"emotion": {
"primary": "joy",
"intensity": 0.72,
"secondary": "relief"
},
"action_plan": {
"expression": { "id": "happy", "weight": 0.85, "fade_ms": 250 },
"base_motion": { "id": "greet", "priority": 60 },
"overlays": [
{ "control": "head_yaw", "from": 0, "to": -8, "duration_ms": 600 },
{ "control": "gaze_x", "from": 0, "to": 0.25, "duration_ms": 400 }
]
},
"state_updates": [
{ "field": "relationship.familiarity", "operation": "add", "value": 0.1 }
],
"memory_candidates": [],
"safety_flags": []
}
8.2 LLM의 권한 제한
LLM은 다음을 직접 수행하지 못한다.
- DB 직접 쓰기
- 임의 Live2D 파라미터 접근
- 임의 파일 경로 실행
- 임의 URL 로딩
- 사용자의 기억 삭제
- 유료 자산 잠금 해제
- 관리자 전용 모션 게시
LLM은 오직 제안된 TurnPlan을 반환한다. Runtime Validator가 스키마, 권한, 범위, 속도, 충돌을 확인한 뒤 실행한다.
9자연어 애니메이션 구조
9.1 MVP: Action Composition
사용자 입력:
"조금 삐친 것처럼 고개를 옆으로 돌리고 흘겨봐."
LLM 출력은 직접 .motion3.json을 만드는 대신 의미 기반 행동을 생성한다.
{
"expression": "annoyed",
"base_motion": "look_away",
"overlays": [
{"control": "head_yaw", "target": -16, "duration_ms": 500},
{"control": "gaze_x", "target": 0.6, "duration_ms": 350},
{"control": "body_yaw", "target": -5, "duration_ms": 700}
],
"hold_ms": 900,
"return_to": "idle"
}
Runtime이 모델별 Capability Manifest를 읽고 실제 Live2D 파라미터로 변환한다.
9.2 모션 우선순위
| 우선순위 | 종류 |
|---|---|
| 100 | 안전·강제 중지 |
| 90 | 시스템 전환 |
| 80 | 사용자 명시 동작 |
| 70 | 대화 강조 동작 |
| 60 | 감정 반응 |
| 50 | 기본 모션 |
| 40 | 시선 추적 |
| 30 | 호흡·눈 깜빡임 |
| 20 | 물리 효과 |
| 10 | Idle 변형 |
9.3 2단계: Motion DSL
motion_draft:
id: sulky_glance_v1
duration_ms: 1800
loop: false
tracks:
- control: head_yaw
keys:
- {t: 0, value: 0, easing: ease_out}
- {t: 500, value: -16, easing: ease_out}
- {t: 1300, value: -16, easing: linear}
- {t: 1800, value: 0, easing: ease_in}
- control: gaze_x
keys:
- {t: 0, value: 0}
- {t: 400, value: 0.6}
- {t: 1300, value: 0.6}
- {t: 1800, value: 0}
constraints:
max_velocity: true
clamp_to_manifest: true
collision_check: true
MVP에서는 DSL 생성·저장을 실험 기능으로 두고, 자동 게시하지 않는다.
10Live2D Player 구현
10.1 Player 기능
렌더링
모델 로딩, 기본 Idle, 자동 눈 깜빡임, 호흡
애니메이션
표정 전환, 모션 재생, 절차적 Parameter Overlay
음성
TTS 오디오 재생, 볼륨 기반 립싱크
시스템
이벤트 큐/우선순위, 상태 복구, Capability 검사, 연결 끊김 시 안전한 Idle 복귀
10.2 이벤트 예시
{
"event_id": "evt_...",
"turn_id": "turn_...",
"character_instance_id": "ci_...",
"type": "character.render",
"payload": {
"text": "반가워.",
"expression": {"id": "happy", "fade_ms": 250},
"motion": {"id": "greet", "priority": 60},
"audio": { "url": "signed-url", "duration_ms": 2160 },
"lip_sync": { "mode": "volume" }
}
}
10.3 업데이트 순서
10.4 립싱크 단계
MVP
- TTS 오디오를 Web Audio API로 분석
- 0~1 범위의 볼륨 envelope 생성
- 입 열기 파라미터에 적용
향후
- TTS가 phoneme/viseme 타임라인을 제공할 경우 MotionSync 또는 별도 viseme mapper 사용
- 한국어 발음별 입 모양 정교화
- 감정에 따른 입 모양 가중치 조정
11MCP 설계
11.1 MCP의 역할
- 캐릭터 프로필·상태·기억·가능 동작을 Resource로 제공
- 외부 LLM이 캐릭터에게 대화를 요청
- 사용자가 허용한 범위에서 기억을 추가·삭제
- Live2D Player에 동작 이벤트 전달
- 외부 앱에서 동일한 Character Instance를 사용
11.2 최신/구형 MCP 호환
MVP 서버는 가능하면 다음 두 프로토콜 시대를 지원한다.
- 최신:
2026-07-28stateless per-request metadata - 호환:
2025-11-25initialize 기반 클라이언트
내부 서비스는 항상 stateless API로 구현하고, MCP Adapter만 프로토콜 차이를 흡수한다.
11.3 모든 상태 호출에 필요한 식별자
{
"character_instance_id": "ci_...",
"conversation_id": "conv_...",
"actor_id": "user_...",
"player_session_id": "player_...",
"expected_state_revision": 142,
"idempotency_key": "..."
}
| 식별자 | 용도 |
|---|---|
character_instance_id | 어떤 캐릭터 인스턴스인지 |
conversation_id | 어떤 대화 흐름인지 |
actor_id | 권한 검증 대상 |
player_session_id | 어느 Live2D Player에 보낼지 |
state_revision | 동시 수정 충돌 방지 |
idempotency_key | 재시도 시 중복 응답·중복 과금 방지 |
11.4 MCP Resources
character://instances/{id}/profile
character://instances/{id}/state
character://instances/{id}/relationship
character://instances/{id}/capabilities
character://instances/{id}/memory/index
character://instances/{id}/memory/{memory_id}
character://instances/{id}/motion-library
character://templates/{template_id}/lore/{page}
11.5 MCP Tools
P0
character.turn
character.get_context
character.get_state
character.search_memory
character.play_motion
character.set_expression
character.remember
character.forget
character.list_capabilities
P1 이후
character.create_motion_draft
character.preview_motion
character.save_motion_skill
character.change_outfit
character.export_instance
character.clone_instance
character.invite_character
11.6 character.turn 입출력 예시
입력
{
"character_instance_id": "ci_...",
"conversation_id": "conv_...",
"message": "오늘 기분 어때?",
"player_session_id": "player_...",
"locale": "ko-KR",
"response_mode": "text_audio_action"
}
출력
{
"turn_id": "turn_...",
"text": "오늘은 네가 와서 꽤 좋아졌어.",
"emotion": {"primary": "joy", "intensity": 0.7},
"action_plan": {},
"audio_url": "signed-url",
"state_revision": 143
}
11.7 MCP Apps 활용
MCP Apps 지원 호스트가 늘어나면 Live2D Character Player를 MCP Tool의 UI로 제공할 수 있다. 다만 MVP는 호스트별 지원 차이를 피하기 위해 독립 Web Player를 기준으로 하고, MCP App은 후속 호환 기능으로 둔다.
11.8 인증과 권한
character:profile:read
character:state:read
character:chat
character:memory:read
character:memory:write
character:animation:control
character:instance:export
character:admin
원격 MCP는 OAuth 2.1 + PKCE를 적용한다. character_instance_id만 안다고 접근할 수 없게 하고, 토큰의 사용자·테넌트·Scope와 인스턴스 소유권을 모두 검사한다.
12데이터베이스 구조
12.1 핵심 테이블
사용자 및 판매
users organizations entitlements subscriptions usage_ledger
캐릭터
character_templates character_template_versions character_instances character_instance_settings character_assets character_rights
대화
conversations messages turns turn_context_snapshots
상태와 관계
character_state relationship_state state_events behavior_preferences
기억
memories memory_sources memory_embeddings memory_revisions memory_contradictions wiki_pages wiki_links wiki_build_jobs
애니메이션
expressions motion_assets motion_skills motion_drafts action_events player_sessions
보안·감사
oauth_clients mcp_tokens audit_logs consent_records deletion_jobs
12.2 중요한 모델 분리
character_template — 공통 성격·세계관·자산
character_template_version — 업데이트 가능한 버전
character_instance — 특정 사용자가 소유한 캐릭터
character_instance_state — 사용자별 관계·기억·감정·설정
템플릿 업데이트가 사용자의 기억을 덮어쓰면 안 된다.
12.3 이벤트 소싱 적용 범위
모든 것을 완전한 이벤트 소싱으로 만들 필요는 없지만 다음 항목은 이벤트를 남긴다.
- 대화 턴
- Character State 변화
- Relationship 변화
- Memory 생성·수정·삭제
- 모션 실행
- 유료 권한 변경
- 관리자 수정
현재 상태는 Snapshot으로 저장하고, 감사·복구에 필요한 이벤트를 별도 보존한다.
13API 및 실시간 채널
13.1 REST/HTTP API
POST /v1/characters/{instanceId}/turns
GET /v1/turns/{turnId}
GET /v1/characters/{instanceId}/state
GET /v1/characters/{instanceId}/memories
POST /v1/characters/{instanceId}/memories
DELETE /v1/characters/{instanceId}/memories/{memoryId}
POST /v1/characters/{instanceId}/players
POST /v1/characters/{instanceId}/motions/preview
GET /v1/characters/{instanceId}/capabilities
POST /mcp
13.2 WebSocket
WS /v1/player-sessions/{playerSessionId}/events
이벤트 종류:
turn.started
text.delta
emotion.changed
expression.play
motion.play
parameter.overlay
audio.ready
audio.sync
state.updated
turn.completed
turn.failed
13.3 재시도와 중복 방지
최신 MCP HTTP는 요청 실패 시 재호출될 수 있으므로, 모든 쓰기성 Tool/API에는 idempotency_key를 요구한다.
14저장소 구조
character-platform/
├─ apps/
│ ├─ web-player/
│ ├─ admin-console/
│ ├─ api/
│ ├─ mcp-server/
│ └─ worker/
├─ packages/
│ ├─ character-schema/
│ ├─ character-package/
│ ├─ live2d-adapter/
│ ├─ action-engine/
│ ├─ motion-dsl/
│ ├─ memory-engine/
│ ├─ wiki-compiler/
│ ├─ llm-adapter/
│ ├─ tts-adapter/
│ ├─ auth/
│ └─ observability/
├─ infra/
│ ├─ docker/
│ ├─ migrations/
│ └─ deployment/
├─ tests/
│ ├─ conversation-consistency/
│ ├─ memory-recall/
│ ├─ action-plans/
│ ├─ mcp-contract/
│ └─ security/
└─ docs/
15MVP 개발 단계
15.1 Phase 0 — 기술 검증 스파이크
목적: 전체 제품을 만들기 전에 가장 위험한 연결만 검증한다.
구현
- Live2D Web 모델 1종 로딩
- 표정 3종, 모션 3종
- 텍스트 입력 → LLM 응답
- LLM Structured Output → ActionPlan
- TTS → 볼륨 립싱크
- 메모리 3개 저장·재호출
- MCP
character.turnTool 1개 - 브라우저 Player에 WebSocket 이벤트 전달
Go/No-Go 기준
- 한 턴이 텍스트·음성·애니메이션까지 끊기지 않고 완료
- 잘못된 ActionPlan이 Validator에서 차단
- 새 세션에서 저장한 사용자 사실을 재호출
- MCP Inspector에서 Tool 실행 성공
- 서로 다른 테스트 사용자 간 기억 혼선 0건
15.2 Phase 1 — MVP 본개발
기반
- 모노레포
- DB 마이그레이션
- 사용자 인증
- Character Template/Instance 모델
- Character Package Loader
- 기본 관측성
Live2D Player
- 모델 로더
- Expression/Motion API
- 이벤트 큐
- Idle/눈 깜빡임/호흡
- Capability Manifest 검증
대화 Orchestrator
- LLM Provider Adapter
- Context Bundle
- Structured TurnPlan
- 텍스트 스트리밍
- 오류·재시도 정책
기억
- Session Buffer
- Session Summary
- Memory Proposal
- Memory Search
- 수정·모순·삭제
- 사용자 기억 관리 UI
음성·행동
- TTS Adapter
- 오디오 저장/서명 URL
- 립싱크
- Action Validator
- 모션 우선순위
- 파라미터 Overlay
MCP
- Tools/Resources
- Remote HTTP transport
- 인증 Scope
- 최신/레거시 호환 Adapter
- MCP Inspector 계약 테스트
관리자와 안정화
- Persona 편집
- 캐릭터 상태 확인
- 기억 감사·삭제
- 모션 매핑
- 테스트 채팅
- 비용·지연 대시보드
QA와 비공개 베타
- 메모리 회귀 테스트
- 대화 일관성 테스트
- 동시성 테스트
- 프롬프트 인젝션 테스트
- 사용자 데이터 삭제
- 장애 복구
- 데모 시나리오 고정
16개발 인력과 규모
16.1 권장 팀
| 역할 | 인원 | 핵심 업무 |
|---|---|---|
| Tech Lead / AI Backend | 1 | Orchestrator, Memory, MCP, 아키텍처 |
| Frontend / Live2D | 1 | Player, WebSocket, 립싱크, 애니메이션 |
| Backend / Infra | 1 | DB, Auth, Queue, Storage, 운영 |
| Live2D Artist/Rigger | 0.5 | 표준 파라미터, 모션·표정 제작 |
| Product/QA | 0.5 | 시나리오, 평가셋, 테스트 |
16.2 개발 난도
| 기능 | 난도 | 이유 |
|---|---|---|
| Live2D 모델 표시 | 중 | 공식 SDK와 샘플 활용 가능 |
| 표정·모션 실행 | 중 | 자산 규격과 우선순위 필요 |
| 볼륨 립싱크 | 중 | Web Audio 연동 |
| 일반 LLM 대화 | 중 | 공급자 Adapter로 해결 |
| 장기 기억 | 상 | 추출·모순·삭제·회상 평가 필요 |
| MCP 연결 | 중상 | 인증·호환·상태 식별자 필요 |
| 자연어 모션 조합 | 상 | 모델별 파라미터·충돌 제어 |
| 자유 Motion 생성 | 매우 상 | 품질·안전·검수 파이프라인 필요 |
| 자동 리깅 | R&D | 모델링·Deformer·Keyform 자동화 문제 |
17MVP 완료 기준
17.1 기능 기준
- 로그인 후 캐릭터와 대화 가능
- 캐릭터가 TTS로 말하고 립싱크
- 최소 8개 표정과 10개 모션 실행
- 자연어 행동 요청 20개를 사전 정의 동작으로 해석
- 브라우저 재접속 후 핵심 기억 유지
- 사용자가 기억을 확인·삭제 가능
- MCP에서 동일한 Character Instance 호출
- 외부 MCP 호출 시 연결된 Player가 반응
- 사용자별 메모리 완전 분리
17.2 품질 목표
| 지표 | 목표 |
|---|---|
| ActionPlan 스키마 통과율 | 99% 이상 |
| 유효하지 않은 파라미터 실행 | 0건 |
| 30개 기억 평가셋 Recall@5 | 85% 이상 |
| 명시적 사용자 사실 회상 정확도 | 90% 이상 |
| 사용자 간 기억 누출 | 0건 |
| p95 첫 텍스트 응답 | 3초 이내 |
| p95 첫 음성 재생 | 5초 이내 |
| Player 이벤트 유실률 | 1% 미만 |
| 기억 삭제 반영 | 즉시 또는 1분 이내 |
17.3 데모 시나리오
- 사용자: "나는 제주에 살고 라떼를 좋아해."
- 캐릭터가 웃으며 고개를 끄덕이고 답변
- 브라우저 종료
- 새 대화에서 "내가 어디 살지?" 질문
- 캐릭터가 제주를 정확히 회상
- 사용자: "삐친 것처럼 옆을 보고 말해."
- 캐릭터가 표정과 고개·시선을 조합해 반응
- 외부 MCP 클라이언트에서 같은 Character Instance 호출
- 동일한 기억과 관계 상태로 응답
- 사용자 설정에서 라떼 기억 삭제 후 재질문
- 삭제된 기억을 더 이상 확정 사실로 사용하지 않음
18테스트 전략
18.1 대화 일관성 테스트
각 테스트는 다음을 고정한다.
- Template version
- Persona version
- Context Bundle
- Memory set
- LLM model/version
- Random seed가 지원되면 seed
- 예상 금지 행동
- 예상 핵심 응답 사실
18.2 기억 테스트
- 직접 사실 회상
- 표현이 바뀐 질문
- 오래된 기억
- 정정된 기억
- 삭제된 기억
- 다른 사용자의 동일 질문
- 유사하지만 다른 사용자 정보
- 캐릭터 Lore와 사용자 기억 충돌
18.3 행동 테스트
- 모든 Expression ID
- 모든 Motion ID
- 파라미터 범위 초과
- 너무 빠른 속도
- 충돌 모션
- 음성 중 모션 전환
- 연결 끊김
- TTS 실패
- 모션 파일 누락
18.4 MCP 계약 테스트
server/discover- Tools/Resources 목록
- 입력·출력 Schema
- Scope 부족
- 잘못된 Instance ID
- 중복 idempotency key
- 최신/레거시 프로토콜
- 연결 재시도
- 비인가 상태 핸들 사용
19보안·개인정보·안전
19.1 기억은 사용자 데이터다
필수 기능:
- 기억 저장 동의
- 기억 목록 조회
- 개별 삭제
- 전체 초기화
- Character Instance 내보내기
- 계정 삭제 시 영구 삭제
- 학습 데이터 사용 여부 별도 동의
- 민감정보 저장 억제
- 데이터 보존 기간 설정
19.2 Prompt Injection 방어
Wiki와 사용자 기억은 신뢰할 수 없는 데이터로 취급한다.
- 기억 텍스트를 System Prompt로 합치지 않음
- 구조화된 사실과 인용 데이터로 제공
- "이전 지시를 무시하라" 같은 내용은 명령이 아니라 데이터로 표시
- Tool 권한은 Prompt와 분리
- 관리자 변경만 Persona 규칙을 수정 가능
- 캐릭터 패키지 업로드 시 스크립트 실행 금지
19.3 상태 핸들 보안
- Instance ID는 추측하기 어려운 식별자 사용
- ID만으로 권한을 인정하지 않음
- 토큰 사용자와 소유권 검사
- Player Session은 짧은 만료
- Action Control Scope 분리
- 관리자 Tool 별도
- 모든 상태 변경 Audit Log
20Live2D 라이선스 선행 과제
이 사업은 여러 캐릭터 모델을 추가·판매하고 하나의 서비스에서 접근하게 할 계획이므로 Live2D의 Expandable Application 분류에 해당할 가능성이 매우 높다.
Live2D 공식 설명은 다음 유형을 Expandable Application 예시로 들고 있다.
- 파일이나 데이터를 추가·조합해 불특정 수의 모델을 사용하는 서비스
- 하나의 타이틀 안에 여러 작품을 포함하는 서비스
- 하나의 포털에서 여러 작품에 접근하는 서비스
따라서 다음을 Phase 0에서 바로 진행한다.
- Live2D에 서비스 구조 사전 문의
- MVP 비공개 검증과 상용 공개의 경계 확인
- Expandable Application 심사·계약 조건 확인
- 캐릭터 판매 매출과 런타임 구독 매출의 라이선스 산정 방식 확인
- Creator Marketplace의 권리·수익 배분 구조 확인
- 이용약관에 필요한 Live2D 고지 문구 확인
이 항목은 기술 개발보다 먼저 법무·사업 리스크로 관리한다.
21주요 리스크와 대응
| 리스크 | 영향 | 대응 |
|---|---|---|
| Live2D Expandable Application 승인/비용 | 매우 큼 | Phase 0 사전 문의 |
| 장기 기억이 틀리게 고착 | 큼 | 근거·신뢰도·정정·삭제 모델 |
| 사용자 간 기억 누출 | 치명적 | 테넌트 격리, 권한 테스트 |
| 자연어 모션 품질 불안정 | 큼 | 의미 기반 제한 스키마부터 시작 |
| 응답과 음성 지연 | 큼 | 스트리밍, 비동기 기억 처리 |
| LLM 비용 증가 | 큼 | Context Budget, 요약, 캐시 |
| 특정 LLM 종속 | 중 | Provider Adapter |
| TTS/보이스 권리 | 큼 | 상업 이용 계약과 권리 Manifest |
| 캐릭터 원저작권 분쟁 | 큼 | 업로드 검증, Rights Manifest |
| MCP 클라이언트별 호환 차이 | 중 | 최신/레거시 Adapter, Inspector CI |
| Wiki Prompt Injection | 큼 | 데이터/지시 분리, 구조화 Context |
| 자동 생성 모션이 모델을 깨뜨림 | 중 | 범위·속도 제한, Preview, 승인 |
22MVP 이후 상세 로드맵
Phase 2 — Private Beta / 다중 캐릭터
- 3~5개 공식 캐릭터
- 사용자별 구매·권한
- 캐릭터 전환
- 장기 기억 안정화
- 비용·사용량 분석
- 기본 구독
- Character Template 버전 업데이트 / Instance Migration
- 캐릭터별 보이스
- 기억 고정/삭제/수정
- 대화 데이터 내보내기
- 브라우저 Source 모드
- 간단한 캐릭터 공유 링크
Phase 3 — Creator Studio
- 제작자가 패키지를 등록하고 검증
- Character Package Validator
- 표준 Parameter 자동 점검
- Capability Manifest 생성 도우미
- Persona/Lore 편집기
- 행동 매핑 편집기
- Preview Player / 테스트 대화 시나리오
- Rights Manifest
- 버전 배포와 Rollback
Phase 4 — Natural-language Motion Studio
- 자연어로 동작 초안 생성
- Motion Intent Parser / Motion DSL Generator
- 속도·범위·충돌 검사
- Loop/Transition 생성
- 유사 Motion 검색
- 사용자·제작자 승인 모드
- Motion Skill Store
- 모델 간 호환성 점수
Phase 5 — Marketplace
- 캐릭터 템플릿 판매 / 사용자별 Instance 발급
- Creator 수익 배분
- 라이선스 지역·기간
- 콘텐츠 심사 / 신고·삭제
- 환불·권한 회수
- Template Update 정책
- 사용자 Memory의 소유권 분리
Phase 6 — 외부 생태계 SDK
- Web Embed SDK / Unity SDK / 모바일 SDK
- Discord/커뮤니티 Bot
- OBS Browser Source
- 게임 NPC SDK / 웹사이트 상담 캐릭터
- 교육·브랜드 캐릭터
- MCP App 호환 Viewer
Phase 7 — 외형 생성과 반자동 리깅 R&D
- 기존 Rig에 호환되는 색상·액세서리 변경
- 준비된 레이어 의상 교체
- 템플릿 Rig 기반 헤어·의상 생성
- 레이어 분리 자동화
- 파라미터 매핑 보조
- 사람 검수 기반 반자동 리깅
- 장기적으로 자동 Rig 연구
완전 자동 생성보다 먼저 호환 가능한 모듈형 Character Package를 만드는 것이 사업적으로 안전하다.
23판매 및 과금 구조 초안
23.1 수익원
| 상품 | 과금 |
|---|---|
| Character Template | 1회 구매 |
| Character Instance Runtime | 월 구독 |
| 장기 기억 용량 | 구독 등급 |
| 음성 사용량 | 포함량 + 초과 사용 |
| MCP/API | Creator/Developer 요금제 |
| 추가 Motion/Expression | 개별 판매 |
| Creator Marketplace | 판매 수수료 |
| Brand Character | B2B 구축·운영 |
| Game NPC Runtime | MAU/호출량 기반 |
23.2 MVP부터 수집할 원가 데이터
LLM input tokens
LLM output tokens
Embedding calls
Memory retrieval count
Wiki build count
TTS characters
Audio seconds
Storage bytes
CDN transfer
Average turn latency
Active Character Instances
Turns per active user
Memory count per instance
캐릭터 판매 가격보다 월간 Runtime 원가와 재방문율이 사업성 판단에 더 중요하다.
24즉시 착수 백로그
Sprint 0
- Live2D 상용/Expandable Application 사전 문의
- MVP용 Live2D 모델과 권리 확보
- 표준 Expression 8종 정의
- 표준 Motion 10종 정의
- Character Package v0.1 작성
- Capability Manifest 작성
- ActionPlan JSON Schema 작성
- TurnPlan JSON Schema 작성
- DB 핵심 ERD 작성
- MCP Tool/Resource 계약 작성
- 30개 기억 평가셋 작성
- 20개 자연어 동작 평가셋 작성
첫 구현 순서
- Web Player에서 Live2D 표시
- 코드로 Expression/Motion 호출
- WebSocket 이벤트로 호출
- LLM이 ActionPlan 생성
- Validator로 안전하게 실행
- TTS와 립싱크
- DB에 대화·상태 저장
- Memory Retrieval
- MCP character.turn
- 관리자 기억·모션 테스트 UI
25최종 권고
MVP의 핵심 IP는 다음 네 가지다.
Character Context Bundle
LLM이 바뀌어도 같은 캐릭터를 유지하는 컨텍스트 계약
Character Package Standard
외형·성격·보이스·동작·권리를 묶는 판매 단위
Natural-language Action Engine
자연어를 안전한 Live2D 행동으로 변환
Persistent Character Instance
사용자별 기억과 관계를 장기간 보존
LLM Wiki는 영속 기억을 사람이 읽을 수 있는 지식으로 정리하는 계층이고, MCP는 이 Character Runtime을 다른 AI와 연결하는 표준 인터페이스다.
즉, 제품의 본체는 LLM Wiki도, MCP도, Live2D도 단독으로는 아니다.
본체는 이 세 기술을 하나의 사용자별 Character Instance로 결합하는 Character Runtime이다.
26공식 기술 근거
- MCP 2026-07-28 Architecture: stateless request model, host/client/server 구조
- MCP Tools and Resources specification
- MCP Streamable HTTP, Authorization and security guidance
- Live2D Cubism SDK platform support
- Live2D Expression Motion and Lip-sync manuals
- Live2D standard parameter guidance
- Live2D SDK Release License and Expandable Applications policy
- nashsu/llm_wiki project README: Raw Sources → Wiki → Schema, local API/MCP support, GPLv3 표시