Doramagic Project Pack ยท Human Manual

guardrails

Guardrails is an open-source Python library that provides validation, correction, and structural guarantees for AI/LLM applications. It enables developers to define constraints on LLM outp...

Getting Started with Guardrails

Related topics: Guard Class Reference, Validators System

Section Related Pages

Continue reading this section for the full explanation and source context.

Section Prerequisites

Continue reading this section for the full explanation and source context.

Section Standard Installation

Continue reading this section for the full explanation and source context.

Section Development Installation

Continue reading this section for the full explanation and source context.

Related topics: Guard Class Reference, Validators System

Getting Started with Guardrails

Overview

Guardrails is an open-source Python library that provides validation, correction, and structural guarantees for AI/LLM applications. It enables developers to define constraints on LLM outputs and automatically validates, corrects, or re-asks the model when outputs violate those constraints. Sources: README.md

The library serves as a critical layer between LLM outputs and application logic, ensuring that AI-generated content meets specified quality, safety, and structural requirements.

Installation

Prerequisites

  • Python 3.8 or higher
  • pip or pipx

Standard Installation

Install Guardrails from PyPI:

pip install guardrails-ai

Development Installation

For contributors or those who want the latest features from the main branch:

# Clone the repository
git clone https://github.com/guardrails-ai/guardrails.git
cd guardrails

# Install in development mode
make dev

# Install pre-commit hooks
pre-commit install

Sources: README.md, CONTRIBUTING.md

Core Concepts

Guard

The Guard is the central component in Guardrails. It wraps LLM calls and applies validation rules to ensure outputs meet specified constraints.

from guardrails import Guard, OnFailAction

guard = Guard().use(
    RegexMatch, regex="\(?\d{3}\)?-? *\d{3}-? *-?\d{4}", on_fail=OnFailAction.EXCEPTION
)

Sources: README.md

Validators

Validators are individual constraint checks that can be applied to LLM outputs. They are installed from the Guardrails Hub or created as custom validators.

from guardrails.hub import RegexMatch, CompetitorCheck, ToxicLanguage

Sources: README.md

OnFailAction

Actions to take when validation fails:

ActionDescription
EXCEPTIONRaise an exception
REASKRe-ask the LLM to produce valid output
FIXAttempt to auto-fix the output
FILTERFilter out invalid parts
REFRAINReturn nothing for invalid fields

Quick Start Guide

Step 1: Configure Guardrails Hub CLI

After installation, configure the Guardrails CLI:

guardrails configure

Step 2: Install Required Validators

Install validators from Guardrails Hub based on your use case:

# Example: Install validators for phone number validation and competitor checking
guardrails hub install hub://guardrails/regex_match
guardrails hub install hub://guardrails/competitor_check
guardrails hub install hub://guardrails/toxic_language

Sources: README.md

Step 3: Create a Guard

Create a Guard instance with your desired validators:

from guardrails import Guard, OnFailAction
from guardrails.hub import CompetitorCheck, ToxicLanguage

guard = Guard().use(
    CompetitorCheck(["Apple", "Microsoft", "Google"], on_fail=OnFailAction.EXCEPTION),
    ToxicLanguage(threshold=0.5, validation_method="sentence", on_fail=OnFailAction.EXCEPTION)
)

Step 4: Validate LLM Output

Apply the Guard to validate outputs:

# Valid output - passes all validations
guard.validate(
    """An apple a day keeps a doctor away.
    This is good advice for keeping your health."""
)

# Invalid output - fails validations
try:
    guard.validate(
        """Shut the hell up! Apple just released a new iPhone."""
    )
except Exception as e:
    print(e)

Sources: README.md

Architecture Overview

graph TD
    A[User Application] --> B[Guard Instance]
    B --> C[Validators Stack]
    C --> D[LLM Call]
    D --> E{Validation Pass?}
    E -->|Yes| F[Return Validated Output]
    E -->|No| G[OnFailAction Handler]
    G --> H[EXCEPTION / REASK / FIX / FILTER / REFRAIN]
    H --> I[Retry if REASK]
    I --> D

Creating Guards

From RAIL String

RAIL (Reliable AI Abstraction Language) is an XML-based specification for defining output constraints:

from guardrails import Guard

rail_string = '''
<rail version="0.1">
    <output>
        <!-- Define output structure and validators -->
    </output>
    <prompt>
        <!-- Define the prompt -->
    </prompt>
</rail>
'''

guard = Guard.from_rail_string(rail_string)

Sources: guardrails/guard.py:45-60

From Pydantic Model

Define output structure using Pydantic BaseModel:

from pydantic import BaseModel, Field
from guardrails import Guard

class Pet(BaseModel):
    pet_type: str = Field(description="Species of pet")
    name: str = Field(description="a unique pet name")

guard = Guard.for_pydantic(Pet)

The Guard uses two methods to generate structured data:

  1. Function calling: For LLMs that support function calling
  2. Prompt optimization: For LLMs that don't support function calling (schema added to prompt)

Sources: README.md, guardrails/guard.py:85-115

Guardrails Hub Validators

The Guardrails Hub provides pre-built validators for common use cases:

ValidatorPurposeExample Usage
RegexMatchValidate string against regex patternPhone number format
CompetitorCheckDetect mentions of competitorsBrand safety
ToxicLanguageDetect toxic/offensive contentContent moderation
LowerCaseEnsure text is lowercaseNormalization
UpperCaseEnsure text is uppercaseNormalization

Installing Validators

# From Guardrails Hub
guardrails hub install hub://guardrails/<validator_name>

# With specific version
guardrails hub install hub://guardrails/regex_match~=1.4

Sources: guardrails/hub/install.py:45-60

Validation Workflow

sequenceDiagram
    participant User
    participant Guard
    participant Validators
    participant LLM
    
    User->>Guard: validate(input)
    Guard->>Validators: Check constraints
    alt Validation Failed
        Validators-->>Guard: ValidationError
        Guard->>Guard: Handle OnFailAction
        alt OnFailAction.REASK
            Guard->>LLM: Request correction
            LLM-->>Guard: New response
            Guard->>Validators: Re-validate
        end
    end
    Guard-->>User: Validated output / Exception

Creating Custom Validators

Use the CLI to scaffold a new validator:

guardrails hub create-validator MyValidator

This creates a template file with the required structure:

from guardrails import Validator
from guardrails.validators import ValidationResult, PassResult

class MyValidator(Validator):
    """Description of what your validator does."""
    
    def __init__(self, arg_1: str, **kwargs):
        # Initialize with custom arguments
        super().__init__(**kwargs)
    
    def validate(self, value: Any, **kwargs) -> ValidationResult:
        # Implement validation logic
        if valid:
            return PassResult()
        else:
            return FailResult()

Sources: guardrails/cli/hub/create_validator.py:35-70

Development Workflow

For contributing to Guardrails:

``bash git clone https://github.com/guardrails-ai/guardrails.git cd guardrails make dev ``

  1. Clone and setup:

``bash make test ``

  1. Run tests:

``bash make autoformat ``

  1. Format code:

``bash make type ``

  1. Type checking:

``bash make docs-gen ``

  1. Update documentation:

Sources: CONTRIBUTING.md

Call History and Debugging

The Guard maintains a history of all calls, useful for debugging and monitoring:

call = guard.validate("123-456-7890")
print(call.iterations)  # View all iterations
print(call.id)          # Unique call identifier

Each Call object contains:

  • iterations: Stack of validation iterations
  • inputs: Original inputs to the Guard
  • exception: Any exception that occurred

Sources: guardrails/classes/history/call.py:15-35

CLI Commands Reference

CommandDescription
guardrails configureConfigure Guardrails Hub CLI
guardrails hub install <package>Install a validator from Hub
guardrails hub create-validator <name>Create a new validator template
guardrails startStart the Guardrails API server

Sources: guardrails/cli/start.py:25-50, guardrails/cli/hub/install.py:20-45

Common Patterns

Input and Output Guards

Apply different validators to input and output:

guard = Guard()

# Input validation
guard.use(InputValidator(CompetitorCheck, competitors=[...]))

# Output validation  
guard.use(OutputValidator(ToxicLanguage))

Multiple Validators

Chain multiple validators on a single Guard:

guard = Guard().use(
    Validator1(param1=value1),
    Validator2(param2=value2),
    Validator3()
)

Streaming Support

Guardrails supports streaming responses:

guard.validate(
    llm_output,
    metadata={"stream": True}
)

Next Steps

  • Explore the Guardrails Hub for available validators
  • Read the API documentation for detailed parameter descriptions
  • Join the Discord community for support
  • Check existing issues and contribute to the project

Sources: README.md, CONTRIBUTING.md

System Architecture

Related topics: Getting Started with Guardrails, Execution Pipeline

Section Related Pages

Continue reading this section for the full explanation and source context.

Section Guard Class

Continue reading this section for the full explanation and source context.

Section AsyncGuard Class

Continue reading this section for the full explanation and source context.

Section Validator Service

Continue reading this section for the full explanation and source context.

Related topics: Getting Started with Guardrails, Execution Pipeline

System Architecture

Overview

Guardrails is a Python library for validating and constraining outputs from Large Language Models (LLMs). The system provides a flexible framework for defining validation rules (validators), composing them into Guards, and applying them to LLM outputs to ensure they meet specified quality and safety criteria.

Sources: README.md:1-20

High-Level Architecture

The Guardrails system consists of several key layers that work together to provide LLM output validation:

graph TB
    subgraph "Presentation Layer"
        Guard["Guard Class"]
        AsyncGuard["AsyncGuard Class"]
    end
    
    subgraph "Schema Layer"
        ProcessedSchema["ProcessedSchema"]
        RailSchema["RailSchema"]
    end
    
    subgraph "Validation Layer"
        ValidatorService["ValidatorService"]
        Validators["Validators"]
    end
    
    subgraph "Integration Layer"
        LLMProviders["LLM Providers"]
        APIClient["APIClient"]
    end
    
    Guard --> ProcessedSchema
    AsyncGuard --> ProcessedSchema
    ProcessedSchema --> ValidatorService
    ValidatorService --> Validators
    Guard --> LLMProviders
    Guard --> APIClient

Sources: guardrails/guard.py:1-50

Core Components

Guard Class

The Guard class is the primary entry point for using Guardrails. It serves as a container for validators and provides methods for validating LLM outputs.

#### Key Features

FeatureDescription
Validator CompositionChain multiple validators using .use() method
Schema SupportSupport for RAIL, Pydantic, and JSON Schema
LLM IntegrationBuilt-in support for various LLM providers
History TrackingRecords all validation iterations and outcomes
Async SupportSeparate AsyncGuard class for async operations

#### Factory Methods

@classmethod
def from_rail(cls, rail_string: str, ...) -> Guard
@classmethod
def for_pydantic(cls, output_class: ModelOrListOfModels, ...) -> Guard

The Guard class provides multiple ways to create instances:

  1. from_rail() - Creates a Guard from a RAIL (Rich Application Information Language) string
  2. for_pydantic() - Creates a Guard using Pydantic models to define output structure

Sources: guardrails/guard.py:200-280

AsyncGuard Class

The AsyncGuard class provides asynchronous validation capabilities, enabling non-blocking LLM output validation for high-throughput applications.

#### Key Differences from Guard

AspectGuardAsyncGuard
ExecutionSynchronousAsynchronous (async/await)
Use CaseStandard applicationsHigh-performance async apps
APIguard.validate()await guard.avalidate()

Validator Service

The ValidatorService is the core validation engine that executes validators against input data.

#### Responsibilities

  • Load and initialize validators
  • Execute validation pipeline
  • Handle validation failures and reasks
  • Collect and aggregate validation results
graph LR
    Input["Input Data"] --> ValidatorService
    ValidatorService --> V1["Validator 1"]
    ValidatorService --> V2["Validator 2"]
    ValidatorService --> VN["Validator N"]
    V1 --> Result1["Result 1"]
    V2 --> Result2["Result 2"]
    VN --> ResultN["Result N"]
    Result1 --> Aggregated["Aggregated Result"]
    Result2 --> Aggregated
    ResultN --> Aggregated

Sources: guardrails/validator_service/validator_service_base.py:1-50

ProcessedSchema

The ProcessedSchema class handles the parsing and processing of validation schemas into an internal format that can be executed by the validator service.

#### Schema Processing Flow

graph TD
    RawSchema["Raw Schema Input"] --> Parser["Schema Parser"]
    Parser --> Processed["ProcessedSchema"]
    Processed --> Serialization["Serialization"]
    Serialization --> Storage["Storage/Caching"]
    Processed --> Execution["Validation Execution"]

Sources: guardrails/classes/schema/processed_schema.py:1-40

Validation Flow

Standard Validation Flow

sequenceDiagram
    participant User
    participant Guard
    participant ProcessedSchema
    participant ValidatorService
    participant Validator
    participant LLM

    User->>Guard: validate(output)
    Guard->>ProcessedSchema: parse_and_validate()
    ProcessedSchema->>ValidatorService: run_validators()
    ValidatorService->>Validator: validate()
    Validator-->>ValidatorService: ValidationResult
    ValidatorService-->>ProcessedSchema: AggregatedResult
    ProcessedSchema-->>Guard: FinalResult
    Guard-->>User: Result/Exception

ReAsk Flow

When initial validation fails, the system can trigger a reask mechanism:

  1. Validation fails for field
  2. System generates reask prompt
  3. LLM receives reask prompt
  4. New output is validated
  5. Process repeats until valid or max iterations reached

Sources: guardrails/guard.py:300-400

Schema System

Supported Schema Formats

FormatMethodDescription
RAILGuard.from_rail()XML-based schema with validators
PydanticGuard.for_pydantic()Python class-based schema
JSON Schemajson_schema_to_rail_output()JSON schema conversion

RAIL Schema Processing

The rail_schema.py module handles conversion between different schema formats:

def json_schema_to_rail_output(
    json_schema: Dict[str, Any], 
    validator_map: ValidatorMap
) -> str:
    """Takes a JSON Schema and converts it to the RAIL output specification."""

Sources: guardrails/schema/rail_schema.py:60-80

History and Call Tracking

The Call class tracks each execution of a Guard, maintaining a history of all iterations:

class Call:
    iterations: Stack[Iteration]  # Stack of iterations for reasks
    inputs: CallInputs             # Original inputs to Guard
    exception: Optional[Exception] # Any exceptions during execution

#### Call Structure

AttributeTypeDescription
iterationsStack[Iteration]Each validation round and reask
inputsCallInputsOriginal prompt, parameters, etc.
exceptionExceptionException if Guard execution failed

Sources: guardrails/classes/history/call.py:10-50

Integration Architecture

LLM Provider Integration

Guardrails integrates with multiple LLM providers through a unified interface:

graph TB
    Guard["Guard Class"]
    ManifestCallable["ManifestCallable"]
    LiteLLMCallable["LiteLLMCallable"]
    CustomCallable["Custom Provider"]
    
    Guard --> ManifestCallable
    Guard --> LiteLLMCallable
    Guard --> CustomCallable

Supported providers include:

  • OpenAI
  • Anthropic
  • LiteLLM (unified interface)
  • Manifest (local models)

Sources: guardrails/llm_providers.py:1-100

API Client Integration

The APIClient enables remote Guard management:

MethodPurpose
upsert_guard()Create or update a Guard on the server
fetch_guard()Retrieve a Guard by name
aupsert_guard()Async version of upsert
async def aupsert_guard(self, guard: Guard) -> Guard:
    existing_guard = await self.afetch_guard(guard.name)
    if existing_guard:
        response = await self.ahttp_client.put(...)
    else:
        response = await self.ahttp_client.post(...)

Sources: guardrails/api_client.py:1-80

Hub Integration

Validator Installation

The Hub system allows dynamic installation of validators:

def install(package_uri: str, ...) -> ModuleType:
    # 1. Validate package URI
    # 2. Fetch manifest
    # 3. Download dependencies
    # 4. Install via pip

#### Installation Flow

graph LR
    A["hub://guardrails/regex_match"] --> B["ValidatorPackageService"]
    B --> C["Fetch Manifest"]
    C --> D["Install Dependencies"]
    D --> E["Load Module"]

Sources: guardrails/hub/install.py:20-60

CLI Architecture

Command Structure

CommandFilePurpose
guardrails configureCLI setupConfigure Guardrails settings
guardrails hub installcli/hub/install.pyInstall validators from Hub
guardrails hub create-validatorcli/hub/create_validator.pyScaffold new validators
guardrails startcli/start.pyStart Guardrails API server

Sources: guardrails/cli/start.py:1-50

Error Handling and Logging

Log Levels

LevelValueUsage
SPAM5Verbose debug information
VERBOSE15Detailed execution info
NOTICE25Important events
SUCCESS35Successful operations

Sources: guardrails/cli/logger.py:1-30

Summary

The Guardrails architecture follows a layered approach:

  1. Presentation Layer - Guard and AsyncGuard classes provide the user-facing API
  2. Schema Layer - ProcessedSchema and RailSchema handle input parsing and validation rules
  3. Validation Layer - ValidatorService executes validators and aggregates results
  4. Integration Layer - LLM providers and API client enable seamless integration with external services

This separation of concerns allows for:

  • Flexible validator composition
  • Multiple schema format support
  • Both sync and async operation modes
  • Extensible provider integrations

Sources: README.md:1-20

Guard Class Reference

Related topics: Validators System, Schema Processing

Section Related Pages

Continue reading this section for the full explanation and source context.

Section Factory Methods

Continue reading this section for the full explanation and source context.

Section Creating from RAIL Strings

Continue reading this section for the full explanation and source context.

Section Creating from Pydantic Models

Continue reading this section for the full explanation and source context.

Related topics: Validators System, Schema Processing

Guard Class Reference

The Guard class is the central orchestrator in the Guardrails library, serving as the primary interface for validating, parsing, and constraining LLM outputs. It acts as a container that manages validators, output schemas, and validation outcomes while maintaining execution history.

Overview

The Guard class provides a unified API for:

  • Defining validation rules through RAIL XML strings or Pydantic models
  • Validating LLM outputs against specified schemas and constraints
  • Parsing raw LLM responses into structured data
  • Tracking validation history across multiple iterations and reasks
  • Configuring behavior on validation failure through OnFailAction strategies
graph TD
    A[LLM Output] --> B[Guard Instance]
    B --> C{Validation}
    C -->|Pass| D[Validated Output]
    C -->|Fail| E{OnFailAction}
    E -->|EXCEPTION| F[Raise Exception]
    E -->|REASK| G[Reask LLM]
    E -->|FIX| H[Return Fixed Value]
    E -->|[None]| I[Return None]
    G --> A

Creating Guard Instances

Factory Methods

The Guard class provides two primary factory methods for instantiation:

MethodInput TypeUse Case
Guard.from_rail()RAIL XML stringComplex schemas with validators
Guard.for_pydantic()Pydantic BaseModelStructured data generation

Creating from RAIL Strings

@classmethod
def from_rail(cls, rail_string: str, *, name: str = None, description: str = None) -> "Guard"

A RAIL (Rich AI Language) string is an XML-based specification that defines:

  • Output schema structure
  • Field-level validators
  • Error handling behaviors
from guardrails import Guard

rail_string = """
<rail version="0.1">
    <output>
        <string name="response" />
    </output>
</rail>
"""

guard = Guard.from_rail(rail_string, name="my-guard")

Sources: guardrails/guard.py:from_rail-method

Creating from Pydantic Models

@classmethod
def for_pydantic(
    cls,
    output_class: ModelOrListOfModels,
    *,
    reask_messages: Optional[List[Dict]] = None,
    messages: Optional[List[Dict]] = None,
    name: Optional[str] = None,
    description: Optional[str] = None,
    output_formatter: Optional[Union[str, BaseFormatter]] = None,
) -> "Guard"

This method accepts Pydantic BaseModel classes and internally converts them to RAIL format for validation.

from guardrails import Guard
from pydantic import BaseModel, Field

class Pet(BaseModel):
    pet_type: str = Field(description="Species of pet")
    name: str = Field(description="a unique pet name")

guard = Guard.for_pydantic(Pet)

Sources: guardrails/guard.py:for_pydantic-method

Internal Schema Processing

Both factory methods ultimately convert their input to an internal RAIL schema representation:

graph LR
    A[Pydantic Model] -->|for_pydantic| B[JSON Schema]
    C[RAIL String] -->|from_rail| D[Schema Parser]
    B --> D
    D --> E[RAIL Schema]
    E --> F[Guard Instance]

Sources: guardrails/schema/rail_schema.py

Guard Configuration

Using Validators with `Guard.use()`

Validators are added to a Guard instance using the .use() method, which chains multiple validators onto the same instance.

from guardrails import Guard, OnFailAction
from guardrails.hub import RegexMatch, CompetitorCheck

guard = Guard().use(
    RegexMatch(regex=r"\d{4}", on_fail=OnFailAction.EXCEPTION),
    CompetitorCheck(["Apple", "Google"], on_fail=OnFailAction.REASK)
)

Sources: README.md:example-code

Validation Process

Core Validation Methods

MethodPurposeReturns
validate()Validates LLM output against schemaValidationOutcome
parse()Parses raw output without full validationParsed result
__call__()Combined call and validationLLM response + validated output

ValidationOutcome Class

The ValidationOutcome class encapsulates the results of validation:

@dataclass
class ValidationOutcome:
    validation_passed: bool
    corrected_output: Any
    error_message: Optional[str]
    reasks: List[ReAsk]

Sources: guardrails/classes/validation_outcome.py

OnFailAction Enum

When validation fails, the configured OnFailAction determines the behavior:

ActionBehavior
EXCEPTIONRaises an exception with error details
REASKAttempts to regenerate the LLM output with feedback
FIXReturns a corrected/fallback value
REFRAINReturns None instead of output
NOOPReturns the original output unchanged
CUSTOMUses a custom handler function

Sources: guardrails/types/on_fail.py

Call History and Iteration Tracking

Call Class Structure

The Call class maintains a complete history of Guard executions:

class Call:
    _id: str | None = None
    iterations: Stack[Iteration] = Field(default_factory=Stack)
    inputs: CallInputs = Field(default_factory=CallInputs)
    exception: Optional[Exception] = None
    
    @computed_field
    @property
    def id(self) -> str:
        """Unique identifier for this Call execution."""
        if not self._id:
            self._id = str(object_id(self))
        return self._id

Sources: guardrails/classes/history/call.py:Call-class

Iteration Stack

Each Call contains a stack of Iteration objects representing:

  1. The initial validation round
  2. Each subsequent reask iteration
graph TD
    A[Call] --> B[Iteration 1: Initial Call]
    A --> C[Iteration 2: Reask 1]
    A --> D[Iteration N: Reask N-1]
    B --> E[Step 1: LLM Call]
    B --> F[Step 2: Validation]
    C --> G[Step: LLM Reask]
    C --> H[Step: Validation]

CallInputs Data Model

The CallInputs class captures all inputs passed to a Guard execution:

FieldTypeDescription
prompt_paramsDictParameters formatted into messages
num_reasksintMaximum reask attempts
metadataDictAdditional runtime data
full_schema_reaskboolReask entire schema vs individual fields
streamboolStreaming mode flag
argsList[Any]Additional positional arguments
kwargsDict[str, Any]Additional keyword arguments

Sources: guardrails/classes/history/call_inputs.py

LLM Provider Integration

PromptCallableBase Interface

The Guard class integrates with multiple LLM providers through the PromptCallableBase interface:

class PromptCallableBase:
    def _invoke_llm(
        self,
        text: Optional[str] = None,
        model: str = "gpt-3.5-turbo",
        messages: Optional[List[Dict]] = None,
        *args,
        **kwargs
    ) -> LLMResponse:
        """Abstract method to invoke LLM."""

Supported providers include:

  • LiteLLM - Unified interface to multiple LLMs
  • Manifest - ML model inference client
  • OpenAI - Direct OpenAI API integration

Sources: guardrails/llm_providers.py

LLM Response Structure

@dataclass
class LLMResponse:
    output: Any  # The raw LLM response
    token_usage: Optional[Dict] = None  # Token consumption metrics
    model_name: Optional[str] = None  # Model identifier

Validator Installation via Hub

Installing Validators

Validators from Guardrails Hub can be installed programmatically:

from guardrails.hub.install import install

RegexMatch = install("hub://guardrails/regex_match").RegexMatch

The installation process:

  1. Validates the package URI format
  2. Fetches the module manifest
  3. Downloads dependencies via pip
  4. Installs to site-packages

Sources: guardrails/hub/install.py

Complete Usage Example

from guardrails import Guard, OnFailAction
from guardrails.hub import RegexMatch, CompetitorCheck

# Create a Guard with multiple validators
guard = Guard().use(
    RegexMatch(
        regex=r"\d{3}-\d{3}-\d{4}",
        on_fail=OnFailAction.EXCEPTION
    ),
    CompetitorCheck(
        competitors=["Apple", "Microsoft"],
        on_fail=OnFailAction.REASK
    )
)

# Validate output
try:
    result = guard.validate("123-456-7890")
    print(f"Validation passed: {result.validation_passed}")
except Exception as e:
    print(f"Validation failed: {e}")

# Access call history
call_history = guard.history  # List of Call objects

Summary

The Guard class serves as the central orchestrator for LLM output validation in the Guardrails library. Key responsibilities include:

  • Schema Management: Creating Guards from RAIL strings or Pydantic models
  • Validation Orchestration: Running validators and applying OnFailAction strategies
  • History Tracking: Maintaining complete execution history with iterations and steps
  • LLM Integration: Supporting multiple LLM providers through a unified interface
  • Extensibility: Allowing composition of multiple validators through the .use() method

Sources: guardrails/guard.py, guardrails/classes/history/call.py, guardrails/types/on_fail.py

Sources: guardrails/guard.py:from_rail-method

Validators System

Related topics: Guard Class Reference, Creating Custom Validators

Section Related Pages

Continue reading this section for the full explanation and source context.

Section High-Level Component Flow

Continue reading this section for the full explanation and source context.

Section Validator Lifecycle

Continue reading this section for the full explanation and source context.

Section Validator Base Class

Continue reading this section for the full explanation and source context.

Related topics: Guard Class Reference, Creating Custom Validators

Validators System

Overview

The Validators System is a core component of the Guardrails framework that provides validation capabilities for LLM (Large Language Model) outputs. Validators are modular, composable validation units that can be attached to a Guard instance to enforce constraints on data before, during, or after LLM inference.

Validators enable developers to:

  • Validate string, structured (JSON), and typed outputs from LLMs
  • Define custom failure handling policies via the on_fail mechanism
  • Chain multiple validators to create complex validation pipelines
  • Track validation history and results through the Call/Iteration data model

Architecture

High-Level Component Flow

graph TD
    A[LLM Output] --> B[Guard.validate]
    B --> C[ValidatorService]
    C --> D[Validator 1]
    C --> E[Validator 2]
    C --> F[Validator N]
    D --> G[ValidationResult]
    E --> H[ValidationResult]
    F --> I[ValidationResult]
    G --> J[ValidationOutcome]
    H --> J
    I --> J
    J --> K[Pass or Fail with Corrections]

Validator Lifecycle

stateDiagram-v2
    [*] --> Initialized
    Initialized --> Running: before_run_validator
    Running --> Success: validate returns PassResult
    Running --> Failed: validate returns FailResult
    Success --> Completed: after_run_validator
    Failed --> Completed: on_fail handler applied
    Completed --> [*]

Core Components

Validator Base Class

Validators inherit from the base Validator class which provides:

  • Standard initialization with on_fail policy configuration
  • validate(value, metadata) method implementation contract
  • Integration with the validator service infrastructure
  • Telemetry and tracing capabilities

Validation Result Classes

The system uses two primary result types:

ClassPurpose
PassResultIndicates validation succeeded
FailResultIndicates validation failed with error details
classDiagram
    class ValidationResult {
        <<abstract>>
    }
    class PassResult {
        +str error_message = None
        +ValidationResult fix_value = None
    }
    class FailResult {
        +str error_message
        +Any fix_value
    }
    ValidationResult <|-- PassResult
    ValidationResult <|-- FailResult

OnFailAction Policies

When validation fails, the on_fail parameter determines the behavior:

PolicyBehavior
REASKTrigger a reask to the LLM
FIXAttempt to fix the value automatically
FILTERRemove invalid elements
REFRAINReturn empty/null value
NOOPReturn the original value unchanged
EXCEPTIONRaise an exception

Sources: guardrails/validator_service/validator_service_base.py

Validator Service

Sequential Validator Service

The SequentialValidatorService executes validators in order, one after another, stopping on the first failure unless configured otherwise.

Key methods:

MethodDescription
before_run_validatorPrepares logging and tracking before validation
after_run_validatorRecords results and timing after validation
run_validatorExecutes a single validator's validation logic

Sources: guardrails/validator_service/validator_service_base.py

Validation Logging

The ValidatorLogs class tracks each validator execution:

validator_logs = ValidatorLogs(
    validatorName=validator_class_name,
    valueBeforeValidation=value,
    registeredName=validator.rail_alias,
    propertyPath=absolute_property_path,
    instanceId=id(validator),
)
FieldDescription
validatorNameClass name of the validator
valueBeforeValidationOriginal value before validation
registeredNameRAIL alias for the validator
propertyPathJSON path to the validated property
instanceIdMemory address of validator instance
start_timeTimestamp when validation began
end_timeTimestamp when validation completed
validation_resultResult of the validation

Sources: guardrails/validator_service/validator_service_base.py

Guard Integration

Attaching Validators to Guard

Validators are attached to a Guard instance using the .use() method:

guard = Guard().use(
    RegexMatch, regex="\\(?\\d{3}\\)?-? *\\d{3}-? *-?\\d{4}"
)

The use() method signature:

ParameterTypeDescription
*validatorsValidatorPositional args for validators
onstrProperty path ("output", "messages", "$.property")
def use(
    self,
    *validators: Validator,
    on: str = "output",
    **kwargs,
) -> "Guard":

Sources: guardrails/guard.py

Validation Flow

sequenceDiagram
    participant User
    participant Guard
    participant ValidatorService
    participant Validator
    participant LLM

    User->>Guard: validate(llm_output)
    Guard->>Guard: parse(llm_output)
    Guard->>ValidatorService: run_validators()
    ValidatorService->>Validator: before_run_validator()
    Validator->>Validator: validate(value, metadata)
    Validator-->>ValidatorService: ValidationResult
    ValidatorService->>Validator: after_run_validator()
    ValidatorService-->>Guard: ValidationOutcome
    Guard-->>User: Pass/Fail with corrections

Getting Attached Validators

Retrieve validators attached to a specific property:

validators = guard.get_validators(on="output")
ParameterValid OptionsDescription
on"output", "messages", "$.path"Property to query

Sources: guardrails/guard.py

Validation History Tracking

Call and Iteration Model

Validation history is tracked through a hierarchical model:

classDiagram
    class Call {
        +str id
        +Stack~Iteration~ iterations
        +CallInputs inputs
        +Exception exception
    }
    class Iteration {
        +Step[] steps
        +IterationOutputs outputs
    }
    class Step {
        +ValidatorLogs[] validator_logs
    }
    Call "1" --> "*" Iteration
    Iteration "1" --> "*" Step
ClassPurpose
CallRepresents a single Guard execution (validate/parse/call)
IterationA single validation round, including reasks
StepContains validator execution logs

Sources: guardrails/classes/history/call.py

Call Inputs

The CallInputs class captures the original inputs to each Guard invocation:

  • llm_output: Raw LLM response
  • ` Prompt parameters and messages
  • Configuration options passed during validation

Telemetry and Tracing

Validator Tracing

The validator tracing system provides observability into validation execution:

graph TD
    A[Validate Request] --> B[trace_validator_decorator]
    B --> C[Create Span]
    C --> D[Execute Validator]
    D --> E{Success?}
    E -->|Yes| F[Record PassResult]
    E -->|No| G[Record FailResult]
    F --> H[Add Attributes]
    G --> H
    H --> I[Close Span]
    I --> J[Return Result]

Key tracing attributes:

AttributeDescription
validator_nameName of the validator class
validator_spanOpenTelemetry span reference
obj_idObject identifier
on_fail_descriptorPolicy applied on failure
init_kwargsValidator initialization arguments
validation_session_idSession identifier

Sources: guardrails/telemetry/validator_tracing.py

Creating Custom Validators

Validator Template

The CLI command guardrails create-validator generates a template:

guardrails create-validator MyValidator

Generated template structure:

from guardrails import Validator
from guardrails.properties import register_validator
from guardrails.classes import ValidationResult

@register_validator(name="my_validator", fmt="native")
class MyValidator(Validator):
    """Validator description.
    
    Args:
        arg_1: Description of the argument.
        on_fail: Policy when validation fails.
    """
    
    def __init__(
        self,
        arg_1: str,
        on_fail: Optional[Callable] = None,
    ):
        super().__init__(on_fail=on_fail, arg_1=arg_1)
        self._arg_1 = arg_1

    def validate(self, value: Any, metadata: Dict) -> ValidationResult:
        """Validates the input value.
        
        Args:
            value: The value to validate.
            metadata: Additional context for validation.
        """
        if value != "pass":
            return FailResult(
                error_message="Value must be 'pass'",
                fix_value="fails"
            )
        return PassResult()

Sources: guardrails/cli/hub/create_validator.py

Validator Registration

Validators are registered using the @register_validator decorator:

ParameterDescription
nameUnique identifier for the validator
fmtFormat ("native" or "raw")
rail_aliasRAIL XML alias

Hub Installation

Installing Validators from Hub

Validators can be installed from Guardrails Hub:

guardrails hub install hub://guardrails/regex_match

The install() function:

ParameterTypeDescription
package_uristrHub package URI (e.g., hub://guardrails/regex_match)
quietboolSuppress output
upgradeboolForce upgrade to latest
>>> RegexMatch = install("hub://guardrails/regex_match").RegexMatch
>>> RegexMatch = install("hub://guard://guardrails/regex_match~=1.4").RegexMatch

Sources: guardrails/hub/install.py

Installation Process

graph LR
    A[Install Request] --> B[Get Validator ID]
    B --> C[Fetch Manifest]
    C --> D[Download Dependencies]
    D --> E[Install via Pip]
    E --> F[Register Validator]

Usage Examples

Basic String Validation

from guardrails import Guard, OnFailAction
from guardrails.hub import RegexMatch

guard = Guard().use(
    RegexMatch, 
    regex="\\(?\\d{3}\\)?-? *\\d{3}-? *-?\\d{4}",
    on_fail=OnFailAction.EXCEPTION
)

guard.validate("123-456-7890")  # Passes

Multiple Validators

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

guard = Guard().use(
    CompetitorCheck(["Apple", "Microsoft"]),
    on_fail=OnFailAction.EXCEPTION
).use(
    ToxicLanguage(threshold=0.5),
    on_fail=OnFailAction.FILTER
)

Custom Validator

from guardrails import Validator
from guardrails.classes import ValidationResult, PassResult, FailResult

class UppercaseValidator(Validator):
    def validate(self, value, metadata):
        if value.isupper():
            return PassResult()
        return FailResult(
            error_message="Value must be uppercase",
            fix_value=value.upper()
        )

guard = Guard().use(UppercaseValidator)

Best Practices

  1. Error Messages: Provide clear, actionable error messages in FailResult
  2. Fix Values: Always provide sensible fix_value when possible
  3. Metadata: Use metadata for context-aware validation (e.g., schema info)
  4. Ordering: Place more restrictive validators first for early failure
  5. Testing: Test both passing and failing cases for each validator
ComponentFileRole
Guardguardrails/guard.pyMain entry point for validation
ValidatorServicevalidator_service_base.pyOrchestrates validation execution
Call Historyclasses/history/call.pyTracks validation execution history
Hub Installhub/install.pyHandles validator distribution
Telemetrytelemetry/validator_tracing.pyObservability into validation

Sources: guardrails/validator_service/validator_service_base.py

Schema Processing

Related topics: Guard Class Reference, Execution Pipeline

Section Related Pages

Continue reading this section for the full explanation and source context.

Section Schema Type System

Continue reading this section for the full explanation and source context.

Section Type Mapping Matrix

Continue reading this section for the full explanation and source context.

Section buildelement Function

Continue reading this section for the full explanation and source context.

Related topics: Guard Class Reference, Execution Pipeline

Schema Processing

Schema Processing is the core system within Guardrails that handles conversion, validation, and transformation of data structures between different schema formats. It provides the foundational infrastructure for validating LLM outputs against defined schemas, supporting multiple schema specification formats including RAIL (Rich AI Language), Pydantic models, and JSON Schema.

Overview

The Schema Processing module enables Guardrails to:

  • Convert JSON Schema to RAIL output specifications
  • Build element hierarchies from JSON Schema definitions
  • Support multiple data types including primitives, dates, times, and enums
  • Map validators to schema elements
  • Generate structured output from LLM responses

Sources: guardrails/schema/rail_schema.py:1-50

Architecture

graph TD
    A[JSON Schema / Pydantic / RAIL] --> B[Schema Processing Module]
    B --> C[rail_schema.py]
    B --> D[pydantic_schema.py]
    B --> E[primitive_schema.py]
    B --> F[validator.py]
    C --> G[build_element]
    C --> H[json_schema_to_rail_output]
    D --> I[Schema Generation]
    E --> J[Type Handling]
    F --> K[Validator Mapping]
    G --> L[XML Element Tree]
    H --> M[RAIL Output String]

Core Components

Schema Type System

The schema processing system uses a dual type classification system:

Type CategoryValuesDescription
SimpleTypesSTRING, INTEGER, NUMBER, BOOLEAN, ARRAY, OBJECT, NULLJSON Schema primitive types
RailTypesSTRING, INTEGER, FLOAT, BOOL, DATE, TIME, DATETIME, PERCENTAGE, ENUMRAIL-specific type representations

Sources: guardrails/schema/rail_schema.py:30-45

Type Mapping Matrix

graph LR
    A[JSON Schema Type] -->|Mapping| B[Internal Schema Type]
    A1[STRING] --> B1[SimpleTypes.STRING]
    A2[integer] --> A2a[integer] --> B2[SimpleTypes.INTEGER]
    A3[number] --> A3a[number] --> B3[SimpleTypes.NUMBER]
    A4[boolean] --> B4[SimpleTypes.BOOLEAN]
    A5[array] --> B5[SimpleTypes.ARRAY]
    A6[object] --> B6[SimpleTypes.OBJECT]

build_element Function

The build_element function is the central dispatcher for converting JSON Schema definitions into XML element structures:

def build_element(
    json_schema: Dict[str, Any],
    validator_map: ValidatorMap,
    *,
    json_path: str = "$",
    elem: Callable[..., _Element] = SubElement,
    tag_override: Optional[str] = None,
    parent: Optional[_Element] = None,
    required: Optional[str] = "true",
    attributes: Optional[Dict[str, Any]] = None,
) -> _Element:

Parameters:

ParameterTypeDefaultDescription
json_schemaDict[str, Any]requiredThe JSON Schema definition to process
validator_mapValidatorMaprequiredMapping of validator names to implementations
json_pathstr"$"Current path in the JSON structure for tracking
elemCallableSubElementElement construction function
tag_overrideOptional[str]NoneOverride the XML tag name
parentOptional[_Element]NoneParent element for nesting
requiredOptional[str]"true"Whether field is required
attributesOptional[Dict[str, Any]]NoneAdditional XML attributes

Sources: guardrails/schema/rail_schema.py:100-130

json_schema_to_rail_output Function

Converts a JSON Schema back to RAIL XML format for interoperability:

def json_schema_to_rail_output(
    json_schema: Dict[str, Any], validator_map: ValidatorMap
) -> str:

Process Flow:

graph TD
    A[JSON Schema Input] --> B[jsonref.replace_refs]
    B --> C[dereferenced_json_schema]
    C --> D[build_element with tag_override='output']
    D --> E[ET.tostring with pretty_print]
    E --> F[canonicalize output]
    F --> G[Replace &#xA; entities]
    G --> H[RAIL XML String]

Sources: guardrails/schema/rail_schema.py:60-75

Type-Specific Processing

String Element Builder

The build_string_element function handles all string-based types with special formatting:

graph TD
    A[String Type Detected] --> B{format.internal_type}
    B -->|DATE| C[Set date-format attribute]
    B -->|TIME| D[Set time-format attribute]
    B -->|DATETIME| E[Set datetime-format attribute]
    B -->|PERCENTAGE| F[Set percentage handling]
    B -->|STRING| G[Standard string processing]
    C --> H[Return Element with attributes]
    D --> H
    E --> H
    F --> H
    G --> H

Date/Time Format Handling:

Internal TypeXML AttributePurpose
RailTypes.DATEdate-formatCustom date patterns
RailTypes.TIMEtime-formatCustom time patterns
RailTypes.DATETIMEdatetime-formatCustom datetime patterns

Sources: guardrails/schema/rail_schema.py:140-180

Format Extraction

The format extraction system maps JSON Schema formats to internal RAIL types:

def extract_format(
    element,
    internal_type: RailTypes,
    internal_format_attr: str,
) -> Optional[Format]:

Supported Format Mappings:

JSON Schema FormatRailTypes ValueInternal Format Attr
dateDATEdate-format
date-timeDATETIMEdatetime-format
timeTIMEtime-format
percentagePERCENTAGE(empty string)
emailSTRING-
uriSTRING-
uuidSTRING-

Sources: guardrails/schema/rail_schema.py:200-250

Integration with Guard Class

The Schema Processing module integrates with the Guard class through multiple factory methods:

Guard.for_pydantic

Creates a Guard instance from a Pydantic BaseModel:

@classmethod
def for_pydantic(
    cls,
    output_class: ModelOrListOfModels,
    *,
    reask_messages: Optional[List[Dict]] = None,
    messages: Optional[List[Dict]] = None,
    name: Optional[str] = None,
    description: Optional[str] = None,
    output_formatter: Optional[Union[str, BaseFormatter]] = None,
):

Sources: guardrails/guard.py:150-180

Guard.for_rail

Creates a Guard instance from a .rail file:

@classmethod
def for_rail(
    cls,
    rail_file: str,
    *,
    name: Optional[str] = None,
    description: Optional[str] = None,
):

Sources: guardrails/guard.py:200-230

Guard.for_rail_string

Creates a Guard instance from a RAIL XML string:

@classmethod
def for_rail_string(
    cls,
    rail_string: str,
    *,
    name: Optional[str] = None,
    description: Optional[str] = None,
):

Sources: guardrails/guard.py:240-270

Data Flow Diagram

sequenceDiagram
    participant User
    participant Guard
    participant SchemaProcessor
    participant ValidatorMap
    participant LLM
    
    User->>Guard: for_pydantic(PetModel)
    Guard->>SchemaProcessor: Convert Pydantic to JSON Schema
    SchemaProcessor->>SchemaProcessor: build_element for each field
    SchemaProcessor->>ValidatorMap: Map validators
    Guard->>LLM: Prompt with schema hints
    LLM->>Guard: Raw output
    Guard->>SchemaProcessor: validate(output)
    SchemaProcessor->>ValidatorMap: Run validators
    ValidatorMap-->>SchemaProcessor: Validation result
    SchemaProcessor-->>Guard: Structured result
    Guard-->>User: GuardResponse

Schema to RAIL Conversion Rules

Type Conversions

JSON SchemaRAIL ElementNotes
{type: string}<string>Default string type
{type: integer}<integer>Whole numbers only
{type: number}<float>Floating point
{type: boolean}<bool>True/false values
{type: array}<list>Array of items
{type: object}<object>Nested structure

Enum Handling

# JSON Schema
{"type": "string", "enum": ["value1", "value2"]}

# Converts to RAIL
<element name="..." type="string" format="enum" values="value1, value2"/>

Sources: guardrails/schema/rail_schema.py:260-280

Configuration Options

Exec Options

The schema processing supports various execution options:

OptionTypeDefaultDescription
num_reasksintNoneNumber of reasking attempts
full_schema_reaskboolNoneReask entire schema vs individual fields
streamboolNoneEnable streaming responses
metadataDict[str, Any]NoneCustom data for validators

Sources: guardrails/classes/history/call_inputs.py:30-50

Error Handling

The schema processing system includes robust error handling for:

  • Missing required fields
  • Invalid type conversions
  • Reference resolution failures
  • Validator mapping errors
graph TD
    A[Schema Processing] --> B{Error Condition}
    B -->|Type Mismatch| C[Raise TypeError]
    B -->|Missing Ref| D[Raise RefResolutionError]
    B -->|Invalid Validator| E[Raise ValidatorError]
    B -->|Success| F[Return Valid Element]

Performance Considerations

  1. Reference Dereferencing: Uses jsonref.replace_refs() for efficient reference resolution
  2. Lazy Element Construction: Elements are built on-demand during validation
  3. Validator Caching: ValidatorMap instances are reused across calls
ComponentFile PathPurpose
Validator Moduleguardrails/schema/validator.pyValidator implementation and mapping
Pydantic Schemaguardrails/schema/pydantic_schema.pyPydantic model conversion
Primitive Schemaguardrails/schema/primitive_schema.pyPrimitive type handling
Guard Classguardrails/guard.pyHigh-level API integration

Summary

Schema Processing in Guardrails provides a comprehensive system for:

  • Converting between multiple schema formats (JSON Schema, RAIL, Pydantic)
  • Building hierarchical XML element structures from JSON definitions
  • Mapping and applying validators to schema elements
  • Supporting rich type system including dates, times, and enums
  • Enabling structured output generation from LLM responses

This modular architecture allows flexible schema definition while maintaining strong validation guarantees for LLM-generated content.

Sources: guardrails/schema/rail_schema.py:1-50

Execution Pipeline

Related topics: Guard Class Reference, Async and Streaming Support

Section Related Pages

Continue reading this section for the full explanation and source context.

Section Runner Classes

Continue reading this section for the full explanation and source context.

Section Execution Flow Architecture

Continue reading this section for the full explanation and source context.

Section Reask Configuration

Continue reading this section for the full explanation and source context.

Related topics: Guard Class Reference, Async and Streaming Support

Execution Pipeline

The Execution Pipeline is the core orchestration mechanism in Guardrails that handles the validation and correction of Large Language Model (LLM) outputs. It manages the lifecycle of a Guard execution from initial prompt submission through iterative validation and potential reasking cycles.

Overview

The Execution Pipeline coordinates multiple components to ensure LLM outputs meet specified validation criteria. When a Guard is invoked, the pipeline:

  1. Receives the raw LLM output
  2. Parses and extracts structured data
  3. Validates the output against defined validators
  4. Triggers reasking workflows when validation fails
  5. Returns sanitized, validated responses

The pipeline supports both synchronous and streaming execution modes, with dedicated runner classes handling different invocation patterns.

Core Components

Runner Classes

The execution pipeline is implemented through several runner classes that extend base execution functionality:

Runner ClassFilePurpose
Runnerrunner.pyBase synchronous execution handler
StreamRunnerstream_runner.pyHandles streaming LLM responses
AsyncRunnerasync_runner.pyManages asynchronous LLM invocations

Execution Flow Architecture

graph TD
    A[Guard.__call__] --> B[Runner/StreamRunner/AsyncRunner]
    B --> C[Parse LLM Output]
    C --> D[Validate Against Validators]
    D --> E{Validation Passed?}
    E -->|Yes| F[Return Sanitized Output]
    E -->|No| G[Check Reask Eligibility]
    G --> H[Reask Action]
    H --> I[Regenerate with Corrections]
    I --> C
    G -->|No Reasks Left| J[Raise Validation Exception]

Reask Action System

The reask mechanism is a critical part of the execution pipeline that handles validation failures intelligently. When output fails validation, the reask action can prompt the LLM to correct its response.

Reask Configuration

Reask behavior is controlled through CallInputs parameters:

ParameterTypeDescription
num_reasksOptional[int]Total number of reask attempts allowed
full_schema_reaskOptional[bool]Whether to reask entire schema or individual fields
metadataOptional[Dict[str, Any]]Additional data for validators during execution

Sources: guardrails/classes/history/call_inputs.py:23-30

Reask Workflow

graph LR
    A[Initial Call] --> B[Iteration 1]
    B --> C{All Validators Pass?}
    C -->|No| D[Create Reask Prompt]
    D --> E[LLM Regeneration]
    E --> F[Iteration 2]
    F --> G{Valid?}
    G -->|No| H{num_reasks exhausted?}
    H -->|No| D
    H -->|Yes| I[Final Exception]
    G -->|Yes| J[Success]
    C -->|Yes| J

Call History and Iterations

Each Guard execution creates a Call object that tracks the full execution history. The call object maintains a stack of Iteration objects representing each round of validation.

Data Model

Call
โ”œโ”€โ”€ _id: str (unique identifier)
โ”œโ”€โ”€ iterations: Stack[Iteration]
โ”‚   โ””โ”€โ”€ Contains validation results per round
โ”œโ”€โ”€ inputs: CallInputs
โ”‚   โ”œโ”€โ”€ prompt_params
โ”‚   โ”œโ”€โ”€ num_reasks
โ”‚   โ””โ”€โ”€ metadata
โ””โ”€โ”€ exception: Optional[Exception]

Sources: guardrails/classes/history/call.py:12-29

Execution Modes

Synchronous Execution

The base Runner class handles synchronous LLM invocations:

raw_response, validated_response = guard(
    llm_api,
    prompt_params={...},
    ...
)

Streaming Execution

StreamRunner processes LLM outputs as they are generated, enabling real-time validation of streaming responses.

Asynchronous Execution

AsyncRunner manages coroutine-based LLM calls for high-throughput applications:

async def validate_async():
    response = await guard(
        async_llm_call,
        prompt_params={...}
    )

Parsing Utilities

The parsing_utils.py module provides utilities for extracting structured data from LLM outputs. These parsers handle various output formats and ensure data can be validated against the schema.

Key parsing responsibilities include:

  • Extracting JSON/XML from raw text responses
  • Handling malformed output gracefully
  • Converting parsed data to appropriate types for validation

Trace Handler Integration

The execution pipeline integrates with TraceHandler for observability:

writer = TraceHandler()
writer.log(
    "guard_name", start_time, end_time,
    "raw_output", "sanitized", "exception?"
)

Sources: guardrails/call_tracing/trace_handler.py:1-50

Logs are stored in SQLite (guardrails_calls.db) by default, with the path configurable via GUARDRAILS_LOG_FILE_PATH environment variable.

Error Handling

The pipeline implements multi-level error handling:

  1. Validation Exceptions: Raised when output fails validator criteria
  2. Reask Exhaustion: Triggered when all reask attempts are consumed
  3. LLM Provider Errors: Propagated from underlying LLM calls
  4. Parsing Errors: Handled when LLM output cannot be parsed

Configuration Parameters

ParameterLocationDefaultDescription
num_reasksCallInputsNoneMaximum reask iterations
full_schema_reaskCallInputsNoneReask scope control
prompt_paramsCallInputs{}Template variables
streamCallInputsNoneEnable streaming mode
metadataCallInputsNoneCustom validator data

See Also

Sources: guardrails/classes/history/call_inputs.py:23-30

Async and Streaming Support

Related topics: Execution Pipeline, LLM Provider Integration

Section Related Pages

Continue reading this section for the full explanation and source context.

Section Runner Class Hierarchy

Continue reading this section for the full explanation and source context.

Section Module Structure

Continue reading this section for the full explanation and source context.

Section AsyncRunner Class

Continue reading this section for the full explanation and source context.

Related topics: Execution Pipeline, LLM Provider Integration

Async and Streaming Support

Overview

Guardrails provides comprehensive support for asynchronous operations and streaming responses, enabling integration with modern LLM APIs that support async calls or streaming output. This capability is essential for building responsive applications that need to handle real-time validation, provide incremental feedback, and maintain high throughput when processing LLM responses.

The async and streaming support in Guardrails is built around a modular runner architecture that separates the concerns of asynchronous execution from streaming output. This design allows developers to use either feature independently or combine them for full async streaming capabilities.

Sources: guardrails/run/__init__.py:1-15

Architecture

Runner Class Hierarchy

The async and streaming functionality is implemented through a class hierarchy that extends a base Runner class with async and streaming capabilities.

graph TD
    A[Runner] --> B[AsyncRunner]
    A --> C[StreamRunner]
    B --> D[AsyncStreamRunner]
    C --> D
    
    A1[Base synchronous runner] 
    B1[Async execution support]
    C1[Streaming output support]
    D1[Combined async + streaming]
    
    A --> A1
    B --> B1
    C --> C1
    D --> D1

Module Structure

The runners are organized under the guardrails.run module with the following structure:

ModulePurpose
guardrails.run.runnerBase synchronous runner
guardrails.run.async_runnerAsync execution support
guardrails.run.stream_runnerStreaming output support
guardrails.run.async_stream_runnerCombined async and streaming
guardrails.run.utilsShared utilities including messages_source

Sources: guardrails/run/__init__.py:1-15

Async Runner

AsyncRunner Class

The AsyncRunner extends the base Runner with asynchronous execution capabilities. It provides methods for calling LLM providers asynchronously and processing validation outcomes without blocking the calling thread.

class AsyncRunner(AsyncRunner, StreamRunner):
    async def async_run(
        self, call_log: Call, prompt_params: Optional[Dict] = None
    ) -> AsyncIterator[ValidationOutcome]:

Key characteristics of AsyncRunner:

  • Supports fully asynchronous LLM calls using async-compatible prompt callables
  • Provides async_call method for making async LLM invocations
  • Integrates with the async validator service for non-blocking validation
  • Returns ValidationOutcome objects containing validated results

Async Prompt Callables

Guardrails supports async prompt callables through the AsyncPromptCallableBase interface. Providers like AsyncManifestCallable implement this interface to enable async LLM calls.

class AsyncManifestCallable(AsyncPromptCallableBase):
    async def invoke_llm(
        self,
        text: str,
        client: Any,
        instructions: Optional[str] = None,
        *args,
        **kwargs,
    ):

Sources: guardrails/run/async_runner.py Sources: guardrails/llm_providers.py:1-100

Streaming Support

StreamRunner Class

The StreamRunner provides streaming output capabilities, allowing Guardrails to process LLM responses incrementally as they are generated. This is particularly useful for long-form content generation where users benefit from seeing results progressively.

Streaming support enables:

  • Incremental validation of streamed chunks
  • Real-time feedback on validation status
  • Memory-efficient processing of large responses

Sources: guardrails/run/stream_runner.py

Async Stream Runner

AsyncStreamRunner Class

The AsyncStreamRunner combines both async execution and streaming output, providing the most comprehensive integration for modern async LLM APIs with streaming support.

class AsyncStreamRunner(AsyncRunner, StreamRunner):
    async def async_run(
        self, call_log: Call, prompt_params: Optional[Dict] = None
    ) -> AsyncIterator[ValidationOutcome]:

The class uses Python's contextvars module for proper context propagation in async environments:

from contextvars import ContextVar, copy_context

This ensures that context variables are correctly copied when running async code, maintaining proper isolation and state management.

Sources: guardrails/run/async_stream_runner.py:1-50

Python Version Compatibility

For Python versions earlier than 3.10, Guardrails provides a polyfill for the anext() builtin function:

if sys.version_info.minor < 10:
    from guardrails.utils.polyfills import anext

This ensures compatibility with Python 3.9+ while maintaining access to async iteration features introduced in Python 3.10.

Sources: guardrails/run/async_stream_runner.py:5-8

Streaming Workflow

sequenceDiagram
    participant Client
    participant AsyncStreamRunner
    participant AsyncValidatorService
    participant LLMProvider
    
    Client->>AsyncStreamRunner: async_run(call_log, prompt_params)
    AsyncStreamRunner->>LLMProvider: async_call(messages)
    LLMProvider-->>AsyncStreamRunner: stream chunks
    
    loop For each chunk
        AsyncStreamRunner->>AsyncValidatorService: validate_chunk(chunk)
        AsyncValidatorService-->>AsyncStreamRunner: ValidationOutcome
        AsyncStreamRunner-->>Client: yield ValidationOutcome
    end
    
    Client->>AsyncStreamRunner: Final validation
    AsyncStreamRunner-->>Client: Final ValidationOutcome

MLflow Integration

The async and streaming runners are instrumented for MLflow tracing through the MLflowInstrumentor class. This provides observability for async operations and streaming workflows.

Instrumented Components

ComponentMethodInstrumentation
AsyncRunnerasync_stepAsync span with step type
AsyncStreamRunnerasync_stepAsync + stream span attributes
Runner.callcallLLM span for synchronous calls
AsyncRunner.async_callasync_callLLM span for async calls

Span Attributes

Async and streaming operations are traced with the following attributes:

{
    "guardrails.version": GUARDRAILS_VERSION,
    "type": "guardrails/guard/step",
    "async": True,
    "stream": True  # Only for streaming runners
}

Sources: guardrails/integrations/databricks/ml_flow_instrumentor.py:1-150

Async Stream Step Instrumentation

The async stream step wrapper handles async iteration properly:

async def trace_async_stream_step_wrapper(
    *args, **kwargs
) -> AsyncIterator[ValidationOutcome[OT]]:
    with mlflow.start_span(...) as step_span:
        exception = None
        try:
            gen = runner_step(*args, **kwargs)
            next_exists = True
            while next_exists:
                try:
                    res = await anext(gen)
                    yield res
                except StopIteration:
                    next_exists = False
                except StopAsyncIteration:
                    next_exists = False
        except Exception as e:
            step_span.set_status(status=SpanStatusCode.ERROR)
            exception = e
        finally:
            # Add step attributes
            if exception:
                raise exception

Sources: guardrails/integrations/databricks/ml_flow_instrumentor.py:80-120

Validation Outcome

Both async and streaming runners return ValidationOutcome objects, which encapsulate the result of validation operations.

ValidationOutcome Structure

FieldTypeDescription
call_logCallExecution history and metadata
validation_responseValidationResponseValidated and corrected output
exceptionExceptionAny exception that occurred

The Call object maintains a stack of Iteration objects, each representing a step or reask that occurred during execution:

class Call:
    iterations: Stack[Iteration] = Field(
        description="A stack of iterations for each step/reask that occurred.",
        default_factory=Stack,
    )
    inputs: CallInputs = Field(
        description="The inputs as passed in to Guard.__call__ or Guard.parse",
        default_factory=CallInputs,
    )

Sources: guardrails/classes/history/call.py:1-50

API Reference

Core Imports

from guardrails.run import (
    Runner,
    AsyncRunner,
    StreamRunner,
    AsyncStreamRunner,
    messages_source,
)

Runner Selection Guide

Use CaseRecommended Runner
Synchronous LLM callsRunner
Async LLM calls (non-streaming)AsyncRunner
Streaming LLM responsesStreamRunner
Async LLM calls with streamingAsyncStreamRunner

Best Practices

Async Context Management

When using async runners, ensure proper context management:

import asyncio
from guardrails.run import AsyncStreamRunner

async def process_stream():
    runner = AsyncStreamRunner(...)
    async for outcome in runner.async_run(call_log):
        # Process each validation outcome
        pass

Error Handling

The async stream runner handles errors gracefully, setting span status and re-raising exceptions:

try:
    # Stream processing
except Exception as e:
    step_span.set_status(status=SpanStatusCode.ERROR)
    raise e

MLflow Tracing

Enable MLflow tracing to monitor async and streaming performance:

from guardrails.integrations.databricks import MLflowInstrumentor

MLflowInstrumentor().instrument()

This automatically wraps all runner methods with appropriate span instrumentation.

Validator Service

The async validator service provides non-blocking validation:

  • Processes validation requests asynchronously
  • Integrates with async runners for parallel validation
  • Maintains thread safety for concurrent operations

LLM Providers

Async-compatible LLM providers include:

  • AsyncManifestCallable for Manifest models
  • LiteLLMCallable with async support
  • Custom providers implementing AsyncPromptCallableBase

Sources: guardrails/llm_providers.py:50-150

Summary

Guardrails' async and streaming support provides a flexible, extensible architecture for handling modern LLM interactions:

  1. Modular Design: The runner hierarchy allows selective use of async and streaming features
  2. Async Compatibility: Full support for async/await patterns with Python 3.9+ compatibility
  3. Streaming Efficiency: Memory-efficient processing of large streaming responses
  4. Observability: Integrated MLflow tracing for monitoring async and streaming operations
  5. Type Safety: Full type hints with generic ValidationOutcome returns

Sources: guardrails/run/__init__.py:1-15

LLM Provider Integration

Related topics: Guard Class Reference, Framework Integrations

Section Related Pages

Continue reading this section for the full explanation and source context.

Section Class Hierarchy

Continue reading this section for the full explanation and source context.

Section Core Components

Continue reading this section for the full explanation and source context.

Section Abstract Methods

Continue reading this section for the full explanation and source context.

Related topics: Guard Class Reference, Framework Integrations

LLM Provider Integration

Overview

The LLM Provider Integration system in Guardrails provides a unified abstraction layer for connecting various Large Language Model (LLM) providers to the Guardrails validation framework. This system enables Guardrails to work with multiple LLM backendsโ€”including OpenAI, LiteLLM, Manifest, and custom providersโ€”while maintaining consistent prompt handling, response parsing, and validation workflows.

The integration architecture follows a callable wrapper pattern, where each LLM provider is wrapped in a standardized PromptCallableBase subclass that normalizes the interface between Guardrails and the underlying LLM API.

Sources: guardrails/llm_providers.py:1-50

Architecture

Class Hierarchy

The LLM provider system is built on an abstract base class that defines the contract for all provider implementations:

graph TD
    A[PromptCallableBase] --> B[LiteLLMCallable]
    A --> C[ManifestCallable]
    A --> D[OpenAICallable]
    
    B --> E[GPTCallable]
    B --> F[AnthropicCallable]
    B --> G[Custom Provider]
    
    A --> H[LLM Response Normalization]
    A --> I[Tracing Integration]
    A --> J[Error Handling]

Sources: guardrails/classes/llm/prompt_callable.py:1-80

Core Components

ComponentPurposeFile Location
PromptCallableBaseAbstract base class defining the LLM interface contractguardrails/classes/llm/prompt_callable.py
LiteLLMCallableWrapper for LiteLLM multi-provider supportguardrails/llm_providers.py
ManifestCallableWrapper for Manifest ML clientguardrails/llm_providers.py
LLMResponseNormalized response objectguardrails/llm_providers.py
CallInputsCaptures invocation parameters and metadataguardrails/classes/history/call_inputs.py
CallRecords execution history and iterationsguardrails/classes/history/call.py

Sources: guardrails/llm_providers.py:50-150

PromptCallableBase

The PromptCallableBase is the foundational abstract class that all LLM providers must implement. It provides:

Abstract Methods

MethodSignatureDescription
_invoke_llm(text, model, messages, *args, **kwargs) -> LLMResponseCore LLM invocation method
_prepare_prompt(text, instructions) -> strPrepares prompt with formatting

Common Functionality

  • Tracing Integration: All providers integrate with Guardrails' tracing system via trace_operation() and trace_llm_call() functions
  • Prompt Normalization: Converts various prompt formats to a standardized structure
  • Error Handling: Wraps provider-specific exceptions in PromptCallableException
  • Streaming Support: Optional streaming via the stream parameter

Sources: guardrails/classes/llm/prompt_callable.py:30-100

LiteLLM Integration

Overview

LiteLLMCallable provides integration with LiteLLM, a unified interface for calling 100+ LLMs including OpenAI, Azure, Anthropic, Cohere, and Hugging Face.

from litellm import completion

raw_llm_response, validated_response = guard(
    completion,
    model="gpt-3.5-turbo",
    prompt_params={...},
    temperature=0.7,
)

Sources: guardrails/llm_providers.py:80-120

Invocation Parameters

ParameterTypeDefaultDescription
textOptional[str]NonePlain text prompt
modelstr"gpt-3.5-turbo"Model identifier
messagesOptional[List[Dict]]NoneChat messages list
*argsAny-Additional positional arguments
**kwargsAny-Provider-specific parameters (temperature, max_tokens, etc.)

Function Calling Support

LiteLLMCallable supports OpenAI-style function calling through the tools parameter:

function_calling_tools = [
    tool.get("function")
    for tool in kwargs.get("tools", [])
    if isinstance(tool, Dict) and tool.get("type") == "function"
]

Sources: guardrails/llm_providers.py:130-160

Manifest Integration

Overview

ManifestCallable provides integration with the Manifest ML client library for models hosted on various backends.

Usage Pattern

from guardrails import Guard

raw_llm_response, validated_response = guard(
    client,
    prompt_params={...},
    ...
)

Prompt Handling

Manifest uses a non-chat prompt format:

prompt = nonchat_prompt(prompt=text, instructions=instructions)
manifest_response = client.run(prompt, *args, **kwargs)

Sources: guardrails/llm_providers.py:20-60

Response Handling

LLMResponse Structure

All providers return a normalized LLMResponse object:

FieldTypeDescription
outputstrThe raw LLM-generated text
modelOptional[str]Model identifier used
usageOptional[Dict]Token usage statistics
providerstrSource provider name

Tracing Integration

Every LLM call is traced with full input/output capture:

trace_operation(
    input_mime_type="application/json",
    input_value={
        **kwargs,
        "model": model,
        "args": args,
    },
)

trace_llm_call(
    input_messages=kwargs.get("messages"),
    invocation_parameters={**kwargs, "model": model},
    function_call=kwargs.get("function_call"),
)

Sources: guardrails/llm_providers.py:140-180

Guard Integration

Guard Class Methods

The Guard class provides factory methods for creating provider-integrated instances:

MethodPurpose
Guard.from_rail()Create Guard from RAIL XML specification
Guard.from_pydantic()Create Guard from Pydantic model
Guard.__call__()Invoke LLM with automatic validation

Sources: guardrails/guard.py:100-200

Call History

Each LLM invocation creates a Call record containing:

class Call:
    iterations: Stack[Iteration]  # Validation iterations
    inputs: CallInputs              # Invocation parameters
    exception: Optional[Exception]  # Any errors during execution

The CallInputs captures:

  • llm_api: The callable used
  • prompt_params: Parameters for prompt interpolation
  • num_reasks: Maximum reask attempts
  • metadata: Custom data for validators
  • full_schema_reask: Whether to reask entire schema
  • stream: Streaming mode flag

Sources: guardrails/classes/history/call.py:20-80

Error Handling

Exception Types

ExceptionTriggerHandling
PromptCallableExceptionMissing dependencies or provider errorsWraps underlying exception with context
ImportErrorRequired package not installedClear installation instructions

Example Error Handling

try:
    from litellm import completion
except ImportError as e:
    raise PromptCallableException(
        "The `litellm` package is not installed. "
        "Install with `pip install litellm`"
    ) from e

Sources: guardrails/llm_providers.py:95-105

Workflow Diagram

sequenceDiagram
    participant User
    participant Guard
    participant PromptCallable
    participant LLMProvider
    participant Validator
    
    User->>Guard: __call__(llm_api, prompt, params)
    Guard->>Guard: Create Call record
    Guard->>PromptCallable: _invoke_llm(text, model, messages)
    PromptCallable->>PromptCallable: trace_operation()
    PromptCallable->>LLMProvider: LLM API call
    LLMProvider-->>PromptCallable: Raw response
    PromptCallable->>PromptCallable: trace_llm_call()
    PromptCallable-->>Guard: LLMResponse
    Guard->>Validator: Validate response
    Validator-->>Guard: ValidationResult
    Guard->>Guard: Record Iteration
    Guard-->>User: (raw_response, validated_response)

Best Practices

  1. Use LiteLLM for Multi-Provider Support: LiteLLM provides the most flexibility for switching between providers
  2. Configure Prompt Parameters: Always provide prompt_params for dynamic prompt interpolation
  3. Enable Tracing in Development: Tracing helps debug LLM interactions and validation failures
  4. Handle Exceptions: Wrap Guard calls in try-except blocks to handle validation failures gracefully
  5. Use Pydantic for Structured Output: The Guard.from_pydantic() method provides the cleanest integration for structured data generation

See Also

Sources: guardrails/llm_providers.py:1-50

Framework Integrations

Related topics: LLM Provider Integration, Guard Class Reference

Section Related Pages

Continue reading this section for the full explanation and source context.

Section Core Components

Continue reading this section for the full explanation and source context.

Section GuardRunnable Class

Continue reading this section for the full explanation and source context.

Section BaseRunnable Abstract Class

Continue reading this section for the full explanation and source context.

Related topics: LLM Provider Integration, Guard Class Reference

Framework Integrations

Guardrails provides official integrations with popular AI frameworks to enable seamless validation of LLM outputs within existing application stacks. These integrations wrap framework-specific components to transparently apply Guard validation without requiring significant changes to existing code.

Architecture Overview

Framework integrations in Guardrails follow a consistent design pattern: they wrap framework-native runnable or engine objects, intercepting inputs and outputs to apply validation through the Guard API.

graph TD
    subgraph "Application Layer"
        User[User Application]
    end
    
    subgraph "Framework Integration Layer"
        GR[Guardrails Wrapper]
        Guard[Guard Instance]
    end
    
    subgraph "Framework Layer"
        LC[LangChain / LlamaIndex]
        DB[Databricks MLflow]
    end
    
    subgraph "Guardrails Core"
        Validators[Validators]
        Schema[RAIL / Pydantic Schema]
    end
    
    User --> GR
    GR --> LC
    GR --> Guard
    Guard --> Validators
    Guard --> Schema
    
    style GR fill:#e1f5fe
    style Guard fill:#fff3e0

LangChain Integration

The LangChain integration provides GuardRunnable and BaseRunnable classes that wrap LangChain components, enabling validation of LLM outputs in chains and agents.

Core Components

ComponentFilePurpose
BaseRunnableguardrails/integrations/langchain/base_runnable.pyBase class providing LangChain-compatible runnable interface
GuardRunnableguardrails/integrations/langchain/guard_runnable.pyConcrete implementation wrapping a Guard instance

GuardRunnable Class

The GuardRunnable class serves as a LangChain-compatible runnable that applies Guard validation to outputs.

Key Features:

  • Implements LangChain's Runnable interface for drop-in compatibility
  • Wraps a Guard instance to validate LLM responses
  • Supports streaming responses with validation
  • Integrates with LangChain's tracing and observability

Usage Pattern:

from guardrails.integrations.langchain import GuardRunnable
from guardrails import Guard

# Create a Guard instance
guard = Guard().use(SomeValidator, ...)

# Wrap it as a LangChain runnable
guard_runnable = GuardRunnable(guard=guard)

# Use in LangChain chains
chain = prompt | llm | guard_runnable

Sources: guardrails/integrations/langchain/guard_runnable.py

BaseRunnable Abstract Class

The BaseRunnable class defines the abstract interface that all Guardrails runnables must implement, ensuring consistency across different framework integrations.

Sources: guardrails/integrations/langchain/base_runnable.py

LlamaIndex Integration

The LlamaIndex integration provides engines that wrap LlamaIndex query and chat engines with Guard validation.

Supported Engine Types

Engine TypeFileDescription
GuardrailsQueryEngineguardrails/integrations/llama_index/guardrails_query_engine.pyValidates query engine responses
GuardrailsChatEngineguardrails/integrations/llama_index/guardrails_chat_engine.pyValidates chat engine responses

GuardrailsQueryEngine

The query engine integration validates responses from LlamaIndex query operations.

Key Capabilities:

  • Wraps base LlamaIndex query engines
  • Validates retrieved context and generated responses
  • Supports custom validators for domain-specific checks
  • Maintains query context through the validation pipeline

Typical Integration:

from guardrails.integrations.llama_index import GuardrailsQueryEngine
from guardrails import Guard
from llama_index import VectorStoreIndex

# Build index
index = VectorStoreIndex.from_documents(documents)

# Create Guard
guard = Guard().use(SomeValidator, ...)

# Wrap query engine
query_engine = index.as_query_engine()
guardrails_engine = GuardrailsQueryEngine(
    query_engine=query_engine,
    guard=guard
)

Sources: guardrails/integrations/llama_index/guardrails_query_engine.py

GuardrailsChatEngine

The chat engine integration validates conversational responses, ensuring consistency and safety across multi-turn interactions.

Features:

  • Validates each response in a conversation
  • Supports conversation context preservation
  • Integrates with LlamaIndex memory components
  • Enables custom validation per conversation turn

Sources: guardrails/integrations/llama_index/guardrails_chat_engine.py

Databricks MLflow Integration

The Databricks integration provides automatic instrumentation for LLM calls within the MLflow tracking ecosystem.

MLflow Instrumentor

ComponentFilePurpose
MLflowInstrumentorguardrails/integrations/databricks/ml_flow_instrumentor.pyAuto-instruments LLM calls for MLflow tracking

Instrumentation Capabilities:

  • Automatically wraps LLM invocations
  • Logs prompts and responses to MLflow
  • Tracks validation outcomes and errors
  • Associates metrics with MLflow runs

Setup:

from guardrails.integrations.databricks import MLflowInstrumentor

# Initialize instrumentor
instrumentor = MLflowInstrumentor()

# Enable instrumentation
instrumentor.instrument()

Sources: guardrails/integrations/databricks/ml_flow_instrumentor.py

Integration Patterns

Common Workflow

sequenceDiagram
    participant App as Application
    participant Wrapper as Guardrails Wrapper
    participant Framework as AI Framework
    participant Guard as Guard Instance
    participant Validators as Validators
    
    App->>Wrapper: Invoke LLM Call
    Wrapper->>Framework: Forward Request
    Framework->>Wrapper: LLM Response
    Wrapper->>Guard: Validate Response
    Guard->>Validators: Run Validators
    Validators-->>Guard: Validation Result
    alt Validation Passes
        Guard-->>Wrapper: Validated Output
        Wrapper-->>App: Return Result
    else Validation Fails
        Guard-->>Wrapper: Validation Error
        Wrapper-->>App: Raise Exception / Return Fix
    end

Validation Flow

When validation fails, the integration architecture determines how to handle the failure based on the configured on_fail action:

ActionBehavior
EXCEPTIONRaises an exception with validation details
REASKAttempts to reask the LLM with corrected context
FIXAttempts to automatically fix the output
FILTERFilters invalid portions from the output
CUSTOMInvokes a custom handler function

Configuration Reference

Guard Configuration

Integrations accept a Guard instance configured with the desired validators:

from guardrails import Guard, OnFailAction

guard = Guard().use(
    Validator1(param1="value1", on_fail=OnFailAction.EXCEPTION),
    Validator2(param2="value2", on_fail=OnFailAction.REASK),
)

Integration-Specific Options

IntegrationOptionDescription
LangChainguardGuard instance for validation
LlamaIndexquery_engineBase query engine to wrap
LlamaIndexchat_engineBase chat engine to wrap
Databricksinstrument()Enable/disable auto-instrumentation

Best Practices

  1. Centralized Guard Configuration: Define Guard instances with all required validators in a single location and reuse across integrations
  2. Fail Action Strategy: Choose appropriate on_fail actions based on use case criticality
  3. Validator Ordering: Place faster validators first to fail fast on common issues
  4. Error Handling: Implement proper exception handling for validation failures
  5. Testing: Test validation logic independently before integration

Dependencies

Framework integrations have specific dependency requirements:

IntegrationRequired Packages
LangChainlangchain>=0.0.XXX
LlamaIndexllama-index>=0.XXX
Databricksmlflow>=2.XXX, databricks-sdk

Sources: guardrails/integrations/langchain/guard_runnable.py

Creating Custom Validators

Related topics: Validators System

Section Related Pages

Continue reading this section for the full explanation and source context.

Section Base Class Structure

Continue reading this section for the full explanation and source context.

Section Validation Result Types

Continue reading this section for the full explanation and source context.

Section Using the CLI Generator

Continue reading this section for the full explanation and source context.

Related topics: Validators System

Creating Custom Validators

Custom validators in Guardrails enable developers to define domain-specific validation logic that can be integrated seamlessly into the Guard validation pipeline. Validators are reusable components that inspect LLM outputs and either pass or fail based on custom criteria.

Overview

Guardrails provides a validator framework where validators are classes that inherit from a base Validator class and implement a validate method. Each validator can receive initialization arguments and define behavior when validation fails through the on_fail parameter.

graph TD
    A[LLM Output] --> B[Guard Pipeline]
    B --> C[Validator 1]
    C --> D[Validator 2]
    D --> E[Validator N]
    E --> F[Validated Output]
    
    C -->|Pass| D
    D -->|Pass| E
    E -->|Pass| F
    
    C -->|Fail| G[On Fail Action]
    D -->|Fail| G
    E -->|Fail| G

Validator Architecture

Base Class Structure

Validators inherit from Validator which provides:

  • Initialization handling for on_fail policy
  • Metadata passing through validation pipeline
  • Integration with the Guard validation system

Each validator must implement:

  1. __init__: Accept initialization arguments and on_fail parameter
  2. validate: Perform validation logic and return PassResult or FailResult

Validation Result Types

Result TypePurpose
PassResultValue passes validation
FailResultValue fails validation with error message

Creating a Custom Validator

Using the CLI Generator

The fastest way to create a validator is using the CLI command:

guardrails hub create-validator MyValidator

This generates a template file ./my_validator.py with the following structure:

from guardrails.validator_base import (
    Validator,
    ValidationResult,
    PassResult,
    FailResult,
)
from typing import Any, Dict, Optional, Callable

class MyValidator(Validator):
    """Description of what your validator does.
    
    ## (Optional) Intended Use
    Describe the intended use of your validator.
    """

    def __init__(
        self,
        arg_1: str,  # FIXME: Replace with your custom init args
        on_fail: Optional[Callable] = None,
    ):
        """Initializes a new instance of the MyValidator class.
        
        Args:
            arg_1 (str): FIXME: Describe the purpose of this argument.
            on_fail (str, Callable): The policy when validation fails.
                If str, must be one of: reask, fix, filter, refrain, noop, 
                exception, or fix_reask.
        """
        super().__init__(on_fail=on_fail, arg_1=arg_1)
        self._arg_1 = arg_1

    def validate(self, value: Any, metadata: Dict) -> ValidationResult:
        """Validates the passed value.
        
        Args:
            value (Any): The value to validate.
            metadata (Dict): Additional metadata for validation.
        
        Returns:
            ValidationResult: PassResult or FailResult
        """
        # Add custom validator logic here
        if value == "pass":
            return PassResult()
        else:
            return FailResult(
                error_message="Validation failed: value must be 'pass'"
            )

Sources: guardrails/cli/hub/create_validator.py:1-80

Validator Template Structure

SectionDescription
Class DefinitionInherits from Validator base class
DocstringDescription and usage examples
__init__Initialization with custom args and on_fail
validateCore validation logic returning ValidationResult

Validator Initialization Parameters

Core Parameters

ParameterTypeRequiredDescription
on_failstr or CallableYesPolicy when validation fails
Custom argsAnyVariesValidator-specific parameters

On Fail Actions

ActionBehavior
reaskRe-ask the LLM for corrected output
fixAttempt to fix the invalid value
filterRemove the invalid value from output
refrainRefrain from providing any value
noopNo operation, continue with original value
exceptionRaise an exception
fix_reaskFix and re-ask if fix fails

Sources: guardrails/validator_service_base.py:1-50

Installation and Registration

Installing from Local Path

Validators can be installed directly from the repository:

guardrails hub install ./path/to/validator.py

Package Structure for Hub Submission

When preparing a validator for Guardrails Hub submission:

# In your validator package
from guardrails.validator_base import Validator, ValidationResult, PassResult, FailResult

class MyValidator(Validator):
    """My custom validator description."""
    
    def __init__(self, threshold: float = 0.5, on_fail: str = None):
        super().__init__(on_fail=on_fail, threshold=threshold)
        self._threshold = threshold
    
    def validate(self, value: Any, metadata: Dict) -> ValidationResult:
        # Custom validation logic
        if self._check_condition(value):
            return PassResult()
        return FailResult(error_message="Condition not met")

Installation Process

sequenceDiagram
    participant CLI as Guardrails CLI
    participant Service as ValidatorPackageService
    participant Hub as Guardrails Hub
    participant Local as Local Environment
    
    CLI->>Service: install_hub_module(validator_id)
    Service->>Hub: Fetch manifest
    Service->>Local: Download dependencies
    Service->>Local: Install via pip
    Service-->>CLI: Installation complete

The installation service handles:

  1. Validating the package URI
  2. Fetching the manifest from Guardrails Hub
  3. Downloading dependencies
  4. Installing the module via pip

Sources: guardrails/hub/install.py:1-60 Sources: guardrails/hub/validator_package_service.py

Using Custom Validators

Basic Usage with Guard

from guardrails import Guard, OnFailAction
from guardrails.hub import MyValidator

# Create guard with custom validator
guard = Guard().use(
    MyValidator(threshold=0.5, on_fail=OnFailAction.EXCEPTION)
)

# Validate output
result = guard.validate("sample_output")

Using with Guardrails Hub Validators

Validators from Guardrails Hub are accessed via the hub module:

from guardrails.hub import RegexMatch, CompetitorCheck, ToxicLanguage

guard = Guard().use(
    RegexMatch(regex=r"\d{3}-\d{4}"),
    CompetitorCheck(["Apple", "Microsoft"]),
    ToxicLanguage(threshold=0.5, validation_method="sentence")
)

Multiple Validators

Multiple validators can be chained on the same output:

graph LR
    A[LLM Output] --> B[RegexMatch]
    B -->|Pass| C[CompetitorCheck]
    C -->|Pass| D[ToxicLanguage]
    D -->|Pass| E[Final Output]
    
    B -->|Fail| F[On Fail: Exception]
    C -->|Fail| F
    D -->|Fail| F

Validation Metadata

Validators receive metadata during execution that can be used for contextual validation:

def validate(self, value: Any, metadata: Dict) -> ValidationResult:
    """Use metadata for contextual validation.
    
    Common metadata keys:
    - prompt_params: Parameters used in the original prompt
    - llm_response: Raw LLM response
    - iterations: Number of validation iterations
    """
    if "custom_key" in metadata:
        # Use metadata for validation decisions
        pass
    
    return PassResult()

Sources: guardrails/classes/history/call_inputs.py:1-60

Best Practices

Validator Design Guidelines

  1. Single Responsibility: Each validator should check one condition
  2. Clear Error Messages: Provide descriptive error messages for failures
  3. Metadata Utilization: Leverage metadata for contextual validation
  4. Default Values: Set sensible defaults for optional parameters
  5. Documentation: Document all parameters and intended use cases

Testing Custom Validators

from guardrails import Guard
from my_validator import MyValidator

guard = Guard().use(MyValidator(arg="expected_value"))

# Test passing case
result = guard.validate("expected_value")
assert result.validation_passed

# Test failing case
result = guard.validate("unexpected_value")
assert not result.validation_passed

CLI Commands Reference

CommandDescription
guardrails hub create-validator <name>Create validator template
guardrails hub install <uri>Install a validator
guardrails hub install -l <uri>Install with local models
guardrails hub install -q <uri>Quiet installation

Sources: guardrails/cli/hub/create_validator.py:1-100 Sources: guardrails/cli/hub/install.py:1-60

Integration with Guard Pipeline

graph TD
    A[User Input] --> B[Guard.__call__]
    B --> C[Call History Created]
    C --> D[Iteration Loop]
    D --> E[Run Validators]
    E --> F{All Validators Pass?}
    F -->|Yes| G[Return ValidationOutcome]
    F -->|No| H[Apply On Fail Action]
    H --> I{Reask Enabled?}
    I -->|Yes| J[Re-ask LLM]
    J --> D
    I -->|No| G

The Guard class orchestrates the validation pipeline, managing iterations and applying on-fail policies as configured.

Sources: guardrails/guard.py:1-100 Sources: guardrails/classes/history/call.py:1-50

Sources: guardrails/cli/hub/create_validator.py:1-80

Doramagic Pitfall Log

Source-linked risks stay visible on the manual page so the preview does not read like a recommendation.

high FIX action silently mutates output - should there be a 'quarantine' tier between LOG and FIX?

First-time setup may fail or require extra isolation and rollback planning.

high Feature request: OWASP ASI06 memory poisoning guard validator

First-time setup may fail or require extra isolation and rollback planning.

high Portable evidence artifacts for validation outcomes

First-time setup may fail or require extra isolation and rollback planning.

high Proposal: Agent Threat Rules detection integration

First-time setup may fail or require extra isolation and rollback planning.

Doramagic Pitfall Log

Doramagic extracted 16 source-linked risk signals. Review them before installing or handing real data to the project.

1. Installation risk: FIX action silently mutates output - should there be a 'quarantine' tier between LOG and FIX?

  • Severity: high
  • Finding: Installation risk is backed by a source signal: FIX action silently mutates output - should there be a 'quarantine' tier between LOG and FIX?. Treat it as a review item until the current version is checked.
  • User impact: First-time setup may fail or require extra isolation and rollback planning.
  • Recommended check: Open the linked source, confirm whether it still applies to the current version, and keep the first run isolated.
  • Evidence: Source-linked evidence: https://github.com/guardrails-ai/guardrails/issues/1448

2. Installation risk: Feature request: OWASP ASI06 memory poisoning guard validator

  • Severity: high
  • Finding: Installation risk is backed by a source signal: Feature request: OWASP ASI06 memory poisoning guard validator. Treat it as a review item until the current version is checked.
  • User impact: First-time setup may fail or require extra isolation and rollback planning.
  • Recommended check: Open the linked source, confirm whether it still applies to the current version, and keep the first run isolated.
  • Evidence: Source-linked evidence: https://github.com/guardrails-ai/guardrails/issues/1488

3. Installation risk: Portable evidence artifacts for validation outcomes

  • Severity: high
  • Finding: Installation risk is backed by a source signal: Portable evidence artifacts for validation outcomes. Treat it as a review item until the current version is checked.
  • User impact: First-time setup may fail or require extra isolation and rollback planning.
  • Recommended check: Open the linked source, confirm whether it still applies to the current version, and keep the first run isolated.
  • Evidence: Source-linked evidence: https://github.com/guardrails-ai/guardrails/issues/1457

4. Installation risk: Proposal: Agent Threat Rules detection integration

  • Severity: high
  • Finding: Installation risk is backed by a source signal: Proposal: Agent Threat Rules detection integration. Treat it as a review item until the current version is checked.
  • User impact: First-time setup may fail or require extra isolation and rollback planning.
  • Recommended check: Open the linked source, confirm whether it still applies to the current version, and keep the first run isolated.
  • Evidence: Source-linked evidence: https://github.com/guardrails-ai/guardrails/issues/1471

5. Installation risk: Proposal: PromptDefenseAudit Hub validator โ€” static system prompt hardening check

  • Severity: high
  • Finding: Installation risk is backed by a source signal: Proposal: PromptDefenseAudit Hub validator โ€” static system prompt hardening check. Treat it as a review item until the current version is checked.
  • User impact: First-time setup may fail or require extra isolation and rollback planning.
  • Recommended check: Open the linked source, confirm whether it still applies to the current version, and keep the first run isolated.
  • Evidence: Source-linked evidence: https://github.com/guardrails-ai/guardrails/issues/1453

6. Installation risk: [bug] 429 Rate Limit Error from Opting into Metrics

  • Severity: high
  • Finding: Installation risk is backed by a source signal: [bug] 429 Rate Limit Error from Opting into Metrics. Treat it as a review item until the current version is checked.
  • User impact: First-time setup may fail or require extra isolation and rollback planning.
  • Recommended check: Open the linked source, confirm whether it still applies to the current version, and keep the first run isolated.
  • Evidence: Source-linked evidence: https://github.com/guardrails-ai/guardrails/issues/1385

7. Capability assumption: [docs] Fix double logo display in pypi

  • Severity: high
  • Finding: Capability assumption is backed by a source signal: [docs] Fix double logo display in pypi. Treat it as a review item until the current version is checked.
  • User impact: The project should not be treated as fully validated until this signal is reviewed.
  • Recommended check: Open the linked source, confirm whether it still applies to the current version, and keep the first run isolated.
  • Evidence: Source-linked evidence: https://github.com/guardrails-ai/guardrails/issues/1362

8. Security or permission risk: Developers should check this security_permissions risk before relying on the project: Best-practice: litellm pin excludes patched CVE versions, unverified-jwt-decode duplication, workflow inputs interpolation

  • Severity: high
  • Finding: Developers should check this security_permissions risk before relying on the project: Best-practice: litellm pin excludes patched CVE versions, unverified-jwt-decode duplication, workflow inputs interpolation
  • User impact: Developers may expose sensitive permissions or credentials: Best-practice: litellm pin excludes patched CVE versions, unverified-jwt-decode duplication, workflow inputs interpolation
  • Recommended check: Before packaging this project, run the relevant install/config/quickstart check for: Best-practice: litellm pin excludes patched CVE versions, unverified-jwt-decode duplication, workflow inputs interpolation. Context: Observed when using python
  • Evidence: failure_mode_cluster:github_issue | fmev_819ae3bfce09ed33a4655a81cf59dd44 | https://github.com/guardrails-ai/guardrails/issues/1485 | Best-practice: litellm pin excludes patched CVE versions, unverified-jwt-decode duplication, workflow inputs interpolation

9. Security or permission risk: Developers should check this security_permissions risk before relying on the project: Feature Request: OWASP ASI06 memory write validation via Agent Memory Guard

  • Severity: high
  • Finding: Developers should check this security_permissions risk before relying on the project: Feature Request: OWASP ASI06 memory write validation via Agent Memory Guard
  • User impact: Developers may expose sensitive permissions or credentials: Feature Request: OWASP ASI06 memory write validation via Agent Memory Guard
  • Recommended check: Before packaging this project, run the relevant install/config/quickstart check for: Feature Request: OWASP ASI06 memory write validation via Agent Memory Guard. Context: Observed when using python
  • Evidence: failure_mode_cluster:github_issue | fmev_2c7b3b6f6709cc847b37fb56bc9973d3 | https://github.com/guardrails-ai/guardrails/issues/1476 | Feature Request: OWASP ASI06 memory write validation via Agent Memory Guard

10. Security or permission risk: Developers should check this security_permissions risk before relying on the project: [bug] Failures and Delayed Responses from guard.validate Method Using Different Validator with Guardrails Hub

  • Severity: high
  • Finding: Developers should check this security_permissions risk before relying on the project: [bug] Failures and Delayed Responses from guard.validate Method Using Different Validator with Guardrails Hub
  • User impact: Developers may expose sensitive permissions or credentials: [bug] Failures and Delayed Responses from guard.validate Method Using Different Validator with Guardrails Hub
  • Recommended check: Before packaging this project, run the relevant install/config/quickstart check for: [bug] Failures and Delayed Responses from guard.validate Method Using Different Validator with Guardrails Hub. Context: Observed when using python, docker, cuda
  • Evidence: failure_mode_cluster:github_issue | fmev_70a43b34234fca351363180353991f27 | https://github.com/guardrails-ai/guardrails/issues/1479 | [bug] Failures and Delayed Responses from guard.validate Method Using Different Validator with Guardrails Hub

11. Security or permission risk: Feature Request: OWASP ASI06 memory write validation via Agent Memory Guard

  • Severity: high
  • Finding: Security or permission risk is backed by a source signal: Feature Request: OWASP ASI06 memory write validation via Agent Memory Guard. Treat it as a review item until the current version is checked.
  • User impact: The project may affect permissions, credentials, data exposure, or host boundaries.
  • Recommended check: Open the linked source, confirm whether it still applies to the current version, and keep the first run isolated.
  • Evidence: Source-linked evidence: https://github.com/guardrails-ai/guardrails/issues/1476

12. Security or permission risk: Integration proposal: Cryptographic audit trail validator with asqav

  • Severity: high
  • Finding: Security or permission risk is backed by a source signal: Integration proposal: Cryptographic audit trail validator with asqav. Treat it as a review item until the current version is checked.
  • User impact: The project may affect permissions, credentials, data exposure, or host boundaries.
  • Recommended check: Open the linked source, confirm whether it still applies to the current version, and keep the first run isolated.
  • Evidence: Source-linked evidence: https://github.com/guardrails-ai/guardrails/issues/1446

Source: Doramagic discovery, validation, and Project Pack records

Community Discussion Evidence

These external discussion links are review inputs, not standalone proof that the project is production-ready.

Sources 12

Count of project-level external discussion links exposed on this manual page.

Use Review before install

Open the linked issues or discussions before treating the pack as ready for your environment.

Community Discussion Evidence

Doramagic exposes project-level community discussion separately from official documentation. Review these links before using guardrails with real data or production workflows.

Source: Project Pack community evidence and pitfall evidence