This is where AI hires are made. Recruiters ask “tell me about a failure” because production AI is ugly — it breaks in ways nobody predicts — and engineers who have shipped know how ugly it gets.
Real production AI is ugly. It breaks in weird ways that nobody predicts. The engineers who have actually shipped know exactly how ugly it gets.
What? A common interviewer bait question. The truthful answer is “no” — but that answer alone isn’t what they’re testing.
Why? Because the right follow-up reveals your reliability mindset, not your LLM knowledge.
How? Truth first: “No. You reduce impact, you don’t eliminate.” Then layered defences:
Scenario 1 — Customer-and-data Q&A
Trust comes from layered defences. Stack: grounded retrieval (RAG) + JSON output + regex rules (“no guaranteed”) + confidence score in metadata. Failure: if any single layer fails, the next catches.
Scenario 2 — Compliance-sensitive output (loan recommendation) Stack: Pre-LLM PII strip + Post-LLM compliance check + LLM-as-judge + human review on any non-zero confidence issue. Failure tolerance: zero. Multiple verifications.
Scenario 3 — Casual Q&A (brochure-style) Stack: grounded retrieval + JSON output. Tolerant of “I don’t know” answers. Failure tolerance: moderate. Single level of defence.
What? The actual symptoms-vs-causes distinction in production. People often treat hallucinations as the problem; they’re almost always the symptom.
Why? Because interviewers want to know if you can diagnose unknowns in unfamiliar systems.
How? Walk the failure tree:
Scenario 1 — “Our retrieval is bad all of a sudden”
Trace: yesterday’s deployment swapped embedding model from MiniLM-L6-v2 to text-embedding-3-small but only re-ingested 30% of documents. Fix: complete re-ingest; verify with cosine_distance(old_emb, new_emb) < 0.2 for known identical inputs.
Scenario 2 — “Hallucination rate jumped last week” Trace: the team added a metadata filter on category but typo’d the column name. Documents being filtered out. Fix: SQL test the metadata filter against a known query; correct the column name.
Scenario 3 — “Same question, different answer each time”
Trace: temperature = 0.7 was left on for an extraction task. JSON mode was off. Result: variation in extracted fields even for identical inputs. Fix: temperature=0, response_format={”type”: “json_object”}, top_p=1.0.
What? A systematic debug ladder. Top of the ladder = data layer; bottom = LLM.
Why? Because the bury-the-hallucination-then-swap-models pattern wastes weeks and money; the diagnostic-ladder pattern fails in hours.
How? Walk in this order:
Scenario 1 — “The answer is just unrelated” Trace: top-k returned irrelevant chunks. Walk up: the chunking strategy was wrong — 4000-token chunks break retrieval. Fix: 800-token chunks with 100-token overlap.
Scenario 2 — “The answer is in the chunks but the LLM drops details” Trace: the prompt was honest, the chunks were correct, but the model summarises aggressively. Fix: tighten prompt: “Quote the answer verbatim; do NOT summarise.”
Scenario 3 — “The answer is sometimes right, sometimes wrong”
Trace: model temp is too high for the deterministic extraction task. Fix: temperature=0, verify reproducibility.
What? A protective layer that bounds cost per request, per session, per user.
Why? Because running for 47 loop iterations × 1M users = $900M daily. Real users accidental loops happen.
How? Three layers:
Scenario 1 — User asks repeatedly for slightly different reformulations Detection: loop detector counts identical intent for >5 consecutive turns. Action: pause and offer: “I think I already covered this. Did I miss something?”
Scenario 2 — Adversarial agent test (jailbreak via context bleed) Detection: per-message token counter. Action: at 80% of cap, refuse further turns and offer escalation.
Scenario 3 — Buggy agent code loops infinitely Detection: timeout on agent run (max 60s); max tool calls per run (max 30); per-agent circuit breaker on cost. Action: tripped breaker → fail fast for 60s.
What? When your security layer (e.g., jailbreak detector) is unavailable, do you let the request through (fail-open) or block it (fail-closed)?
Why? Because both have failure modes; you must choose.
How? Trade-off matrix:
| Failure | Fail-open | Fail-closed |
|---|---|---|
| Lakera Guard down for 5 min | Requests go through, but Lakera is bypassed | Every request blocks |
| Cost of false negative | Customer sees a jailbreak | Customer is locked out |
| Cost of false positive | User retries, harmless | User abandons, revenue loss |
| Risk if attacker waits for downtime | High | Low |
Scenario 1 — Outbound prompt-injection (Lakera is down) Pick: fail-open with logged warning. Lakera is advisory; Presidio still runs. Block-all would lock every user out for 5 minutes.
Scenario 2 — Outbound PII-redaction (Presidio is down) Pick: fail-closed. Sending raw PII to LLM models breaches FCA & regulation. Block until Presidio is back.
Scenario 3 — Inbound authentication (JWT verifier is down) Pick: fail-closed (every request that lacks JWT is rejected). Disallowing unauthenticated traffic is safer than allowing it.
What? Three traces per agent: input, output, decision reasoning. Plus per-system metrics for latency, cost, error rate.
Why? Because without traces, debugging is guesswork. Without metrics, alerting is guesswork.
How? Langfuse for per-LLM-call traces (cost, latency, prompt, completion) wrapped as parent spans. Prometheus for HTTP-level metrics (rate, errors, duration). Logs structured with JSON formatter so simple grep works.
Scenario 1 — “It worked in dev, doesn’t in prod” Trace comparison: Langfuse shows prompt difference; runtime env vars are different. *Fix: parity env setup test in CI.
Scenario 2 — “Latency unexpectedly high” Tracing: Langfuse shows LLM call has 800ms latency, while other components add 400ms — total 1.2s, vs SLO of 1s. *Fix: model warm-pool; retries on the LLM provider; cache frequently-returned completions.
Scenario 3 — “Cost exploded overnight” Tracing: Langfuse shows 4x normal usage of one tool on Tuesday night — likely a runaway cron. *Fix: patch the cron, alert on per-tool-call rate.