Ship production AI
AI Engineering Bootcamp
maven.com/tailabs/ai-engineering-bootcamp
Why prompts fail in production, and what to build instead
Same model. Same prompt. Different outcome. The difference is the system around the call.

Dr. Aki Wijesundara
Co-Founder, TAI Labs
Two paths from TAI Labs. Each card shows exactly what we cover.

For engineers & technical builders
Build and ship production AI agents
What we cover
Scan to enrol
maven.com/tailabs/ai-engineering-bootcamp

For PMs, founders & operators
Direct AI tools and ship real products
What we cover
Scan to enrol
maven.com/theaiinternship/ai-pm-bootcamp-and-cert
Same model. Same prompt. Every check you wrote passes.
Same model. Same prompt. The first real user breaks it.
If you have shipped an agent that worked in testing and failed in production, we will map that failure to a layer later.
Not the model. Not the prompt.
The system around the model call.
What runs, in what order, and when it stops
What the model can see at this step
What it is allowed to touch
How you know the output is good
What survives between steps and between runs
Almost every agent failure lives in one of these five, not in the prompt.
An agent that cannot stop itself is not autonomous, it is unsupervised. The common failure is not an infinite loop. It is the agent that declares success on step two because nothing was checking.
Most teams treat context as an append-only log. Treat it as a query: “What does this step need to know?” every single time.
Classic failure: a tool kept write access because it was convenient in development and nobody removed it. Permissions failures are rare and expensive. Everything else is common and cheap.
Three tiers, cheapest first:
Does it parse? Are required fields present? Are types right?
Values in range? Referenced IDs exist? Does the arithmetic hold?
LLM or human check, only for what the first two cannot catch.
The dangerous failure is the plausible wrong answer: it passes casual review and reaches the user. Schema and rules are free and catch most of it. Reach for judgement last: slow, costly, and itself unreliable.
State is what makes attempt two different from attempt one. Without it, a retry is the same failing call again, at three times the cost. When an agent asks the same question twice, that is usually a state problem in your system, not a memory problem in the model.
The layers are not independent. This is where most designs go wrong.
Four out of five is not eighty percent of a harness. The missing layer is usually where the incident comes from.
def agent(user_input):
result = model(user_input)
return resultFailure modes hiding in one line:
Five failures. Five layers. That is not a coincidence.
from pydantic import BaseModel
class Result(BaseModel):
action: str
target_id: str
confidence: float
raw = model(user_input)
parsed = Result.model_validate_json(raw) # throws on malformedYou just moved “always return valid JSON” out of the prompt and into code that enforces it. The prompt asks. The schema guarantees. That distinction is the whole session.
for attempt in range(MAX_ATTEMPTS):
raw = model(build_context(state))
try:
parsed = Result.model_validate_json(raw)
state = state.update(parsed)
break
except ValidationError as e:
state.log_failure(str(e)) # error goes back in
else:
return escalate(state)The loop is not the interesting part. The interesting part is state.log_failure feeding into build_context: the only reason attempt two can succeed where attempt one failed.
ALLOWED = {"search", "read_record"} # note: no writes
result = model(
context=build_context(state),
tools=[t for t in TOOLS if t.name in ALLOWED],
)
if state.steps > MAX_STEPS or state.is_complete():
return finalize(state)The allowlist is a per-step decision. A planning step and an execution step should not have the same tools available.
def agent(user_input):
return model(user_input)Schema validation · state · per-step context · tool allowlist · step budget · escalate path
The model is identical. The prompt is nearly identical. One of these survives a real user, and the difference is roughly thirty lines that have nothing to do with AI.
Order matters: schema first (nearly free), then rules, then anything that needs another model call.
What good output looks like.
What happens when the output is not good.
| What you wrote in the prompt | Where it actually belongs |
|---|---|
| “Always return valid JSON” | Schema validation |
| “Never delete anything” | Tool allowlist |
| “Remember what the user said earlier” | State |
| “Do not make things up” | Retrieval + grounding check |
| “Stop when you have enough information” | Termination condition |
| “Be concise, use British spelling” | Stays in the prompt |
If you are writing “always” or “never” in a system prompt, you are describing a control, not an instruction. Every “never” is a guarantee you are hoping for instead of building.
This is why failing prompts keep growing: each incident adds a sentence, the sentences compete, and past a point they degrade each other. The harness scales the other way: it is code, and code composes.
| What you saw | Layer that broke | First thing to add |
|---|---|---|
| Agent looped forever | Workflow control | Step budget |
| Answered from stale data | Context | Rebuild context per step |
| Deleted the wrong record | Permissions | Per-step allowlist |
| Shipped a plausible wrong answer | Evaluation | Rules tier, not just schema |
| Forgot the user mid-task | State | Persist confirmed facts |
| Retried and failed identically | State + context | Feed the error back in |
Same two programmes. Scan a QR, then take the next step.

For engineers & technical builders
Build and ship production AI agents
What we cover
Scan to enrol
maven.com/tailabs/ai-engineering-bootcamp

For PMs, founders & operators
Direct AI tools and ship real products
What we cover
Scan to enrol
maven.com/theaiinternship/ai-pm-bootcamp-and-cert
AI Engineering Bootcamp: build and ship production AI agents
maven.com/tailabs/ai-engineering-bootcamp

Dr. Aki Wijesundara
TAI Labs