
LangGraph + Unity로 만드는 「의지를 가진 NPC」: SSE를 통한 실시간 감정 동기화 구현 가이드
요약
LangGraph와 Unity를 결합하여 AI의 사고 프로세스와 NPC의 애니메이션을 실시간으로 동기화하는 'Nebula System' 구현 가이드를 소개합니다. SSE를 통해 감정을 전달하고, RAG와 MCP를 활용해 몰입감 넘치는 지능형 NPC를 구축하는 방법을 다룹니다.
핵심 포인트
- LangGraph를 활용한 루프형 사고 로직 및 상태 관리 구현
- SSE(Server-Sent Events)를 이용한 AI-Unity 간 실시간 데이터 동기화
- RAG(ChromaDB)와 MCP를 통한 NPC의 세계관 유지 및 외부 정보 활용
- SQLAlchemy를 이용한 대화 및 호감도 데이터의 영속화
서론
안녕하세요. Tyora입니다. AI 개발 입문자로서 매일 「AI와 인간의 새로운 대화 형태」를 모색하고 있습니다.
최근 LLM (대규모 언어 모델)을 게임의 NPC에 통합하려는 시도가 활발하지만, 단순히 텍스트를 표시하는 것만으로는 「인간미」가 부족하다고 느낄 때가 있습니다. 그래서 저는 AI의 사고 프로세스와 Unity의 애니메이션을 실시간으로 동기화하는 시스템인 "Nebula System"을 개발했습니다.
"Nebula System"은 원래 챗봇으로서 개발이 시작되었으나, AI의 사고나 감정을 더욱 직접적으로 구체화하기 위해 Unity 상의 NPC로 구현하는 형태로 진화했습니다. 이를 통해 시각적으로도 감정이 전달되는 더욱 풍부한 표현이 가능해졌습니다.
본 기사에서는 LangGraph를 통한 상태 관리와, **SSE (Server-Sent Events)**를 이용한 이종 시스템 간의 통신 기반에 대해 자세히 해설합니다.
시스템의 진화: 챗봇에서 「의지를 가진 NPC」로
Nebula System의 개발 과정은 단순한 기능 추가가 아니라, 아키텍처의 근본적인 개선의 연속이었습니다. 주요 진화 포인트는 다음 5가지입니다.
1. 🧠 프론트엔드의 쇄신: React에서 Unity로
처음에는 React 기반의 Web UI로 프로토타입을 구축하고 있었으나, NPC의 감정이나 실재감을 최대한 끌어내기 위해 3D 게임 엔진인 Unity로 이행했습니다. 이를 통해 텍스트 기반의 대화에서 시각적인 표정이나 제스처를 동반한 몰입감 (Immersion) 있는 체험으로 진화했습니다.
2. 🔄 로직의 고도화: LangChain에서 LangGraph로
단순한 선형 처리 (Chain)로는 복잡한 사고 프로세스나 상태의 왕복을 표현하기 어려웠습니다. 그래서 LangGraph를 채택하여 감정 분석, 지식 검색, 응답 생성을 「그래프 상의 노드」로 정의했습니다. 이를 통해 NPC가 상황에 따라 자율적으로 판단을 내리는 루프형 사고 로직이 가능해졌습니다.
3. 💾 기억의 영속화: 온메모리에서 데이터베이스 관리로
단기적인 대화뿐만 아니라 장기적인 관계를 구축하기 위해, 기억 관리를 온메모리에서 SQLAlchemy/SQLite를 통한 영속화로 변경했습니다. 서버를 재시작해도 플레이어와의 과거 추억이나 호감도 (Mood)를 유지하여 지속적인 체험을 제공할 수 있게 되었습니다.
4. 🔍 외부 세계로의 접속: MCP를 통한 리얼리티 추구
「닫힌 AI」에서 탈피하기 위해 **MCP (Model Context Protocol)**를 통합했습니다. 이를 통해 NPC가 Google Maps 등의 외부 도구를 통해 현실 세계의 지리 정보를 취득할 수 있게 되었으며, 대화 속에 「지금 도쿄는 비가 오네」와 같은 리얼리티를 포함하는 데 성공했습니다.
5. 📚 지식의 확장: RAG를 통한 세계관의 정착
NPC가 독자적인 세계관이나 설정을 정확하게 파악하기 위해 ChromaDB를 이용한 **RAG (검색 증강 생성)**를 구현했습니다. 방대한 설정 자료로부터 관련 정보를 순식간에 검색하여, 할루시네이션 (환각)을 억제하면서 설정에 충실한 답변을 생성할 수 있는 메커니즘을 구축했습니다.
기술적인 심층 분석: 복잡성과 속도, 그리고 안정성의 추구
Nebula System의 심장부는 LangGraph로 구축되어 있습니다. 하지만 기능을 확장함에 따라 새로운 엔지니어링상의 과제에 직면했습니다.
1. LangGraph를 통한 에이전트 설계
NPC의 사고를 「감정 분석 (Analyzer)」, 「지식 검색 (World Node)」, 「응답 생성 (Soul Node)」의 3가지 노드로 분할했습니다. 이를 통해 NPC는 단순히 응답하는 것뿐만 아니라, 「먼저 상대의 의도를 파악하고 배경 지식을 확인한 뒤에 말을 내뱉는」 인간다운 사고 프로세스를 획득했습니다.
NPC의 사고 프로세스를 정의하기 위해 다음과 같은 그래프 구조를 구축했습니다. 단순한 일방향 처리가 아니라, 감정 상태 (Mood)에 따라 루트가 동적으로 변화하는 것이 특징입니다.
# 워크플로우 구축: NPC의 사고 프로세스를 정의
builder = StateGraph(CombinedState)
# 1. 입력을 받고, 먼저 「감정 분석」을 실행
...
2. 「다기능화」가 불러온 대가: 응답 지연의 극복
RAG나 MCP 등의 스킬이 늘어남에 따라, 에이전트가 최종적인 답변을 내놓기까지의 계산 시간(Latency)이 증대되었습니다. 모든 처리가 끝날 때까지 플레이어를 기다리게 하는 것은 게임이나 일상 대화 경험으로서 치명적입니다.
이 과제를 해결하기 위해, **SSE(Server-Sent Events)**를 통한 스트리밍 통신을 도입했습니다.
서버 측에서 문장이 생성될 때마다 1토큰씩 Unity로 전송합니다. 나아가, 독자적인 **인밴드 신호 프로토콜(In-band signaling protocol)**을 설계하여, 텍스트 안에 **[[ANIM:HAPPY]]**와 같은 제어 태그를 삽입했습니다. 이를 통해 Unity 측은 문장 중간에 애니메이션을 재생할 수 있게 되었고, 플레이어에게 '대기 시간'을 느끼게 하지 않는 실시간 연출이 가능해졌습니다.
▼ 서버 측: 신호 주입
서버 측에서는 FastAPI의 StreamingResponse를 사용하여 LangGraph의 각 이벤트를 실시간으로 yield 합니다. 문장의 마지막에는 현재의 감정값을 인밴드 신호로 주입하고 있습니다.
# app/api/chat.py (발췌)
async def graph_streamer(payload, db, background_tasks):
# LangGraph의 스트림을 실행
...
▼ Unity 측: 신호 해석
Unity 측에서는 수신한 문자열 버퍼에 대해 정규 표현식(Regex)을 적용하여 [[KEY:VALUE]] 형식의 태그를 추출합니다. 추출된 태그는 즉시 액션(애니메이션 전환 등)으로 변환되며, 남은 순수한 텍스트만이 UI에 표시됩니다.
// NebulaManager.cs (발췌)
private void ProcessIncomingChunk(string chunk)
{
...
3. 「AI가 멈추지 않기」 위한 삼중 보호 전략 (Fallback)
개발을 진행하는 과정에서 클라우드 LLM의 API 제한(429)이나 일시적인 서버 다운(503)으로 인해 NPC가 갑자기 '무반응' 상태가 되는 문제에 직면했습니다. 이러한 '뇌사' 상태를 방지하기 위해, 삼중의 강등 보호(Fallback) 전략을 구현했습니다.
-
메인: gemini-3.5-flash/gemini-3.1-flash-lite (고정밀 사고)
-
제1 백업: llama-3.1-70b-versatile (클라우드 장애 시 고속 대체)
-
최종 방어선: Ollama (Llama 3.2) (완전 오프라인 · 로컬 추론)
만약 클라우드 측이 모두 불능 상태가 되더라도, 자신의 PC 내에서 동작하는 Ollama가 뇌를 대행하며, 말미에 **[[SYSTEM:OFFLINE]]**이라는 신호를 부가하여 NPC가 '조금 몸 상태가 좋지 않은(기운이 없는) 상태'임을 Unity에 전달합니다.
# app/chains/agents.py (발췌)
# 클라우드 LLM 생성: Gemini를 메인으로 하고, 실패 시 Groq(Llama)로 자동 전환
def create_cloud_llm(model_name, temperature=0):
...
마치며
Nebula System은 이제 막 첫걸음을 내디딘 프로젝트입니다.
이번에 LangGraph를 통한 상태 관리와 SSE 통신을 통한 실시간 동기화를 구현함으로써, NPC는 단순한 '텍스트 봇'에서 플레이어의 말에 반응하고 감정을 실어 행동하는 '의지를 가진 파트너'에 한 걸음 더 다가갈 수 있었습니다.
LLM의 진화는 게임의 방식과 인간과 컴퓨터의 관계를 근본적으로 바꾸어 놓을 것이라 믿습니다. 향후에는 음성 인식(STT) 및 음성 합성(TTS)의 통합, 나아가 멀티모달(Multimodal) 시각 정보의 부여에도 도전하여, 더욱 '살아있는' 것처럼 느껴지는 NPC 개발에 매진하겠습니다.
본 프로젝트의 소스 코드는 GitHub에 공개되어 있습니다. 혹시 관심이 생기셨다면 스타(Star)나 피드백을 주시면 엔지니어로서 큰 격려가 됩니다.
🌟 GitHub Repository: https://github.com/bshcl/nebula
AI 영역의 'Growing Star'로서, 지금은 아직 작은 빛일지 모르지만, 매일 지식을 흡수하여 언젠가 기술의 미래를 밝히는 존재가 될 수 있도록 앞으로도 계속 발신하겠습니다.
끝까지 읽어주셔서 감사합니다!
Discussion

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