📕 Read the full ebook AI Product Shipping Field Guide · 15pages
Your browser cannot display PDFs inline. Open in new tab
This post is a condensed rewrite. The PDF is the full book.

This is for engineers and product leads who have already built an AI feature and are now staring at the harder problem: sending it to real users. The argument is simple and, I think, underappreciated. When AI products fail in production, the root cause is rarely model quality. It is almost always that nobody decided, ahead of time, when the system should stop.

Teams routinely spend weeks tuning a model and then decide how the system should react to a bad output the night before launch, if they decide it at all. That ordering is backwards. A better model reduces the frequency of incidents. It does not eliminate them. If you have not decided in advance what to halt and what to keep running when things go wrong, then even a highly accurate model is sitting inside a system nobody can actually trust in production.

Illustration of the core idea of AI Products Don't Fail Because of the Model. They Fail Because Nobody Defined When to Stop. A visual metaphor for the article’s key idea.

The Smart-Model Illusion That Breaks Production

The first question most teams ask when building an AI feature is how smart is this model. They compare benchmark scores, swap in a different model, tweak the prompt, and repeat. None of that is wrong on its own. The problem is that no amount of progress on that question tells you whether the system is safe to ship.

How smart a model is and whether this model should be deployed to our service are two different questions. Answering the second one requires someone to first decide, in plain terms, what output should follow from what input, which categories of wrong answers are tolerable, and which are not tolerable under any circumstance. Without that standard, no evaluation score means anything. A ninety percent accuracy number is only meaningful once someone has defined what the other ten percent is allowed to look like.

The failure pattern that shows up again and again in practice looks like this. A team compares two or three candidate models, picks the one that feels better, skims a handful of qualitative examples, and calls it good enough. That judgment quietly becomes the deployment approval. Nowhere in that process is there an explicit definition of what counts as a failure or what the system does when one occurs. The team ends up improvising that definition under pressure, right after the first real incident.

Evaluation design is a decision-making exercise, not a development task. The goal is not to collect the largest possible dataset. It is to concentrate effort on the inputs that actually move business outcomes. A small dataset built around decision-relevant inputs is worth more than a much larger dataset assembled by grabbing whatever was easiest to collect.

So the opening question needs to change. Instead of asking how smart is this model, ask under what conditions could this model produce a failure we cannot absorb. Only once you can answer that question are you ready to design the pipeline and deployment strategy that sit downstream of it.

Evaluation Is a Stop Rule, Not a Report

Defining an evaluation standard is not the finish line. If that standard lives as a document someone has to read and interpret every release, it is functionally the same as having no standard at all. People are busy, tired, and under deadline pressure. A criterion that depends on human judgment is the first thing to erode on the day the pressure is highest.

An evaluation pipeline should run through four connected stages: data collection, definition of expected outputs, automated measurement, and a release gate. No matter how careful the first three stages are, if the final stage, the release gate, is not automated, then most of that earlier effort goes to waste. When measured results fall short of the threshold, the deployment pipeline itself should stop. The moment someone can wave a failing result through as an exception, the gate stops being a gate and becomes decoration.

A common mistake here is collapsing everything into a single metric. Exact string matching alone will not catch an answer that is formatted correctly but semantically wrong. The right metric depends on the task. Classification problems need visibility into which direction errors skew, not just whether they occurred. Generative outputs often need a relevance measure that looks past surface-level string overlap, because two very different strings can express the same correct idea.

When you design a release gate, define the failure path as carefully as the passing threshold. What happens to a model that does not clear the gate? Does the system automatically roll back to the previous version, or does it simply hold the release? Without a clear answer, a gate becomes something that raises a warning and then does nothing to stop the deployment from proceeding anyway.

The point of evaluation was never to earn a good score. It is to automatically block a bad release. Teams that treat evaluation as a report and teams that treat it as a gate can look, from the outside, like they are doing the same work. The difference only becomes visible the day something actually goes wrong.

Deployment Is a Reversible Procedure, Not a Switch

Passing evaluation does not make it safe to send a model to all of your traffic at once. Even a carefully constructed evaluation dataset cannot perfectly reproduce the distribution of real user inputs. There is always something that only shows up once traffic is real, and that something is exactly what a good deployment procedure exists to catch early.

So deployment needs to be designed as a reversible procedure, not a binary switch. Canary deployment exposes a new model to a small slice of traffic first, confirms nothing is wrong, and then gradually widens that slice. Blue-green deployment stands up the new model in a fully separate environment while leaving the previous environment running, then cuts traffic over to it. Both approaches share the same core property: if something goes wrong, the system needs to be able to return to the previous state immediately, not eventually.

That reversal only works in practice if model versioning came first. You need to record not just the model file, but the configuration that produced it, the evaluation results it passed, and the exact moment it was deployed. Without that record, when something goes wrong you cannot even determine which version is safe to roll back to, let alone execute the rollback quickly.

It also helps to remember that the pipeline itself has three internal stages: preprocessing, inference, and postprocessing. A failure can originate in any of the three, and each one needs its own predefined behavior for when things go wrong. If preprocessing detects an unusual input, it is usually better to reject it right there than to send it forward into inference. If postprocessing detects a malformed model output, replacing it with a safe default is almost always better than exposing the raw output to a user.

Teams that treat deployment as a procedure recover from incidents in minutes. Teams that treat deployment as a switch start figuring out how to reverse it only after the incident has already begun. That difference in preparation is what determines how long an outage actually lasts.

Four Failure Types, Four Very Different Responses

AI systems fail differently from traditional software, because the code does not always execute a fixed, deterministic operation the way conventional software does. Input variation is wide, and the model’s behavior is itself probabilistic, which means the same input can produce a different result at a different point in time.

Splitting failure into four categories makes the correct response obvious in a way that a generic error-handling wrapper never will. The first category is runtime errors: memory exhaustion, network interruptions, cases where inference itself fails to complete. These behave like conventional software failures, and conventional patterns work here, retries, fallbacks, and circuit breakers.

The second category is output format errors, where the model does not return a response in the expected shape. These are best handled by reprocessing the input or routing to an alternate inference path rather than surfacing a broken response. The third category is quality degradation, where inference technically succeeds but the output is factually wrong or misreads the intent of the input. This is the hardest category to manage automatically, because the response looks structurally fine, so nothing about its shape signals that anything is wrong.

The fourth category is latency inflation, where inference suddenly takes longer than usual. This can quietly violate a service-level agreement well before anyone notices a hard failure, which is why it needs continuous monitoring rather than a one-time check. Treating all four categories as a single undifferentiated error class leads to exactly the wrong instincts: rolling back a problem that a simple retry would have fixed, or retrying a problem that actually needed a rollback.

Failure Type Typical Cause First Response
Runtime error Memory exhaustion, network interruption Retry, fallback, circuit breaker
Output format error Parsing failure, missing required field Reprocess or route to alternate path
Quality degradation Factually wrong output, misread intent Human review or safe default
Latency inflation Load spike, resource contention Continuous monitoring, threshold alert

What this table really shows is that accurate response depends entirely on accurate classification. A system that skips classification and treats every failure the same way ends up producing incidents of its own making, retry storms that overload a struggling backend, or rollbacks triggered for problems a retry would have resolved on the second attempt.

No System Is Either Fully Up or Fully Down

AI systems are rarely in a binary state of fully working or fully broken. Most real failures are partial. A system that combines several models can lose one of them and keep serving a reasonable response using the ones that are still healthy.

Handling partial failure well requires separating core functionality from supporting functionality at design time, not during an incident. If a search product adds an AI summary on top of its results, the summary failing should never take the underlying search results down with it. Any architecture where an AI feature’s failure drags a core feature down with it is a design mistake made long before the incident, not a bad-luck event during the incident.

Skip that separation up front, and you are forced to decide, in the middle of an active incident, what to sacrifice and what to protect. Improvised decisions made under acute pressure are wrong more often than not. What to protect and what to let go should be decided while things are calm, written down, and tested, not reasoned out in real time while an alert is firing.

Designing for partial failure also reduces cost, because it removes the need to build every component to the same standard of robustness. Core functionality deserves investment in redundancy and fast fallbacks. Supporting functionality can often be allowed to fail quietly and disappear from the response without anyone noticing, which is a far more efficient use of engineering effort than treating every component as equally critical.

A Gate With No Eyes Cannot Stop Anything

Everything discussed so far, the evaluation gate, the deployment procedure, the failure taxonomy, becomes powerless without observability behind it. A gate can be extremely well designed and still fail its purpose if nobody can see what it is currently looking at when something starts to go wrong.

The signals worth watching fall into three categories. System signals are infrastructure-level metrics: resource utilization, network latency, the kind of numbers a standard monitoring stack already collects. Model signals describe the model’s own behavior: inference latency, inference success rate, the distribution of input and output sizes. Business signals describe how model output translates into business outcomes, things like conversion rate after an AI response or click-through rate on an AI recommendation.

Watching only one of these three categories narrows your field of view in a specific, predictable way. Watch only system signals, and you will miss a model quietly degrading while the infrastructure underneath it looks completely healthy. Watch only business signals, and you will know that conversion dropped without being able to tell whether the model caused it or something else entirely did. You need all three together to trace what is degrading and why.

This kind of observability matters especially because of model drift. A model that performed well at deployment time can lose performance over time as the underlying data distribution or usage pattern shifts underneath it. The practical approach is to treat the model’s performance at deployment as a baseline, then trigger an alert whenever subsequent data deviates meaningfully from that baseline.

Drift detection itself operates at two distinct levels: data drift, which tracks changes in the distribution of inputs, and prediction drift, which tracks changes in the distribution of model outputs. A data drift alert usually points toward a shift in the collection pipeline or in user behavior. A prediction drift alert usually points toward the model itself having gone stale. Keeping the two separate is what lets you narrow down the actual cause instead of guessing.

Conclusion: Design the Stop Before You Design the Model

Evaluation, deployment, failure handling, and observability look like four separate disciplines, but they all converge on a single question: when should this stop. Evaluation decides the stopping criteria before deployment. Deployment procedure builds the path to stop and reverse after deployment. Failure taxonomy identifies which signals should trigger a stop. Observability is what actually catches those signals in time to act on them.

Making the model smarter still matters. It just cannot substitute for deployment safety. Every model, no matter how good, will eventually encounter an input it was not prepared for and fail in a way nobody predicted. What the system was built to do at that exact moment is what determines whether users trust it afterward.

So here is the order worth proposing to any team preparing to ship an AI product. Decide your stopping criteria before you pick a model. Build a reversal procedure before you press deploy. Define your failure taxonomy before an incident forces you to invent one on the spot. And put eyes on all of it before you need them. Teams that follow this order recover from incidents in minutes. Teams that skip it relearn the same lesson, from scratch, every time something breaks.

Chapter Illustrations

Chapter 3 illustration Chapter 4 illustration

Tags: ai-deployment, canary-deployment, eval-gates, failure-handling, mlops, model-monitoring, observability, production-reliability

Categories:

Updated: