MiroFish-Offline: a local multi-agent opinion simulator with Neo4j and Ollama
Offline multi-agent simulation & prediction engine. English fork of MiroFish with Neo4j + Ollama local stack.
At a glance
- What is it?
- MiroFish-Offline is an English fork of MiroFish that replaces Zep Cloud and DashScope with Neo4j Community Edition and Ollama. It runs a document through graph extraction, persona generation, a social simulation and a report, entirely on your own hardware.
- Who is it for?
- Adopt MiroFish-Offline if your documents cannot leave your network and you have the hardware the README lists: 16 GB of RAM minimum, 10 GB of VRAM for the 14b model, and enough patience for a local LLM to generate hundreds of personas. Do not adopt it if you want a hosted service, a mobile app, or a model small enough to run on a laptop CPU, because the 32b default will not fit there.
- Can I use it commercially?
- Yes, with strict conditions. AGPL-3.0 is a network copyleft licence: if people use a modified version over a network, for example as a hosted service, you must offer them its source code under the same licence.
- Is it still maintained?
- Yes. The repository last received commits 175 days ago.
- What is it written in?
- Mainly Python, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 15, 2026, and from our analysis. They are not legal advice.
DEEP OPEN-SOURCE ANALYSIS
The problem MiroFish-Offline solves: opinion simulation without sending documents to a cloud API
The original MiroFish, by 666ghj, was built for the Chinese market. Its README counterpart stack used Zep Cloud for graph memory, DashScope or OpenAI for generation, and a Chinese interface. That is a problem for anyone whose input is an unpublished press release, a draft regulation or an internal financial report: the document leaves your network before the simulation even starts.
MiroFish-Offline is a fork by nikmcfly that removes the cloud dependency. The README states the swap plainly: Zep Cloud becomes Neo4j Community Edition 5.15, DashScope and OpenAI become Ollama running models such as qwen2.5 or llama3, Zep Cloud embeddings become nomic-embed-text through Ollama, and the interface is translated into English across what the README describes as more than 1,000 strings. The repository describes itself as an English fork with a Neo4j and Ollama local stack.
The intended user is narrow. You need a document worth simulating, a machine with a GPU, and a reason not to use a hosted model. PR teams testing a crisis statement, analysts feeding in financial news, and policy researchers testing a draft regulation are the cases the README names. A reader who just wants to chat with an AI should look elsewhere; this is a pipeline, not a chatbot.
Graph build, persona generation and the simulation loop
The workflow has five stages, and the first one is the one that decides whether the rest is useful. Graph Build extracts entities (people, companies, events) and their relationships from your uploaded document, then writes them into Neo4j as a knowledge graph with separate individual and group memory. Env Setup then generates hundreds of agent personas, each with a personality, an opinion bias, a reaction speed, an influence level and a memory of past events. Simulation runs those agents on simulated social platforms where they post, reply, argue and shift opinions, while the system tracks sentiment evolution, topic propagation and influence dynamics. Report hands the post-simulation environment to a ReportAgent, which interviews a focus group of agents, searches the knowledge graph for evidence and produces a structured analysis. Interaction lets you chat with any agent afterwards, with memory and personality persisting.
The architecture section shows how the local stack is wired. A Flask API exposes graph.py, simulation.py and report.py. Below it sits a service layer with EntityReader, GraphToolsService, GraphMemoryUpdater and ReportAgent. Those talk to an abstract GraphStorage interface, and Neo4jStorage is the implementation, containing an EmbeddingService, a NERExtractor and a SearchService. Storage is reached through app.extensions['neo4j_storage'], which the README presents as dependency injection instead of global singletons.
Two details are worth flagging. First, retrieval is hybrid: the README gives the weighting as 0.7 times vector similarity plus 0.3 times BM25 keyword search. Second, named entity and relation extraction is synchronous through the local LLM, which the README describes as replacing Zep's async episodes. That is a real trade-off: synchronous extraction is easier to reason about and to debug, but every graph build waits on the model, and on a 32b model that wait is not small.
Installing MiroFish-Offline with Docker Compose
The Docker path is the one the README recommends. It clones the repository, copies the environment template, and brings up three services: the application, Neo4j and Ollama.
git clone https://github.com/nikmcfly/MiroFish-Offline.git
cd MiroFish-Offline
cp .env.example .env
docker compose up -dThe compose file starts the application on ports 3000 and 5001, Neo4j on 7474 for the browser and 7687 for Bolt, and Ollama on 11434. The application container waits for Neo4j to report healthy before starting. The Ollama service declares an NVIDIA device reservation, so a machine without the NVIDIA container runtime will not get GPU access even though the rest of the stack comes up.
Models are not baked into the image. You pull them into the running Ollama container by name:
docker exec mirofish-ollama ollama pull qwen2.5:32b
docker exec mirofish-ollama ollama pull nomic-embed-textAfter that, the README says to open http://localhost:3000. If the page loads but simulations stall, the usual cause is that the model name in .env does not match what you pulled, or that the base URLs still point at localhost from inside a container. The .env.example file carries commented Docker overrides for exactly this: LLM_BASE_URL=http://ollama:11434/v1, NEO4J_URI=bolt://neo4j:7687, EMBEDDING_BASE_URL=http://ollama:11434 and OPENAI_API_BASE_URL=http://ollama:11434/v1. Uncomment them when every service runs inside Docker.
There is also a manual path: run Neo4j 5.15-community in Docker, start Ollama and pull the models, then install backend requirements and run python run.py, and finally npm install and npm run dev in the frontend. The repository's package.json also exposes npm run setup:all, which installs frontend dependencies and runs uv sync in the backend.
The .env file is the whole configuration surface
Everything configurable lives in one file. The LLM block points at an OpenAI-compatible endpoint, which is why the README can say the stack works with any OpenAI-compatible API: swap Ollama for Claude or GPT by changing LLM_BASE_URL and LLM_API_KEY. The Neo4j block sets the Bolt URI and credentials, and the embedding block sets the model and its base URL separately from the chat model, because nomic-embed-text is served by Ollama on a different endpoint shape.
LLM_API_KEY=ollama
LLM_BASE_URL=http://localhost:11434/v1
LLM_MODEL_NAME=qwen2.5:32b
NEO4J_URI=bolt://localhost:7687
NEO4J_USER=neo4j
NEO4J_PASSWORD=mirofish
EMBEDDING_MODEL=nomic-embed-text
EMBEDDING_BASE_URL=http://localhost:11434There is a fifth block that is easy to miss. CAMEL-AI, which the README associates with the OASIS simulation layer, reads OPENAI_API_KEY and OPENAI_API_BASE_URL rather than the LLM_ variables. The template sets both to the same local Ollama server. If you change the chat endpoint and forget these two, the simulation layer and the graph layer will disagree about where the model lives, and the failure will look like a simulation bug rather than a configuration one.
Hardware limits and where this is the wrong tool
The README's hardware table is the most useful part of the documentation. Minimum is 16 GB of RAM, 10 GB of VRAM for the 14b model, 20 GB of disk and 4 CPU cores. Recommended is 32 GB of RAM, 24 GB of VRAM for the 32b model, 50 GB of disk and 8 or more cores. The default model in .env.example is qwen2.5:32b, which sits at the recommended tier, not the minimum one.
The README does state that CPU-only mode works but is significantly slower for LLM inference, and points to qwen2.5:14b or qwen2.5:7b for lighter setups. Read that as a warning rather than an option. Generating hundreds of personas and then running a multi-round social simulation means a large number of sequential model calls, and synchronous NER extraction adds more on top. On CPU, the pipeline does not become unusable so much as impractical for anything beyond a small document.
There are other boundaries. The stack is a web application served on localhost, not a mobile app; anyone searching for an APK or an iOS build will not find one in this repository, which contains a Flask backend, a Vue frontend and Docker files. There are no retrieved releases, so installation means building from the repository or cloning it. The README does not document rollback, migration between graph schemas, or what happens to an in-progress simulation if a container restarts; the compose file sets restart: unless-stopped on all three services, and the application mounts ./backend/uploads, but the Neo4j and Ollama volumes are named Docker volumes, so deleting them deletes your graphs and downloaded models. Finally, the last push to this repository was on 2026-03-24, so treat it as a snapshot rather than a project with a fast-moving upstream.
How MiroFish-Offline differs from the original MiroFish and from generic agent frameworks
The honest alternative is the project this is forked from. Original MiroFish targets the Chinese market with a Chinese interface, uses Zep Cloud for graph memory and DashScope for generation, and therefore requires cloud API keys. It is the better choice if you are comfortable with a hosted graph service and want the maintained upstream rather than a fork, and if Chinese-language output is what you need. MiroFish-Offline differs in the opposite direction on all three points: English UI, Neo4j Community Edition 5.15 as the graph store, and Ollama as the only model provider, with zero cloud dependencies as the stated goal.
The second comparison is to general multi-agent frameworks. Those give you agents, tools and orchestration primitives, and leave the simulation design to you. MiroFish-Offline ships an opinionated pipeline instead: document in, knowledge graph, personas, simulated social platform, report out. That is convenient if your problem matches the pipeline, and constraining if it does not. The GraphStorage abstraction is the escape hatch the README highlights: implementing one class should let you swap Neo4j for another graph database, though the README does not document a second implementation, so that claim is untested by anything in the repository.
Editorial conclusion
Adopt MiroFish-Offline if your documents cannot leave your network and you have the hardware the README lists: 16 GB of RAM minimum, 10 GB of VRAM for the 14b model, and enough patience for a local LLM to generate hundreds of personas. Do not adopt it if you want a hosted service, a mobile app, or a model small enough to run on a laptop CPU, because the 32b default will not fit there. Before trusting a simulation, verify three things: that your .env points at the right Ollama and Neo4j endpoints for your deployment mode, that qwen2.5:32b and nomic-embed-text are actually pulled into the Ollama volume, and that the knowledge graph built from your document contains the entities you expected.
Frequently asked questions
Does MiroFish-Offline need any cloud API keys?
No. The README describes the fork as having zero cloud dependencies, with Neo4j Community Edition replacing Zep Cloud and Ollama replacing DashScope. The .env.example sets LLM_API_KEY to the literal value ollama, and notes that any non-empty value works for a local server.
What hardware does MiroFish-Offline require to run the simulation?
The README lists 16 GB of RAM, 10 GB of VRAM for the 14b model, 20 GB of disk and 4 CPU cores as the minimum, and 32 GB of RAM with 24 GB of VRAM for the 32b model as recommended. CPU-only mode is documented as working but significantly slower, with qwen2.5:14b or qwen2.5:7b suggested for lighter setups.
How do I install and start MiroFish-Offline?
The README's Docker path clones the repository, copies .env.example to .env, runs docker compose up -d, then pulls qwen2.5:32b and nomic-embed-text into the mirofish-ollama container. The application is then reachable at http://localhost:3000.
Community notes