I forked MiroFish, replaced its cloud knowledge-graph service with local Neo4j and Ollama, and translated more than 1,000 interface strings into English.
The result is MiroFish-Offline: a version that can build and run a multi-agent simulation without sending the source document to a cloud model or cloud memory service.
“Can” matters here. It stays local only when the user selects local models and runs the required services on their own hardware.
What MiroFish does
MiroFish turns a source document into a simulated social environment.
The workflow has five parts:
- It extracts people, organizations, events, and relationships from the document.
- It stores that information in a knowledge graph.
- It creates many agent profiles with different attributes and starting opinions.
- The agents post, reply, and react inside a simulated network.
- A reporting agent summarizes patterns in the generated activity.
The output is a set of possible reactions created by language models under chosen assumptions. It is not a poll, a representative sample, or evidence that real people will behave the same way.
Why I wanted a local version
The original project used a hosted graph-memory service and was designed primarily for Chinese users. That created two practical limits for my use:
- the interface was difficult for an English-speaking team to operate;
- a sensitive press release, strategy document, or policy draft could leave the local machine.
Moving the graph and model calls onto local hardware made the data path easier to understand. It also made installation heavier and inference slower.
The three main changes
1. Neo4j replaced the cloud graph service
The original backend expected one provider to store entities, relationships, and memory. I replaced that dependency with Neo4j Community Edition.
This required more than changing a connection string. The application needed a storage layer that could create and search entities, retrieve relationships, preserve simulation memory, and return data in the shape expected by the rest of the system.
I first mapped every place where the old service appeared. Then I defined the replacement operations and changed one part of the pipeline at a time.
2. Ollama made local model calls possible
The fork can use models served through Ollama for entity extraction, agent generation, and simulation work. Local embeddings are used for similarity search inside the graph.
Users can still choose another compatible provider, but that changes the privacy boundary. If an external API is selected, prompts and document-derived data may be sent to that provider.
3. The visible interface moved to English
The frontend contained more than 1,000 Chinese strings across 20 files. These included buttons, instructions, progress messages, graph labels, logs, and report screens.
I translated the user-facing interface while preserving backend patterns that depended on the original response format. A translation can be linguistically correct and still break software if a parser expects a particular marker.
Planning made the migration manageable
Before editing the code, I created four short working documents:
- a technical map of the cloud dependency and target local stack;
- a migration plan broken into dependent tasks;
- a progress file recording completed and blocked work;
- a publishing checklist covering the original AGPL license and attribution.
Claude Code implemented much of the migration from those documents. The useful part was not that an AI wrote many lines quickly. The useful part was that every session had a defined boundary and a record of what remained.
Local simulation has real hardware costs
The repository currently lists 16 GB of RAM as a minimum and 32 GB as the recommended amount. A compatible GPU makes the simulation much faster; CPU-only inference works but can be slow.
Local processing also means the operator owns:
- model installation and storage;
- Neo4j data and backups;
- memory and GPU limits;
- software updates;
- access control on the machine;
- deletion of source documents and simulation data.
Removing a cloud dependency does not remove operational work. It moves that work to the user.
Use the output to ask questions, not claim predictions
A simulation can be useful for exploring how a message might be misunderstood, which groups of assumptions create conflict, or which narrative deserves further testing.
It should not be presented as:
- a forecast of public opinion;
- a replacement for interviews or polling;
- a trading signal with known accuracy;
- proof that a policy will succeed or fail;
- a model of a population that was never represented in the input.
The safest workflow is to compare several scenarios, record the assumptions behind each one, and use the generated reactions to design real research.
For example, a team can run two versions of a press release, collect the strongest objections produced by each simulation, and turn those objections into interview questions for actual customers. The value is the question set, not a percentage labeled “predicted sentiment.”
If you want to test the fork, start with a short public document and a small simulation. Check the hardware requirements and privacy settings before using confidential material. The installation guide and source code are in the MiroFish-Offline repository.