A 2024 study tested 162 personas across 9 models and 2,410 factual questions. Adding personas to system prompts produced no improvement compared to a no-persona baseline. Some personas actively decreased accuracy. Automatic persona selection performed no better than random selection.
That result didn't surprise me. What surprised me was how many orchestrators I'd seen — including earlier versions of the one I was building — still opened every agent with "You are a senior software engineer with 10 years of experience in distributed systems."
That sentence does nothing. I removed it. Things got better.

Why "You are a..." doesn't work
The role-playing framing made sense for human teams. A job title communicates expectations, constraints, and scope to a person who has a self-concept. Models don't work that way. A model doesn't have a self to override with a persona. It has a next-token prediction function. Telling it "you are an architect" doesn't activate architecture knowledge — that knowledge is already there. What changes output is telling it what to produce, what to avoid, and what failure looks like.
The research backs this up. The models with the highest baseline accuracy saw the most persona-related degradation. The better the model, the worse the persona helped. A "senior security engineer" persona might produce output that reads more like a security review without catching more vulnerabilities. The identity is cosmetic. The constraints are not.
Constraints as the whole persona
Nanika's personas don't start with identity. They start with ## Constraints. No backstory, no role fiction. Just:
- What this agent must do
- What it must never do
- What a correct output looks like
- What patterns to avoid
That's it. The ten personas that ship with nanika — architect, senior-backend-engineer, staff-code-reviewer, devops-engineer, and the rest — are all structured this way. The architect persona's first constraint is "trade-offs are the deliverable: every decision must document what was chosen, what was rejected, and why." Not "you think like an architect." It defines the output contract.
Each persona follows the same format: ## Constraints first, then ## Output Contract, then ## Methodology, then ## Anti-Patterns. The structure means every persona answers the same four questions before it touches any work. You can read any persona file in under a minute and know exactly what it will and won't produce.
How missions work
Nanika is a multi-agent orchestrator for Claude Code. You give it a task. It breaks it into phases, assigns each phase a persona and objective, and runs them — in parallel where the dependency graph allows, in sequence where it doesn't.

The unit of work is a PHASE line:
PHASE: implement | OBJECTIVE: Build the auth handlers and tests | PERSONA: senior-backend-engineer | DEPENDS: designEach phase gets its own Claude Code session, its own workspace, and its own persona. Workers don't share state directly — they communicate through artifacts. The output from design becomes the input to implement. The output from implement goes to review. If review fails, the engine injects a fix-then-re-review cycle before continuing.
You can write PHASE lines yourself or let the decomposer generate them. I use pre-written PHASE lines for anything I care about — the LLM decomposer is fine for exploratory work but unpredictable for anything production. When you write PHASE lines, the orchestrator bypasses its LLM decomposer entirely and runs exactly what you specified.
The whole thing is a Go binary with two external dependencies: Cobra for the CLI and modernc/sqlite for pure-Go SQLite. No LangChain. No message broker. Each worker runs as an isolated subprocess that inherits a controlled environment. When the subprocess dies, it writes its findings to SQLite and disappears. The next worker reads from there.
The part that watches itself
This is where I spent the most time. Running 400+ missions teaches you things, but only if you're collecting the data and acting on it.
Nanika has a system called Nen — named after the ability system in Hunter x Hunter, which felt like the right level of nerd for a tool that watches itself improve. Six abilities, each with a specific job.

Gyo watches mission metrics for anomalies — phases taking 3x longer than their z-score baseline, retry rates spiking on a specific persona, review gates looping. It answers why, not just that something failed.
Shu does broad sweeps of overall system health. When health scores drop, it generates a finding. When findings cross a severity threshold, it proposes a remediation mission — an actual orchestrator mission file that fixes the problem. You review and approve it, the scheduler dispatches it.
Ko is the eval engine. YAML test suites with assertions against LLM output. When Shu says "decomposer accuracy dropped," Ko reruns the relevant suite, verifies the regression, and confirms the fix worked. Promptfoo-compatible format so you can bring your own suites.
En, Ryu, Zetsu run automatically via the daemon. En checks binary freshness and workspace hygiene. Ryu analyzes token costs and flags retry waste. Zetsu strips untrusted input at trust boundaries so workers don't get injected.
In practice this loop catches things you'd miss watching manually. Persona mis-routing on implementation tasks is subtle — the mission succeeds, the output is just slightly off. Gyo flags the anomaly. Ko runs assertions. You fix the persona, Ko confirms the score improved. The system gets better without you watching it full-time.
Haiku beat Sonnet at persona routing
When I was investigating why persona selection accuracy was lower than expected, I built a 23-case benchmark and ran it against two models.
Haiku: 91.3% (21/23). Sonnet: 82.6% (19/23).
Haiku outperformed Sonnet on persona routing. The misses were telling — Sonnet sent deployment rollback to a staff-code-reviewer, operational readiness to a qa-engineer. It over-thought the boundary cases. Haiku routed faster and more accurately. The primary LLM selector now runs Haiku with a 15-second timeout, falls back to keyword matching if it fails, and logs the fallback so you know when it's happening.
I don't have a clean explanation for why this works. My guess is that persona routing is a classification task with clear boundaries, and Haiku's lower latency and simpler reasoning happens to fit that better than Sonnet's tendency to consider edge cases. But it's a guess. The benchmark is in the repo if you want to run it yourself.
It's open source
I've been running this for six weeks. 400+ missions, 90%+ success rate. It's not polished software — it's a working system that I use daily and am continuing to build. The self-improvement loop is real and running.
The code is at github.com/joeyhipolito/nanika. Docs at howtoai.sh/nanika. The installer is interactive — it checks prerequisites, lets you pick plugins, and runs doctor checks before it's done.
git clone https://github.com/joeyhipolito/nanika
cd nanika
scripts/install.shThen open it in Claude Code, run a mission, and see what you think. If you find something broken or wrong, open an issue. If the constraint-first persona approach is interesting to you, the full persona spec is in docs/PERSONA-STANDARD.md.
The personas will probably go away eventually. The direction is composable constraint modules — stacks of behavioral rules that apply to any worker without an identity layer at all. The goal is to make the role concept unnecessary, not to simulate it better. But that's later.
Right now it works and it's open.