Skip to content

Production and Frontier

Shipping to production

Cost, latency, HITL, reliability

A working agent in a notebook is maybe a fifth of the job. Production is where the token bill, the p95 latency SLO, compounding per-step errors, and irreversible side-effects all bite at once. This lesson is the systems architecture, economics, reliability primitives, and the eval / observability / guardrail stack that turns a demo into a service you can actually trust.

Capability is not your blocker

The frontier lab surveys are blunt about where teams get stuck. In LangChain's State of Agent Engineering 2025 (1,340 respondents), 57% already run agents in production, but the top blockers are quality (~32%) and latency (~20%), not model IQ. Cost fell down the list year-over-year, because caching and routing worked. And there is a telling gap: 89% have observability, yet only ~52% run offline evals.[1] Teams can see failures but cannot catch regressions before they ship.

The shipping thesis

Production agents are stateful, non-deterministic, error-compounding distributed systems that happen to call an LLM. Everything below, economics, reliability primitives, the architecture, exists to tame those four properties. The governing principle still holds: start simple, measure, and add autonomy only when it demonstrably improves outcomes, because more autonomy buys capability at the price of latency, cost, and predictability.[2]

The root problem: errors compound over long runs

A stateless request/response service fails one request at a time. An agent is a loop: reason, act, observe, reason again, each step mutating state the next step depends on. So per-step reliability does not add, it multiplies. If every step is independently reliable with probability p, an n-step task finishes end-to-end only p^n of the time.[2] A very-good-looking 95% per step is a 36% task over 20 steps.

Per-step reliabilityOver 10 stepsOver 20 stepsOver 30 steps
99% / step~90%~82%~74%
95% / step~60%~36%~21%
90% / step~35%~12%~4%
Why long runs are fragile. End-to-end success is p^n, so a great 95%-per-step agent finishes only ~36% of 20-step tasks. Every primitive in this lesson exists to bend this curve or survive being on it.

Two lessons fall straight out of this curve. First, measure the whole task, never the per-step average, the average hides the multiplication.[2] Second, the practical fixes are architectural: shorten n (fewer, sharper steps), raise p at the riskiest steps (validation, a better tool interface), and add recovery so a single bad step does not restart the whole run.

Token economics: the cheapest token is the one you do not send

Production spend is dominated by three composable levers. Learn them in order, because they stack.

Lever 1: Prompt caching (kill the fixed prefix)

Every request re-sends a big stable prefix: system prompt, tool schemas, few-shot examples, policy docs. lets repeat requests re-read that prefix instead of paying to process it again. The Anthropic mechanics are exact and worth memorising:[3]

  1. A cache read is about 0.1x base input (a 90% discount); a cache write costs more, 1.25x for the 5-minute TTL, 2.0x for the 1-hour TTL. Caching pays off once a prefix is read more than a couple of times.
  2. cache_control marks a breakpoint; the write is a hash of the entire prefix ending at that block, and reads walk backward up to 20 blocks to find a prior write.
  3. Invalidation is hierarchical: tools, system, messages. Editing tool definitions busts everything below them, so keep tool schemas and the system prompt stable.
  4. There is a per-model minimum cacheable prefix (for example ~1,024 tokens) below which caching is silently skipped. Verify with usage.cache_read_input_tokens: zero means it never happened.

The #1 caching bug: a breakpoint on volatile content

Put the breakpoint on a timestamp, per-request context, or the newest user turn and the prefix hash changes every call, so about 0% hit rate, and you still pay the 1.25x/2x write premium for nothing. The golden rule: the breakpoint goes on the last block that is identical across requests.
# WRONG - hash changes every request -> always a miss
system = [{"text": f"Time: {now}. You are a support agent...",
           "cache_control": {"type": "ephemeral"}}]

# RIGHT - stable prefix cached; volatile bits placed AFTER the breakpoint
system = [{"text": STABLE_POLICY_AND_FEWSHOTS,          # ~8k stable tokens
           "cache_control": {"type": "ephemeral"}},   # breakpoint on LAST stable block
          {"text": f"Time: {now}."}]                    # volatile - not cached, fine
Put the cache breakpoint on the last stable block, never on volatile content.

Lever 2: Model routing and cascades (stop paying frontier prices for easy work)

Roughly 40 to 60% of requests do not need a frontier model at all.[4] Two shapes:

Routing

A one-shot classifier decides before execution which tier handles the query. Overhead is tiny: ~1 ms rule-based, ~10 to 30 ms for a small classifier, ~20 to 50 ms semantic.[4] Simple ticket to Haiku; hard reasoning to Sonnet/Opus.

Cascade

Try the cheap model first; if a confidence or verifier check fails, escalate to a bigger one. Trades a bit of extra latency (and occasional double-billing on escalations) for big savings on the easy majority.

Reported outcome across the routing literature: cost cuts of 45 to 85% while keeping about 95% of quality.[4] The same idea applies inside a run: dispatch cheap sub-tasks (classification, extraction, summarising a tool result) to a small model and reserve the frontier model for the reasoning that needs it.

Lever 3: Batching (for anything a human is not waiting on)

Async/batch APIs give a roughly 50% discount for latency-tolerant work: evals, backfills, bulk generation.[5] Batch stacked on top of caching pushes effective savings past 90% on the right workloads.

The levers compose: a worked bill

A support agent at 1M requests/month with a stable 8k-token prefix plus a ~500-token user turn, priced at illustrative Sonnet-class rates, runs ~$30k/mo naively. Add caching on the 8k prefix (its cost drops 90%) and the bill roughly halves to ~$15k. Route the ~50% of trivial tickets to a Haiku-class model and it drops again to ~$5 to 6k/mo, an ~80% cut, with the frontier model still handling everything that genuinely needs it. Caching kills the fixed prefix cost; routing kills the frontier-price-for-easy-queries cost.[4]

The counterweight: multi-agent is a 15x token multiplier

Parallel sub-agents each carry their own context window. Anthropic's multi-agent research system used about 15x the tokens of a chat turn (about 4x a single agent), and token usage alone explained about 80% of the variance in quality.[6] Reach for multi-agent only when the task value clears that bar and the work parallelises cleanly, not for tightly-coupled work like most coding.

Latency budgets and streaming

is not one number: decompose it so you optimise the part users feel, time-to-first-token (TTFT, responsiveness), tokens/sec (throughput), and time-to-last-token (total wall clock). The single biggest perceived-latency win is streaming: whenever a human is waiting, return tokens as they generate so they start reading before the run finishes.[7]

  1. Smaller / faster tier. The same routing that cuts cost cuts latency: a Haiku-class model answers the easy half faster.
  2. Cap max_tokens. Generation time scales with output length; bound it and stop runaway completions.[7]
  3. Parallelise and cache. Fire independent tool calls concurrently; a warm prompt cache also shortens TTFT on the stable prefix.

Reliability primitives: ship these from day one

Agents retry aggressively and hold state for a long time, so the classic distributed-systems toolkit is mandatory, applied to non-deterministic calls.[8]

  1. Bounded retries with exponential backoff plus jitter. Wrap every tool and model call; add timeouts and so one flaky dependency cannot take the run down.
  2. Idempotency keys tied to the originating user request. Attach one to every state-changing action (DB writes, charges, emails, external API calls). Without it, an aggressive retry on a non-idempotent endpoint becomes a duplicate charge or a double-sent email.[8]
  3. Durable execution plus checkpointing. Persist progress so a crash resumes from the last checkpoint instead of restarting a long, expensive run. Anthropic's long-running harness makes git commits, a progress file, and a feature checklist the external memory that survives a lost context window.[9]
  4. Bound the loop and the budget. Set a max-iteration cap, a per-run token/cost budget, and loop detection (hash of recent tool plus args) so a stuck agent hits a wall instead of a runaway bill.[2]

The production architecture

Now assemble it. This is where the eval / observability / guardrail work from the reliability module stops being three separate lessons and becomes one request path. Read it as a request flowing through the gateway into a central orchestrator, fanning down into capabilities, wrapped by guardrail rails and an observability plane that spans everything.

Tap a node to see what it does.

A production agent architecture. Guardrails are a pipeline of rails, not a prompt: an input rail on entry, an execution rail plus human checkpoint gating irreversible tool calls, and an output rail before the reply. An observability plane emits OpenTelemetry spans into a cost/latency dashboard beneath everything.

This diagram is the reliability module, wired together

Each rail is a lesson: input/output rails plus allow/deny lists are guardrails; the execution rail plus HITL gate the tool calls that prompt injection and the lethal trifecta would otherwise hijack; the observability plane is tracing; and the online signals it captures feed your evals. NeMo Guardrails formalises exactly these five rail types: input, dialog, retrieval, execution, output.[10]

Human-in-the-loop on the irreversible, not on everything

For irreversible or high-stakes actions, refunds, deletes, external sends, pause and get a human decision. in LangGraph is an interrupt() backed by a mandatory checkpointer, offering four decisions, approve / edit / reject / respond, and conditional interrupts that gate on the tool's arguments (auto-approve reads; interrupt only writes over a threshold or outside a workspace).[11] Because it is checkpointed, a paused run resumes rather than restarts, the same durability primitive as above.

Guardrails are not a security boundary you can buy at 95%

Model-based moderation has a ceiling; a vendor guardrail that "catches 95% of attacks" is a security failure, not a win.[12] The robust layer is deterministic: allow/deny lists on tools, domains, file paths, SQL operations, and recipients, and an architecture where an agent exposed to untrusted content simply cannot reach a consequential action.

Deployment topology: do not kill agents mid-run

A normal rolling deploy assumes requests finish in milliseconds. Agents hold state for minutes to hours, so a rollout that drains the old version kills in-flight runs. The fix is a : run old and new versions concurrently and shift traffic gradually, letting long runs finish on the version they started on.[6] Pair it with a stateless orchestrator plus durable state store so any worker can resume any run from its last checkpoint.[9]

The dashboard: what production actually watches

You cannot improve what you cannot see, and the goal is to minimise MTTD (mean time to detect) and MTTR (mean time to respond), which means designing observability in from the start, not bolting it on after an incident.[13] Get raw traces flowing first; the tooling choice matters less than having the data.[14] The canonical wire format is the OpenTelemetry GenAI convention: an invoke_agent span with child chat and execute_tool spans carrying gen_ai.usage.*_tokens and finish_reasons.[15]

DimensionWhat to watch
Cost & efficiency$ per task, tokens per run, cache-hit %, escalation rate. Tokens drive ~80% of outcome variance, so treat cost as a first-class SLO.
Latencyp50 / p95 wall clock, TTFT, tokens/sec. Watch the tail: the p95 breaks the SLO, not the average.
ReliabilityIterations per run (loop detector), retry rate, timeout / circuit-breaker trips, task success from online eval.
SafetyGuardrail trigger rate per rail, HITL rate, edit/reject counts. A spiking input-rail rate is often an attack signal.
What a production agent dashboard tracks. Cost is a first-class SLO because token usage explains most of the quality variance.

The cost / latency lever board

Reach for these in order: the top three do most of the work.

LeverMechanismTypical effectTouches
Prompt cachingCache the stable prefix; breakpoint on the last identical block~90% off the cached prefix; lower TTFTcost + latency
Model routing / cascadeSend the easy 40 to 60% to a cheap tier; escalate on need45 to 85% cost cut at ~95% qualitycost + latency
Cheap sub-task modelsSmall model for classify / extract / summarise inside a runfewer frontier calls per taskcost + latency
BatchingAsync API for anything a human is not waiting on~50% off; stacks with cachingcost
StreamingReturn tokens as generatedlarge perceived-latency winlatency
Parallel tool callsFire independent calls concurrentlycollapses serial waitlatency
Context compactionSummarise history; retrieve just-in-time vs dump the repofewer input tokens, less context rotcost + quality
The production lever board. The top three levers, caching, routing, and cheap sub-task models, do most of the work.

Check yourself

Match each production concern to the technique that most directly addresses it.

drop here

prompt caching and a model cascade

drop here

streaming tokens as they generate

drop here

a human approval gate

drop here

idempotency keys

A 15-step agent whose every step is 95% reliable finishes an end-to-end task about how often?

Where should you place the cache_control breakpoint to actually get cache hits?

Your agent retries a failed issue_refund call after a network blip. What one primitive stops the retry from double-charging the customer, and what must it be tied to?

Where does the key come from? Try to state it, then check.

Lock it in

  • Reliability, not capability, is the blocker. Agents are stateful, non-deterministic, and error-compounding: end-to-end success is p^n, so 95%-per-step is 36% over 20 steps. Shorten n, harden the risky steps, and add recovery.
  • The cheapest token is the one you do not send. Cache the stable prefix (breakpoint on the last identical block), route the easy 40 to 60% to a cheap tier, batch the rest: the levers compose to ~80%+ savings. Multi-agent is a 15x counterweight; use it only when it pays.
  • Ship the reliability toolkit from day one: bounded retries plus backoff/jitter, idempotency keys tied to the user request, timeouts plus circuit breakers, durable checkpointing, and a capped loop plus budget.
  • The architecture is the reliability module wired together: gateway, orchestrator/router, model plus tools plus memory, wrapped by input/execution/output rails, HITL on the irreversible, and an OTel observability plane feeding a cost/latency dashboard.
  • Deploy without killing in-flight runs (rainbow deployments plus durable state), and watch the tail, p95 latency, cache-hit %, iterations/run, guardrail rate, to minimise MTTD and MTTR.

Primary source

Anthropic, Building Effective Agents

The canonical foundation for shipping: the workflow-vs-agent split, the start simple, escalate only on measured need doctrine, compounding errors and the max-iteration cap, and designing the agent-computer interface. Read it once, then the caching / routing / observability specifics slot into place.

Sources

  1. 1.LangChain, State of Agent Engineering 2025
  2. 2.Anthropic, Building Effective Agents
  3. 3.Anthropic, Prompt caching docs
  4. 4.Tian Pan, LLM routing and model cascades
  5. 5.Anthropic, Pricing (batch discount)
  6. 6.Anthropic, Building a multi-agent research system
  7. 7.OpenAI, Production best practices
  8. 8.OpenAI, A practical guide to building AI agents
  9. 9.Anthropic, Effective harnesses for long-running agents
  10. 10.NVIDIA, NeMo Guardrails
  11. 11.LangChain, Human-in-the-loop docs
  12. 12.Simon Willison, The lethal trifecta
  13. 13.Chip Huyen, Building a GenAI platform
  14. 14.Hamel Husain, LLM observability office hours
  15. 15.OpenTelemetry, GenAI observability