MiroFish-Offline: 문서 하나로 여론을 시뮬레이션하는 완전 로컬 멀티 에이전트 엔진

MiroFish-Offline 소개

새 정책 초안이나 보도자료, 실적 보고서를 내보내기 전에 "사람들이 어떻게 반응할까"를 미리 가늠해 보고 싶을 때가 있습니다. MiroFish-Offline 은 이 질문을 시뮬레이션으로 풀어 보는 멀티 에이전트 군집 지능(swarm intelligence) 엔진으로, 문서 한 편을 올리면 저마다 성격이 다른 수백 명의 AI 에이전트를 만들어 소셜 미디어에서의 여론 반응을 시간 단위로 모사합니다. 게시물과 논쟁, 의견 변화가 시간이 지나며 어떻게 번지는지를 관찰할 수 있습니다.

MiroFish-Offline의 가장 큰 특징은 이름 그대로 완전 로컬(fully local) 이라는 점입니다. 이 프로젝트는 원본 MiroFish를 포크한 것인데, 원본은 중국어 UI에 그래프 메모리로 Zep Cloud, LLM으로 DashScope API를 쓰는 등 클라우드 서비스에 의존했습니다. 이 포크는 UI를 영어로 옮기고(1,000개 이상의 문자열 번역), 그래프 메모리를 Neo4j 커뮤니티 에디션으로, LLM을 로컬 Ollama로 바꿔 클라우드 의존성을 없앴습니다. 그 결과 문서도, 시뮬레이션 데이터도 사용자의 기기 밖으로 나가지 않습니다.

기술적으로는 Python 백엔드에 Neo4j와 Ollama 로컬 스택을 결합한 구조입니다. 업로드한 문서에서 엔티티와 관계를 추출해 지식 그래프를 만들고, 그 위에 개성을 가진 에이전트들을 올려 상호작용을 돌린 뒤, 결과를 구조화된 분석 보고서로 정리합니다. 본 게시물에서는 MiroFish-Offline의 5단계 시뮬레이션 워크플로우, 클라우드를 걷어낸 로컬 스택, 내부 아키텍처, 그리고 설치·실행 방법을 정리합니다.

MiroFish-Offline의 5단계 시뮬레이션 워크플로우

MiroFish-Offline은 문서 한 편을 다섯 단계를 거쳐 여론 시뮬레이션으로 바꿉니다. 첫 단계인 그래프 구축(Graph Build) 에서는 문서에서 인물, 기업, 사건 같은 엔티티와 그 관계를 추출해 Neo4j에 개인 기억과 집단 기억을 갖춘 지식 그래프를 만듭니다. 두 번째 환경 설정(Env Setup) 단계에서는 수백 명의 에이전트 페르소나를 생성하는데, 각 에이전트는 고유한 성격과 의견 편향, 반응 속도, 영향력 수준, 과거 사건에 대한 기억을 가집니다.

세 번째 시뮬레이션(Simulation) 단계에서는 에이전트들이 모사된 소셜 플랫폼에서 글을 올리고, 답하고, 논쟁하고, 의견을 바꿉니다. 시스템은 이 과정에서 감정(sentiment) 변화와 주제 확산, 영향력 동역학을 실시간으로 추적합니다. 네 번째 보고서(Report) 단계에서는 ReportAgent가 시뮬레이션이 끝난 환경을 분석하고, 에이전트들로 구성된 포커스 그룹을 인터뷰하며, 지식 그래프에서 근거를 찾아 구조화된 분석을 생성합니다. 마지막 상호작용(Interaction) 단계에서는 시뮬레이션 세계의 특정 에이전트와 직접 대화하며 왜 그런 글을 올렸는지 물어볼 수 있고, 이때 에이전트의 기억과 성격은 그대로 유지됩니다.

MiroFish-Offline이 클라우드를 걷어낸 방식

이 포크가 원본과 가장 크게 갈라지는 지점은 외부 클라우드 서비스를 로컬 구성요소로 대체했다는 데 있습니다. 그래프 메모리는 Zep Cloud 대신 Neo4j 커뮤니티 에디션 5.15를 쓰고, LLM은 DashScope나 OpenAI API 대신 Ollama로 띄운 로컬 모델(qwen2.5, llama3 등)을 사용하며, 임베딩도 Ollama 기반 nomic-embed-text 로 처리합니다.

항목 원본 MiroFish MiroFish-Offline
UI 언어 중국어 영어 (1,000개 이상 문자열 번역)
그래프 메모리 Zep Cloud Neo4j Community Edition 5.15
LLM DashScope / OpenAI API Ollama (qwen2.5, llama3 등)
임베딩 Zep Cloud Ollama 기반 nomic-embed-text
클라우드 의존성 클라우드 API 키 필요 클라우드 의존성 없음

설정은 모두 .env 파일에 모여 있습니다. LLM은 OpenAI 호환 API로 로컬 Ollama(http://localhost:11434/v1)를 가리키도록 되어 있고, Neo4j 접속 정보와 임베딩 모델도 여기서 지정합니다. OpenAI 호환 API라면 무엇이든 연결되므로, LLM_BASE_URLLLM_API_KEY 만 바꾸면 Ollama 대신 Claude나 GPT 같은 다른 제공자로 교체할 수도 있습니다.

MiroFish-Offline의 아키텍처

이 포크는 애플리케이션과 그래프 데이터베이스 사이에 깔끔한 추상화 계층을 둔 것이 특징입니다. Flask API(graph.py, simulation.py, report.py)가 서비스 계층(EntityReader, GraphToolsService, GraphMemoryUpdater, ReportAgent)을 호출하고, 그 아래에 추상 인터페이스인 GraphStorage 가 있어 구체 구현인 Neo4jStorage 가 임베딩과 개체명 인식(NER), 하이브리드 검색을 담당합니다.

┌─────────────────────────────────────────┐
│              Flask API                   │
│  graph.py  simulation.py  report.py      │
└──────────────┬───────────────────────────┘
               │ app.extensions['neo4j_storage']
┌──────────────▼───────────────────────────┐
│           Service Layer                   │
│  EntityReader  GraphToolsService          │
│  GraphMemoryUpdater  ReportAgent          │
└──────────────┬───────────────────────────┘
               │ storage: GraphStorage (추상)
┌──────────────▼───────────────────────────┐
│   Neo4jStorage                            │
│   EmbeddingService ← Ollama               │
│   NERExtractor     ← Ollama LLM           │
│   SearchService    ← Hybrid search        │
└──────────────┬───────────────────────────┘
               │
        ┌──────▼──────┐
        │  Neo4j CE   │
        │  5.15       │
        └─────────────┘

핵심 설계 결정은 두 가지입니다. GraphStorage 를 추상 인터페이스로 두어 클래스 하나만 구현하면 Neo4j를 다른 그래프 데이터베이스로 바꿀 수 있게 했고, 전역 싱글톤 대신 Flask의 app.extensions 를 통한 의존성 주입(dependency injection)으로 구성요소를 연결합니다.

MiroFish-Offline 설치 및 사용법

가장 쉬운 방법은 Docker Compose로 Neo4j, Ollama, MiroFish를 한 번에 띄우는 것입니다. 저장소를 클론하고 환경 파일을 복사한 뒤 서비스를 올리고, Ollama에 필요한 모델을 받아 둡니다.

git clone https://github.com/nikmcfly/MiroFish-Offline.git
cd MiroFish-Offline
cp .env.example .env

# 모든 서비스 실행 (Neo4j, Ollama, MiroFish)
docker compose up -d

# Ollama에 필요한 모델 내려받기
docker exec mirofish-ollama ollama pull qwen2.5:32b
docker exec mirofish-ollama ollama pull nomic-embed-text

이후 http://localhost:3000 을 열면 됩니다. Docker를 쓰지 않는다면 Python 3.11 이상, Node.js 18 이상, Neo4j 5.15 이상, Ollama를 준비해 Neo4j와 Ollama를 각각 실행하고, backend 에서 pip install -r requirements.txtpython run.py 로 백엔드를, frontend 에서 npm installnpm run dev 로 프런트엔드를 띄웁니다. VRAM이 부족하면 qwen2.5:32b 대신 qwen2.5:14b 를 사용할 수 있습니다.

MiroFish-Offline의 라이선스

MiroFish-Offline은 AGPL-3.0 라이선스로 공개되어 있습니다. AGPL-3.0은 소스 공개 의무가 강한 카피레프트(copyleft) 라이선스로, 이 코드를 사용한 파생물은 물론 네트워크 너머로 서비스(예: SaaS)할 때도 전체 소스를 동일 라이선스로 공개해야 합니다. 상업적으로 활용하려면 LICENSE 파일과 AGPL-3.0 조항을 직접 확인하는 것이 좋습니다.

:github: MiroFish-Offline 프로젝트 GitHub 저장소

더 읽어보기




이 글은 GPT 모델로 정리한 글을 바탕으로 한 것으로, 원문의 내용 또는 의도와 다르게 정리된 내용이 있을 수 있습니다. 관심있는 내용이시라면 원문도 함께 참고해주세요! 읽으시면서 어색하거나 잘못된 내용을 발견하시면 덧글로 알려주시기를 부탁드립니다. :hugs:

:pytorch:파이토치 한국 사용자 모임:south_korea:이 정리한 이 글이 유용하셨나요? 회원으로 가입하시면 주요 글들을 이메일:love_letter:로 보내드립니다!
텔레그램(Telegram)이나 Slack/Discord/Teams/Dooray/GoogleChat 등으로도 새 글 알림을 받으실 수 있습니다. :smiley:

:wrapped_gift: 아래:down_right_arrow:쪽에 좋아요:+1:를 눌러주시면 새로운 소식들을 정리하고 공유하는데 힘이 됩니다~ :star_struck: