guardrail frame and recorded.
How it works
- A new
messagearrives. If the config has refusal domains or escalation rules, a separate model call (the classifier) judges the message against them. It reads the message plus, by default, the two most recent prior exchanges on the conversation, so a short follow-up is judged in context. It runs before any model round. - If a refusal domain fired, the turn ends with a fixed refusal. Nothing is looked up. An escalation rule that fired on the same message is not recorded.
- If an escalation rule fired, the turn continues and ends with
stop_reason: "escalated", unless an output check or the output-token limit ends it with its own stop reason. - If the config has output checks, the assistant’s prose from every model round is held back and checked before it is streamed. A match withholds it.
500 guardrail_evaluation_failed and does not run. Guardrail policy never passes silently. The classifier’s model usage is metered to your org with the turn.
Resumes (tool_results, confirmations) are not classified again; the message that started the turn was.
Rule families
All three families share one list of unique rule ids. Every rule must name at least one eval scenario id inscenarios, the scenario that proves the rule works. A rule without one fails validation.
route is a label you choose for where escalated conversations go. The platform stores it with the rule and does not route on it; your application decides what to do with an escalated turn.
What happens when a rule fires
The refusal text is fixed, not written by the model. It names each fired rule by id and description, says the check ran before anything was read, and offers the ways forward:
Output checks
checkis a regular expression in Go (RE2) syntax, matched case-insensitively, with.matching newlines.- When an instance has output checks, assistant prose is not streamed as it is written. Each round’s prose is sent as one
text_deltaafter it passes. Expect answers to arrive in larger pieces. - A pattern that does not compile fails every turn with
500 guardrail_config_invalidbefore anything streams. Validation checks only thatcheckis non-empty, so test new patterns with an eval run before you publish.
Where decisions are recorded
Every decision is stored as a guardrail event with the turn id, the rule id, the decision, and the config hash that was in force. Guardrail events appear in the conversation export and are kept when retention deletes conversation content.Test your guardrails
Write eval scenarios whose rubrics usemust_refuse or must_escalate with your rule ids, and final_must_not_contain for output checks. Put them in the gate suite so the publish gate runs them. A regression blocks a publish only when the latest released version has a recorded gate run to compare against, a scenario newly fails or a new scenario fails, the candidate config sets evals.on_regression: "block", and the request carries no waiver. The first gate run records a baseline and passes. See the eval gate rules and Evaluation.
Evaluation
Scenarios and rubrics that prove each rule.
Turns and streaming
The
guardrail frame and stop reasons.