Guardrails fire on every request and decide whether the response goes out. Evals fire on a sampled population and decide whether the system is meeting its quality bar. Huyen's platform post puts input and output guardrails on the request path and treats evaluation as a separate step at every stage of development 1. Both are necessary. Neither substitutes for the other.
Foundations carries the chapter-length treatment; the production plumbing lives in the production section.
What each is for
A guardrail is a runtime check with a binary consequence (pass or block). Synchronous on every request or response. On the critical path. Latency is part of the user-facing budget. Examples: PII redactor on input, toxicity classifier on output, JSON-schema validator, refund-policy regex.
An eval is a measurement of system quality on a sample. Asynchronous (offline on a benchmark, or online on sampled production traces). Does not block any individual response. Produces a score that informs human decisions (release-gate, drift alert, calibration update) 2. Examples: a calibrated LLM judge scoring 5% of production traces for faithfulness, a nightly CI run on a 200-example regression set, an A/B with bootstrap intervals.
The shared substrate is the trace stream. Both read traces, both write to the trace store, both produce labels.
| Property | Guardrail | Eval |
|---|
| When | every request | sampled, scheduled |
| Latency | tens to hundreds of ms | seconds to minutes |
| Consequence | block or pass | score, no block |
| Owner | platform or safety team | eval team |
| Failure mode | false positive blocks real users | sampling bias, miscalibration |
| Aggregate | per-request precision and recall | per-population pass rate with CI |
Where each fires
A typical request path:
- Input guardrail. PII redaction, jailbreak filter, schema validation on input.
- Retrieval (RAG only).
- Generation.
- Output guardrail. Toxicity, factuality classifier, schema validation on output.
- Response returned.
- Trace write to store.
- Async eval sampler picks a fraction.
- Async judge scores the trace.
- Aggregate metrics roll up.
Steps 1, 4, and 6 are the request path. Steps 7, 8, and 9 are the eval path. Different processes with different SLAs.
Streaming complicates step 4. Tokens reach the user as they are generated, so an output check that needs the full response can only act after partial text is already on screen 1. Buffer the stream for the categories where one failure is catastrophic and accept the added latency there; let the rest stream and fall to the eval path.
Figure: Guardrails vs evals in the request path: input and output guardrails run synchronously on every request inside a 200-500 ms p95 budget, while the eval pipeline asynchronously samples 1-5% of traces from the shared trace store for LLM-judge scoring and aggregate pass rates. Two pipelines, one trace store.
The three failure modes of confusing the two
Eval-as-guardrail. The team puts the LLM judge on the request path and blocks responses below a threshold. User-facing latency doubles, the judge's TPR/TNR become production constraints rather than calibration targets, and any judge drift becomes a user-visible reliability issue. Judge cost scales with traffic, not sampling.
Guardrail-as-eval. The team treats the guardrail pass-through rate as the quality metric. Guardrails only catch what they were designed to catch (PII, toxicity, schema violations); they say nothing about helpfulness, correctness, or brand voice. A 99.9% guardrail pass rate is consistent with a 60% quality pass rate.
Shared rubric, shared owner. The team writes one rubric used for both. The guardrail rubric needs to be cheap, deterministic, very low false-positive rate (FP rate translates directly to blocked users). The eval rubric needs to distinguish "merely acceptable" from "good." Trying to satisfy both kills the rubric for both. Shankar et al. find that criteria shift as people grade real outputs, which is why a rubric frozen for blocking and a rubric still being refined for scoring cannot be one document 3.
Architectural fix in all three: separation. Different rubrics, different latency budgets, different owners.
When each fires (the decision table)
| Failure category | Guardrail | Eval | Why |
|---|
| PII leak in output | yes | also yes (trend) | catastrophic single failure justifies block |
| Toxic language | yes | also yes (trend) | same |
| Schema violation | yes | maybe | block prevents downstream errors |
| Off-brand tone | no | yes | subjective, judge-quality, no block warranted |
| Policy misquoting | yes | also yes | high-cost single failure |
| Faithfulness in RAG | maybe | yes | judge expensive, block hurts UX |
| Conciseness | no | yes | preference signal, never blocks |
| Sycophancy | no | yes | subtle, judge-only |
Five high-stakes single-failure categories (PII, toxicity, schema, policy, hard safety) belong in the guardrail layer; everything quality-related belongs in the eval layer. Overlap rows are where teams confuse themselves; resolve by latency and consequence.
Sharing data, not logic
The guardrail layer and the eval layer share the trace stream; they do not share logic. The eval layer reads guardrail decisions as features (a guardrail-triggered trace is an interesting sample for open coding). The guardrail layer reads aggregated eval results as inputs to threshold tuning (judge identifies a faithfulness regression; team adds a faithfulness-specific guardrail with a higher threshold). Two pipelines, one trace store.
The guardrail layer in practice
Four classes of checks. Input sanitizers (PII redaction, prompt-injection detection, schema validation) at 10-50 ms. Input classifiers (small distilled models flagging restricted topics) at sub-100ms; the OWASP Top 10 for LLM Applications is the reference categorization 4. Output classifiers (toxicity, factuality, schema) on the buffered response, or in parallel with the stream when partial display is acceptable. Hard-coded rules (regex for forbidden promises, blocklist matches, response-length caps) at sub-millisecond. Combined p95 budget: 200-500 ms.
Policy-following classifiers change how a rule is written. Mistral's Shieldstral (3B, Apache 2.0, August 2026) takes a plain-language policy at inference time for text and images 5, and gpt-oss-safeguard classifies against a custom policy you supply 6. A guardrail rule becomes a versioned prompt, so score each revision of the policy against labeled traces from the eval program and read its false-positive rate before it blocks anyone.
For agents the enforcement point moves from the response to the tool call, which is where Excessive Agency does its damage. OWASP's Agent Control Standard, an early specification (v0.1.0) published in September 2026, defines lifecycle hooks such as a tool-call request and a tool-call result where a guardian can allow, deny, modify, ask, or defer an action before it runs 7. Treat those hooks as guardrail points, and score the agent's tool-call decisions on the eval path with the agent trajectory evaluation methods. Do not let the classifier that gates those tool calls also grade them: a payload written to flip the gate flips the eval too, and decision models as judges shows how that hides an attack behind a clean pass.
The eval layer in practice
Three loops at three frequencies. Synchronous offline (per release): CI runs the regression set and release-gate eval 8. Sampled online (continuous): async judging of 1-5% of traffic with daily aggregation; the online evaluation page covers mechanics. Weekly human cadence: open-coding loop on 10-20 fresh traces, failure-biased on guardrail-triggered or low-judge-score traces, with a fuller pass over 100+ fresh traces every two to four weeks and after any major change 8; the error analysis page covers the discipline. The three loops feed each other; Shankar's flywheel is the formalization 9.
What good looks like
A guardrail layer with clear ownership, measured per-request precision and recall, p95 latency under 500ms. An eval layer with separate ownership, measured per-population pass rate with intervals, asynchronous off the request path. A shared trace store with provenance fields that distinguish guardrail decisions from eval scores. Weekly human review on failure-biased samples from guardrail triggers and low-judge-score traces. A decision policy that adds a guardrail rule when the eval program surfaces a regression and adds an eval dimension when a guardrail rule starts producing many borderline cases.