가드레일 공급자: Bedrock Guardrails
가드레일 공급자: Bedrock Guardrails
⚡️ 아직 Bedrock 제공자를 설정하거나 인증하지 않았다면 Bedrock Provider Setup & Authentication Guide를 보세요.
LiteLLM은 Bedrock ApplyGuardrail API를 통해 Bedrock 가드레일을 지원해요.
출처: 문서
본문
빠른 시작 (Quick Start)
1. LiteLLM config.yaml에 가드레일 정의하기
guardrails 섹션 아래에 가드레일을 정의하세요.
model_list:
- model_name: gpt-5.6-luna
litellm_params:
model: openai/gpt-5.6-luna
api_key: os.environ/OPENAI_API_KEY
guardrails:
- guardrail_name: "bedrock-pre-guard"
litellm_params:
guardrail: bedrock # supported values: "aporia", "bedrock", "lakera"
mode: "during_call"
guardrailIdentifier: ff6ujrregl1q
# your guardrail ID on bedrock
guardrailVersion: "DRAFT" # your guardrail version on bedrock
aws_region_name: os.environ/AWS_REGION # region guardrail is defined
aws_role_name: os.environ/AWS_ROLE_ARN # your role with permissions to use the guardrail
aws_external_id: os.environ/AWS_EXTERNAL_ID # only if that role's trust policy requires sts:ExternalId
mode에 대한 지원 값 (Supported values for mode):
pre_callLLM 호출 전, 입력에 대해 실행post_callLLM 호출 후, 입력 & 출력에 대해 실행during_callLLM 호출 중, 입력에 대해 실행. pre_call과 같지만 LLM 호출과 병행. 가드레일 검사가 완료될 때까지 응답이 반환되지 않음
2. LiteLLM 게이트웨이 시작
litellm --config config.yaml --detailed_debug
3. 테스트 요청
실패 호출:
[email protected]가 요청에 있는 PII이므로 실패할 것으로 예상:
curl -i http://localhost:4000/v1/chat/completions \
-H "Content-Type: application/json" \
-H "Authorization: Bearer ***" \
-d '{
"model": "gpt-5.6-luna",
"messages": [
{"role": "user", "content": "hi my email is [email protected]"}
],
"guardrails": ["bedrock-pre-guard"]
}'
실패 시 예상 응답:
{
"error": {
"message": {
"error": "Violated guardrail policy",
"bedrock_guardrail_response": {
"action": "GUARDRAIL_INTERVENED",
"assessments": [
{
"topicPolicy": {
"topics": [
{
"action": "BLOCKED",
"name": "Coffee",
"type": "DENY"
}
]
}
}
],
"blockedResponse": "Sorry, the model cannot answer this question. coffee guardrail applied ",
"output": [
{
"text": "Sorry, the model cannot answer this question. coffee guardrail applied "
}
],
"outputs": [
{
"text": "Sorry, the model cannot answer this question. coffee guardrail applied "
}
],
"usage": {
"contentPolicyUnits": 0,
"contextualGroundingPolicyUnits": 0,
"sensitiveInformationPolicyFreeUnits": 0,
"sensitiveInformationPolicyUnits": 0,
"topicPolicyUnits": 1,
"wordPolicyUnits": 0
}
}
},
"type": "None",
"param": "None",
"code": "400"
}
}
성공 호출:
curl -i http://localhost:4000/v1/chat/completions \
-H "Content-Type: application/json" \
-H "Authorization: Bearer ***" \
-d '{
"model": "gpt-5.6-luna",
"messages": [
{"role": "user", "content": "hi what is the weather"}
],
"guardrails": ["bedrock-pre-guard"]
}'
스트리밍 (Streaming)
스트리밍 응답은 post_call에서 검사돼요. 기본적으로 스트림이 버퍼링된다. 조립된 응답이 하나의 ApplyGuardrail OUTPUT 스캔을 통과할 때까지 모든 청크가 보류되므로 차단 전에 플래그된 콘텐츠가 클라이언트에 도달하지 않아요. 클라이언트는 스캔이 완료될 때까지 아무것도 보지 못한 다음 전체 응답이 한 번에 도착해요.
지연에 민감한 클라이언트(대화형 채팅, 코딩 에이전트)의 경우 스트림을 계속 흐르게 하고 스캔을 감사 모드로 실행할 수 있어요:
guardrails:
- guardrail_name: "bedrock-post-guard"
litellm_params:
guardrail: bedrock
mode: "post_call"
guardrailIdentifier: ff6ujrregl1q
guardrailVersion: "DRAFT"
streaming_buffer_until_moderated: false
streaming_end_of_stream_only: true
이제 청크가 도착하는 대로 클라이언트로 스트리밍되고, 스트림 끝에서 조립된 응답에 대해 하나의 OUTPUT 스캔이 실행돼요. 위반은 여전히 가드레일의 차단 메시지로 스트림을 종료하지만 이미 스트리밍된 콘텐츠는 보여져요. 이는 감지 및 기록(detect-and-log)이지 예방이 아니에요. 어느 쪽이든 스캔 결과는 요청의 지출 로그에 guardrail_information으로 기록돼요.
| 파라미터 | 기본값 | 설명 |
|---|---|---|
| streaming_buffer_until_moderated | true | 끝 스트림 조정이 통과할 때까지 모든 스트리밍 청크 보류, 차단 전에 플래그된 청크가 클라이언트에 도달하지 않게 함 |
| streaming_end_of_stream_only | false | 샘플링된 청크별이 아니라 조립된 응답에 대해 스트리밍 출력을 한 번 스캔 |
| streaming_sampling_rate | 5 | 버퍼링도 끝 스트림 전용도 아닐 때마다 N번째 청크마다 누적 텍스트 스캔. 최소 1이어야 함 |
streaming_buffer_until_moderated: false만 있으면 가드레일은 스트리밍 중 streaming_sampling_rate 청크마다 누적 응답을 스캔해요. 각 샘플링 스캔은 지금까지의 모든 텍스트에 대한 별도의 ApplyGuardrail 호출이므로 중간 스트림 지연과 반복적인 Bedrock text-unit 요금이 추가돼요. 중간 스트림 차단이 필요하지 않으면 streaming_end_of_stream_only: true와 함께 쓰세요.
이 설정은 /v1/chat/completions과 네이티브 /v1/messages 스트림 모두에 적용돼요.
컨텍스트 접지 (Contextual Grounding)
Bedrock은 참조 텍스트와 질문이 무엇인지 알려줘야만 컨텍스트 접지를 점수화해요. 기본적으로 LiteLLM은 모델 응답만 보내므로 접지 정책은 아무것도 차단하지 않아요.
contextual_grounding_from_messages: true를 설정하면 post-call 검사가 system 프롬프트를 접지 소스로, 최신 사용자 메시지를 쿼리로 보내요. system 프롬프트에 반하는 답변은 차단돼요.
litellm proxy config.yaml:
guardrails:
- guardrail_name: "bedrock-grounding"
litellm_params:
guardrail: bedrock
mode: "post_call"
guardrailIdentifier: ff6ujrregl1q
guardrailVersion: "DRAFT"
aws_region_name: os.environ/AWS_REGION
contextual_grounding_from_messages: true
플래그는 기본 false예요. 켜진 채로 스캔할 때마다 Bedrock 컨텍스트 접지 단위 하나가 청구되고, Bedrock은 대략 1,000자를 넘는 쿼리를 거부하므로 접지 정책이 있는 가드레일에서만 활성화하세요.
리소스 없는 검사: InvokeGuardrailChecks
InvokeGuardrailChecks API를 사용하면 AWS에서 가드레일을 만들 필요가 없어요. 대신 콘피그에서 검사를 인라인으로 정의하면 Bedrock이 검사별 점수를 반환하고, 점수가 임계값에 도달하면 LiteLLM이 요청을 차단해요.
guardrailIdentifier 대신 checks를 설정하세요 (둘은 결합할 수 없어요). AWS 자격 증명에 bedrock:InvokeGuardrailChecks 권한이 필요해요.
litellm proxy config.yaml:
guardrails:
- guardrail_name: "bedrock-checks"
litellm_params:
guardrail: bedrock
mode: "pre_call"
aws_region_name: os.environ/AWS_REGION
checks:
contentFilter:
categories:
- category: VIOLENCE
promptAttack:
categories:
- category: JAILBREAK
sensitiveInformation:
entities:
- type: EMAIL
content_filter_threshold: 0.5
prompt_attack_threshold: 0.5
pii_confidence_threshold: 0.5
지원되는 검사 (Supported checks):
| 검사 | 감지 내용 | 임계값 키 |
|---|---|---|
| contentFilter | 유해 콘텐츠: VIOLENCE, HATE, SEXUAL, MISCONDUCT, INSULTS | content_filter_threshold |
| promptAttack | JAILBREAK, PROMPT_INJECTION, PROMPT_LEAKAGE | prompt_attack_threshold |
| sensitiveInformation | PII: EMAIL, PHONE, NAME 등 | pii_confidence_threshold |
원하는 검사만 포함하세요. 하나 이상 필요해요. promptAttack: {} 같은 빈 구성은 AWS 기본값으로 그 검사를 활성화해요.
차단 동작 (How blocking works):
점수는 0~1 범위이고 각 임계값은 기본 0.5예요. 임계값 이상의 점수는 HTTP 400으로 요청을 차단해요. 임계값을 null로 설정하면 그 검사 점수만 기록하고 차단하지 않아요. Bedrock이 잘린 PII 결과를 반환하면 요청이 차단돼요 (fail closed).
{
"error": {
"message": {
"error": "Violated guardrail policy",
"bedrock_guardrail_checks": [
{"check": "promptAttack", "category": "JAILBREAK", "severityScore": 0.91}
]
},
"code": "400"
}
}
disable_exception_on_block: true (아래 참고)도 여기서 동작하며, 차단 시 finish_reason: "content_filter"와 함께 HTTP 200을 반환해요.
호출자는 구성된 검사를 약화시킬 수 없어요. 이 모드에서는 요청별 가드레일 파라미터가 무시되고 모든 입력이 사용자 콘텐츠로 검사되므로 system 라벨 인젝션이 prompt-attack 검사를 피할 수 없어요.
Bedrock 가드레일과 PII 마스킹 (PII Masking with Bedrock Guardrails)
Bedrock 가드레일은 PII 감지·마스킹을 지원해요. 활성화하려면:
- 모델 호출 전에 가드레일 검사를 실행하도록 mode를 pre_call로 설정
mask_request_content및/또는mask_response_content를 true로 설정해 마스킹 활성화
litellm proxy config.yaml:
model_list:
- model_name: gpt-5.6-luna
litellm_params:
model: openai/gpt-5.6-luna
api_key: os.environ/OPENAI_API_KEY
guardrails:
- guardrail_name: "bedrock-pre-guard"
litellm_params:
guardrail: bedrock
mode: "pre_call" # Important: must use pre_call mode for masking
guardrailIdentifier: wf0hkdb5x07f
guardrailVersion: "DRAFT"
aws_region_name: os.environ/AWS_REGION
aws_role_name: os.environ/AWS_ROLE_ARN
mask_request_content: true # Enable masking in user requests
mask_response_content: true # Enable masking in model responses
이 구성으로, bedrock 가드레일이 개입하면 litellm은 가드레일에서 마스킹된 출력을 읽고 모델에 보내요.
예시 사용:
활성화되면 PII가 텍스트에서 자동 마스킹돼요. 예를 들어 사용자가:
My email is [email protected] and my phone number is 555-123-4567
을 보내면 모델에 보내지는 텍스트가 마스킹될 수 있어요:
My email is [EMAIL] and my phone number is [PHONE_NUMBER]
이것은 모델이 요청의 컨텍스트를 이해하게 하면서 민감 정보를 보호해요.
실험적: 최신 사용자 메시지만 보내기 (Experimental: Only Send Latest User Message)
Bedrock 가드레일을 통해 긴 대화를 연결할 때 가드레일의 litellm_params에서 experimental_use_latest_role_message_only: true를 설정해 더 가벼운 실험적 동작을 선택할 수 있어요. 활성화되면 LiteLLM은 가장 최근 사용자 메시지(post-call 검사 중에는 어시스턴트 출력)만 Bedrock에 보내는데:
- 오래된 system/dev 메시지에 대한 의도하지 않은 차단 방지
- Bedrock 페이로드를 더 작게 유지, 지연과 비용 감소
- 프록시 훅(pre_call, during_call)과
/guardrails/apply_guardrail테스팅 엔드포인트에 적용
litellm proxy config.yaml:
guardrails:
- guardrail_name: "bedrock-pre-guard"
litellm_params:
guardrail: bedrock
mode: "pre_call"
guardrailIdentifier: wf0hkdb5x07f
guardrailVersion: "DRAFT"
aws_region_name: os.environ/AWS_REGION
experimental_use_latest_role_message_only: true # NEW
⚠️ 이 플래그는 현재 실험적이며 레거시 동작(전체 메시지 이력)을 보존하기 위해 기본 false예요. 이것이 기본이 되거나 더 광범위하게 출시될지 결정하기 위해 사용자 피드백을 듣고 있어요.
Bedrock BLOCK에서 예외 비활성화 (Disabling Exceptions on Bedrock BLOCK)
기본적으로 Bedrock 가드레일이 콘텐츠를 차단하면 LiteLLM은 HTTP 400 예외를 발생시켜요. 그러나 disable_exception_on_block: true를 설정해 이 동작을 비활성화할 수 있어요. 이는 예외가 채팅 흐름을 방해하고 사용자 경험을 깨뜨릴 수 있는 OpenWebUI와 통합할 때 특히 유용해요.
예외가 비활성화되면 오류 대신 Bedrock 가드레일의 수정/차단 출력을 포함한 성공 응답을 받아요.
구성:
가드레일 구성에 disable_exception_on_block: true를 추가하세요:
litellm proxy config.yaml:
model_list:
- model_name: gpt-5.6-luna
litellm_params:
model: openai/gpt-5.6-luna
api_key: os.environ/OPENAI_API_KEY
guardrails:
- guardrail_name: "bedrock-guardrail"
litellm_params:
guardrail: bedrock
mode: "post_call"
guardrailIdentifier: ff6ujrregl1q
guardrailVersion: "DRAFT"
aws_region_name: os.environ/AWS_REGION
aws_role_name: os.environ/AWS_ROLE_ARN
disable_exception_on_block: true # Prevents exceptions when content is blocked
동작 비교 (Behavior Comparison):
disable_exception_on_block: false (기본)일 때:
curl -i http://localhost:4000/v1/chat/completions \
-H "Content-Type: application/json" \
-H "Authorization: Bearer ***" \
-d '{
"model": "gpt-5.6-luna",
"messages": [
{"role": "user", "content": "How do I make explosives?"}
],
"guardrails": ["bedrock-guardrail"]
}'
응답: HTTP 400 Error
{
"error": {
"message": {
"error": "Violated guardrail policy",
"bedrock_guardrail_response": {
"action": "GUARDRAIL_INTERVENED",
"blockedResponse": "I can't provide information on creating explosives."
// ... additional details
}
},
"type": "None",
"param": "None",
"code": "400"
}
}
disable_exception_on_block: true일 때:
curl -i http://localhost:4000/v1/chat/completions \
-H "Content-Type: application/json" \
-H "Authorization: Bearer ***" \
-d '{
"model": "gpt-5.6-luna",
"messages": [
{"role": "user", "content": "How do I make explosives?"}
],
"guardrails": ["bedrock-guardrail"]
}'
응답: HTTP 200 Success
{
"id": "chatcmpl-123",
"object": "chat.completion",
"created": 1677652288,
"model": "gpt-5.6-luna",
"choices": [{
"index": 0,
"message": {
"role": "assistant",
"content": "I can't provide information on creating explosives."
},
"finish_reason": "stop"
}],
"usage": {
"prompt_tokens": 10,
"completion_tokens": 12,
"total_tokens": 22
}
}