AI · Automation · Engineering

Why Agentic AI Stalls at the Demo

By Lazar MilicevicJuly 31, 20269 min read
Empty demo room with large screen showing code, symbolizing agentic AI stalling after the demo

A founder showed me a demo last month. Beautiful. An agent read a spreadsheet, called three APIs, drafted a proposal, sent it for approval. Six steps, twelve seconds, live in a Zoom window. Then he asked the question I always get: "Why can't we just run this every hour?" We tried. It failed on run 4, silently, and produced a proposal addressed to "Dear {{first_name}}." That gap, between the demo that dazzles and the system you can leave alone for a weekend, is where most agentic projects die.

I have been shipping autonomous systems for over a decade. Some of them run 24/7 with no human watching. Others got scrapped after two weeks because I could not make them boring enough. What follows are the patterns that separate a toy from a tool, drawn from agents I actually run in production, including BizFlowAI ContentStudio, which researches, writes, and publishes across multiple sites without me touching it.

The demo-to-production gap is 50x more work than founders expect

A working demo covers the happy path in a controlled input. Production covers every path in every input, forever. In my experience, a demo that took 3 days becomes a 6 to 10 week engineering effort before I trust it unattended, and the difference is not model quality. It is state, retries, idempotency, observability, cost controls, and human checkpoints.

Here is the split I see most often across projects:

Concern Demo effort Production effort
Agent logic and prompts 60% 15%
State + persistence 5% 20%
Retry / recovery 0% 15%
Observability + eval 5% 20%
Human checkpoints 0% 10%
Cost + rate limit control 0% 10%
Security + auth 5% 10%

If your team is spending 80% of build time on prompts and tool wiring, you are still building a demo. The people who ship production agents spend most of their time on the boring five rows.

Persist state after every meaningful step, not at the end

The single change that took my agents from "flaky demo" to "runs unattended" was treating state like a database problem, not a memory problem. Every step that costs real money or has a side effect gets written to a persistent store before I move on. That way, when something crashes at step 7, I resume at step 7, not step 1.

Concretely, I model an agent run as a row in Postgres with a status machine, and every tool call as a child row with input hash, output, cost, and timestamp. Something like:

create table agent_runs (
  id uuid primary key,
  workflow text not null,
  status text not null check (status in
    ('pending','running','awaiting_human','failed','done','cancelled')),
  current_step text,
  input jsonb not null,
  context jsonb not null default '{}',
  cost_usd numeric(10,4) default 0,
  created_at timestamptz default now(),
  updated_at timestamptz default now()
);

create table agent_steps (
  id uuid primary key,
  run_id uuid references agent_runs(id),
  step_name text not null,
  input_hash text not null,
  output jsonb,
  tokens_in int, tokens_out int, cost_usd numeric(10,4),
  status text, error text,
  created_at timestamptz default now(),
  unique (run_id, step_name, input_hash)
);

The unique (run_id, step_name, input_hash) line is the whole game. If the same step retries with the same input, I return the cached output instead of paying the LLM twice or, worse, calling a payment API twice. This is idempotency, and it is the difference between an agent that costs $40 a day and one that costs $400 the first time a queue backs up.

Retry policies are per-tool, not global

The mistake I see in almost every early-stage agent codebase is one retry policy for everything. retry(3) wrapped around the whole run. That is fine for demos and dangerous in production because failure modes are wildly different across tools.

My rough rules after years of this:

  • Deterministic API (search, fetch, DB read): 5 retries, exponential backoff starting at 1s, jitter. Cheap and safe.
  • LLM calls: 3 retries with backoff, but only on 429 / 5xx / timeout. On a schema validation failure, retry once with the validator error appended to the prompt, then escalate. Do not retry a hallucinated schema forever.
  • Payment / write / send-email: zero automatic retries. These need idempotency keys and human review on failure. An email sent twice is a real complaint. A payment charged twice is a lawsuit.
  • Tool that costs > $0.10 per call: retry only after human ack, or with a circuit breaker.

I also cap total run cost. Every run has a max_cost_usd in its config, and the orchestrator halts and marks awaiting_human if the running total exceeds it. This has saved me from a runaway loop more times than I want to admit, including one memorable morning where a scraper started returning empty pages and the agent kept "trying harder" with longer prompts. Cap hit at $8. Would have been $600 by lunch.

Human checkpoints are a design decision, not a fallback

The teams that ship reliable agents decide upfront which steps a human must approve, and they build the UI for it before they scale the agent. Retrofitting human-in-the-loop is painful because you have to rewire state, notifications, and auth after the fact.

I use three checkpoint patterns:

  1. Hard gate. Agent pauses, writes a row, sends a Slack or email with an approve/reject link. Nothing continues until a human clicks. Used for: sending client emails, publishing to production, spending over a threshold.
  2. Soft review. Agent proceeds but logs to a review queue. Human samples 5% and can roll back. Used for: internal drafts, non-customer-facing content, analytics writes.
  3. Silent audit. Agent proceeds, logs everything, no review UI. Used for: read-only research, internal search, log summarization.

The trick is picking the right pattern per step, not per agent. In my ContentStudio pipeline, research is silent audit, drafting is soft review, and publishing to certain sites is hard gate. That mix is what lets it run overnight without a human, but still not embarrass me when it makes a weird call.

Here is the state transition I use for hard-gate steps:

running -> awaiting_human (row written, notification sent)
   |                |
   |                v
   |         human approves    -> running (next step)
   |         human rejects     -> failed (with reason)
   |         timeout 24h       -> failed (with 'timeout')

The 24h timeout is important. Without it, awaiting_human rows accumulate and clog your dashboards.

Observability that answers "what did this agent actually do?"

Logs are not enough. When an agent takes 40 tool calls and 12 LLM turns to complete one task, console.log output is unreadable. You need a run view that a non-engineer can open and understand within 30 seconds.

What I build into every production agent:

  • Run timeline UI. Steps as rows, colored by status. Click a step, see input, output, tokens, cost, latency, and the exact prompt sent.
  • Cost per run + rolling 7-day average. If today's runs cost 40% more than the trailing average, something is off. Alert.
  • Success rate per step, not per run. Overall run success hides the truth. If step 3 succeeds 99% of the time but step 7 succeeds 82%, that is where your engineering hours go.
  • Sample outputs, weekly. I pull 20 random completed runs every Monday and read them. This has caught more real issues than any automated eval, including a prompt that started subtly hallucinating dates after an API changed its response format.

For the eval side, I lean on the same patterns I wrote about in my RAG evaluation piece. LLM-as-judge is fine for offline eval, but in production I trust deterministic checks first: schema validation, regex on required fields, "does the output reference a real customer ID that exists in the DB." The soft checks come after.

Design for graceful degradation, not perfection

Production agents will encounter states the model has never seen: an API returns a shape it did not before, a tool times out for 20 minutes, a rate limit halves overnight. The agents I trust unattended have a fallback for every external dependency, and a clear "give up and hand off" behavior when fallbacks are exhausted.

A few concrete patterns:

  • Two providers for critical model calls. Primary is Claude Sonnet, fallback is OpenAI or a local Llama for the write path. Not because they are equivalent, but because a two-hour Anthropic outage should not kill the agent.
  • Cached last-known-good context. If a tool that provides context fails, the agent uses the last successful output from that tool, marked as stale=true, and either proceeds with reduced confidence or halts, depending on the step.
  • Explicit "abort" path. When retries and fallbacks are exhausted, the agent writes a structured failure record, notifies the right human channel, and stops. It does not "try to be helpful" by making something up. The worst production agents I have debugged were the ones that never failed cleanly. They failed dirty, then kept going.

One concrete number: on my content pipeline, I aim for 97%+ successful autonomous completion. The other 3% must land in awaiting_human with a clean reason, not failed with a stack trace. That ratio is what makes the difference between "I check it every morning" and "I check it every Friday."

What I'd do if I were starting a new agent project tomorrow

Skip the demo phase. Or rather, use the demo to prove the concept in one afternoon, then throw it away and rebuild with these constraints from day one:

  1. Persist every step to a database with idempotency keys. No exceptions. Even the "quick prototype."
  2. Write the run timeline UI in week one. Ugly, functional, one page. You cannot debug what you cannot see.
  3. Pick checkpoint patterns per step before writing the orchestrator. Draw it on a whiteboard. Get the operator to sign off.
  4. Cap cost per run and per day. Hard cap. Kills the run when exceeded.
  5. Ship a fallback model provider before you ship to real users. Not after.
  6. Read 20 random outputs every week. Put it on your calendar. This is the highest ROI eval you will ever run.
  7. Aim for 95%+ clean autonomous completion, not 100%. The last 5% is where you burn six months and lose the project. Route it to humans with a good UX.

The teams that ship agentic systems in weeks instead of quarters are not the ones with better prompts. They are the ones who treat the agent as a distributed system with an LLM inside, not an LLM with some tools bolted on.

Close

If you are staring at a beautiful demo and wondering why it keeps breaking when nobody is watching, the answer is almost never the model. It is state, retries, checkpoints, and observability, the same problems every distributed system has had for 30 years, with a new failure mode on top.

If you are building something like this and want a second set of eyes, or you need someone to own the production hardening end to end, you can reach me at lazar-milicevic.com/#contact. More posts on shipping agents and LLM systems in production are on the blog.

Frequently asked questions

Why do agentic AI demos fail when moved to production?

Because a demo only covers the happy path on controlled inputs, while production has to handle every path on every input, forever. In my experience, a 3-day demo becomes a 6-10 week engineering effort, and the gap is not model quality, it is state persistence, retries, idempotency, observability, cost controls, and human checkpoints. Teams that spend 80% of their build time on prompts and tool wiring are still building demos. The boring infrastructure work is what separates a toy from a tool you can leave running unattended over a weekend.

How should I persist state in an agentic AI workflow?

Treat state as a database problem, not a memory problem. Persist every meaningful step to a durable store like Postgres before moving on, modeling each run as a row with a status machine and each tool call as a child row containing input hash, output, cost, and timestamp. Add a unique constraint on (run_id, step_name, input_hash) so retries return cached outputs instead of paying the LLM twice or double-calling side-effect APIs. This idempotency is what lets an agent resume at step 7 after a crash instead of restarting from step 1.

What retry policy should I use for AI agent tool calls?

Retry policies must be per-tool, never global. For deterministic reads (search, fetch, DB) I use 5 retries with exponential backoff and jitter. For LLM calls I use 3 retries only on 429/5xx/timeout, plus one schema-validation retry with the validator error appended to the prompt. For payments, writes, or emails I use zero automatic retries, those require idempotency keys and human review, because a double-sent email is a complaint and a double charge is a lawsuit.

How do I prevent an AI agent from running up huge costs?

Set a max_cost_usd cap on every run and have the orchestrator halt and mark the run as awaiting_human when the running total exceeds it. This stops runaway loops, I once had a scraper return empty pages and the agent kept 'trying harder' with longer prompts; the $8 cap saved me from a $600 bill by lunch. Also enforce circuit breakers on expensive tools (over $0.10 per call) and require human acknowledgment before retrying them. Cost control is not optional, it is a core production requirement.

When should I add human-in-the-loop checkpoints to an AI agent?

Decide upfront, before you scale the agent, because retrofitting human review means rewiring state, notifications, and auth after the fact. I use three patterns: hard gates (agent pauses and waits for approval, used for client emails, production publishing, and spending over a threshold), soft review (agent proceeds but a human samples ~5% from a review queue), and silent audit (agent proceeds with full logging but no review UI, used for read-only research). Pick the right pattern per step, not per agent, in one pipeline research is silent, drafting is soft review, and publishing is a hard gate.

Lazar Milicevic

Lazar Milićević

Senior Technical Engineer. I build AI automation, GenAI/LLM systems and cloud architecture — autonomous systems that run while you sleep. Founder of BizFlowAI.

Building something hard with AI or automation? I am open to talk.

Get in touch

← All posts