Dev48
Language
  • About
  • Services
  • Industries
  • Technologies
  • Articles
  • Contacts
Book a call
    Home/Articles/Agent failures dont throw
Dev48

© 2026 · All rights reserved.

Agent Failures Don't Throw

Фото: Brett Jordan (Unsplash) — https://unsplash.com/photos/brown-wooden-letter-letter-letter-blocks-ehKaEaZ5VuU?utm_source=dev48&utm_medium=referral

Agent Failures Don't Throw

Source: Morph

An agent loops, a user gives up, a jailbreak slips past, and the trace still says 200 OK. The failures that matter to agents are semantic, and your logs can't see them. Reflexes are small classifiers that read every turn and label the ones that broke: frustration, jailbreaks, loops, policy violations. Eight ship out of the box, one API call, under 90ms. Train your own in an hour.

September 25, 2026

A web server fails by throwing. You get a 500, a stack trace, a line number. An agent fails by succeeding at the wrong thing. It loops for twenty turns, refuses a reasonable request, gets talked out of its system prompt, closes the ticket by deleting the test. Every call returns 200 OK.

That's the gap. Your traces, your logs, your latency graphs all watch the plumbing. None of them watch the conversation.

The stakes keep climbing while the visibility stays flat. Agents pull from more tools every month, call their own subagents, run for hours with no human in the loop, and now sit in healthcare, finance, and support queues where a quiet failure costs real money. The harder the agent works, the less a 200 tells you.

A reflex reads each turn, sorts the breaks into signals like frustration and jailbreaks, surfaces them across every chat, and feeds what it finds back into the agent.

The failures live in the text

Error rate and latency throw, which is why you already watch them. The signals that actually tell you whether the agent is any good never make it to your logs at all, because they're semantic. They're buried in what the user and the agent said to each other. A user typing "this is the third time I've asked" and then giving up. A prompt that coaxes the agent out of its own rules. An agent hitting the same tool eight times, getting the same error every time, and trying a ninth. A perfectly reasonable request the agent refused for no reason anyone can find. The agent spilling its chain of thought into the reply.

None of that surfaces on its own. Something has to read the turn and put a label on it, and that something is what we call a reflex: a small classifier that looks at one turn and gives you back one answer. Not a 1-to-10 score that slides around every time you tweak the wording. An actual label, the kind of thing you can count, watch across a release, and get paged over when it jumps.

Eight reflexes, one API call

Nothing to train up front. Send a turn to the API and the label is back in under 90ms. Eight of them come ready to go:

One call, one classifier, one label:

Run every turn through it. frustrated at 0.97 becomes a row in your dashboard instead of a number sitting in a transcript nobody's ever going to open.

A rate you can alert on

One label on its own is just a data point. Point that same reflex at all of your traffic and it turns into a rate, and a rate is what you actually run a product on. Frustration sits flat at some baseline for a while. Then a deploy goes out and it jumps:

The new system prompt went out at v2.4 and the frustration rate doubled inside a few hours. Nobody had to sit down with a thousand transcripts to catch it. The reflex read every turn and the chart just showed you.

Now shipping becomes an experiment. Push a prompt or model change to 5% of traffic, keep the rest as control, and watch the rates move. If refusals or frustration climb once the change lands, you shipped a regression, and you found out that same day instead of a week later through the churn numbers. That's A/B testing on what the agent actually did, not on what your eval set guessed it would do.

When we don't ship the signal, train it

Eight reflexes cover the common failures. Your product has failures that are yours alone: a medical agent that should never give dosing advice, a coding agent that quietly stubs out a failing test, a support agent drifting off-policy. Describe the behavior, bring a few labeled examples or let us generate a synthetic set, and you have a custom reflex in under an hour. It serves on the same API, at the same latency, beside the built-ins. The public surface is OpenAI-fine-tuning-compatible, so if you've trained a model through the OpenAI SDK, you already know the shape.

The labels feed back into the agent

A reflex is a detector, but the output is training signal. Every label is a row that can become an eval case, a fine-tune example, or a reward term in RL. The turn that flagged as frustrated today is the behavior your main agent learns to avoid tomorrow.

I learned this at Tesla, building the stack that went through driving data at scale to surface the frames engineers wanted to train on: the obscured camera, the rare cut-in, the long-tail case the model kept missing. The fleet produced petabytes. Nothing accurate enough to be useful was cheap enough to run on all of it, so the whole game was finding a filter you could afford to run on everything, because the rare event you need is never in the sample.

Treat your production traffic as a funnel. At the top, reflexes run on 100% of turns and flag a few percent. That flagged slice is small enough to hand to the expensive review you could never point at all of production: your team reads the turns that matter, and your own agents dig into the rest. Reflexes don't replace that judgment. They decide what's worth it, so nobody drowns in transcripts that returned 200 and meant nothing.

That only works because the detector is cheap enough to leave running on everything. One backbone pass labels every turn with many heads, so the tenth reflex costs almost nothing. Read how we built it.

The label was never the hard part. Running it on all of production was. That is the problem we solved.

Try a reflex on your own traffic, or read the docs.

← All articles