AI Sparkup

최신 AI 쉽게 깊게 따라잡기⚡

RAG 에이전트 팁 – 프롬프트 인젝션과 오남용으로부터 보호하는 방법

RAG 에이전트는 외부 문서를 검색해 답변을 생성하는 특성상 기본 챗봇보다 공격 표면이 넓다. 검색된 문서 자체에 악성 지침이 포함될 수 있고, 사용자가 시스템 프롬프트를 탈취하려 시도할 수 있다. 이 글에서는 Viget의 RAG 에이전트 보안 구현 사례를 바탕으로 기본·심화 보안 전략을 정리한다.

기본 보호: 프롬프트 필터링

입력을 에이전트에 전달하기 전에 악성 패턴을 사전 필터링한다.

import re
from dataclasses import dataclass

@dataclass(frozen=True)
class PromptFilterResult:
    safe: bool
    reason: str | None = None

_PATTERNS: list[tuple[re.Pattern[str], str]] = [
    (
        re.compile(
            r"\b(ignore|disregard|forget|override)\s+"
            r"(?:(?:your|all|the|any|previous|prior|earlier|above|preceding)\s+){1,3}"
            r"(instructions?|rules?|prompts?|system\s+prompt|directives?)",
            re.IGNORECASE,
        ),
        "instruction-override phrase",
    ),
    (
        re.compile(
            r"\b(reveal|show|print|tell|repeat|output|leak|dump|expose|share)\s+"
            r"(me\s+)?(your|the)\s+"
            r"(system\s+prompt|instructions?|rules?|directives?|initial\s+prompt)",
            re.IGNORECASE,
        ),
        "request to reveal system prompt",
    ),
]

def filter_prompt(user_input: str) -> PromptFilterResult:
    for pattern, reason in _PATTERNS:
        if pattern.search(user_input):
            return PromptFilterResult(safe=False, reason=reason)
    return PromptFilterResult(safe=True)

이 필터를 에이전트 호출 전에 실행해, 악성으로 판단된 입력은 에이전트에 전달하지 않는다.

심화 보호: AWS Bedrock Guardrail

인프라 레이어에서 더 강력한 가드레일을 적용한다. Bedrock Guardrail은 유해 콘텐츠 차단, 프롬프트 인젝션 탐지, PII 익명화를 서비스 수준에서 제공한다.

가드레일 생성

import boto3

bedrock = boto3.client("bedrock")

response = bedrock.create_guardrail(
    name="rag-agent-guardrail",
    contentPolicyConfig={
        "filtersConfig": [
            {"type": "SEXUAL", "inputStrength": "HIGH", "outputStrength": "HIGH"},
            {"type": "VIOLENCE", "inputStrength": "HIGH", "outputStrength": "HIGH"},
            {"type": "HATE", "inputStrength": "HIGH", "outputStrength": "HIGH"},
            {"type": "MISCONDUCT", "inputStrength": "HIGH", "outputStrength": "HIGH"},
        ]
    },
    sensitiveInformationPolicyConfig={
        "piiEntitiesConfig": [
            {"type": "EMAIL", "action": "ANONYMIZE"},
            {"type": "PHONE", "action": "ANONYMIZE"},
            {"type": "SSN", "action": "BLOCK"},
            {"type": "CREDIT_DEBIT_CARD_NUMBER", "action": "BLOCK"},
        ]
    },
    promptAttackPolicyConfig={
        "filtersConfig": [{"type": "PROMPT_ATTACK", "inputStrength": "HIGH"}]
    },
)
guardrail_id = response["guardrailId"]
guardrail_version = response["version"]
print(f"Guardrail ID: {guardrail_id}, Version: {guardrail_version}")

에이전트에 적용

import os

def build_model_settings() -> BedrockModelSettings:
    settings: dict = {"max_tokens": 4096}
    
    guardrail_id = os.getenv("BEDROCK_GUARDRAIL_ID")
    guardrail_version = os.getenv("BEDROCK_GUARDRAIL_VERSION")
    
    if guardrail_id and guardrail_version:
        settings["guardrail"] = {
            "guardrailIdentifier": guardrail_id,
            "guardrailVersion": guardrail_version,
        }
    else:
        raise ValueError(
            "Bedrock guardrail not applied: both BEDROCK_GUARDRAIL_ID and "
            "BEDROCK_GUARDRAIL_VERSION must be set."
        )
    
    return BedrockModelSettings(**settings)

주요 위협과 대응 전략

위협 유형설명대응
프롬프트 인젝션“이전 지침을 무시하고 X를 해라”입력 필터링 + Bedrock 프롬프트 공격 차단
시스템 프롬프트 탈취“시스템 프롬프트를 보여줘”입력 필터링으로 사전 차단
문서 오염검색된 문서 내 악성 지침문서 소스 검증 + 출력 모니터링
PII 유출민감 정보 노출Bedrock PII 익명화·차단
유해 콘텐츠 생성폭력·혐오 출력Bedrock 콘텐츠 정책 필터

보안 레이어 설계 원칙

  1. 입력 레이어: 명백한 악성 패턴을 에이전트 도달 전에 차단한다
  2. 인프라 레이어: Bedrock Guardrail처럼 서비스 레이어에서 광범위한 정책을 적용한다
  3. 출력 레이어: 에이전트 응답을 배포 전에 검토하는 단계를 추가한다

단일 레이어에 의존하지 않고 여러 레이어를 겹쳐 적용하는 심층 방어(defense in depth) 원칙이 핵심이다.

누가 읽으면 좋은가

  • RAG 챗봇이나 문서 기반 Q&A 에이전트를 프로덕션에 배포하는 팀
  • 고객 대면 AI 서비스에서 보안 리스크를 줄이려는 엔지니어
  • AWS 기반 AI 인프라에서 Bedrock Guardrail 도입을 검토하는 아키텍트

관련 문서

참고 자료



AI Sparkup 구독하기

최신 게시물 요약과 더 심층적인 정보를 이메일로 받아 보세요! (무료)