- A product manager who asks whether the chatbot can be made to never say something embarrassing is asking for a guarantee that guardrails cannot give. They lower the rate of bad output, they do not remove it.
- Published research bypassed six commercial guardrail systems, including Microsoft's Azure Prompt Shield and Meta's Prompt Guard, with up to 100 percent evasion success. Treat any detector as evadable.
- Guards sit in three places: on the input, inside the inference call, and on the output. A serious defence uses all three and specifies fail closed behaviour at each, because most implementations fail open under load.
- Every guard is an extra check, often another model call, so a full guard stack can add more latency and cost than the generation it protects.
- The design rule that follows: anything you truly cannot allow must be enforced outside the model, in code the model cannot talk its way past.
A product manager asks a simple question. Can we make the chatbot never say anything embarrassing? The honest answer is no, and the developer who says yes has just signed up to be wrong in public. What you can do is lower the odds, often dramatically, and the gap between never and lower the odds is the entire subject of LLM guardrails. Get the framing right with the product manager first, because a guardrail sold as a guarantee becomes a broken promise the moment someone clever, or just unlucky, gets through.
Guardrails are worth building. A good stack turns a feature that misbehaves often into one that misbehaves rarely, which is the difference between shippable and not. The mistake is not building them, it is describing what they buy. They buy a rate, not a promise, and everything below follows from taking that sentence seriously. The rate has a cause worth understanding first, since models are graded in a way that rewards a confident guess over an admission of uncertainty.
The clearest way to hold that idea is to compare it to a guard everyone already trusts without expecting perfection. A spam filter catches the vast majority of junk and lets the occasional message through, and nobody considers it broken for that, because the alternative is no filter at all. AI guardrails are the same kind of tool. They move a feature from unacceptable to acceptable by lowering a rate, and the day you start describing them as a guarantee is the day you set yourself up to be blamed for the one that got through. Keep the spam filter in mind whenever the conversation drifts toward the word never.
Can a guardrail guarantee the bot never misbehaves?
No, and the evidence is unusually direct. A 2025 study titled Bypassing LLM Guardrails ran evasion attacks against six protection systems, among them Microsoft's Azure Prompt Shield and Meta's Prompt Guard, and reported that its methods could evade detection while keeping the attack effective, reaching up to 100 percent evasion success in some cases. These are the commercial detectors a team would reach for first, and they were defeated with character level tricks and adversarial machine learning techniques. The lesson is not that these products are bad, it is that a detector trained to recognise attacks can be fooled by an attack shaped to look benign, which is a property of the approach rather than a bug in one vendor.
So the correct mental model is a filter that catches most of what it has seen and misses what has been shaped to slip past. That is genuinely useful, in the way a spam filter is useful, and it is not a wall. Anyone who has probed a system for weaknesses recognises this immediately, which is why the discipline of red teaming an AI system pairs with guardrails: you build the guard, then you try to walk through it, and the rate at which you succeed is the number you report, not a claim that you cannot.
Where does each guard sit?
Three places, and a serious defence uses all three rather than betting on one. Datadog's guidance on guardrails names the same split: input guardrails that check the user prompt with static filters and classifiers, guardrails built into the prompt construction, and output guardrails that post process the model's reply. The layers catch different things, and the figure below shows them in the order a request passes through, ending with the one that is not a model guard at all.
| Guard layer | What it reliably catches | Its limit |
|---|---|---|
| Input guard | Known injection patterns, obvious PII, off topic prompts | Evadable by reshaped attacks, up to 100 percent in tests |
| Inference constraints | Shape and scope, via system prompt and output schema | The model can still be talked out of the instruction |
| Output guard | Toxic content, schema violations, ungrounded claims | Classifier misses, and cost of a second pass |
| Hard boundary in code | Actions the model must never take | Only covers what you can express as a rule outside the model |
The input guard screens the prompt before the model sees it: strip personal data, scope the topic, and run an injection or jailbreak classifier. The inference constraints shape the call itself: a firm system prompt, a required output schema so the reply has to hold a known form, and tool permissions scoped so the model can only call what this feature needs. Forcing the output into a schema is its own small guard, and the mechanics of making a model hold that shape are worth their own read in the piece on getting a model to return valid JSON. The output guard is the last model side check: classify the reply for toxicity, validate it against the schema, and for a retrieval feature check that the answer is grounded in the sources rather than invented. Open source frameworks like Guardrails build exactly these, running input and output validators that detect and mitigate specific risks and fail the call when a check does not pass.
The input guard is where the phrase input output filtering comes from, and it is worth being precise about what it filters. A prompt injection defense here is usually a classifier that flags text trying to override the system's instructions, and a jailbreak detection classifier flags text trying to unlock disallowed behaviour. Both are the exact detectors the evasion research defeated, so treat them as the first thin layer rather than the wall. Stripping PII is the more dependable input guard, because removing an email address or a card number from a prompt is a deterministic operation rather than a judgement call, and deterministic guards are the ones that actually hold.
This is why the right frame for guardrails for AI applications is defense in depth, the phrase Datadog uses, rather than a single magic filter. No one layer is trusted to catch everything, so the layers stack and a request has to pass all of them. An attack that slips the input classifier may still be caught when its output is classified, or blocked when the action it wants is simply not exposed to the model. The value is not in any single guard's accuracy, it is in the product of the layers, and in the fact that an attacker now has to defeat several different mechanisms rather than one.
One output guard is different from the rest, and worth leaning on because it does not depend on a fallible classifier. Output validation against a schema is deterministic, since either the reply is valid JSON with the required fields or it is not, and if it is not you reject or re ask rather than pass a malformed answer downstream. Unlike a toxicity classifier that guesses, schema validation is a hard check, which is why forcing structured output doubles as a guard. The same goes for tool scoping, because a model given only read tools cannot perform a write no matter what it is convinced to attempt. Wherever you can replace a probabilistic guard with a deterministic one, do it, since the deterministic guards are the layers that do not get evaded.
What does a layered defence look like in practice?
Take one real feature, a support assistant that answers from your help centre, and walk the layers with the failure behaviour specified at each, because that specification is the part most implementations skip. On the input, strip any customer data out of the prompt and run an injection classifier; if the classifier errors or times out, the request is refused, not waved through. Inside the call, a system prompt scopes the assistant to support topics, the output is required to fit a schema, and the assistant is given read only tools with no ability to change an account. On the output, classify the reply and check it is grounded in a real help article; if grounding fails, return a safe fallback rather than the model's guess. The system prompt is doing real work here, and what belongs in it, versus what does not, is its own discipline covered in the guide to what belongs in a system prompt.
The phrase that matters in that walk is if it errors, refuse. Most guard stacks fail open, meaning that when a check breaks or the service is slow, the request sails through unguarded, which is the opposite of what you want and exactly what happens under the load of a real incident. Deciding fail closed at each layer, so a broken guard blocks rather than permits, is the single most valuable design choice in the stack, and it is free. It costs nothing to implement and it is the difference between a guard that protects you on your worst day and one that quietly stops protecting you precisely when you are being attacked.
What does a full guard stack cost?
Often more than the thing it protects, which is the trade nobody puts in the proposal. Each guard is a check, and the strong ones, the injection classifier, the toxicity classifier, the grounding check, are themselves model calls. Stack an input classifier, a schema pass, and an output classifier around a single generation and you have made three or four model calls where you planned one, each adding its own latency and its own bill. For a cheap high volume feature, the guard stack can cost more than the generation, and the latency it adds is latency the user feels on every request. That is not a reason to skip guards, it is a reason to size them to the risk. A high stakes action deserves the full stack, a low stakes cosmetic reply does not, and running the heavy classifiers on every trivial call taxes the whole feature for the sake of the rare dangerous one. The costing here rhymes with the wider lesson that a defence you run inline is a model call you pay for, the same tradeoff we drew for tracing in the piece on what to record for LLM observability.
Make the cost concrete. A single generation might be one model call. Wrap it in an input injection classifier, an output toxicity classifier, and a grounding check, and you are at four model calls, each with its own latency, for one user reply. If the generation costs a cent, the guarded version can cost three or four, and the user waits for all of them to finish. On a feature handling millions of calls that is a real budget line, and it is why the sizing question, which guards run on which paths, is an engineering decision rather than a checkbox. The cheapest guard is always the deterministic one that needs no model call at all, which is another reason to prefer schema validation and tool scoping over yet another classifier.
What about the guards that block real users?
Every guard that can wrongly permit an attack can also wrongly block a customer, and the second failure is the one that quietly costs you business. An injection classifier tuned aggressively enough to catch clever attacks will also flag the support ticket that happens to contain the word ignore, and an output filter strict about medical language will refuse a pharmacy's legitimate question. This is the false positive tax, and it is the reason you cannot simply turn every guard to maximum. The rate you are lowering is bad output, but the rate you are raising is blocked good users, and the two move together. The practical answer is to measure both, tune to an acceptable balance rather than an impossible zero, and reserve the strictest settings for the highest stakes paths where a wrong block is cheaper than a wrong allow.
What should you tell the product manager?
Give them a rate and a principle, not a promise. The honest sentence is that guardrails reduce the frequency of bad output to a low level you can measure and keep lowering, and that no configuration makes it zero, because the detectors are evadable and the model is non deterministic. That is not a disappointing answer once it is framed right, it is the same deal as fraud detection or spam filtering, both of which run businesses despite catching most rather than all. Report the rate, commit to improving it, and refuse to promise the zero.
In practice the conversation goes better than developers expect. Told plainly that the assistant will get it wrong roughly one time in some measurable number, and that the number is tracked and falling, most product managers hear a normal engineering tradeoff rather than a failure, because it is one. What they cannot accept, and should not, is finding out after launch that the guarantee they were sold was never real. The five minutes spent setting the expectation correctly is cheaper than the incident review that follows a broken promise, and it is among the highest value things a developer can do before the feature ships.
The principle is the more important half, and it changes the architecture. Anything you truly cannot allow, a refund issued without approval, a database row deleted, a price set to zero, must be enforced outside the model, in ordinary code the model has no way to talk past. A guardrail asks the model nicely and checks its answer. A hard boundary in your application simply does not expose the dangerous action to the model in the first place, so no clever prompt can reach it. Use guardrails to lower the rate of the embarrassing, and use code to make the catastrophic impossible. When you draw the line that way, the product manager's question finally has a clean answer: we cannot promise the bot never says something awkward, but we can promise it can never do something irreversible, because that promise lives in code, not in a filter. And whatever you build, hold it to the standard we hold our own systems to on the MaShop security page, where the boundary that matters is the one the model cannot cross, no matter how the prompt is worded or how the guard is tuned.