Skip to main content

I Built a Council of AI Advisors Because the Old One Died Right When I Needed It

Back to Brain Dumps
I Built a Council of AI Advisors Because the Old One Died Right When I Needed It
July 21, 2026
6 min read
AI coding agentspimulti-modelLLM context windowbuilding in publicopen source

Here's the setup most people running an AI coding agent land on eventually: put a cheap, fast model in the driver's seat. It's grinding through edits, running tests, renaming variables. Work where the expensive model's extra IQ buys you nothing. So you save the money.

Good call, most of the time.

The problem is the handful of moments that aren't most of the time. The architecture fork. The "should I even build this." The bug the agent's been circling for twenty minutes, confidently wrong. That's where cheap-and-fast makes the call it shouldn't, and you don't notice until three commits later when you're unpicking it.

The fix is obvious once you say it out loud: keep a smarter, pricier model on the bench, and call it in only for those moments. I'd already run exactly this in a private tool of my own, well before I needed it in pi: cheap models doing the grunt work, a stronger one steering. I knew the pattern held. So when I wanted it in pi, I reached for the advisor extension that already existed.

And then it died on me. Repeatedly.

Not in an interesting way. In a boring, frustrating way. I'd be deep in a session — the exact kind of long, tangled session where a second opinion is worth the most, and the advisor call would just error out.

The reason, once I dug in, was almost funny. The extension forwarded the entire session to the advisor model. Every message, every tool call, every result. What it never did was check whether the advisor's own context window could actually hold all that.

And an advisor doesn't have to be the same size as your executor. Point a small, cheap advisor — or a CLI model with a 32k window — at a session your big executor has been happily filling to 128k, and the advisor call overflows its own window and falls over.

So the advisor quit at precisely the moment the session got long enough to need it. It's the localhost-on-production of AI tooling — everything works in the demo, nothing works when it counts. A second opinion that can't survive a real session isn't a second opinion. It's decoration.

Fixing the bug, then going way past it

The actual fix is a context engine that sits in front of every advisor call. And the budget it works to is read per call, from that specific advisor's real context window, not a global constant someone guessed once. A flash-tier advisor gets fitted to its window; an 8k CLI model gets fitted to its window; a council fits everyone to the smallest window in the roster so the weakest member can't be the one that blows up. That's the whole reason "cheap executor, expensive advisor" works instead of theoretically working.

The first version of that fit was blunt, though: keep the first couple of messages, keep the last several, drop the middle, char-cap what's left. It never overflowed. But "keep recent, drop old" is a lousy proxy for "keep what matters." In a long debugging session the line that explains why you're stuck is usually buried in the middle, and blindly truncating a message shreds the one stack trace the advisor actually needed. So now it classifies before it cuts.

Every message gets a deterministic tag — directive, diff, failing-output, stack-trace — from what it is, never from the stuck model's own judgment (the stuck model being the worst possible judge of what's safe to drop). Then it fills the window by priority: your question pinned first, the latest failure and diff kept verbatim, the old exploration path compressed down to one-line signals (edit y.ts (+30/-5), $ npm test (exit 1)), then dropped. Compress the path, preserve the payload.

And because it now decides what to keep, it can hand you the receipt. Every consult comes back with a ledger: how many messages it kept whole, compressed, clipped, dropped, and the token count it fitted into. You can watch a 150k session get folded into a 28k advisor and see exactly what survived. If you ever suspect the fit is dropping something it shouldn't, that's the measuring tape.

No more guessing whether the second opinion saw the thing you were asking about.

But here's where I stopped writing a bugfix and started building a thing. If you're already paying to spin up a second model, why stop at one? And why only use it to review after the fact?

One advisor is fine. A whole council is better.

bpx-consult ships four modes, sized to the question. Solo is one advisor, one answer — the quick second opinion for a normal day. Gut-check is a cheap fast model giving you a terse "does this smell off?" before you do something you're already 90% sure about. Those two cover the small calls.

The big ones get the interesting modes. Council runs several models in parallel, each with a persona and a stance, and a synthesizer merges their verdicts. Debate is sequential and adversarial — an advocate makes the case, a critic tears into it, the advocate rebuts, then a referee calls it. For the genuinely contentious decisions where you want the strongest version of both sides before you commit.

You don't hand-build the roster from a config file, either. You can describe the decision ("I'm choosing a database for a write-heavy analytics workload") and it seats a council of personas for that question. Or type /consult and set the whole thing up in a menu: modes, models, the roster, the auto-triggers, all from the models you've actually got authed. Before it seats a model it fires a test probe, so a bad key gets caught right there instead of blowing up your first real consult.

And here's the part that closes the loop on the whole story. The old extension died when one call failed. This council can mix inline models and external CLIs in the same room, and if one provider falls over mid-session, the council doesn't collapse with it. It notes the empty seat and the rest carry on.

The exact failure that started all this can't take the whole thing down anymore. That felt good to ship.

The part I care about most: no fake consensus

Here's the failure mode I was scared of. You seat a "critic" persona and it rubber-stamps everything. You seat an "advocate" and it caves the moment anyone pushes. You get three models nodding along and a confident, unanimous, useless answer.

A council that always agrees is worse than no council, because it launders a bad decision in fake authority.

So the stances only bias what each persona hunts for — never the verdict it's allowed to reach. A persona told to argue for the design can still land on "don't do this" if the evidence takes it there. And when members genuinely disagree, the synthesizer is told to surface the split, not average it into mush.

Every council result carries a confidence score, and it's honest about disagreement. Ask a council whether to ship a half-built feature for the next morning's demo, and you get back something shaped like this:

VERDICT — STOP. Demo the pre-recorded flow; ship the real feature once it's tested.
confidence 0.83   (success 1.0 · agreement 0.5 · alignment 1.0)

That agreement 0.5 is two of three advisors holding opposing stances, and the confidence dial dropping because of it. I want that. A number that only ever reads "very confident" is a number you learn to ignore.

Where it lives

bpx-consult is the first extension in a little monorepo I'm building called bpx-mono, small sharp tools for pi, which is a lovely, lean terminal coding harness that stays out of your way. The idea across all of them is the same: pi does the work, these add the bits I kept wishing it had. It installs on its own:

pi install npm:@booplex/bpx-consult

If you want the full design — the personas, the confidence math, the context-engine pipeline, and the decisions behind each. It's all in the project write-up and the SPEC on GitHub. And if you build coding agents and you've ever watched a cheap model confidently drive off a cliff, you already know why I bothered.

Topics:AI coding agentspimulti-modelLLM context windowbuilding in publicopen source

Found This Useful?

Share it with someone who might learn from my mistakes!