How to Give the Agent a Way to Check Its Own Work

In working with coding agents, I’ve found that one of the most effective moves isn’t just picking the best model. It’s giving the agent a way to know when it’s wrong.

If you’ve spent time with these tools, this will be familiar. You give the agent some work on your codebase and it reports back that it’s finished. The code looks clean. The explanation sounds confident. Then you dig in: it doesn’t run, or it runs but does the wrong thing, or it quietly introduces a regression somewhere else.

A more capable model will get more of this right. But it will still hand you its best guess and leave you to find what’s wrong. What changes the picture is giving the agent a way to check its own work. There’s a name for that: backpressure.

Backpressure is any automatic signal that tells the agent its output is wrong: a failing test, a type error, a lint violation, a broken build, a browser test that won’t pass. Geoffrey Huntley uses the term for exactly this. The strongest of these are deterministic, a true pass or fail with no judgment to argue with.

But a signal only counts if the agent runs it. A test sitting in your repo that the agent never executes creates no pressure at all. Backpressure has to live inside the agent’s loop, while it’s still working, not after it hands the job to you.

Think back to that moment when the agent said it was done but the code didn’t run. With no check in place, that broken “done” just sits there until you catch it. You’re the error detector, and there’s only one of you. Now give the agent a test that exercises the feature, and require it to run that test before it can call the job finished. It runs the test, sees it fail, reads the error, fixes the code, and runs it again until the test passes. You’ve gone from being inside the loop, catching every mistake yourself, to standing outside it, reviewing work that already runs.

Diagram of the agent loop. The agent writes a change and a check gates it. On failure the agent reads the error and fixes the change, and only passing changes reach human review.

Backpressure closes the loop: the agent corrects itself, and you review only what already runs.

Notice what that test just became. For years, tests, types, and linters were a quiet tax on velocity. Clearly worth paying, but a tax all the same.

Put an agent on the work, and that changes. The same checks stop being a tax and become rails. A train on rails isn’t slower for being constrained. It’s faster, and it runs without anyone steering it every second. The constraints are what let it go. Tests, types, and linters do the same for an agent. They mark the track, and the more track you lay, the further the agent runs before it needs you.

The cost of laying that track keeps dropping, too, because the agent that needs the rails can help build them. Ask it to write the lint rule, the type, or the test. That’s cheap, and once the rail exists it holds for everything the agent does next.

Most of the friction you feel with an agent is you standing in for a check that doesn’t exist, and you may not notice you’re doing it. The agent hands you code that doesn’t run, so you paste the error back into the chat. It gives you a UI that’s subtly misaligned, so you eyeball the layout and describe what’s off. You’re not sure the change even works, so you run it yourself to see what broke. Every one of those is a signal, and you’re the one producing it by hand. It feels like the agent is just bad at this. More often, the signal isn’t automated.

Backpressure is what makes the check fire on its own. It automates the signal you’ve been producing by hand. Huntley calls the manual rescue an anti-pattern. Rather than patch the output, he says, “engineer away that failure concern.” Close the loop and the agent keeps working until the checks go quiet. Leave it open, with nothing automated, and the only signal in the room is you.

Sometimes you do need a smarter model. But even the best one needs backpressure, because no model can verify its own output from the inside. It generates its best answer and moves on, with no way of knowing whether that answer is wrong unless something outside it checks. So find the rescue you catch yourself doing most often, and ask whether it can be automated, so the agent runs that check as part of its own work. When it can, the agent catches and fixes that mistake without you. Then move on to the next rescue. The real question isn’t only which model to use or how to prompt it. It’s how much of your day you’re still spending as a signal the loop should provide on its own.

Next
Next

An Era of Disposable Software