보호 장치

adk-guardrail를 사용한 입력/출력 검증 및 콘텐츠 안전성.

개요

보호 장치는 안전성, 규정 준수 및 품질을 보장하기 위해 에이전트의 입력과 출력을 검증하고 변환합니다. 보호 장치는 에이전트 실행과 병렬로 실행되며 다음을 수행할 수 있습니다.

  • 유해하거나 주제에서 벗어난 콘텐츠 차단
  • PII(이메일, 전화번호, SSN, 신용카드 정보) 수정
  • 출력에 JSON 스키마 적용
  • 콘텐츠 길이 제한

설치

[dependencies]
adk-guardrail = "2.1.0"

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

핵심 개념

GuardrailResult

모든 보호 장치는 다음 세 가지 결과 중 하나를 반환합니다.

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

심각도 수준

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

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 유형:

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]

콘텐츠 필터링

유해한 콘텐츠를 차단하거나 주제 제약을 적용합니다:

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

사용자 지정 콘텐츠 필터

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

스키마 검증

에이전트 출력에 JSON 스키마를 적용합니다(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,                              // Overall pass/fail
    pub transformed_content: Option<Content>,      // Modified content (if any)
    pub failures: Vec<(String, String, Severity)>, // (name, reason, severity)
}

사용자 지정 가드레일

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
    }
}

에이전트와의 통합

가드레일은 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()?;

실행 흐름

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

예제

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

모범 사례

실천 방법설명
레이어 가드레일안전을 위해 입력 가드레일을 사용하고, 품질을 위해 출력 가드레일을 사용합니다
입력의 PIIPII가 모델에 도달하기 전에 마스킹합니다
출력의 스키마구조화된 출력을 JSON 스키마로 검증
적절한 심각도Critical은 신중하게 사용하고, 경고에는 Low 사용
철저한 테스트Guardrails는 보안에 중요한 코드

이전: ← 액세스 제어 | 다음: 메모리 →

보호 장치 - ADK-Rust 문서 | ADK-Rust