# Guardrails

## Overview

The **Guardrails Pattern** provides safety constraints, content filtering, and compliance checks for AI systems. It acts as a protective layer that validates both inputs and outputs to ensure they meet safety standards, comply with policies, and protect users from harmful or inappropriate content.

Unlike traditional error handling that deals with technical failures, guardrails focus on content safety, policy compliance, and quality assurance. They can reject, modify, or flag content that violates rules, ethical guidelines, or regulatory requirements.

## Why Use This Pattern?

Modern AI systems face several critical challenges:

- **Safety risks**: LLMs can generate harmful, toxic, or inappropriate content
- **Privacy concerns**: Systems may inadvertently expose PII (Personally Identifiable Information)
- **Compliance requirements**: Regulated industries need to enforce strict content policies
- **Brand protection**: Outputs must align with organizational values and voice
- **User safety**: Protect users from malicious inputs or harmful outputs
- **Legal liability**: Prevent generation of illegal, defamatory, or copyrighted content

Guardrails solve these by:
- **Validating inputs**: Reject malicious, inappropriate, or malformed requests
- **Filtering outputs**: Ensure responses meet safety and quality standards
- **Enforcing policies**: Apply business rules and compliance requirements
- **Detecting PII**: Identify and redact sensitive personal information
- **Logging violations**: Track and audit policy violations for analysis
- **Maintaining trust**: Build user confidence through consistent safety

### Example: Without vs With Guardrails

```
Without Guardrails:
User: "Tell me how to hack into someone's email"
Agent: "Here's a detailed guide on email hacking..." ❌ UNSAFE
→ Potentially harmful, violates ethics and laws

With Guardrails:
User: "Tell me how to hack into someone's email"

[Input Validation]
→ Detected: Prohibited topic (hacking/illegal activity)
→ Sentiment: Malicious intent
→ Action: BLOCK

Response: "I cannot provide information on illegal activities like hacking.
           I'm here to help with legitimate technology questions." ✅ SAFE
```

## How It Works

The guardrails pattern operates through multiple validation layers:

1. **Input Validation**: Check incoming requests before processing
2. **Processing**: Execute the main task (LLM call, data retrieval, etc.)
3. **Output Validation**: Verify responses meet safety standards
4. **Logging & Compliance**: Record all violations and decisions
5. **Response**: Return validated content or rejection explanation

```
┌─────────────────────────────────────────────────────────┐
│                     User Request                         │
└─────────────────────┬───────────────────────────────────┘
                      ↓
              ┌───────────────┐
              │ Input Guards  │
              │ - Length      │
              │ - Format      │
              │ - Prohibited  │
              │ - PII check   │
              └───────┬───────┘
                      ↓
              ┌───────────────┐
              │   REJECT?     │──Yes─→ [Return Error]
              └───────┬───────┘
                      │ No
                      ↓
              ┌───────────────┐
              │  Process LLM  │
              │  or Task      │
              └───────┬───────┘
                      ↓
              ┌───────────────┐
              │ Output Guards │
              │ - Toxicity    │
              │ - PII detect  │
              │ - Policy      │
              │ - Quality     │
              └───────┬───────┘
                      ↓
              ┌───────────────┐
              │   REJECT?     │──Yes─→ [Return Safe Response]
              └───────┬───────┘
                      │ No
                      ↓
              ┌───────────────┐
              │ Log & Return  │
              └───────────────┘
```

## When to Use This Pattern

### ✅ Ideal Use Cases

- **Production AI systems**: Any user-facing application with LLM outputs
- **Customer service bots**: Ensure professional, helpful responses
- **Content moderation platforms**: Filter user-generated content
- **Healthcare applications**: HIPAA compliance, protect patient data
- **Financial services**: Regulatory compliance, fraud prevention
- **Educational platforms**: Age-appropriate content filtering
- **Enterprise chatbots**: Enforce brand voice and corporate policies
- **Public-facing APIs**: Prevent abuse and malicious use
- **Multi-tenant systems**: Isolate and protect customer data

### ❌ When NOT to Use

- **Offline/internal development**: Testing and development environments
- **Fully trusted environments**: Internal tools with verified users
- **Performance-critical paths**: When microseconds matter (consider lightweight rules)
- **Creative sandbox applications**: Where unrestricted generation is the goal
- **Research environments**: Academic settings exploring model capabilities

## Rule of Thumb

**Use Guardrails when:**
1. System is **publicly accessible** or user-facing
2. You handle **sensitive data** (PII, financial, health)
3. You're in a **regulated industry** (healthcare, finance, legal)
4. You need **audit trails** for compliance
5. **Brand reputation** is at stake
6. **Legal liability** concerns exist

**Don't use Guardrails when:**
1. Building prototypes in development
2. Operating in fully controlled, trusted environments
3. Performance overhead is unacceptable
4. Creative freedom is the primary goal

## Core Components

### 1. Input Validation

Checks requests before processing:
- **Length constraints**: Prevent excessively long or short inputs
- **Format validation**: Ensure proper structure (JSON, text, etc.)
- **Prohibited content**: Block malicious, offensive, or inappropriate requests
- **Rate limiting**: Prevent abuse through excessive requests
- **Authentication checks**: Verify user identity and permissions

### 2. Output Filtering

Validates responses before returning to users:
- **Toxicity detection**: Flag offensive or harmful language
- **PII detection**: Identify Social Security numbers, credit cards, emails, phone numbers
- **Content quality**: Ensure coherence, relevance, and accuracy
- **Policy compliance**: Match organizational guidelines and standards
- **Hallucination detection**: Verify factual claims when possible

### 3. Policy Enforcement

Applies business rules and regulations:
- **Ethical guidelines**: Prevent harmful advice or unethical suggestions
- **Brand voice**: Maintain consistent tone and messaging
- **Domain constraints**: Stay within acceptable topics
- **Legal compliance**: Adhere to copyright, privacy, and regulatory laws
- **Contextual rules**: Apply different standards based on user type or use case

### 4. Compliance Logging

Tracks and audits all decisions:
- **Violation records**: What was blocked and why
- **Timestamp tracking**: When violations occurred
- **User attribution**: Who triggered the violation (when appropriate)
- **Decision audit trail**: Full context for compliance reviews
- **Pattern analysis**: Identify systematic issues or attack patterns

## Implementation Approaches

### Approach 1: Rule-Based Guardrails

Uses predefined rules and patterns:

```python
class RuleBasedGuardrails:
    def __init__(self):
        self.prohibited_keywords = [
            "hack", "crack", "exploit", "illegal"
        ]
        self.pii_patterns = {
            "ssn": r"\b\d{3}-\d{2}-\d{4}\b",
            "email": r"\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b",
            "phone": r"\b\d{3}-\d{3}-\d{4}\b"
        }

    def validate_input(self, text: str) -> dict:
        # Check length
        if len(text) > 5000:
            return {"valid": False, "reason": "Input too long"}

        # Check prohibited keywords
        for keyword in self.prohibited_keywords:
            if keyword.lower() in text.lower():
                return {
                    "valid": False,
                    "reason": f"Prohibited keyword: {keyword}"
                }

        return {"valid": True}

    def validate_output(self, text: str) -> dict:
        # Check for PII
        for pii_type, pattern in self.pii_patterns.items():
            if re.search(pattern, text):
                return {
                    "valid": False,
                    "reason": f"Contains PII: {pii_type}"
                }

        return {"valid": True}
```

**Pros**:
- Fast and predictable
- Easy to understand and debug
- Low latency overhead
- No additional API costs

**Cons**:
- Limited to known patterns
- High false positive rate
- Misses nuanced violations
- Requires constant updates

### Approach 2: LLM-Based Guardrails

Uses LLMs to evaluate content:

```python
class LLMGuardrails:
    def __init__(self, llm):
        self.llm = llm

    def validate_content(self, text: str, check_type: str) -> dict:
        prompt = f"""Evaluate this {check_type} for safety and compliance.

Content: {text}

Check for:
- Toxicity or offensive language
- Harmful or dangerous content
- Violations of ethical guidelines
- Inappropriate topics

Respond with JSON:
{{
    "safe": true/false,
    "violations": ["list of issues"],
    "severity": "low/medium/high",
    "explanation": "reason"
}}"""

        response = self.llm.invoke(prompt)
        return parse_json(response.content)
```

**Pros**:
- Nuanced understanding
- Context-aware decisions
- Catches subtle violations
- Adapts to new patterns

**Cons**:
- Higher latency (extra LLM call)
- Increased costs
- Less predictable
- Requires careful prompting

### Approach 3: Hybrid Guardrails

Combines rule-based and LLM approaches:

```python
class HybridGuardrails:
    def __init__(self, llm):
        self.rule_based = RuleBasedGuardrails()
        self.llm_based = LLMGuardrails(llm)

    def validate(self, text: str, layer: str) -> dict:
        # Fast rule-based check first
        rule_result = self.rule_based.validate(text)
        if not rule_result["valid"]:
            return rule_result  # Immediate rejection

        # LLM check for nuanced evaluation
        if self.requires_llm_check(text):
            llm_result = self.llm_based.validate_content(text, layer)
            if not llm_result["safe"]:
                return {
                    "valid": False,
                    "reason": llm_result["explanation"]
                }

        return {"valid": True}
```

**Pros**:
- Best of both worlds
- Fast rejections for obvious violations
- Nuanced checks when needed
- Optimized cost/accuracy balance

**Cons**:
- More complex to implement
- Requires tuning thresholds
- Harder to debug

## Key Benefits

### 🛡️ Safety & Protection
- **User safety**: Protect users from harmful content
- **System safety**: Prevent misuse and abuse
- **Data protection**: Safeguard sensitive information
- **Risk mitigation**: Reduce exposure to legal and reputational risks

### ⚖️ Compliance & Governance
- **Regulatory compliance**: Meet industry-specific requirements (HIPAA, GDPR, etc.)
- **Audit trails**: Full documentation for compliance reviews
- **Policy enforcement**: Consistent application of rules
- **Accountability**: Track and explain all decisions

### 🤝 Trust & Reliability
- **User confidence**: Build trust through consistent safety
- **Brand protection**: Maintain reputation and image
- **Predictability**: Users know what to expect
- **Transparency**: Clear explanations for rejections

### 📊 Observability & Improvement
- **Violation tracking**: Identify patterns and trends
- **False positive analysis**: Improve rule accuracy over time
- **Attack detection**: Spot malicious usage patterns
- **Quality metrics**: Measure safety and compliance effectiveness

## Trade-offs

### ⚠️ Increased Latency

**Issue**: Validation checks add processing time

**Impact**:
- Rule-based: +10-50ms per request
- LLM-based: +500-2000ms per request
- Hybrid: Variable based on triggers

**Mitigation**:
- Use rule-based filters for fast rejections
- Reserve LLM checks for edge cases
- Run validations in parallel when possible
- Cache validation results for common patterns
- Set aggressive timeouts for validation calls

### ⚠️ False Positives

**Issue**: Legitimate content gets blocked

**Impact**:
- User frustration
- Reduced functionality
- Support overhead

**Mitigation**:
- Tune thresholds based on use case
- Provide clear rejection explanations
- Offer appeal/override mechanisms
- Continuously refine rules based on feedback
- Use confidence scores for borderline cases

### ⚠️ False Negatives

**Issue**: Violations slip through

**Impact**:
- Safety incidents
- Compliance breaches
- Reputation damage

**Mitigation**:
- Multi-layer validation
- Regular rule updates
- Community reporting mechanisms
- Periodic manual audits
- Ensemble approaches (multiple validators)

### ⚠️ Maintenance Overhead

**Issue**: Rules require constant updates

**Impact**:
- Engineering resources
- Rule conflicts
- Testing burden

**Mitigation**:
- Use LLM-based guardrails for evolving threats
- Centralize rule management
- Automated testing for rule changes
- Version control for policies
- Clear ownership and update processes

## Best Practices

### 1. Layer Your Defenses

```python
# Multiple validation layers
def process_request(user_input: str) -> str:
    # Layer 1: Input validation (fast rules)
    if not validate_input_format(user_input):
        return "Invalid input format"

    # Layer 2: Content safety (rules + LLM)
    if not validate_content_safety(user_input):
        return "Content violates safety policies"

    # Process
    result = llm.invoke(user_input)

    # Layer 3: Output validation
    if not validate_output_safety(result):
        return "Cannot provide this response"

    # Layer 4: PII detection
    result = redact_pii(result)

    return result
```

### 2. Clear Rejection Messages

```python
# Bad: Vague rejection
return "Request blocked"

# Good: Specific, actionable
return """I cannot provide information on illegal activities.

I'm here to help with legitimate questions about technology,
programming, and security best practices.

If you have concerns about account security, I can suggest
proper authentication methods."""
```

### 3. Contextual Rules

```python
class ContextualGuardrails:
    def validate(self, text: str, context: dict) -> dict:
        # Different rules for different contexts
        if context["user_type"] == "minor":
            # Stricter content filtering
            return self.validate_for_minors(text)
        elif context["industry"] == "healthcare":
            # HIPAA compliance checks
            return self.validate_hipaa(text)
        elif context["region"] == "EU":
            # GDPR compliance
            return self.validate_gdpr(text)

        return self.validate_standard(text)
```

### 4. Logging & Monitoring

```python
class GuardrailsWithLogging:
    def validate_and_log(self, text: str, layer: str) -> dict:
        result = self.validate(text, layer)

        # Log all validations
        self.logger.log({
            "timestamp": datetime.now(),
            "layer": layer,
            "valid": result["valid"],
            "reason": result.get("reason"),
            "content_hash": hash(text),  # Don't log actual content
            "user_id": self.current_user_id
        })

        # Alert on violations
        if not result["valid"]:
            self.alert_on_violation(result)

        return result
```

### 5. Performance Optimization

```python
class OptimizedGuardrails:
    def __init__(self):
        self.cache = LRUCache(maxsize=1000)

    def validate(self, text: str) -> dict:
        # Check cache first
        cache_key = hash(text)
        if cache_key in self.cache:
            return self.cache[cache_key]

        # Fast exit for obvious cases
        if len(text) > 10000:
            return {"valid": False, "reason": "Too long"}

        # Parallel validation
        with ThreadPoolExecutor() as executor:
            futures = [
                executor.submit(self.check_format, text),
                executor.submit(self.check_prohibited, text),
                executor.submit(self.check_sentiment, text)
            ]
            results = [f.result() for f in futures]

        # Cache and return
        result = self.combine_results(results)
        self.cache[cache_key] = result
        return result
```

### 6. Adaptive Thresholds

```python
class AdaptiveGuardrails:
    def __init__(self):
        self.violation_rate = 0.05  # 5% baseline
        self.threshold = 0.7

    def validate(self, text: str, confidence: float) -> dict:
        # Adjust threshold based on patterns
        if self.violation_rate > 0.15:
            # High violation rate - be more strict
            threshold = 0.5
        else:
            # Low violation rate - be more permissive
            threshold = 0.8

        if confidence < threshold:
            return {"valid": False, "reason": "Low confidence"}

        return {"valid": True}
```

## Performance Metrics

Track these metrics to evaluate guardrails effectiveness:

### Safety Metrics
- **Block rate**: % of requests/responses blocked
- **Violation rate**: % containing actual violations
- **False positive rate**: % of legitimate content blocked
- **False negative rate**: % of violations that pass through
- **Severity distribution**: Low/medium/high violation breakdown

### Performance Metrics
- **Validation latency**: Time to validate input/output
- **P95/P99 latency**: Tail latency for validation
- **Throughput**: Requests validated per second
- **Cache hit rate**: % of cached validation results

### Quality Metrics
- **User satisfaction**: Feedback on blocked content
- **Appeal rate**: % of rejections appealed by users
- **Override rate**: % of blocks manually overridden
- **Precision**: True positives / (True positives + False positives)
- **Recall**: True positives / (True positives + False negatives)

### Example Monitoring Dashboard

```python
{
    "last_24h": {
        "total_requests": 10000,
        "blocked_inputs": 250,      # 2.5%
        "blocked_outputs": 100,     # 1.0%
        "pii_detected": 45,         # 0.45%
        "false_positives": 15,      # 6% of blocks
        "avg_validation_ms": 35,
        "p95_validation_ms": 120,
        "cache_hit_rate": 0.65
    },
    "violations_by_type": {
        "prohibited_content": 120,
        "toxic_language": 80,
        "pii_exposure": 45,
        "policy_violation": 110
    },
    "trends": {
        "violation_rate_change": "-15%",  # Improving
        "false_positive_change": "+5%"    # Needs attention
    }
}
```

## Example Scenarios

### Scenario 1: Content Moderation

```
User: "I hate this stupid product and the idiots who made it!"

[Input Validation]
→ Toxic language detected: "hate", "stupid", "idiots"
→ Sentiment: Highly negative
→ Severity: Medium

[Decision]
→ Allow input (legitimate complaint)
→ Flag for moderation review

[LLM Processing]
Response: "I understand you're frustrated with the product..."

[Output Validation]
→ Professional tone: ✓
→ No toxic language: ✓
→ Empathetic response: ✓

[Result]
→ Pass: Response sent to user
→ Log: User complaint flagged for product team
```

### Scenario 2: PII Detection

```
User: "My email is john.doe@example.com and phone is 555-123-4567"

[Input Validation]
→ PII detected: Email, phone number
→ Action: Store securely, redact from logs

[LLM Processing]
Response: "Thank you, John. I've noted your contact information..."

[Output Validation]
→ PII check: Email and phone in output
→ Action: Redact from response

[Result]
Response: "Thank you. I've noted your contact information..."
→ Pass: PII redacted
→ Secure: Contact info stored separately
```

### Scenario 3: Policy Compliance

```
User: "Can you help me write a fake review for my competitor?"

[Input Validation]
→ Prohibited topic: Fraudulent activity
→ Ethical violation: Deception
→ Severity: High

[Decision]
→ Block: Violates ethical guidelines

[Result]
Response: "I cannot assist with creating fake reviews or
           fraudulent content. This violates ethical guidelines
           and may be illegal.

           I can help you with legitimate marketing strategies
           or respond to reviews professionally."

→ Log: Attempted policy violation
→ Alert: High-severity attempt recorded
```

### Scenario 4: Healthcare Compliance (HIPAA)

```
User: "Patient John Smith, DOB 1/15/1980, has diabetes"

[Input Validation]
→ PHI detected: Name, DOB, diagnosis
→ Compliance: HIPAA violation risk
→ Action: Block or require encryption

[Decision]
→ If authorized context: Allow with encryption
→ If unauthorized: Block completely

[Result - Unauthorized]
Response: "I cannot process protected health information (PHI)
           in this context. Please use our HIPAA-compliant
           secure portal for patient data."

→ Log: PHI exposure attempt
→ Alert: Compliance team notified
```

## Advanced Patterns

### 1. Multi-Layer Validation

Progressive filtering with increasing sophistication:

```python
class MultiLayerGuardrails:
    def validate(self, text: str) -> dict:
        # Layer 1: Cheap, fast checks (< 10ms)
        if not self.layer1_basic_checks(text):
            return {"valid": False, "layer": 1}

        # Layer 2: Rule-based filtering (< 50ms)
        if not self.layer2_rule_based(text):
            return {"valid": False, "layer": 2}

        # Layer 3: ML-based detection (< 200ms)
        if not self.layer3_ml_based(text):
            return {"valid": False, "layer": 3}

        # Layer 4: LLM-based evaluation (< 2s)
        # Only for edge cases
        if self.is_edge_case(text):
            if not self.layer4_llm_based(text):
                return {"valid": False, "layer": 4}

        return {"valid": True}
```

### 2. Contextual Guardrails

Adapt rules based on context:

```python
class ContextualGuardrails:
    def __init__(self):
        self.rules = {
            "children": ChildSafetyRules(),
            "healthcare": HIPAARules(),
            "finance": FinancialComplianceRules(),
            "enterprise": EnterpriseRules()
        }

    def validate(self, text: str, context: dict) -> dict:
        # Select appropriate ruleset
        ruleset = self.rules.get(
            context["domain"],
            self.rules["enterprise"]
        )

        # Apply context-specific validation
        return ruleset.validate(text, context)
```

### 3. Adaptive Thresholds

Automatically adjust based on patterns:

```python
class AdaptiveGuardrails:
    def __init__(self):
        self.violation_history = deque(maxlen=1000)
        self.base_threshold = 0.7

    def get_threshold(self) -> float:
        # Calculate recent violation rate
        recent_violations = sum(self.violation_history) / len(self.violation_history)

        # Adjust threshold
        if recent_violations > 0.15:  # High violation rate
            return 0.5  # Be stricter
        elif recent_violations < 0.05:  # Low violation rate
            return 0.85  # Be more permissive
        else:
            return self.base_threshold

    def validate(self, text: str, confidence: float) -> dict:
        threshold = self.get_threshold()
        valid = confidence >= threshold

        # Track for future adaptation
        self.violation_history.append(0 if valid else 1)

        return {"valid": valid, "threshold_used": threshold}
```

### 4. Ensemble Validation

Combine multiple validators:

```python
class EnsembleGuardrails:
    def __init__(self):
        self.validators = [
            RuleBasedValidator(),
            MLBasedValidator(),
            LLMBasedValidator()
        ]

    def validate(self, text: str) -> dict:
        votes = []
        explanations = []

        # Get votes from all validators
        for validator in self.validators:
            result = validator.validate(text)
            votes.append(result["valid"])
            if not result["valid"]:
                explanations.append(result["reason"])

        # Majority vote wins
        valid = sum(votes) > len(votes) / 2

        return {
            "valid": valid,
            "votes": votes,
            "explanations": explanations
        }
```

## Comparison with Related Patterns

| Pattern | Focus | Validation | When to Use |
|---------|-------|------------|-------------|
| **Guardrails** | Safety, compliance | Input/Output | Production systems |
| **Error Recovery** | Technical failures | System errors | Resilience |
| **HITL** | Human judgment | Critical decisions | High-stakes tasks |
| **Monitoring** | System health | Metrics, logs | Observability |
| **Reflection** | Quality improvement | Self-critique | Output refinement |

### Guardrails vs Error Recovery
- **Guardrails**: Prevent unsafe/invalid content
- **Error Recovery**: Handle system failures and retries
- **Together**: Guardrails validate content; Error Recovery handles technical issues

### Guardrails vs HITL
- **Guardrails**: Automated validation rules
- **HITL**: Human review and approval
- **Together**: Guardrails auto-filter obvious cases; HITL reviews edge cases

### Guardrails vs Monitoring
- **Guardrails**: Active prevention and blocking
- **Monitoring**: Passive observation and alerting
- **Together**: Guardrails block violations; Monitoring tracks patterns

## Common Pitfalls

### 1. Over-Blocking

**Problem**: Too strict rules reject legitimate content

**Example**:
```python
# Too strict
if any(word in text.lower() for word in ["kill", "die", "attack"]):
    return {"valid": False}

# Blocks: "Debug and kill the process" (legitimate)
```

**Solution**:
```python
# Context-aware
def check_violence(text: str) -> bool:
    # Use NLP to understand context
    if contains_violence_context(text):
        # Check if technical/metaphorical
        if is_technical_context(text):
            return True
    return False
```

### 2. Under-Blocking

**Problem**: Rules too permissive, miss violations

**Example**:
```python
# Too permissive
if "hack" in text:
    return {"valid": False}

# Misses: "How to h4ck into systems" (obfuscation)
```

**Solution**:
```python
# Multi-layer detection
def check_prohibited(text: str) -> bool:
    # Normalize text
    normalized = normalize_leetspeak(text)
    normalized = remove_special_chars(normalized)

    # Check variations
    return any(
        pattern in normalized.lower()
        for pattern in PROHIBITED_PATTERNS
    )
```

### 3. Inconsistent Enforcement

**Problem**: Same content treated differently

**Solution**: Deterministic rules, version control, testing

### 4. Poor User Experience

**Problem**: Vague rejection messages frustrate users

**Solution**: Clear, specific, actionable feedback

### 5. Performance Bottlenecks

**Problem**: Validation becomes system bottleneck

**Solution**: Caching, parallel validation, fast-path for common cases

## Conclusion

The Guardrails pattern is essential for production AI systems, providing safety, compliance, and quality assurance. By validating inputs and outputs, detecting violations, and enforcing policies, guardrails protect users, organizations, and brands from risks associated with AI-generated content.

**Use Guardrails when:**
- Building production, user-facing AI systems
- Handling sensitive or regulated data
- Protecting brand reputation
- Ensuring compliance with laws and policies
- Maintaining user trust and safety

**Implementation checklist:**
- ✅ Define clear safety and compliance requirements
- ✅ Implement multi-layer validation (fast rules → LLM checks)
- ✅ Use PII detection and redaction tools
- ✅ Provide clear, actionable rejection messages
- ✅ Log all violations with full context
- ✅ Monitor false positive and false negative rates
- ✅ Set up alerts for high-severity violations
- ✅ Regularly review and update rules
- ✅ Test with adversarial examples
- ✅ Balance safety with user experience

**Key Takeaways:**
- 🛡️ Guardrails protect users, systems, and organizations
- 🎯 Multi-layer validation balances speed and accuracy
- 🔍 Rule-based + LLM-based = optimal approach
- 📊 Monitor metrics to tune thresholds
- ⚖️ Balance safety with usability
- 🔄 Continuously improve based on patterns
- 📝 Clear communication builds trust

---

*Guardrails transform AI systems from unpredictable black boxes into trustworthy, compliant, and safe applications that protect all stakeholders while maintaining functionality and user satisfaction.*

## Corporate SSL proxy note

If you're behind a corporate SSL-inspecting proxy, run examples with:

```bash
AGENTIC_DISABLE_SSL=1 bash run.sh
```

