Inspiration
The seed for this project wasn't "build a multi-agent framework" , it was a thought experiment about designing an AI society: not a single clever agent, but a population of agents with distinct roles, competing and cooperating under rules, governed by something like institutions rather than a single hard-coded control loop. The moment that crystallized it was realizing that the interesting problems in that thought experiment weren't technical at all. They were institutional-design problems: who decides, who checks the decider, what happens when two agents disagree, and how do you keep a shared record of why something happened rather than just what happened.
That reframing is what became Instagents: instead of one big prompt doing everything, a hub-and-spoke system where an orchestrator decomposes work, specialist agents bid and execute in parallel, a critic gates every output, and a bounded council + arbiter resolve what the critic alone can't , with every handoff between agents forced through a typed schema (extra="forbid", no raw strings crossing a boundary) so the whole thing stays auditable rather than becoming an opaque conversation.
What it does
Given a natural-language task, an orchestrator (qwen-max) decomposes it into a small DAG of subtasks with explicit dependencies and acceptance criteria. Independent subtasks run in parallel across a Redis-backed worker pool. Every artifact a worker produces is reviewed by a critic before it's accepted , one repair attempt is granted on failure, and if that fails too, the task escalates to a bounded worker↔critic negotiation (max 2 rounds) that a single arbiter call resolves once: accept, reject, or accept-with-repair. Tasks whose ownership is genuinely ambiguous (e.g. "summarize the findings" could be a researcher's job or a writer's) go through a contract-net bidding round instead of a coin flip. A circuit breaker, a hard per-run budget, and crash-recovery via orphaned-queue-item requeuing keep the whole thing from silently spinning or blowing through cost. Layered on top, a reputation system, a diversity-preserving prompt-variant selector, and a playbook of distilled successes let the population's behavior improve across runs, not just within one. A single-agent baseline and a live dashboard exist specifically to keep the system honest about whether any of this negotiation overhead is actually worth it.
How we built it
The build order followed the dependency order of trust: first the wire formats (schemas.py), because nothing else can be honest about its own guarantees if the data crossing agent boundaries is just strings. Then the blackboard , a thin Redis wrapper with optimistic concurrency control via a single atomic Lua check-and-set script, so a stale write raises VersionConflict instead of silently clobbering another writer's work. Then the shared agent loop (base_agent.py): call the model, parse tool calls, execute or terminate, feed results back, repeat , with a TERMINAL_TOOLS mechanism so the orchestrator, critic, and arbiter can get schema-locked JSON out of a tool-calling model without any prose parsing. Only after that scaffolding existed did the actual roles get layered on: researcher, coder, writer, critic, arbiter, each scoped to its own tool set (the critic, notably, has zero mutation tools , it is structurally incapable of fixing what it's reviewing, not just told not to).
The fault-tolerance layer came from asking "what happens when this runs unattended and something goes wrong": a circuit breaker that opens per role after consecutive failures, a run-scoped budget shared across worker threads via Redis INCR, and a dead-letter queue for anything that exhausts repair and escalation.
The most recent layer grew directly out of the original thought experiment. Having built the institutions (critic, arbiter, bidding), the natural next question was whether the population could get better over time instead of restarting from zero every run:
- Reputation , a Beta(1,1)-smoothed trust score per role, updated from every critic verdict and arbiter ruling:
$$ \text{score}(s) = \frac{\text{successes}(s) + 1}{\text{attempts}(s) + 2} $$
A subject with no history starts neutral at $0.5$ rather than being punished or favored by default, and folds into contract-net bid scoring as a gentle nudge:
$$ \text{score}(b) = \text{confidence}(b) - 0.02 \cdot \text{steps}(b) + 0.2\big(\text{rep}(b) - 0.5\big) $$
- Diversity preservation , since each role is a single reused instance per run, without intervention every dispatch would run the identical prompt: a population of one. Each worker role gets two stance variants, chosen epsilon-greedily against per-variant reputation:
$$ \pi(v \mid \text{role}) = \begin{cases} \text{Uniform}(V) & \text{w.p. } \epsilon = 0.2 \ \arg\max_{v} \ \text{rep}(\text{role}, v) & \text{w.p. } 1-\epsilon \end{cases} $$
so a merely-unlucky-early stance doesn't get permanently starved out.
- Playbook , a capped list of first-attempt successes per role, fed back as few-shot context: a prompt-level stand-in for fine-tuning, since these agents call a hosted endpoint with no weights to actually update.
Each of the three was scoped tightly against a real design question rather than added speculatively , we explicitly reasoned through, and rejected, giving agents a persistent episodic memory graph, since that would let behavior drift on private state nothing else in the system could audit, directly against the "every handoff is typed and visible" principle the rest of the architecture is built on.
Challenges we ran into
The most persistent challenge was concurrency correctness, not agent prompting. Multiple workers claiming tasks, bidding rounds firing in parallel threads, and the orchestrator's poll loop resolving escalations all touch the same Redis-backed task graph , the optimistic-concurrency Lua script and the disciplined "reread and back off, don't guess" response to VersionConflict took several iterations to get right, especially distinguishing genuine race conditions (two writers touching the same version) from conditions that only look like races but are actually crash-recovery re-claims of an orphaned task.
The second, more uncomfortable challenge was intellectual honesty about the results. Running the multi-agent pipeline against the single-agent baseline on both a sequential and a breadth-heavy task showed the multi-agent system running at roughly $0.44\text{–}0.53\times$ the baseline's speed, slower, not faster, even with real parallelism and bidding firing correctly, because the per-subtask critic-review overhead outweighed the parallelism gain at this task scale. It would have been easy to cherry-pick a more favorable task or bury that finding; instead the dashboard reports it directly.
The third challenge was scope discipline on the reputation/diversity/playbook layer: it would have been easy to over-build this into a full memory-graph, RL-style credit assignment system. Repeatedly asking "does this specific mechanism need to exist, or am I building it because the original thought experiment mentioned it" is what kept reputation to a two-field Redis hash instead of a training pipeline.
Accomplishments that we're proud of
Reporting the 0.44 – 0.53x baseline comparison honestly instead of quietly tuning the demo task until multi-agent looked faster: the defensible claim (reliability at a latency cost, evidenced by the critic catching a real filename-mismatch bug the ungated baseline had no mechanism to catch) is more useful than a flattering but misleading one. We're proud of the critic's structural powerlessness to fix what it reviews, a separation-of-powers guarantee enforced by the tool registry, not a prompt instruction an agent could be talked out of. We're proud that every negotiation (bids, council turns, arbiter rulings, reputation updates) writes to one append-only decision log, so the entire history of a task's journey through the system, including its disagreements, is inspectable after the fact, not just its final artifact. And we're proud that the reputation/diversity/playbook layer, added last, integrated without touching a single existing schema, a sign the original typed-handoff discipline actually paid for itself.
What we learned
The deepest lesson tracked the original inspiration almost exactly: the hard problems in building a multi-agent system are institutional, not technical. Bounding a negotiation (MAX_ROUNDS=2, one arbiter ruling, arbiter_ruled blocking re-escalation) is a governance decision disguised as a constant. Deciding that the critic gets zero mutation tools is a separation-of-powers decision disguised as a tool registry. And deciding not to give agents persistent memory was, in the end, the same kind of call a constitution makes about what power an institution is and isn't granted , bounded, auditable, and legible mattered more than capable-but-opaque, at every layer of this system.
What's next for Instagents
A few directions feel like natural continuations rather than scope creep. First, testing whether the negotiation overhead actually reverses in Instagents' favor at larger scale or higher parallelism , the current honest finding was measured on small demo tasks, and the architecture's real thesis (reliability compounding faster than latency cost as task complexity grows) is still untested. Second, ConflictEvent.resolution == "escalated_to_council" is defined in the schema but intentionally unused today, since this architecture makes true semantic dependency conflicts structurally impossible; a version of Instagents with mutable shared artifacts (rather than immutable-once-committed ones) would need to actually implement that path. Third, extending reputation and the playbook from single-run demos into a longer-lived deployment to see whether the epsilon-greedy diversity mechanism converges sensibly over hundreds of tasks rather than the handful we've been able to test against live. And if hosted fine-tuning access becomes available, the playbook's distilled exemplars are already the exact dataset a real distillation loop would train on , the in-context version was deliberately built as a stepping stone, not a permanent substitute.

Log in or sign up for Devpost to join the conversation.