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
Continue reading this section for the full explanation and source context.
Continue reading this section for the full explanation and source context.
Continue reading this section for the full explanation and source context.
Continue reading this section for the full explanation and source context.
Related Pages
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:
| Action | Description |
|---|---|
EXCEPTION | Raise an exception |
REASK | Re-ask the LLM to produce valid output |
FIX | Attempt to auto-fix the output |
FILTER | Filter out invalid parts |
REFRAIN | Return 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 --> DCreating 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:
- Function calling: For LLMs that support function calling
- 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:
| Validator | Purpose | Example Usage |
|---|---|---|
RegexMatch | Validate string against regex pattern | Phone number format |
CompetitorCheck | Detect mentions of competitors | Brand safety |
ToxicLanguage | Detect toxic/offensive content | Content moderation |
LowerCase | Ensure text is lowercase | Normalization |
UpperCase | Ensure text is uppercase | Normalization |
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 / ExceptionCreating 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 ``
- Clone and setup:
``bash make test ``
- Run tests:
``bash make autoformat ``
- Format code:
``bash make type ``
- Type checking:
``bash make docs-gen ``
- 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 iterationsinputs: Original inputs to the Guardexception: Any exception that occurred
Sources: guardrails/classes/history/call.py:15-35
CLI Commands Reference
| Command | Description |
|---|---|
guardrails configure | Configure Guardrails Hub CLI |
guardrails hub install <package> | Install a validator from Hub |
guardrails hub create-validator <name> | Create a new validator template |
guardrails start | Start 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
Continue reading this section for the full explanation and source context.
Continue reading this section for the full explanation and source context.
Continue reading this section for the full explanation and source context.
Continue reading this section for the full explanation and source context.
Related Pages
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 --> APIClientSources: 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
| Feature | Description |
|---|---|
| Validator Composition | Chain multiple validators using .use() method |
| Schema Support | Support for RAIL, Pydantic, and JSON Schema |
| LLM Integration | Built-in support for various LLM providers |
| History Tracking | Records all validation iterations and outcomes |
| Async Support | Separate 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:
from_rail()- Creates a Guard from a RAIL (Rich Application Information Language) stringfor_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
| Aspect | Guard | AsyncGuard |
|---|---|---|
| Execution | Synchronous | Asynchronous (async/await) |
| Use Case | Standard applications | High-performance async apps |
| API | guard.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 --> AggregatedSources: 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/ExceptionReAsk Flow
When initial validation fails, the system can trigger a reask mechanism:
- Validation fails for field
- System generates reask prompt
- LLM receives reask prompt
- New output is validated
- Process repeats until valid or max iterations reached
Sources: guardrails/guard.py:300-400
Schema System
Supported Schema Formats
| Format | Method | Description |
|---|---|---|
| RAIL | Guard.from_rail() | XML-based schema with validators |
| Pydantic | Guard.for_pydantic() | Python class-based schema |
| JSON Schema | json_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
| Attribute | Type | Description |
|---|---|---|
iterations | Stack[Iteration] | Each validation round and reask |
inputs | CallInputs | Original prompt, parameters, etc. |
exception | Exception | Exception 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 --> CustomCallableSupported 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:
| Method | Purpose |
|---|---|
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
| Command | File | Purpose |
|---|---|---|
guardrails configure | CLI setup | Configure Guardrails settings |
guardrails hub install | cli/hub/install.py | Install validators from Hub |
guardrails hub create-validator | cli/hub/create_validator.py | Scaffold new validators |
guardrails start | cli/start.py | Start Guardrails API server |
Sources: guardrails/cli/start.py:1-50
Error Handling and Logging
Log Levels
| Level | Value | Usage |
|---|---|---|
SPAM | 5 | Verbose debug information |
VERBOSE | 15 | Detailed execution info |
NOTICE | 25 | Important events |
SUCCESS | 35 | Successful operations |
Sources: guardrails/cli/logger.py:1-30
Summary
The Guardrails architecture follows a layered approach:
- Presentation Layer -
GuardandAsyncGuardclasses provide the user-facing API - Schema Layer -
ProcessedSchemaandRailSchemahandle input parsing and validation rules - Validation Layer -
ValidatorServiceexecutes validators and aggregates results - 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
Continue reading this section for the full explanation and source context.
Continue reading this section for the full explanation and source context.
Continue reading this section for the full explanation and source context.
Continue reading this section for the full explanation and source context.
Related Pages
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
OnFailActionstrategies
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 --> ACreating Guard Instances
Factory Methods
The Guard class provides two primary factory methods for instantiation:
| Method | Input Type | Use Case |
|---|---|---|
Guard.from_rail() | RAIL XML string | Complex schemas with validators |
Guard.for_pydantic() | Pydantic BaseModel | Structured 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
| Method | Purpose | Returns |
|---|---|---|
validate() | Validates LLM output against schema | ValidationOutcome |
parse() | Parses raw output without full validation | Parsed result |
__call__() | Combined call and validation | LLM 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:
| Action | Behavior |
|---|---|
EXCEPTION | Raises an exception with error details |
REASK | Attempts to regenerate the LLM output with feedback |
FIX | Returns a corrected/fallback value |
REFRAIN | Returns None instead of output |
NOOP | Returns the original output unchanged |
CUSTOM | Uses 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:
- The initial validation round
- 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:
| Field | Type | Description |
|---|---|---|
prompt_params | Dict | Parameters formatted into messages |
num_reasks | int | Maximum reask attempts |
metadata | Dict | Additional runtime data |
full_schema_reask | bool | Reask entire schema vs individual fields |
stream | bool | Streaming mode flag |
args | List[Any] | Additional positional arguments |
kwargs | Dict[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:
- Validates the package URI format
- Fetches the module manifest
- Downloads dependencies via pip
- 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
Continue reading this section for the full explanation and source context.
Continue reading this section for the full explanation and source context.
Continue reading this section for the full explanation and source context.
Continue reading this section for the full explanation and source context.
Related Pages
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_failmechanism - 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_failpolicy 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:
| Class | Purpose |
|---|---|
PassResult | Indicates validation succeeded |
FailResult | Indicates 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 <|-- FailResultOnFailAction Policies
When validation fails, the on_fail parameter determines the behavior:
| Policy | Behavior |
|---|---|
REASK | Trigger a reask to the LLM |
FIX | Attempt to fix the value automatically |
FILTER | Remove invalid elements |
REFRAIN | Return empty/null value |
NOOP | Return the original value unchanged |
EXCEPTION | Raise 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:
| Method | Description |
|---|---|
before_run_validator | Prepares logging and tracking before validation |
after_run_validator | Records results and timing after validation |
run_validator | Executes 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),
)
| Field | Description |
|---|---|
validatorName | Class name of the validator |
valueBeforeValidation | Original value before validation |
registeredName | RAIL alias for the validator |
propertyPath | JSON path to the validated property |
instanceId | Memory address of validator instance |
start_time | Timestamp when validation began |
end_time | Timestamp when validation completed |
validation_result | Result 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:
| Parameter | Type | Description |
|---|---|---|
*validators | Validator | Positional args for validators |
on | str | Property 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 correctionsGetting Attached Validators
Retrieve validators attached to a specific property:
validators = guard.get_validators(on="output")
| Parameter | Valid Options | Description |
|---|---|---|
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| Class | Purpose |
|---|---|
Call | Represents a single Guard execution (validate/parse/call) |
Iteration | A single validation round, including reasks |
Step | Contains 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:
| Attribute | Description |
|---|---|
validator_name | Name of the validator class |
validator_span | OpenTelemetry span reference |
obj_id | Object identifier |
on_fail_descriptor | Policy applied on failure |
init_kwargs | Validator initialization arguments |
validation_session_id | Session 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:
| Parameter | Description |
|---|---|
name | Unique identifier for the validator |
fmt | Format ("native" or "raw") |
rail_alias | RAIL 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:
| Parameter | Type | Description |
|---|---|---|
package_uri | str | Hub package URI (e.g., hub://guardrails/regex_match) |
quiet | bool | Suppress output |
upgrade | bool | Force 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
- Error Messages: Provide clear, actionable error messages in
FailResult - Fix Values: Always provide sensible
fix_valuewhen possible - Metadata: Use metadata for context-aware validation (e.g., schema info)
- Ordering: Place more restrictive validators first for early failure
- Testing: Test both passing and failing cases for each validator
Related Components
| Component | File | Role |
|---|---|---|
| Guard | guardrails/guard.py | Main entry point for validation |
| ValidatorService | validator_service_base.py | Orchestrates validation execution |
| Call History | classes/history/call.py | Tracks validation execution history |
| Hub Install | hub/install.py | Handles validator distribution |
| Telemetry | telemetry/validator_tracing.py | Observability into validation |
Sources: guardrails/validator_service/validator_service_base.py
Schema Processing
Related topics: Guard Class Reference, Execution Pipeline
Continue reading this section for the full explanation and source context.
Continue reading this section for the full explanation and source context.
Continue reading this section for the full explanation and source context.
Continue reading this section for the full explanation and source context.
Related Pages
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 Category | Values | Description |
|---|---|---|
| SimpleTypes | STRING, INTEGER, NUMBER, BOOLEAN, ARRAY, OBJECT, NULL | JSON Schema primitive types |
| RailTypes | STRING, INTEGER, FLOAT, BOOL, DATE, TIME, DATETIME, PERCENTAGE, ENUM | RAIL-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:
| Parameter | Type | Default | Description |
|---|---|---|---|
json_schema | Dict[str, Any] | required | The JSON Schema definition to process |
validator_map | ValidatorMap | required | Mapping of validator names to implementations |
json_path | str | "$" | Current path in the JSON structure for tracking |
elem | Callable | SubElement | Element construction function |
tag_override | Optional[str] | None | Override the XML tag name |
parent | Optional[_Element] | None | Parent element for nesting |
required | Optional[str] | "true" | Whether field is required |
attributes | Optional[Dict[str, Any]] | None | Additional 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 
 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 --> HDate/Time Format Handling:
| Internal Type | XML Attribute | Purpose |
|---|---|---|
RailTypes.DATE | date-format | Custom date patterns |
RailTypes.TIME | time-format | Custom time patterns |
RailTypes.DATETIME | datetime-format | Custom 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 Format | RailTypes Value | Internal Format Attr |
|---|---|---|
| date | DATE | date-format |
| date-time | DATETIME | datetime-format |
| time | TIME | time-format |
| percentage | PERCENTAGE | (empty string) |
| STRING | - | |
| uri | STRING | - |
| uuid | STRING | - |
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: GuardResponseSchema to RAIL Conversion Rules
Type Conversions
| JSON Schema | RAIL Element | Notes |
|---|---|---|
{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:
| Option | Type | Default | Description |
|---|---|---|---|
num_reasks | int | None | Number of reasking attempts |
full_schema_reask | bool | None | Reask entire schema vs individual fields |
stream | bool | None | Enable streaming responses |
metadata | Dict[str, Any] | None | Custom 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
- Reference Dereferencing: Uses
jsonref.replace_refs()for efficient reference resolution - Lazy Element Construction: Elements are built on-demand during validation
- Validator Caching: ValidatorMap instances are reused across calls
Related Components
| Component | File Path | Purpose |
|---|---|---|
| Validator Module | guardrails/schema/validator.py | Validator implementation and mapping |
| Pydantic Schema | guardrails/schema/pydantic_schema.py | Pydantic model conversion |
| Primitive Schema | guardrails/schema/primitive_schema.py | Primitive type handling |
| Guard Class | guardrails/guard.py | High-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.
Execution Pipeline
Related topics: Guard Class Reference, Async and Streaming Support
Continue reading this section for the full explanation and source context.
Continue reading this section for the full explanation and source context.
Continue reading this section for the full explanation and source context.
Continue reading this section for the full explanation and source context.
Related Pages
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:
- Receives the raw LLM output
- Parses and extracts structured data
- Validates the output against defined validators
- Triggers reasking workflows when validation fails
- 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 Class | File | Purpose |
|---|---|---|
Runner | runner.py | Base synchronous execution handler |
StreamRunner | stream_runner.py | Handles streaming LLM responses |
AsyncRunner | async_runner.py | Manages 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:
| Parameter | Type | Description |
|---|---|---|
num_reasks | Optional[int] | Total number of reask attempts allowed |
full_schema_reask | Optional[bool] | Whether to reask entire schema or individual fields |
metadata | Optional[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| JCall 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:
- Validation Exceptions: Raised when output fails validator criteria
- Reask Exhaustion: Triggered when all reask attempts are consumed
- LLM Provider Errors: Propagated from underlying LLM calls
- Parsing Errors: Handled when LLM output cannot be parsed
Configuration Parameters
| Parameter | Location | Default | Description |
|---|---|---|---|
num_reasks | CallInputs | None | Maximum reask iterations |
full_schema_reask | CallInputs | None | Reask scope control |
prompt_params | CallInputs | {} | Template variables |
stream | CallInputs | None | Enable streaming mode |
metadata | CallInputs | None | Custom validator data |
See Also
- Guard Class - Main API entry point
- Validator System - Validation rules
- Call History - Execution tracking
- Hub Validators - Pre-built validators
Async and Streaming Support
Related topics: Execution Pipeline, LLM Provider Integration
Continue reading this section for the full explanation and source context.
Continue reading this section for the full explanation and source context.
Continue reading this section for the full explanation and source context.
Continue reading this section for the full explanation and source context.
Related Pages
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 --> D1Module Structure
The runners are organized under the guardrails.run module with the following structure:
| Module | Purpose |
|---|---|
guardrails.run.runner | Base synchronous runner |
guardrails.run.async_runner | Async execution support |
guardrails.run.stream_runner | Streaming output support |
guardrails.run.async_stream_runner | Combined async and streaming |
guardrails.run.utils | Shared 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_callmethod for making async LLM invocations - Integrates with the async validator service for non-blocking validation
- Returns
ValidationOutcomeobjects 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 ValidationOutcomeMLflow 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
| Component | Method | Instrumentation |
|---|---|---|
AsyncRunner | async_step | Async span with step type |
AsyncStreamRunner | async_step | Async + stream span attributes |
Runner.call | call | LLM span for synchronous calls |
AsyncRunner.async_call | async_call | LLM 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
| Field | Type | Description |
|---|---|---|
call_log | Call | Execution history and metadata |
validation_response | ValidationResponse | Validated and corrected output |
exception | Exception | Any 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 Case | Recommended Runner |
|---|---|
| Synchronous LLM calls | Runner |
| Async LLM calls (non-streaming) | AsyncRunner |
| Streaming LLM responses | StreamRunner |
| Async LLM calls with streaming | AsyncStreamRunner |
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.
Related Components
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:
AsyncManifestCallablefor Manifest modelsLiteLLMCallablewith 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:
- Modular Design: The runner hierarchy allows selective use of async and streaming features
- Async Compatibility: Full support for async/await patterns with Python 3.9+ compatibility
- Streaming Efficiency: Memory-efficient processing of large streaming responses
- Observability: Integrated MLflow tracing for monitoring async and streaming operations
- Type Safety: Full type hints with generic
ValidationOutcomereturns
Sources: guardrails/run/__init__.py:1-15
LLM Provider Integration
Related topics: Guard Class Reference, Framework Integrations
Continue reading this section for the full explanation and source context.
Continue reading this section for the full explanation and source context.
Continue reading this section for the full explanation and source context.
Continue reading this section for the full explanation and source context.
Related Pages
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
| Component | Purpose | File Location |
|---|---|---|
PromptCallableBase | Abstract base class defining the LLM interface contract | guardrails/classes/llm/prompt_callable.py |
LiteLLMCallable | Wrapper for LiteLLM multi-provider support | guardrails/llm_providers.py |
ManifestCallable | Wrapper for Manifest ML client | guardrails/llm_providers.py |
LLMResponse | Normalized response object | guardrails/llm_providers.py |
CallInputs | Captures invocation parameters and metadata | guardrails/classes/history/call_inputs.py |
Call | Records execution history and iterations | guardrails/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
| Method | Signature | Description |
|---|---|---|
_invoke_llm | (text, model, messages, *args, **kwargs) -> LLMResponse | Core LLM invocation method |
_prepare_prompt | (text, instructions) -> str | Prepares prompt with formatting |
Common Functionality
- Tracing Integration: All providers integrate with Guardrails' tracing system via
trace_operation()andtrace_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
streamparameter
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
| Parameter | Type | Default | Description |
|---|---|---|---|
text | Optional[str] | None | Plain text prompt |
model | str | "gpt-3.5-turbo" | Model identifier |
messages | Optional[List[Dict]] | None | Chat messages list |
*args | Any | - | Additional positional arguments |
**kwargs | Any | - | 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:
| Field | Type | Description |
|---|---|---|
output | str | The raw LLM-generated text |
model | Optional[str] | Model identifier used |
usage | Optional[Dict] | Token usage statistics |
provider | str | Source 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:
| Method | Purpose |
|---|---|
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 usedprompt_params: Parameters for prompt interpolationnum_reasks: Maximum reask attemptsmetadata: Custom data for validatorsfull_schema_reask: Whether to reask entire schemastream: Streaming mode flag
Sources: guardrails/classes/history/call.py:20-80
Error Handling
Exception Types
| Exception | Trigger | Handling |
|---|---|---|
PromptCallableException | Missing dependencies or provider errors | Wraps underlying exception with context |
ImportError | Required package not installed | Clear 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
- Use LiteLLM for Multi-Provider Support: LiteLLM provides the most flexibility for switching between providers
- Configure Prompt Parameters: Always provide
prompt_paramsfor dynamic prompt interpolation - Enable Tracing in Development: Tracing helps debug LLM interactions and validation failures
- Handle Exceptions: Wrap Guard calls in try-except blocks to handle validation failures gracefully
- 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
Continue reading this section for the full explanation and source context.
Continue reading this section for the full explanation and source context.
Continue reading this section for the full explanation and source context.
Continue reading this section for the full explanation and source context.
Related Pages
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:#fff3e0LangChain Integration
The LangChain integration provides GuardRunnable and BaseRunnable classes that wrap LangChain components, enabling validation of LLM outputs in chains and agents.
Core Components
| Component | File | Purpose |
|---|---|---|
BaseRunnable | guardrails/integrations/langchain/base_runnable.py | Base class providing LangChain-compatible runnable interface |
GuardRunnable | guardrails/integrations/langchain/guard_runnable.py | Concrete 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
Runnableinterface 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 Type | File | Description |
|---|---|---|
GuardrailsQueryEngine | guardrails/integrations/llama_index/guardrails_query_engine.py | Validates query engine responses |
GuardrailsChatEngine | guardrails/integrations/llama_index/guardrails_chat_engine.py | Validates 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
| Component | File | Purpose |
|---|---|---|
MLflowInstrumentor | guardrails/integrations/databricks/ml_flow_instrumentor.py | Auto-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
endValidation Flow
When validation fails, the integration architecture determines how to handle the failure based on the configured on_fail action:
| Action | Behavior |
|---|---|
EXCEPTION | Raises an exception with validation details |
REASK | Attempts to reask the LLM with corrected context |
FIX | Attempts to automatically fix the output |
FILTER | Filters invalid portions from the output |
CUSTOM | Invokes 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
| Integration | Option | Description |
|---|---|---|
| LangChain | guard | Guard instance for validation |
| LlamaIndex | query_engine | Base query engine to wrap |
| LlamaIndex | chat_engine | Base chat engine to wrap |
| Databricks | instrument() | Enable/disable auto-instrumentation |
Best Practices
- Centralized Guard Configuration: Define Guard instances with all required validators in a single location and reuse across integrations
- Fail Action Strategy: Choose appropriate
on_failactions based on use case criticality - Validator Ordering: Place faster validators first to fail fast on common issues
- Error Handling: Implement proper exception handling for validation failures
- Testing: Test validation logic independently before integration
Dependencies
Framework integrations have specific dependency requirements:
| Integration | Required Packages |
|---|---|
| LangChain | langchain>=0.0.XXX |
| LlamaIndex | llama-index>=0.XXX |
| Databricks | mlflow>=2.XXX, databricks-sdk |
Sources: guardrails/integrations/langchain/guard_runnable.py
Creating Custom Validators
Related topics: Validators System
Continue reading this section for the full explanation and source context.
Continue reading this section for the full explanation and source context.
Continue reading this section for the full explanation and source context.
Continue reading this section for the full explanation and source context.
Related Pages
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| GValidator Architecture
Base Class Structure
Validators inherit from Validator which provides:
- Initialization handling for
on_failpolicy - Metadata passing through validation pipeline
- Integration with the Guard validation system
Each validator must implement:
__init__: Accept initialization arguments andon_failparametervalidate: Perform validation logic and returnPassResultorFailResult
Validation Result Types
| Result Type | Purpose |
|---|---|
PassResult | Value passes validation |
FailResult | Value 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
| Section | Description |
|---|---|
| Class Definition | Inherits from Validator base class |
| Docstring | Description and usage examples |
__init__ | Initialization with custom args and on_fail |
validate | Core validation logic returning ValidationResult |
Validator Initialization Parameters
Core Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
on_fail | str or Callable | Yes | Policy when validation fails |
| Custom args | Any | Varies | Validator-specific parameters |
On Fail Actions
| Action | Behavior |
|---|---|
reask | Re-ask the LLM for corrected output |
fix | Attempt to fix the invalid value |
filter | Remove the invalid value from output |
refrain | Refrain from providing any value |
noop | No operation, continue with original value |
exception | Raise an exception |
fix_reask | Fix 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 completeThe installation service handles:
- Validating the package URI
- Fetching the manifest from Guardrails Hub
- Downloading dependencies
- 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| FValidation 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
- Single Responsibility: Each validator should check one condition
- Clear Error Messages: Provide descriptive error messages for failures
- Metadata Utilization: Leverage metadata for contextual validation
- Default Values: Set sensible defaults for optional parameters
- 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
| Command | Description |
|---|---|
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| GThe 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
Doramagic Pitfall Log
Source-linked risks stay visible on the manual page so the preview does not read like a recommendation.
First-time setup may fail or require extra isolation and rollback planning.
First-time setup may fail or require extra isolation and rollback planning.
First-time setup may fail or require extra isolation and rollback planning.
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.
Count of project-level external discussion links exposed on this manual page.
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.
- Feature request: OWASP ASI06 memory poisoning guard validator - github / github_issue
- Proposal: Agent Threat Rules detection integration - github / github_issue
- Best-practice: litellm pin excludes patched CVE versions, unverified-jwt - github / github_issue
- Lift litellm <1.82.6 pin to allow post-incident safe releases (1.83+) - github / github_issue
- [[SECURITY] Supply Chain Compromise in guardrails-ai v0.10.1 on PyPI](https://github.com/guardrails-ai/guardrails/issues/1473) - github / github_issue
- [[bug] 429 Rate Limit Error from Opting into Metrics](https://github.com/guardrails-ai/guardrails/issues/1385) - github / github_issue
- [[bug] Failures and Delayed Responses from guard.validate Method Using Di](https://github.com/guardrails-ai/guardrails/issues/1479) - github / github_issue
- [[feat] Attempt to repair JSON before triggering NonParseableReAsk](https://github.com/guardrails-ai/guardrails/issues/1380) - github / github_issue
- Feature Request: OWASP ASI06 memory write validation via Agent Memory Gu - github / github_issue
- FIX action silently mutates output - should there be a 'quarantine' tier between LOG and FIX? - GitHub / issue
- Portable evidence artifacts for validation outcomes - GitHub / issue
- Proposal: PromptDefenseAudit Hub validator โ static system prompt hardening check - GitHub / issue
Source: Project Pack community evidence and pitfall evidence