november 2026 · 5 min

Stop Fighting the Model

Many people fight the model. They look at its output, say meh, complain, and then start interfering with how it works. They manufacture context for it instead of letting it figure things out. They decide how its files are laid out. They decide naming. They argue with it, reshape what it did, argue again.

All of that effort lands at the bottom of the funnel, on one output, and it's gone by the next run. The work belongs at the top of the funnel: loops, harnesses, evaluation criteria, supporting agents.

The difference between the two is what I mean by working with the model versus working against it.

What Fighting Looks Like

Each of these comes from a reaction. You saw something you didn't like, and you reached in to change it. That's the habit to break. Working with the model means you don't dramatically react to the things you see and don't like.

Bad output still matters. It tells you something about your system. The useful question is never "how do I make it do this differently?". It's "what would have caught this, without me?"

Opus 6 Is Coming

My bet: Opus 6 is going to be released sometime soon. Then Opus 7. Then Opus 8. I think that's inevitable, and it changes the math on everything you do today.

Whatever you're doing, if it works with the models, it only gets better. A loop with a good evaluation at the end gets a stronger worker every time a model ships, and you barely touch it.

If it works against the models, you're injecting shit practices that make the better model work in a worse way. That rules file full of old complaints doesn't retire itself. It keeps steering the smarter model the way the last one needed steering. The context you hand-picked for today's model limits what the next one gets to see.

I think much of today's prompting is a fool's errand, because we're instructing AI to do things it very soon won't need to be told. Fighting the model is the same mistake with more effort behind it.

What the Top of the Funnel Looks Like

You build the thing that produces and judges outputs. In a few lines:

#!/bin/sh
# task.md says what done means. The gate decides if it's done.
failure=""
for attempt in 1 2 3 4 5; do
  claude -p "$(cat task.md) $failure" --allowedTools "Read,Edit,Write,Bash"
  if out=$(/opt/gates/gate.sh 2>&1); then exit 0; fi
  failure="The gate failed: $out"
done
exit 1

Nothing here says how to do the work. task.md is the outcome. The gate is your judgment, written down -- tests, a lint, a benchmark, an invariant. When it fails, its output goes back to the model and the model deals with it. If every attempt fails the script exits non-zero and a person looks. It allows Bash, so run it somewhere disposable. Swap in the next model and this script barely changes.

Now the reaction has somewhere to go. Don't like what you saw? Add a check:

One rule: keep the gate where the worker can't write to it, which is why it lives outside the working tree above. If the agent can edit the check, it isn't a check.

This is the same shift I keep coming back to. Software is becoming manufacturing, and on a factory floor you don't argue with a part as it goes by. You fix the line and you fix the inspection. Most of the job becomes forms of QA and forms of design, and this is what that looks like at the keyboard.

There's no Free Lunch

This has real costs, and it isn't always the right move.

A gate is only as good as what it checks. A weak one passes garbage with a green light -- a 200 is not a pass -- and writing a strong one is real engineering, up front, before you see any output. For a one-off change, just make the change. Nobody needs a harness to rename a variable.

Some things also deserve to be dictated, because they aren't the model's call: a public API contract, a data format other systems depend on, a compliance rule. Those are requirements, so put them in the gate, where they stay true for every model.

And you still have to read the output. If you can't tell good from bad, you can't write the gate.

Next time an output annoys you, go look at the line.

← all posts