ガードレール
adk-guardrail を使用した入出力の検証とコンテンツの安全性確保。
概要
ガードレールは、Agent の入力と出力を検証および変換し、安全性、コンプライアンス、品質を確保します。これらは Agent の実行と並行して実行され、次のことが可能です。
- 有害またはトピック外のコンテンツをブロックする
- PII (メールアドレス、電話番号、SSN、クレジットカード番号) を編集する
- 出力に JSON schema を適用する
- コンテンツの長さを制限する
インストール
[dependencies]
adk-guardrail = "0.2.0"
# For JSON schema validation
adk-guardrail = { version = "0.2.0", features = ["schema"] }
主要な概念
GuardrailResult
すべてのガードレールは、次の3つの結果のいずれかを返します。
pub enum GuardrailResult {
Pass, // コンテンツは有効
Fail { reason: String, severity: Severity }, // コンテンツは拒否されました
Transform { new_content: Content, reason: String }, // コンテンツは変更されました
}
Severity レベル
pub enum Severity {
Low, // 警告のみ、ブロックはしない
Medium, // ブロックするが、他のチェックは続行する
High, // 直ちにブロックする
Critical, // ブロックし、即座に失敗させる
}
PII 編集
個人を特定できる情報を自動的に検出して編集します。
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]
サポートされている PII タイプ:
| タイプ | パターン | 編集 |
|---|---|---|
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] |
コンテンツフィルタリング
有害なコンテンツをブロックしたり、トピックの制約を適用したりします。
use adk_guardrail::ContentFilter;
// 有害なコンテンツパターンをブロックする
let filter = ContentFilter::harmful_content();
// 特定のキーワードをブロックする
let filter = ContentFilter::blocked_keywords(vec![
"forbidden".into(),
"banned".into(),
]);
// トピックの関連性を強制する
let filter = ContentFilter::on_topic("cooking", vec![
"recipe".into(),
"cook".into(),
"bake".into(),
]);
// コンテンツの長さを制限する
let filter = ContentFilter::max_length(1000);
カスタム Content Filter
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);
スキーマ検証
Agent の出力に JSON schema を適用します (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);
バリデーターは、次から JSON を抽出します。
- 生の JSON テキスト
- Markdown コードブロック (
json ...)
GuardrailSet
複数のガードレールを組み合わせます。
use adk_guardrail::{GuardrailSet, ContentFilter, PiiRedactor};
let guardrails = GuardrailSet::new()
.with(ContentFilter::harmful_content())
.with(ContentFilter::max_length(5000))
.with(PiiRedactor::new());
GuardrailExecutor
ガードレールを実行し、詳細な結果を取得します:
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, // 全体的な合否
pub transformed_content: Option<Content>, // 変更されたコンテンツ (存在する場合)
pub failures: Vec<(String, String, Severity)>, // (名前, 理由, 重大度)
}
カスタムガードレール
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
}
// 他のガードレールと並行して実行 (デフォルト: true)
fn run_parallel(&self) -> bool {
true
}
// このガードレールの失敗時に即座に中断 (デフォルト: true)
fn fail_fast(&self) -> bool {
true
}
}
Agent との統合
Guardrails は 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()?;
実行フロー
ユーザー入力
│
▼
┌─────────────────────┐
│ 入力ガードレール │ ← PII の編集、コンテンツフィルタリング
│ (並列) │
└─────────────────────┘
│
▼ (変換またはブロック済み)
┌─────────────────────┐
│ Agent 実行 │
└─────────────────────┘
│
▼
┌─────────────────────┐
│ 出力ガードレール │ ← スキーマ検証、安全チェック
│ (並列) │
└─────────────────────┘
│
▼
最終応答
例
# 基本的な PII とコンテンツフィルタリング
cargo run --example guardrail_basic --features guardrails
# JSON スキーマ検証
cargo run --example guardrail_schema --features guardrails
# 完全な Agent 統合
cargo run --example guardrail_agent --features guardrails
ベストプラクティス
| 実践 | 説明 |
|---|---|
| ガードレールを階層化する | 入力ガードレールを安全性のため、出力ガードレールを品質のために使用します |
| 入力時のPII | モデルに到達する前にPIIを編集します |
| 出力時のスキーマ | JSONスキーマを使用して構造化された出力を検証します |
| 適切な重大度 | Criticalは控えめに使用し、Lowは警告に使用します |
| 徹底的にテストする | ガードレールはセキュリティ上重要なコードです |