> ## Documentation Index
> Fetch the complete documentation index at: https://docs.praison.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Agent Guardrails

> LLM-based output validation and quality assurance for task outputs

## Overview

Guardrails provide a powerful validation and quality assurance layer for task outputs in PraisonAI. They allow you to define validation criteria that are checked against task results, ensuring outputs meet specific requirements before being accepted.

```mermaid theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
flowchart LR
    subgraph Task Execution
        A[Agent] --> B[Execute Task]
        B --> C[Generate Output]
    end
    
    subgraph Guardrail Validation
        C --> D{Guardrail Check}
        D -->|Pass| E[Accept Output]
        D -->|Fail| F[Retry/Reject]
        F --> G[Error Message]
        F -.->|Retry| B
    end
    
    style D fill:#f9a825,color:#000
    style E fill:#4caf50,color:#fff
    style F fill:#f44336,color:#fff
```

## Types of Guardrails

<CardGroup cols={2}>
  <Card title="Function Guardrails" icon="code">
    Python functions that programmatically validate outputs with precise control
  </Card>

  <Card title="LLM Guardrails" icon="brain">
    Use natural language criteria evaluated by an LLM for flexible validation
  </Card>
</CardGroup>

## Quick Start

<Tabs>
  <Tab title="Function Guardrail">
    ```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
    from praisonaiagents import Agent, Task

    def validate_length(output):
        """Ensure output is between 100-500 characters"""
        length = len(output.raw)
        if 100 <= length <= 500:
            return (True, output)  # Pass: (success, result)
        else:
            return (False, f"Output must be 100-500 chars, got {length}")  # Fail: (success, error)

    task = Task(
        description="Write a product description",
        agent=agent,
        guardrails=validate_length
    )
    ```
  </Tab>

  <Tab title="String Guardrail">
    ```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
    from praisonaiagents import Agent, Task

    # LLM evaluates this criteria automatically
    task = Task(
        description="Write marketing copy",
        agent=agent,
        guardrails="Check if professional, no offensive language, includes 3+ benefits"
    )
    ```
  </Tab>
</Tabs>

## API Reference

### GuardrailResult

The return type for guardrail validation functions.

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
class GuardrailResult:
    success: bool   # Whether the validation passed
    result: Any     # Modified output if any, or None
    error: str      # Error message if failed (default: "")
```

### LLMGuardrail

Creates an LLM-based guardrail for natural language validation.

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
LLMGuardrail(
    criteria: str,                    # Natural language validation criteria
    llm_model: str = "gpt-4",        # LLM model to use
    temperature: float = 0.1,         # Low temperature for consistency
    max_tokens: int = 100            # Token limit for response
)
```

### Task Parameters

Configure guardrails on tasks:

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
Task(
    description: str,
    agent: Agent,
    guardrails: Union[Callable, LLMGuardrail, str, None] = None,
    max_retries: int = 3,  # Max retries if guardrail fails
    expected_output: str = None
)
```

## Implementation Examples

### Basic Validation

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
def validate_email_format(output: str) -> GuardrailResult:
    """Ensure output contains valid email addresses"""
    import re
    email_pattern = r'\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b'
    
    if re.search(email_pattern, output):
        return GuardrailResult(
            success=True,
            error="Valid email found in output"
        )
    else:
        return GuardrailResult(
            success=False,
            error="Output must contain at least one valid email address"
        )

# Use with task
task = Task(
    description="Extract contact emails from the document",
    agent=data_agent,
    guardrails=validate_email_format
)
```

### Complex Structure Validation

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
def validate_json_structure(output: str) -> GuardrailResult:
    """Validate JSON output has required fields"""
    import json
    
    try:
        data = json.loads(output)
        required_fields = ["title", "summary", "tags", "date"]
        
        missing = [f for f in required_fields if f not in data]
        if missing:
            return GuardrailResult(
                success=False,
                message=f"Missing required fields: {', '.join(missing)}"
            )
        
        if not isinstance(data.get("tags"), list):
            return GuardrailResult(
                success=False,
                error="'tags' must be a list"
            )
        
        return GuardrailResult(
            success=True,
            error="JSON structure is valid"
        )
        
    except json.JSONDecodeError as e:
        return GuardrailResult(
            success=False,
            message=f"Invalid JSON: {str(e)}"
        )
```

### LLM-based Content Validation

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
# Create sophisticated content guardrail
content_guardrail = LLMGuardrail(
    criteria="""
    Evaluate the output based on:
    
    1. Accuracy: Information should be factually correct
    2. Completeness: All requested points should be addressed
    3. Clarity: Language should be clear and unambiguous
    4. Tone: Professional but approachable
    5. Structure: Well-organized with clear sections
    
    The output should NOT contain:
    - Personal opinions presented as facts
    - Promotional language or bias
    - Technical jargon without explanation
    - Grammatical or spelling errors
    
    Rate as VALID only if all criteria are met.
    """,
    llm_model="gpt-4",
    temperature=0.1
)

# Apply to content generation task
task = Task(
    description="Write a technical blog post about cloud computing",
    agent=writer_agent,
    guardrails=content_guardrail,
    max_retries=2
)
```

### Output Modification Guardrails

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
def sanitize_pii(output: str) -> GuardrailResult:
    """Remove personally identifiable information"""
    import re
    
    # Check for PII patterns
    ssn_pattern = r'\b\d{3}-\d{2}-\d{4}\b'
    if re.search(ssn_pattern, output):
        # Modify output to remove PII
        sanitized = re.sub(ssn_pattern, '[SSN-REDACTED]', output)
        return GuardrailResult(
            success=True,
            message=f"PII removed. Modified output: {sanitized}"
        )
    
    return GuardrailResult(
        success=True,
        error="No PII detected"
    )
```

## Creating an Implementation Guide

### Step 1: Identify Validation Needs

Determine what aspects of the output need validation:

* Format requirements (JSON, XML, Markdown)
* Content requirements (specific information, tone)
* Security concerns (no sensitive data, safe content)
* Business rules (pricing limits, compliance)

### Step 2: Choose Guardrail Type

<Table>
  <TableHeader>
    <TableRow>
      <TableHeaderCell>Use Function Guardrails When</TableHeaderCell>
      <TableHeaderCell>Use LLM Guardrails When</TableHeaderCell>
    </TableRow>
  </TableHeader>

  <TableBody>
    <TableRow>
      <TableCell>Validation rules are clear and programmatic</TableCell>
      <TableCell>Validation requires judgment or context</TableCell>
    </TableRow>

    <TableRow>
      <TableCell>Performance is critical</TableCell>
      <TableCell>Natural language criteria are easier to define</TableCell>
    </TableRow>

    <TableRow>
      <TableCell>Deterministic results needed</TableCell>
      <TableCell>Flexibility in interpretation is valuable</TableCell>
    </TableRow>

    <TableRow>
      <TableCell>Checking formats, patterns, or calculations</TableCell>
      <TableCell>Evaluating quality, tone, or completeness</TableCell>
    </TableRow>
  </TableBody>
</Table>

### Step 3: Implement Guardrails

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
from praisonaiagents import Agent, Task, GuardrailResult, LLMGuardrail

# Example: E-commerce product description validation
def validate_product_description(output: str) -> GuardrailResult:
    """Validate product descriptions meet requirements"""
    
    # Check minimum length
    if len(output) < 50:
        return GuardrailResult(
            success=False,
            error="Description too short (min 50 characters)"
        )
    
    # Check for required elements
    required_words = ["features", "benefits", "specifications"]
    missing = [w for w in required_words if w.lower() not in output.lower()]
    
    if missing:
        return GuardrailResult(
            success=False,
            message=f"Missing sections: {', '.join(missing)}"
        )
    
    # Check for price format
    import re
    price_pattern = r'\$\d+\.?\d{0,2}'
    if not re.search(price_pattern, output):
        return GuardrailResult(
            success=False,
            error="Must include price in format $XX.XX"
        )
    
    return GuardrailResult(
        success=True,
        error="Product description meets all requirements"
    )

# Combine with LLM guardrail for quality
quality_guardrail = LLMGuardrail(
    criteria="""
    Check if the product description:
    1. Is engaging and persuasive
    2. Highlights unique selling points
    3. Uses active voice
    4. Avoids superlatives without evidence
    5. Includes sensory details where appropriate
    """
)

# Create agent and tasks
product_agent = Agent(
    name="ProductWriter",
    role="E-commerce Copywriter"
)

# Task with multiple validation steps
description_task = Task(
    description="Write product description for wireless headphones",
    agent=product_agent,
    guardrails=validate_product_description  # Format validation
)

quality_task = Task(
    description="Enhance the description for engagement",
    agent=product_agent,
    guardrails=quality_guardrail,  # Quality validation
    context=[description_task]
)
```

## Best Practices

<CardGroup cols={2}>
  <Card title="Clear Validation Criteria" icon="check-circle">
    * Be specific about what constitutes valid output
    * Provide examples of valid and invalid outputs
    * Consider edge cases and exceptions
    * Document validation rules clearly
  </Card>

  <Card title="Balanced Strictness" icon="balance-scale">
    * Too strict: May cause excessive retries
    * Too lenient: May accept poor quality outputs
    * Test with various inputs to find the right balance
    * Consider allowing partial success where appropriate
  </Card>

  <Card title="Helpful Error Messages" icon="comment-dots">
    * Clearly explain why validation failed
    * Suggest how to fix the issue
    * Include specific examples when helpful
    * Avoid generic error messages
  </Card>

  <Card title="Retry Configuration" icon="redo">
    * Default is 3 retries, adjust based on task complexity
    * Consider the cost of retries (API calls, time)
    * Some tasks may benefit from no retries
    * Log retry attempts for debugging
  </Card>
</CardGroup>

## Common Use Cases

### Content Moderation

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
moderation_guardrail = LLMGuardrail(
    criteria="""
    Ensure the content is appropriate for all audiences:
    - No profanity or offensive language
    - No discriminatory or biased statements  
    - No violence or graphic descriptions
    - Maintains respectful tone throughout
    """
)
```

### Data Format Validation

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
def validate_csv_output(output: str) -> GuardrailResult:
    """Ensure output is valid CSV with required columns"""
    import csv
    import io
    
    try:
        reader = csv.DictReader(io.StringIO(output))
        required_columns = ["name", "email", "phone", "address"]
        
        if not all(col in reader.fieldnames for col in required_columns):
            return GuardrailResult(
                success=False,
                message=f"Missing columns. Required: {required_columns}"
            )
        
        return GuardrailResult(success=True, error="Valid CSV format")
        
    except Exception as e:
        return GuardrailResult(
            success=False,
            message=f"Invalid CSV: {str(e)}"
        )
```

### Compliance Checking

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
compliance_guardrail = LLMGuardrail(
    criteria="""
    Verify the output complies with GDPR requirements:
    1. Includes privacy policy reference
    2. Mentions data retention period
    3. Explains user rights (access, deletion, portability)
    4. Identifies data controller
    5. No unnecessary personal data collection
    """
)
```

### Quality Control

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
def validate_code_quality(output: str) -> GuardrailResult:
    """Check generated code meets quality standards"""
    
    # Check for common issues
    if "eval(" in output or "exec(" in output:
        return GuardrailResult(
            success=False,
            error="Unsafe functions (eval/exec) detected"
        )
    
    # Check indentation
    lines = output.split('\n')
    if any(line.startswith(' ') and len(line) - len(line.lstrip()) % 4 != 0 
           for line in lines):
        return GuardrailResult(
            success=False,
            error="Inconsistent indentation (use 4 spaces)"
        )
    
    return GuardrailResult(
        success=True,
        error="Code meets quality standards"
    )
```

## Real-world Example

### Financial Report Validation

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
from praisonaiagents import Agent, Task, AgentTeam, GuardrailResult, LLMGuardrail
import json
import re

def validate_financial_report(output: str) -> GuardrailResult:
    """Validate financial report structure and calculations"""
    try:
        report = json.loads(output)
        
        # Check required sections
        required_sections = ["revenue", "expenses", "profit", "summary"]
        missing = [s for s in required_sections if s not in report]
        if missing:
            return GuardrailResult(
                success=False,
                message=f"Missing sections: {missing}"
            )
        
        # Validate calculations
        revenue = report.get("revenue", {}).get("total", 0)
        expenses = report.get("expenses", {}).get("total", 0)
        stated_profit = report.get("profit", {}).get("total", 0)
        calculated_profit = revenue - expenses
        
        if abs(stated_profit - calculated_profit) > 0.01:
            return GuardrailResult(
                success=False,
                message=f"Profit calculation error: stated {stated_profit}, should be {calculated_profit}"
            )
        
        # Check for negative values where inappropriate
        if revenue < 0:
            return GuardrailResult(
                success=False,
                error="Revenue cannot be negative"
            )
        
        return GuardrailResult(
            success=True,
            error="Financial report validated successfully"
        )
        
    except Exception as e:
        return GuardrailResult(
            success=False,
            message=f"Report validation error: {str(e)}"
        )

# LLM guardrail for report quality
report_quality_guardrail = LLMGuardrail(
    criteria="""
    Evaluate the financial report for:
    1. Clear executive summary with key insights
    2. Proper context for all numbers (YoY growth, percentages)
    3. Risk factors and mitigation strategies mentioned
    4. Future outlook based on current trends
    5. Professional language appropriate for stakeholders
    6. No speculation presented as fact
    """
)

# Create workflow
analyst = Agent(
    name="FinancialAnalyst",
    role="Senior Financial Analyst",
    goal="Create accurate financial reports"
)

# Multi-step validation
generate_report = Task(
    description="Generate Q4 financial report from data",
    agent=analyst,
    guardrails=validate_financial_report,  # Structural validation
    max_retries=2
)

enhance_report = Task(
    description="Add analysis and insights to the report",
    agent=analyst,
    guardrails=report_quality_guardrail,  # Quality validation
    context=[generate_report]
)

# Execute workflow
workflow = AgentTeam(
    agents=[analyst],
    tasks=[generate_report, enhance_report]
)

result = workflow.start()
```

## Summary

Guardrails in PraisonAI provide:

✅ **Output Validation** - Ensure task outputs meet specific criteria\
✅ **Quality Assurance** - Maintain consistent quality standards\
✅ **Error Prevention** - Catch issues before they propagate\
✅ **Flexible Implementation** - Use functions or LLMs for validation\
✅ **Automatic Retries** - Built-in retry mechanism for failed validations

Use guardrails whenever you need:

* Structured output validation
* Content quality checks
* Compliance verification
* Security and safety checks
* Business rule enforcement
