Barreiras de proteção

Validação de entrada/saída e segurança de conteúdo usando adk-guardrail.

Visão geral

As barreiras de proteção validam e transformam as entradas e saídas do agente para garantir segurança, conformidade e qualidade. Elas são executadas em paralelo à execução do agente e podem:

  • Bloquear conteúdo prejudicial ou fora do tópico
  • Remover PII (e-mails, telefones, SSNs, cartões de crédito)
  • Impor o esquema JSON nas saídas
  • Limitar o tamanho do conteúdo

Instalação

[dependencies]
adk-guardrail = "2.1.0"

# For JSON schema validation
adk-guardrail = { version = "2.1.0", features = ["schema"] }

Conceitos básicos

GuardrailResult

Cada barreira de proteção retorna um de três resultados:

pub enum GuardrailResult {
    Pass,                                    // Content is valid
    Fail { reason: String, severity: Severity },  // Content rejected
    Transform { new_content: Content, reason: String },  // Content modified
}

Níveis de severidade

pub enum Severity {
    Low,      // Warning only, doesn't block
    Medium,   // Blocks but continues other checks
    High,     // Blocks immediately
    Critical, // Blocks and fails fast
}

Remoção de PII

Detecte e remova automaticamente informações de identificação pessoal:

use adk_guardrail::{PiiRedactor, PiiType};

// Default: emails, phones, SSNs, credit cards
let redactor = PiiRedactor::new();

// Or select specific types
let redactor = PiiRedactor::with_types(&[
    PiiType::Email,
    PiiType::Phone,
]);

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

Tipos de PII compatíveis:

TypePatternRedaction
Emailuser@domain.com[EMAIL REDACTED]
Phone555-123-4567[PHONE REDACTED]
Ssn123-45-6789[SSN REDACTED]
CreditCard4111-1111-1111-1111[CREDIT CARD REDACTED]
IpAddress192.168.1.1[IP REDACTED]

Filtragem de conteúdo

Bloqueie conteúdo prejudicial ou aplique restrições de tópicos:

use adk_guardrail::ContentFilter;

// Block harmful content patterns (developer-friendly: excludes "hack"/"exploit")
let filter = ContentFilter::harmful_content();

// Strict variant that also blocks "hack" and "exploit"
let filter = ContentFilter::harmful_content_strict();

// Block specific keywords
let filter = ContentFilter::blocked_keywords(vec![
    "forbidden".into(),
    "banned".into(),
]);

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

// Limit content length
let filter = ContentFilter::max_length(1000);

Filtro de conteúdo personalizado

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);

Validação de esquema

Aplique o esquema JSON às saídas do agente (requer o recurso schema):

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);

O validador extrai JSON de:

  • Texto bruto de JSON
  • Blocos de código Markdown (```json ... ```)

GuardrailSet

Combine vários guardrails:

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

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

GuardrailExecutor

Execute os guardrails e obtenha resultados detalhados:

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,                              // Overall pass/fail
    pub transformed_content: Option<Content>,      // Modified content (if any)
    pub failures: Vec<(String, String, Severity)>, // (name, reason, severity)
}

Guardrails personalizados

Implemente o trait Guardrail:

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
    }

    // Run in parallel with other guardrails (default: true)
    fn run_parallel(&self) -> bool {
        true
    }

    // Fail fast on this guardrail's failure (default: true)
    fn fail_fast(&self) -> bool {
        true
    }
}

Integração com agentes

Os guardrails integram-se ao LlmAgentBuilder:

Os guardrails de entrada configurados são executados antes da execução do modelo, e os guardrails de saída configurados são executados nas respostas geradas antes de serem retornadas ao chamador.

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()?;

Fluxo de execução

User Input
    │
    ▼
┌─────────────────────┐
│  Input Guardrails   │ ← PII redaction, content filtering
│  (parallel)         │
└─────────────────────┘
    │
    ▼ (transformed or blocked)
┌─────────────────────┐
│  Agent Execution    │
└─────────────────────┘
    │
    ▼
┌─────────────────────┐
│  Output Guardrails  │ ← Schema validation, safety checks
│  (parallel)         │
└─────────────────────┘
    │
    ▼
Final Response

Exemplos

cargo check -p adk-guardrail
cargo check -p adk-rust --no-default-features --features guardrail

Práticas recomendadas

PráticaDescrição
Guardrails em camadasUse guardrails de entrada para segurança e de saída para qualidade
PII na entradaRemova PII antes que ela chegue ao modelo
Esquema na saídaValide saídas estruturadas com o esquema JSON
Severidade apropriadaUse Crítica com moderação; Baixa para avisos
Teste minuciosamenteAs barreiras de proteção são código crítico para a segurança

Anterior: ← Controle de acesso | Próximo: Memória →