Most "agents" I've tested fail at the boring part, not the reasoning part
I built a small internal agent to handle a genuinely narrow task: pull data from three internal APIs, reconcile it, and produce a report. Not an ambitious multi-step research agent, just a focused tool-use loop. I expected the hard part to be getting the model to plan the right sequence of calls. It wasn't. The model figured out the right sequence almost every time. What broke, repeatedly, was everything around the actual tool call.
The failure modes that actually showed up
A malformed JSON argument on maybe 1 in 30 calls — close enough to valid that a naive parser would silently drop a field instead of erroring loudly. An API returning a 429 rate limit and the agent interpreting the error message as data rather than as a signal to back off and retry. A tool call that succeeded but returned an empty result for a valid-but-uncommon input, which the model then treated as "this data doesn't exist" instead of "maybe retry with a different parameter." None of these are reasoning failures. They're the equivalent of a junior engineer not handling edge cases, except the junior engineer usually asks a clarifying question and the agent just guesses and moves on.
The fix that actually improved reliability the most wasn't a better model or a fancier planning framework. It was writing much stricter tool schemas with explicit error-shape definitions, and adding a retry-with-backoff wrapper around every tool call that the agent couldn't bypass. Boring infrastructure work, and it moved our end-to-end success rate more than any prompt change did.
The gap between "it usually works" and "it's safe to run unattended"
A 95% success rate sounds good until you do the math on what happens over a hundred runs a day, unattended. That's five failures a day, and if even one of them is silent — the agent confidently produces a wrong report instead of failing loudly — you've built something worse than not automating the task at all, because now someone has to notice the wrongness instead of just doing the work.
I'd rather have an agent that fails loudly 10% of the time than one that's silently wrong 2% of the time. The second one is much harder to catch and much more expensive when you do.
What I'd tell someone starting an agent project today
- Spend more time on tool schemas and error handling than on the system prompt. It's less interesting work and it matters more.
- Instrument every tool call, not just the final output — you need to know when the agent retried, when it gave up, and when it silently proceeded with bad data.
- Design for loud failure. An agent that stops and asks for help is more useful in production than one that always produces an answer.