Back to News & Insights
Artificial Intelligence September 2, 2026 · 9 min read

I Replaced 200 Lines of Code With One AI Agent — Here's What Broke

Here are 200 lines of the most boring code I have ever written, compressed to twelve: //...

I Replaced 200 Lines of Code With One AI Agent — Here's What Broke

Here are 200 lines of the most boring code I have ever written, compressed to twelve:

It took eight months to accumulate. Every regex in it is a scar. It was 91% accurate on our 1,200-row eval set and nobody enjoyed touching it.

Six lines. Same eval set, same afternoon: 96%. Five points better than eight months of regexes, and I deleted 194 lines to get it.

I want to be completely clear about this, because the rest of the article is going to sound like a warning and it isn't one: the agent was better at the job. It never got worse. That number held. The measurement was real.

What broke was never the accuracy. What broke was all the stuff the 200 lines were doing that nobody had written down, because nobody had ever needed to.

Three weeks in, support forwarded a ticket. A customer had asked about a duplicate charge and been routed to billing instead of refunds. Wrong queue, four-day delay, angry customer.

The request had succeeded. Status 200. The agent had returned billing, which is a real handler, spelled correctly, in the enum, on schema. Every check in the pipeline had passed because every check in the pipeline was checking whether the answer was well-formed, and it was. The answer was well-formed and wrong, and those two things had never needed to be distinguished before — because when a regex is wrong it falls through to fallback, and fallback is loud.

I ran it again. refunds. Again. refunds. Nine times out of ten it was right. The tenth time it wasn't, and I could not make the tenth time happen on purpose.

That was the actual moment. Not the wrong answer — the unreproducible wrong answer. I had spent a career on a foundation I'd never once articulated: if I run it again with the same input, I get the same thing. Two hundred lines of ugly regex gave me that for free. Six lines of beautiful agent call took it away, and took about five other things with it that I only found by tripping over them one at a time.

fallback is a real state. It's logged, it's counted, there's a dashboard tile for it, and when it spikes somebody adds a regex. The system's ignorance was a value. It was in the type. You couldn't not handle it.

Confident. Valid. Wrong. There is no fallback because the agent will always pick something — that's what picking means. I had accidentally removed the only channel through which the system could say I don't know, and I removed it in the same commit that made the system more accurate, which is why nobody caught it in review.

The regexes couldn't be uncertain, so they expressed uncertainty structurally, by failing. The agent can be uncertain and expresses it by not mentioning it. If you don't ask, you don't get it. The cache started serving a wrong answer forever

There was a cache in front of the router. Of course there was — it had been there for a year, it was keyed on a hash of the input text, and it had been correct every single day of that year, because a pure function of its input can be cached by its input. That is what pure means.

Read it now, with a non-deterministic route() behind it, and it stops being a cache. It's a coin flip with a 30-day memory. The first time a phrasing came through, whatever the agent happened to say that time became the permanent answer for that phrasing. If that was the 2% roll, every user who ever phrased it that way for the next month went to the wrong queue. Consistently. Which made it look like a routing rule, not a flake, which is exactly why it took three weeks to find — I was looking for a bug in the rules and there were no rules.

Nothing in that cache changed. Nobody touched it. It didn't break. The thing it was built on top of stopped being true, and it had no way to notice.

Go find your caches, your memos, your useMemo, your idempotency keys, your dedupe-by-hash. Every one of them is a contract that says same input, same output. When you put an agent under one, you are not adding a feature. You are invalidating a contract that something else in your codebase is already relying on, silently, from a file you have not opened. Cost became a function of traffic

The 200 lines cost the same at ten requests a day and ten million: nothing. CPU that rounds to zero. That's not a small property, it's the property that lets you not think about it — you can call route() in a loop, call it twice because it's easier than plumbing the result through, call it on every keystroke.

And we did. There was a place — a live-preview panel — that called route() on input change, debounced at 150ms, because it was free.

Want to discuss this further?

Book a free strategy call with our team to see how these insights apply to your specific business goals.

Book a consultation