The gap between an LLM agent that works in a demo and one that works reliably in production is larger than most engineering teams anticipate. Tool use—calling external functions, APIs, and databases on behalf of a user—is where most production agent systems accumulate their failures. Incorrect parameter types, hallucinated tool names, runaway loops, and unpredictable token costs are not edge cases; they are the normal failure modes of poorly instrumented agent architectures.
This guide covers the engineering patterns that production teams have converged on to address these problems.
Why LLM Agent Failures Are Different From Traditional Software Failures
Traditional software fails deterministically: a null pointer exception, a failed network call, an out-of-bounds index. The failure mode is reproducible and traceable to a specific line of code. LLM agent failures are probabilistic—the same prompt can produce correct tool use in 19 out of 20 runs and a hallucinated function call on the twentieth. This makes standard debugging and testing approaches inadequate on their own.
The three most common categories of production agent failure are: tool selection errors (the agent calls the wrong tool or fabricates a tool name that doesn't exist in the schema); parameter errors (the agent calls the correct tool but passes incorrectly typed, out-of-range, or semantically wrong arguments); and reasoning loops (the agent enters a chain of tool calls that doesn't terminate, consuming tokens and budget without making progress). All three require different mitigation strategies. Addressing them requires treating the LLM as an unreliable but correctable component within a larger architecture.
Designing Tool Schemas That Agents Use Correctly
The quality of a tool schema directly determines how reliably a model selects and uses that tool. Vague or ambiguous schemas produce inconsistent behavior regardless of which model you use. This is the most impactful lever available before reaching for prompt tuning.

Image: AI Studio's UI October 2025 — (CC0), via Wikimedia Commons
The patterns that consistently improve tool selection accuracy include precise, distinct tool names (search_product_catalog is better than search—the name is the first signal the model uses to select the tool); explicit parameter constraints in JSON Schema (specify minimum, maximum, enum values, and pattern constraints wherever applicable—models are more likely to stay within bounds when the schema makes them explicit); mandatory descriptions for every parameter (each parameter's description field should state what valid values look like, what units are expected, and what the parameter controls—don't assume the model infers this from the name alone); and separation of concerns (a single tool with 12 optional parameters is harder for a model to use correctly than two tools with 4 parameters each).
Retry Logic, Fallback Strategies, and Graceful Degradation
Even with well-designed schemas, tool calls will occasionally fail. The question is whether your system handles those failures gracefully or surfaces them as raw errors to the user. A reliable retry strategy for tool-use agents should include several components.
Typed error returns: when a tool call fails validation, return a structured error object that describes what went wrong in a way the model can act on—not a generic exception stack trace. For example: {"error": "invalid_date_format", "received": "July 5", "expected_format": "YYYY-MM-DD"}. The model can read this and retry with the corrected format.
Maximum retry limits: set an explicit retry cap—typically two to three retries for a single tool call. Without a hard cap, a model can enter a correction-and-retry loop that consumes significant tokens on a single step. Fallback tool chains: for critical operations, define a fallback: if the primary tool fails after retries, route to a simpler version of the task or return a partial result with a clear explanation of what succeeded and what didn't. Idempotency awareness: if a tool mutates state (writes a record, sends an email), retrying on failure can produce duplicate side effects. Either build idempotency into the tool itself using idempotency keys, or flag it as non-retryable and handle failures at the orchestration layer.
Managing Context in Multi-Step Agent Workflows
Context window management is the most underappreciated challenge in multi-step agent deployment. As an agent executes a chain of tool calls, it accumulates the results of each call in its context window. In long workflows, this rapidly consumes the available context budget and degrades the quality of subsequent reasoning—models perform poorly in very long contexts or run out of tokens mid-task.
Established mitigation strategies include result summarization: after each tool call, instead of appending the raw result to context, have the model generate a concise summary of what was learned. This is particularly effective for search results, database query outputs, and long API responses. A sliding window context approach maintains a window of the N most recent interactions plus a persistent working memory summary of earlier steps, updated at each step rather than growing unboundedly. Structured context objects—a key-value store the model can query selectively—prevent context from becoming a monolithic blob that's difficult to reason about. Finally, step budgeting: establish a maximum number of tool calls per agent invocation. When the agent approaches this limit, it should finalize with the best available answer rather than initiate further calls.
Observability: What to Instrument in Agent Systems
Debugging a production agent that failed at step 7 of a 12-step workflow without tracing is nearly impossible. Standard logging (request-in, response-out) is insufficient because the failure often lies in the intermediate steps—a subtly incorrect tool argument on step 3 that produced a plausible-looking but wrong result that cascaded forward.

Image: Software developer at work 01 — daudi_mukiibi (CC BY-SA 4.0), via Wikimedia Commons
The minimum viable observability layer for a production agent includes span-level tracing per tool call: each tool invocation produces a trace span recording the tool name, input arguments (sanitized of sensitive data), execution duration, output summary, and success/failure status. Token attribution tracks which step consumed how many tokens—surfacing both cost anomalies and reasoning-quality issues (a step consuming 10x normal tokens often indicates the model is struggling). Agent decision logging captures not just what the agent did but what it considered and why—requiring the model to emit its reasoning before taking action. Failure classification categorizes failures (schema error, tool failure, reasoning error, context overflow) to identify systematic patterns in your evaluations over time.
Cost Control Without Sacrificing Reliability
Multi-step agent workflows can consume significantly more tokens per task than a single model call, and costs can spike unexpectedly if tool calls are inefficient or if the agent enters a long reasoning loop. Cost control requires structural guardrails, not just monitoring after the fact.
| Challenge | Common Mistake | Recommended Pattern |
|---|---|---|
| Tool schema design | Vague descriptions, no parameter constraints | Explicit JSON Schema constraints + distinct tool names |
| Error handling | Raw exception traces returned to model | Typed error returns with actionable correction hints |
| Context management | Unbounded context growth across tool calls | Per-step summarization + sliding window memory |
| Observability | Request-level logging only | Span-level tracing per tool call + token attribution |
| Cost control | No step limits or budget guardrails | Max steps + per-invocation token budget cap |
| Testing | Manual spot-checking of demo scenarios | Deterministic unit tests per tool + behavioral evals |
Effective cost guardrails include a per-invocation token budget—when the budget is 80% consumed, the agent should finalize rather than initiate new tool calls. Model tiering uses a smaller, cheaper model for routine tool selection and parameter extraction, reserving the largest model for steps requiring complex reasoning or synthesis. Tool result caching stores results from tools that query stable data (product catalogs, reference tables, static documents) with an appropriate TTL—identical queries within a session are common in multi-step workflows and should not trigger redundant API calls. Parallel tool execution dispatches independent tool calls simultaneously rather than sequentially, reducing both latency and the token overhead of intermediate reasoning while waiting for results.
Frequently Asked Questions
Should we build our own agent framework or use an existing one?
For most production use cases, building on an established framework—LangGraph, LlamaIndex, or the Anthropic or OpenAI agent SDKs—provides significant advantages: battle-tested retry logic, built-in tracing integrations, and a shared vocabulary for tool schemas. Custom frameworks are warranted only when existing options impose architectural constraints that conflict with specific requirements, such as deeply custom memory management or integration with a proprietary tool registry.
How do we test agent behavior without running expensive end-to-end calls?
A two-layer testing strategy works well: first, write deterministic unit tests for each individual tool—verifying that the tool returns correct outputs for valid and invalid inputs, independent of the LLM. Second, use a behavioral eval framework, a suite of representative tasks with known correct outputs, that you run against the full agent on a schedule. For evals, record reference outputs from a high-quality model run and compare new agent outputs against them using an LLM judge or structured correctness rubric. This separates tool correctness from agent reasoning quality.
What is the best way to prevent an agent from taking destructive actions?
Defense in depth works best here. First, audit which tools have irreversible side effects (sending emails, deleting records, making payments) and flag them as confirmation-required—the agent must emit a structured confirmation request and receive explicit approval before executing these. Second, scope tool permissions to the minimum necessary: an agent handling read-only queries should not have access to write tools in its schema at all. Third, add a lightweight guardrail layer that validates the agent's intended action against a policy before execution, independent of the LLM's own reasoning.
Bottom Line
Running LLM agents reliably in production is a systems engineering problem, not a prompting problem. The teams that ship dependable agentic systems treat the model as one component in a larger architecture that includes typed schemas, structured error handling, context-bounded execution, span-level observability, and hard budget guardrails. None of these is optional for a production deployment that users will rely on. We recommend implementing them in the order listed in the comparison table—schema quality and error handling provide the most immediate reliability gains, while observability pays compound dividends over time as your system scales and you need to diagnose failures efficiently.
Sources & References:
This article reflects established engineering practices in LLM systems design. For further technical reference, see the official documentation for Anthropic Tool Use, OpenAI Function Calling, and the LangGraph framework.
Disclaimer: This article is for informational purposes only. Technology landscapes change rapidly; verify information with official sources before making technical decisions.