Back to Blog
Developer Productivity · Essay

How I route models, and why no agent reviews its own work

Simon Doba·July 30, 2026·8 min read

For about a year I did what most people do with coding agents. Pick the model that's supposed to be best, open a chat, describe the task, read what comes back.

That works until the work gets big enough that you can't read all of it.

What I run now is less a tool choice and more a system: work gets routed to a model based on what kind of judgment it needs, plans get written before code, and nothing an agent produces is reviewed only by the agent that produced it. This post is that system, and the two rules that carry most of the weight.

I should say up front what this post is not. I have no before/after throughput number for you. I've been running this setup for months and it feels substantially better, but I never measured my baseline properly, so anything I told you would be a guess dressed up as data. What I do have is an empirical study I ran on 24,560 pull requests — in my own time, out of curiosity about whether the "AI code is worse" claim survived matching — and that study is where the reasoning below comes from.

Routing: capability first, cost last

The mistake I made for a long time was treating model choice as a budget question. Cheaper model for small stuff, expensive model for hard stuff.

That's the wrong axis. Cost is a tiebreaker, not a criterion. The two things I actually route on are:

  • Intelligence — how hard a problem the model can handle unsupervised. Not how well it does with me watching. How well it does when I've handed it a spec and gone to do something else.
  • Taste — UI and UX, code quality, API design, naming, product judgment, user-facing copy.

These come apart more than you'd expect. A model can be excellent at a well-specified migration and produce interface copy that makes you wince. Another one writes a paragraph you'd ship and gets the edge cases wrong.

So I keep a rough score for both and route accordingly:

WorkGoes toWhy
Well-specified implementation, mechanical refactors, migrations, testsgpt-5.6-terraClear spec, verifiable output. Most work lives here.
Extraction, classification, file-by-file transforms, batches of narrow checksgpt-5.6-lunaCheap and repeatable. Never anything needing judgment.
Ambiguous work, architecture, hard debugging, security-sensitive changesgpt-5.6-sol or Fable 5High intelligence bar; Fable 5 when it also needs taste.
Anything a user sees — UI, copy, API surface, namingFable 5 or OpusHard taste floor. Technical correctness does not clear it.
  • Well-specified implementation, mechanical refactors, migrations, test creation, repo investigation with a defined questiongpt-5.6-terra through Codex. This is where most work lives.
  • Extraction, classification, file-by-file transformations, large batches of narrow checksgpt-5.6-luna. Cheap, repeatable, easy to verify. Never anything requiring judgment.
  • Ambiguous or underspecified work, architecture, hard debugging, security-sensitive changesgpt-5.6-sol, or Fable 5 when the problem needs taste as well as intelligence.
  • Anything a user will see — UI, UX, copy, API surface, naming — goes to Fable 5 or Opus, or at minimum gets reviewed by one of them. There's a hard taste floor here and technical correctness doesn't clear it.

That last one is the rule I break least. A technically flawless feature with copy that sounds like a compliance document is not done.

I don't treat the scores as fixed. They're defaults I override when the output doesn't clear the bar, and I'd rather redo a task on a stronger model than ship something mediocre. Escalating costs less than shipping badly, almost always.

Plan before code

Nothing gets implemented before there's a written plan.

Not a mental plan. A file, with the reasoning, the steps, and a checklist. The plan gets reviewed before a single line of implementation happens, and it gets updated as the work goes so that someone picking it up later can actually pick it up.

This sounds like process overhead and it is. It's also the single cheapest thing I do, because the failure mode it prevents is the expensive one: an agent confidently building the wrong thing for twenty minutes, and me only noticing at review time when the whole shape is wrong.

A plan is also the artifact that lets me hand work to a cheaper model. Most of what makes a task "hard" is that it's underspecified. Specify it properly and the intelligence bar drops.

No agent reviews its own work

This is the rule I'd keep if I had to throw the rest away.

The agent that implemented something is the worst possible reviewer of it. It has every reason to believe its own output is correct — that belief is what let it finish. Ask it to check its work and it will find the problems it was already looking for, which are by definition not the ones it missed.

So review is always a different model. Often two, with deliberately different lenses: Opus or Fable 5 on taste and whether the thing is actually good, gpt-5.6-sol on correctness, edge cases and repository consistency.

The corollary matters more than the rule: a successful run is not evidence that the result is correct. Exit code zero means the process finished. That's all it means. Before I accept delegated work I look at the actual diff, check it solves the task I asked for rather than a neighbouring one, look for abstractions nobody needed and unrelated changes that snuck in, and run typecheck, lint and the relevant tests.

If an agent writes tests, I check whether the tests validate the intended behaviour or just assert whatever the implementation happens to do. Those look identical in a green CI run.

Two things make that checkpoint cheaper. The first is a second machine reviewer: point a code-review bot at the pull request — Greptile, CodeRabbit, whatever fits your stack — so the diff gets read by something that didn't write it before it reaches you. It catches the obvious things and leaves you the judgment calls.

The second is not a tool. Read up to a hundred lines of code a day yourself, deliberately, even on days when nothing needs reviewing. It finds things no bot flags, and it stops the slow drift where you stop being able to read the code you're shipping.

Here's where my own data comes in. In that study, when a human PR fails CI, 23.4% eventually get repaired. For AI-authored PRs it's 9.3%. Ninety-one percent of failed AI pull requests are simply abandoned — the agent generated, submitted, and moved on, and nobody came back.

That number is what an unreviewed pipeline looks like from the outside. The fix isn't a better model. It's a human checkpoint the work has to pass through before it counts as done.

Parallel agents need their own worktrees

Once you're running more than one agent against the same repository, they will collide. Two processes editing the same files with different intentions produces a mess that's harder to untangle than either task was.

So any agent that can write files and runs in parallel gets its own git worktree. It's not free — setup cost and disk per agent — so I only do it when agents actually mutate files. Read-only investigation can share a checkout, as long as the reports they write don't collide either.

The other half of that is scoping. Parallel agents get non-overlapping responsibilities, and no two implementation agents get handed the same files. When their recommendations conflict, a separate reviewer reconciles them. And I never merge parallel work without looking at the combined effect — each half can be correct and the sum still wrong.

Worth noting that tooling is starting to build this in. T3 Code, Theo's GUI layer over Codex, Claude and Cursor, has git worktree integration as a first-class feature rather than something you script yourself. I've been using it, and one recent change to it turned out to matter more than I expected — enough that it got its own post.

I stopped typing prompts

Small thing, disproportionate effect: I dictate almost everything now. Voice to text, no CLI.

Part of it is speed, but that's not the main part. When I type a prompt I write the shortest thing that might work. When I talk, I explain — context, what I've already tried, what I actually want, what I don't want. The result is a better specified task, and per the section above, better specification is what lets the work go to a cheaper model and come back correct.

It also changed what I delegate. Describing a task out loud is cheap enough that I hand off things I'd previously have just done myself.

What this doesn't fix

Being honest about the limits, because I think this genre of post usually isn't.

  • Review is now my bottleneck. I read far more code than I used to. The work moved rather than disappeared, and on a bad day it doesn't feel like a win.
  • The system has real overhead. Plans, worktrees, review passes. On a small task it's slower than just doing the thing. I don't use it for one-line fixes.
  • None of this makes an agent understand your codebase. It makes the output checkable. That's a different and smaller claim.

Next

The short version:

  • Route on intelligence and taste. Cost decides ties, nothing else.
  • Write the plan first. Under-specification is what makes tasks expensive.
  • The implementer never reviews itself, and a green run proves nothing.
  • Give parallel writers their own worktrees, and non-overlapping files.

Next thing I want to work out is measurement. Not throughput — I'm suspicious of that number for reasons I've written about at length — but a definition of "good" precise enough that a script can compute it, so a run can score itself while I'm not watching. That turns out to be a harder problem than it sounds, mostly because the loop starts optimising the definition.

If you're running something similar, I'd like to know how you decide what to delegate, and what finally convinced you to stop trusting a green run.

The study referenced here is my own, run in my spare time out of curiosity. Model names reflect what I was using in July 2026 and will date quickly; the routing logic is the part I'd expect to hold.

Share this article

Building something similar?

I write about setups I actually use. If you're working on something comparable, I'd be curious what your workflow looks like.

Get in touch

Cookie Settings

We use cookies for analytics and to improve our website. Privacy policy