Case study · MiroFish-Offline · 2026
A fork I run daily, not an engine I wrote
MiroFish-Offline is a fork of MiroFish: upload a document and hundreds of AI agents with their own personalities simulate the public reaction on social media. The engine is not mine. My part is running it fully local, keeping it alive, and fixing what got in the way — and it is now a daily tool in the BYRIS workflow.
What the engine is, and whose it is
MiroFish was built for the Chinese market: Chinese UI, Zep Cloud for graph memory, DashScope for the model. The MiroFish-Offline fork replaces all of that with an English UI, Neo4j Community, and Ollama — zero cloud dependencies, AGPL-3.0. Neither the engine nor the fork is my work, and this page does not claim otherwise.
What I did is make it run on my machine, on my models, every day: a local 9B model (Bonsai 2) for personas and ontology, nomic-embed-text for embeddings, Neo4j 5.18 in Docker, a Flask backend and a Vue frontend. The first end-to-end run built a 9-node graph of real entities and finished a 4-agent, 72-round Twitter simulation in 109 seconds — 37 posts and 86 action traces, no cloud call in the loop.
What I fixed to make it a daily driver
- Dependency pins that unbreak the install: Python 3.11 (not 3.12 — the README oversells), mcp 1.6.0 with pydantic 2.9.2, so the camel-ai chain imports at all
- A Windows workaround for LoRA loading, where drive-letter colons split the adapter path — fixed with a relative-path launcher instead of patching the loader
- A local proxy adapter for a subscription LLM provider that only speaks streaming: it accepts non-stream requests, forwards SSE, reassembles the deltas, and enforces a max-tokens floor so JSON actions stop getting truncated mid-object
- A report pipeline that stops the report agent from hallucinating: every quote is checked verbatim against Neo4j facts and the simulation log (9/9 verified on the last run), a dedup pass rejects corrupted output, and a limitations appendix ships with every report
- Small correctness fixes: the report endpoint now returns the newest report instead of a random directory listing, and the parallel runner honors the simulation model settings it previously ignored
How BYRIS uses it
BYRIS is a census of 1,170 Indonesian exporters, and its workflow needs a way to stress-test how material lands before it ships. MiroFish is the simulation layer for that: build a graph from a document, generate personas against it, run the swarm, and read the report. It runs daily, which is a different bar than a demo — every failure above was found because the work depended on it that morning.
What is still broken
Action diversity in long parallel runs is poor: one model refreshes far more than it posts, so some simulations come back flat. The mixed-model setup (local model for personas, subscription model for interactions) is installed but not yet proven end to end. And report generation dies silently if the backend reloads mid-run — a known failure mode I work around rather than a bug I have fixed.
← Back to the work · BYRIS, the work it serves → · About the author