Guardrails

Eingabe-/Ausgabevalidierung und Inhaltssicherheit mit adk-guardrail.

Übersicht

Guardrails validieren und transformieren Agent-Eingaben und -Ausgaben, um Sicherheit, Konformität und Qualität zu gewährleisten. Sie laufen parallel zur Agent-Ausführung und können:

  • Schädliche oder themenfremde Inhalte blockieren
  • PII (E-Mails, Telefonnummern, SSNs, Kreditkarten) unkenntlich machen
  • JSON-Schema für Ausgaben erzwingen
  • Inhaltslänge begrenzen

Installation

[dependencies]
adk-guardrail = "0.2.0"

# Für die JSON-Schema-Validierung
adk-guardrail = { version = "0.2.0", features = ["schema"] }

Kernkonzepte

GuardrailResult

Jeder Guardrail gibt eines von drei Ergebnissen zurück:

pub enum GuardrailResult {
    Pass,                                    // Inhalt ist gültig
    Fail { reason: String, severity: Severity },  // Inhalt abgelehnt
    Transform { new_content: Content, reason: String },  // Inhalt modifiziert
}

Schweregrade

pub enum Severity {
    Low,      // Nur Warnung, blockiert nicht
    Medium,   // Blockiert, setzt aber andere Prüfungen fort
    High,     // Blockiert sofort
    Critical, // Blockiert und schlägt sofort fehl
}

PII-Unkenntlichmachung

Automatische Erkennung und Unkenntlichmachung von persönlich identifizierbaren Informationen:

use adk_guardrail::{PiiRedactor, PiiType};

// Standard: E-Mails, Telefonnummern, SSNs, Kreditkarten
let redactor = PiiRedactor::new();

// Oder bestimmte Typen auswählen
let redactor = PiiRedactor::with_types(&[
    PiiType::Email,
    PiiType::Phone,
]);

// Direkte Unkenntlichmachung
let (redacted, found_types) = redactor.redact("Email: test@example.com");
// redacted = "Email: [EMAIL REDACTED]"
// found_types = [PiiType::Email]

Unterstützte PII-Typen:

TypMusterUnkenntlichmachung
Emailuser@domain.com[E-MAIL UNKENNTLICH GEMACHT]
Phone555-123-4567[TELEFON UNKENNTLICH GEMACHT]
Ssn123-45-6789[SSN UNKENNTLICH GEMACHT]
CreditCard4111-1111-1111-1111[KREDITKARTE UNKENNTLICH GEMACHT]
IpAddress192.168.1.1[IP UNKENNTLICH GEMACHT]

Inhaltsfilterung

Schädliche Inhalte blockieren oder Themenbeschränkungen erzwingen:

use adk_guardrail::ContentFilter;

// Schädliche Inhaltmuster blockieren
let filter = ContentFilter::harmful_content();

// Spezifische Schlüsselwörter blockieren
let filter = ContentFilter::blocked_keywords(vec![
    "forbidden".into(),
    "banned".into(),
]);

// Themenrelevanz erzwingen
let filter = ContentFilter::on_topic("cooking", vec![
    "recipe".into(),
    "cook".into(),
    "bake".into(),
]);

// Inhaltslänge begrenzen
let filter = ContentFilter::max_length(1000);

Benutzerdefinierter Inhaltsfilter

use adk_guardrail::{ContentFilter, ContentFilterConfig, Severity};

let config = ContentFilterConfig {
    blocked_keywords: vec!["spam".into()],
    required_topics: vec!["rust".into(), "programming".into()],
    max_length: Some(5000),
    min_length: Some(10),
    severity: Severity::High,
};

let filter = ContentFilter::new("custom_filter", config);

Schema-Validierung

JSON-Schema für Agent-Ausgaben erzwingen (erfordert das schema-Feature):

use adk_guardrail::SchemaValidator;
use serde_json::json;

let schema = json!({
    "type": "object",
    "properties": {
        "name": { "type": "string" },
        "age": { "type": "integer", "minimum": 0 }
    },
    "required": ["name"]
});

let validator = SchemaValidator::new(&schema)?
    .with_name("user_schema")
    .with_severity(Severity::High);

Der Validator extrahiert JSON aus:

  • Rohem JSON-Text
  • Markdown-Codeblöcken (```json ... ```)

GuardrailSet

Mehrere Guardrails kombinieren:

use adk_guardrail::{GuardrailSet, ContentFilter, PiiRedactor};

let guardrails = GuardrailSet::new()
    .with(ContentFilter::harmful_content())
    .with(ContentFilter::max_length(5000))
    .with(PiiRedactor::new());

GuardrailExecutor

Führen Sie Guardrails aus und erhalten Sie detaillierte Ergebnisse:

use adk_guardrail::{GuardrailExecutor, GuardrailSet, PiiRedactor};
use adk_core::Content;

let guardrails = GuardrailSet::new()
    .with(PiiRedactor::new());

let content = Content::new("user")
    .with_text("Contact: test@example.com");

let result = GuardrailExecutor::run(&guardrails, &content).await?;

if result.passed {
    // Use transformed content if available
    let final_content = result.transformed_content.unwrap_or(content);
    println!("Content passed validation");
} else {
    for (name, reason, severity) in &result.failures {
        println!("Guardrail '{}' failed: {} ({:?})", name, reason, severity);
    }
}

ExecutionResult

pub struct ExecutionResult {
    pub passed: bool,                              // Gesamtstatus bestanden/fehlgeschlagen
    pub transformed_content: Option<Content>,      // Modifizierter Inhalt (falls vorhanden)
    pub failures: Vec<(String, String, Severity)>, // (Name, Grund, Schweregrad)
}

Benutzerdefinierte Guardrails

Implementieren Sie das Guardrail-Trait:

use adk_guardrail::{Guardrail, GuardrailResult, Severity};
use adk_core::Content;
use async_trait::async_trait;

pub struct ProfanityFilter {
    words: Vec<String>,
}

#[async_trait]
impl Guardrail for ProfanityFilter {
    fn name(&self) -> &str {
        "profanity_filter"
    }

    async fn validate(&self, content: &Content) -> GuardrailResult {
        let text: String = content.parts
            .iter()
            .filter_map(|p| p.text())
            .collect();

        for word in &self.words {
            if text.to_lowercase().contains(word) {
                return GuardrailResult::Fail {
                    reason: format!("Contains profanity: {}", word),
                    severity: Severity::High,
                };
            }
        }

        GuardrailResult::Pass
    }

    // Parallel zu anderen Guardrails ausführen (Standard: true)
    fn run_parallel(&self) -> bool {
        true
    }

    // Bei einem Fehler dieser Guardrail sofort abbrechen (Standard: true)
    fn fail_fast(&self) -> bool {
        true
    }
}

Integration mit Agents

Guardrails integrieren sich mit LlmAgentBuilder:

use adk_agent::LlmAgentBuilder;
use adk_guardrail::{GuardrailSet, ContentFilter, PiiRedactor};

let input_guardrails = GuardrailSet::new()
    .with(ContentFilter::harmful_content())
    .with(PiiRedactor::new());

let output_guardrails = GuardrailSet::new()
    .with(SchemaValidator::new(&output_schema)?);

let agent = LlmAgentBuilder::new("assistant")
    .model(model)
    .instruction("You are a helpful assistant.")
    .input_guardrails(input_guardrails)
    .output_guardrails(output_guardrails)
    .build()?;

Ausführungsfluss

User Input
    │
    ▼
┌─────────────────────┐
│  Input Guardrails   │ ← PII-Redaktion, Inhaltsfilterung
│  (parallel)         │
└─────────────────────┘
    │
    ▼ (transformiert oder blockiert)
┌─────────────────────┐
│  Agent Execution    │
└─────────────────────┘
    │
    ▼
┌─────────────────────┐
│  Output Guardrails  │ ← Schema-Validierung, Sicherheitsprüfungen
│  (parallel)         │
└─────────────────────┘
    │
    ▼
Final Response

Beispiele

# Grundlegende PII- und Inhaltsfilterung
cargo run --example guardrail_basic --features guardrails

# JSON-Schema-Validierung
cargo run --example guardrail_schema --features guardrails

# Vollständige Agent-Integration
cargo run --example guardrail_agent --features guardrails

Best Practices

PraxisBeschreibung
Leitplanken schichtenVerwenden Sie Eingabe-Leitplanken für die Sicherheit, Ausgabe-Leitplanken für die Qualität
personenbezogene Daten bei der EingabeRedigieren Sie personenbezogene Daten, bevor sie das Modell erreichen
Schema bei der AusgabeValidieren Sie strukturierte Ausgaben mit JSON-Schema
Angemessener SchweregradVerwenden Sie Kritisch sparsam, Niedrig für Warnungen
Gründlich testenLeitplanken sind sicherheitskritischer Code

Zurück: ← Zugriffssteuerung | Weiter: Speicher →