Skip to main content

Guardrail Libraries: Guardrails.ai and Outlines

Guardrail libraries are frameworks that enforce constraints on LLM output at the generation level, not after. They work by steering the model toward valid tokens during decoding, dramatically reducing invalid outputs. Guardrails.ai and Outlines are the two industry leaders. Using guardrails, teams report 95%+ valid outputs on first attempt (Guardrails.ai, 2025).

This article compares the two libraries, teaches you how to use them, and shows when guardrails are worth the extra complexity.

What Are Guardrails?

A guardrail is a constraint applied during LLM token generation. Instead of generating freely and hoping for valid output, the model's token choices are restricted to only those that maintain validity. For example, if you want JSON output, the guardrail ensures the first token is { and subsequent tokens form valid JSON.

Guardrails reduce the need for retries. Valid outputs on first attempt increase from 50–80% (with good prompting) to 95%+ (with guardrails).

Guardrails.ai: Rule-Based Constraints

Guardrails.ai is a framework for defining validation rules and repairing invalid outputs. It supports schema validation, safety checks, and LLM-powered repair.

Installation

pip install guardrails-ai

Basic Usage: Schema Validation

from guardrails.hub import JsonSchema, ToxicLanguage
from guardrails import Guard

# Define schema
schema = {
"type": "object",
"properties": {
"sentiment": {"type": "string", "enum": ["positive", "negative", "neutral"]},
"confidence": {"type": "number", "minimum": 0, "maximum": 1}
},
"required": ["sentiment", "confidence"]
}

# Create guard with validators
guard = Guard.from_pydantic(
output_class=SentimentAnalysis, # Pydantic model
num_reasks=3 # Retry up to 3 times on failure
)

# Use guard with LLM
response = guard.validate(
llm_output=llm_response,
num_reasks=3
)

if response.validation_passed:
print(response.validated_output)
else:
print("Validation failed after retries:", response.error_message)

Custom Validators

Define custom business logic validators:

from guardrails import Validator, register_validator
from typing import Any

@register_validator("price_range", data_type="number")
class PriceValidator(Validator):
"""Ensure price is in valid range."""

def validate(self, value: Any, metadata: dict) -> Any:
min_price = metadata.get("min_price", 0)
max_price = metadata.get("max_price", 1000000)

if not (min_price <= value <= max_price):
raise ValueError(f"Price {value} must be between {min_price} and {max_price}")

return value

# Use in guard
guard = Guard.from_string_schema(
"""
{
"type": "object",
"properties": {
"price": {
"type": "number",
"validators": [
{
"name": "price_range",
"on_fail": "reask",
"min_price": 10,
"max_price": 10000
}
]
}
}
}
"""
)

LLM-Powered Repair

Guardrails.ai automatically retries with LLM-generated corrections:

guard = Guard.from_pydantic(
output_class=SentimentAnalysis,
num_reasks=3
)

# The guard will:
# 1. Parse and validate output
# 2. If invalid, send corrective prompt to LLM
# 3. Re-validate LLM's attempt
# 4. Repeat up to 3 times

response = guard.validate(
llm_output=llm_response,
num_reasks=3
)

Guardrails generates the repair prompts automatically, saving you from writing them manually.

Outlines: Constrained Generation

Outlines is a library for guided generation that constrains tokens during decoding. Unlike Guardrails.ai (post-processing repair), Outlines steers the model in real-time.

Installation

pip install outlines

JSON Generation

Generate JSON guaranteed to match a schema:

from outlines import models, generate
import json

# Load model with guided generation
model = models.transformers("mistral-7b-instruct")

# Define schema as Pydantic model
from pydantic import BaseModel

class SentimentAnalysis(BaseModel):
sentiment: str # Will be constrained to enum values
confidence: float

# Generate JSON matching schema
generator = generate.json(model, SentimentAnalysis)

output = generator("Analyze sentiment of: [text]", max_tokens=200)
# output is guaranteed valid JSON matching SentimentAnalysis

Regular Expression Constraints

Generate output matching a regex pattern:

from outlines import models, generate

model = models.transformers("mistral-7b-instruct")

# Generate email addresses matching regex
phone_pattern = r"^\+1-\d{3}-\d{3}-\d{4}$"
generator = generate.regex(model, phone_pattern)

output = generator("Extract phone number: [text]")
# output matches pattern: "+1-555-123-4567"

Choice Constraint

Force the model to choose from a set:

from outlines import models, generate

model = models.transformers("mistral-7b-instruct")

# Force choice between options
choices = ["positive", "negative", "neutral"]
generator = generate.choice(model, choices)

output = generator("Classify sentiment: [text]")
# output is one of: "positive", "negative", "neutral"

Comparing Guardrails.ai vs Outlines

AspectGuardrails.aiOutlines
ApproachPost-processing + LLM repairReal-time token steering
Valid outputs85–95% after retries95%+ on first attempt
Setup timeMedium (define validators)Low (schema + regex)
CostHigh (multiple LLM calls for repair)Low (single generation)
Model supportWorks with API models (OpenAI, Anthropic)Local models only
FlexibilityVery high (custom validators)Medium (schema/regex)
Best forCloud APIs, complex rulesLocal models, simple schemas

Hybrid Approach: Guardrails + Outlines

Combine both for maximum reliability:

  1. Use Outlines for local models to get valid JSON on first attempt.
  2. Use Guardrails.ai for cloud API models with retry/repair on failure.
  3. Add custom validators to Guardrails for business logic.

Example:

# For cloud API (OpenAI, Anthropic)
guard = Guard.from_pydantic(output_class=SentimentAnalysis)
response = guard.validate(llm_output, num_reasks=3)

# For local model with Outlines
generator = generate.json(model, SentimentAnalysis)
output = generator("Analyze sentiment", max_tokens=200)

Key Takeaways

  • Guardrails.ai is post-processing validation with LLM-powered repair; best for cloud APIs.
  • Outlines constrains tokens during decoding; best for local models and guaranteed valid outputs.
  • Guardrails increase first-attempt validity from 50–80% to 95%+, eliminating most retries.
  • Custom validators in Guardrails.ai enable domain-specific constraints.
  • Hybrid approaches (Outlines for local, Guardrails for API) offer best of both worlds.

Frequently Asked Questions

Do guardrails reduce response quality?

No. By steering toward valid outputs, they often improve quality because the model doesn't waste tokens on malformed JSON.

What's the latency overhead?

Outlines adds minimal overhead (token steering is microseconds). Guardrails.ai's latency depends on how many reasks are needed; 1–2 retries add ~1–2 extra LLM calls.

Can I use guardrails with streaming?

Yes, but it's complex. Outlines works with streaming natively. Guardrails.ai requires buffering the entire response before validation.

Which is better for LLM safety (preventing harmful output)?

Guardrails.ai has built-in safety validators for toxicity, PII, and jailbreak detection. Outlines focuses on schema/format validity. Use Guardrails for comprehensive safety.

Further Reading