Garde-fous
Validation des entrées/sorties et sécurité du contenu à l’aide de adk-guardrail.
Vue d’ensemble
Les garde-fous valident et transforment les entrées et les sorties des agents afin de garantir la sécurité, la conformité et la qualité. Ils s’exécutent en parallèle de l’exécution de l’agent et peuvent :
- Bloquer les contenus nuisibles ou hors sujet
- Masquer les informations personnelles identifiables (e-mails, numéros de téléphone, numéros de sécurité sociale, cartes de crédit)
- Imposer le schéma JSON aux sorties
- Limiter la longueur du contenu
Installation
[dependencies]
adk-guardrail = "2.1.0"
# For JSON schema validation
adk-guardrail = { version = "2.1.0", features = ["schema"] }
Concepts fondamentaux
GuardrailResult
Chaque garde-fou renvoie l’un des trois résultats suivants :
pub enum GuardrailResult {
Pass, // Content is valid
Fail { reason: String, severity: Severity }, // Content rejected
Transform { new_content: Content, reason: String }, // Content modified
}
Niveaux de gravité
pub enum Severity {
Low, // Warning only, doesn't block
Medium, // Blocks but continues other checks
High, // Blocks immediately
Critical, // Blocks and fails fast
}
Masquage des informations personnelles identifiables
Détecter et masquer automatiquement les informations personnelles identifiables :
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]
Types d’informations personnelles identifiables pris en charge :
| Type | Pattern | Redaction |
|---|---|---|
Email | user@domain.com | [EMAIL REDACTED] |
Phone | 555-123-4567 | [PHONE REDACTED] |
Ssn | 123-45-6789 | [SSN REDACTED] |
CreditCard | 4111-1111-1111-1111 | [CREDIT CARD REDACTED] |
IpAddress | 192.168.1.1 | [IP REDACTED] |
Filtrage du contenu
Bloquer le contenu nuisible ou imposer des contraintes thématiques :
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);
Filtre de contenu personnalisé
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);
Validation du schéma
Appliquer le schéma JSON aux sorties de l’agent (nécessite la fonctionnalité 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);
Le validateur extrait JSON depuis :
- Le texte brut JSON
- Les blocs de code Markdown (
```json ... ```)
GuardrailSet
Combiner plusieurs garde-fous :
use adk_guardrail::{GuardrailSet, ContentFilter, PiiRedactor};
let guardrails = GuardrailSet::new()
.with(ContentFilter::harmful_content())
.with(ContentFilter::max_length(5000))
.with(PiiRedactor::new());
GuardrailExecutor
Exécuter les garde-fous et obtenir des résultats détaillés :
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)
}
Garde-fous personnalisés
Implémenter le 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
}
}
Intégration avec les agents
Les garde-fous s’intègrent à LlmAgentBuilder :
Les garde-fous d’entrée configurés s’exécutent avant l’exécution du modèle, et les garde-fous de sortie configurés s’exécutent sur les réponses générées avant leur renvoi à l’appelant.
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()?;
Flux d’exécution
User Input
│
▼
┌─────────────────────┐
│ Input Guardrails │ ← PII redaction, content filtering
│ (parallel) │
└─────────────────────┘
│
▼ (transformed or blocked)
┌─────────────────────┐
│ Agent Execution │
└─────────────────────┘
│
▼
┌─────────────────────┐
│ Output Guardrails │ ← Schema validation, safety checks
│ (parallel) │
└─────────────────────┘
│
▼
Final Response
Exemples
cargo check -p adk-guardrail
cargo check -p adk-rust --no-default-features --features guardrail
Bonnes pratiques
| Pratique | Description |
|---|---|
| Superposer des garde-fous | Utilisez des garde-fous pour les entrées à des fins de sécurité, et pour les sorties à des fins de qualité |
| Données personnelles en entrée | Masquez les données personnelles avant qu’elles n’atteignent le modèle |
| Schéma en sortie | Valider les sorties structurées avec le schéma JSON |
| Gravité appropriée | Utiliser « Critique » avec parcimonie, et « Faible » pour les avertissements |
| Tester rigoureusement | Les garde-fous sont du code critique pour la sécurité |
Précédent : ← Contrôle d’accès | Suivant : Mémoire →