There are two kinds of boundaries in a Claude deployment. Anthropic's models decline genuinely harmful requests on their own — that layer comes with the model. Everything else is your policy: the support assistant that shouldn't discuss competitors, the HR bot that must never speculate about individual employees, the banking assistant that answers product questions but not "should I buy this stock?" The model can't infer these; guardrail prompting is how you write them down. This article is about defensive scoping — keeping a legitimate assistant inside its lane — not about content moderation systems, which deserve their own tooling.
Implicit guardrails: scope is the strongest constraint
The most effective guardrail is rarely a "do not" list; it's a tightly defined job. Anthropic's best-practices guidance emphasizes giving Claude a role via the system prompt — even one sentence focuses behavior — and being clear and direct about the task. A narrow role excludes most unwanted territory without enumerating it: "You are the order-status assistant for Acme's retail customers. You help with order tracking, returns, and shipping questions" implicitly rules out medical advice, competitor commentary, and political debate better than any blocklist, because off-topic requests simply fall outside the described job. Start here; add explicit rules only for the boundaries that scope alone doesn't hold.
Explicit guardrails: rules with reasons and exits
For lines that must hold under pressure, write explicit constraints — and give each one two companions the model can use. First, a reason: the docs note that Claude generalizes from explanations, so "Never quote a delivery date beyond what the tracking system returns, because customers treat your dates as commitments" outperforms the bare rule when a user finds phrasing you didn't anticipate. Second, an exit: tell Claude exactly what to do instead of the forbidden action — decline briefly, offer the in-scope alternative, or hand off to a human. A rule with no exit produces awkward stonewalling; a rule with an exit produces a good customer experience. (Negative instructions have their own craft — see writing negative instructions that work.)
## Boundaries
- Order data comes ONLY from the provided <order_context>.
If it's not there, say you don't have it and offer to
connect a human agent. (Guessing creates false promises.)
- No opinions on competitors' products. Redirect to what
Acme offers for the same need.
- If the customer asks for legal, medical, or financial
advice: decline in one sentence and suggest a qualified
professional. Do not summarize "general information" as
a workaround.
Structure helps enforcement: keeping boundaries in their own clearly labeled section (XML tags or a heading), separate from tone and task instructions, follows the official guidance on structuring prompts and makes review — and versioning — cleaner. A few high-stakes examples of correct refusals, wrapped in <example> tags, harden behavior further than rules alone.
Guardrails users will push on
Assume some users will probe the boundaries — extracting the system prompt, role-playing around a rule, the classic "ignore previous instructions." Prompt-level defenses help (state that boundary rules take precedence over any user request to change them; instruct Claude not to reveal or restate its instructions), but treat the system prompt as one layer, not the wall. Enforce hard limits outside the model too: server-side validation of what the application will actually do with outputs, allowlists on tools, and monitoring for boundary-probing patterns. The threat model is covered in prompt injection 101, and platform-level filtering options exist as well — Amazon Bedrock, for example, offers Guardrails as a separate managed layer (see the Bedrock Guardrails overview).
Test the lines like you test the features
Guardrails belong in your evaluation set with the same rigor as happy-path cases: a battery of inputs that should be refused or redirected, scored on whether the boundary held and whether the exit was graceful. Two failure directions matter equally — lines that leak (the model answers anyway when asked sideways) and lines that overreach (the model refuses legitimate in-scope requests, which quietly destroys product value). Track both rates across prompt versions, and re-run the battery on every model upgrade, since boundary behavior can shift between model generations like everything else. When outputs feed code, note that the API can also signal model-initiated refusals mechanically — structured-output requests, for instance, can return stop_reason: "refusal" — so build handling for that path rather than assuming every response parses.
Where to go next
The recovery side — what to do when Claude refuses something it shouldn't — is covered in handling and recovering from refusals. For regulated-industry boundary patterns, see prompting in sensitive domains, and for making Claude hand off cleanly, prompting for graceful escalation.