> ## Documentation Index
> Fetch the complete documentation index at: https://docs.coreweave.com/llms.txt
> Use this file to discover all available pages before exploring further.

# 가드레일 설정

> 프로덕션 애플리케이션에서 LLM 안전성을 보장하고 출력 품질을 측정하세요

가드레일은 LLM 평가자의 점수를 기반으로 LLM 애플리케이션의 동작에 개입합니다. 가드레일은 출력이 사용자에게 전달되기 전에 실시간으로 실행되며, 점수가 임계값을 초과하면 응답을 차단하거나 수정할 수 있습니다. 가드레일을 사용하면 유해한 콘텐츠를 차단하거나, 응답에서 개인 식별 정보(PII)를 필터링하거나, 사용자의 악의적인 입력을 차단할 수 있습니다.

이 가이드에서는 Weave 가드레일의 작동 방식과 성능 조정 방법을 설명합니다. 또한 기본 제공 Scorer, 맞춤형 Scorer, AWS Bedrock Guardrails를 사용해 프로덕션 LLM 애플리케이션을 보호하는 예시를 단계별로 살펴봅니다.

<h2 id="how-weave-guardrails-work">
  Weave 가드레일의 작동 방식
</h2>

Weave 가드레일은 인라인 [Weave Scorer](/ko/products/wandb/weave/guides/evaluation/scorers)를 사용해 사용자의 입력이나 LLM의 출력을 평가하고, LLM의 응답을 실시간으로 조정합니다. 맞춤형 Scorer를 설정하거나 [기본 제공 Scorer](/ko/products/wandb/weave/guides/evaluation/builtin_scorers)를 사용해 다양한 목적으로 콘텐츠를 평가할 수 있습니다. 이 가이드에서는 두 가지 유형의 Scorer를 모두 가드레일로 사용하는 방법을 보여 줍니다.

애플리케이션의 제어 흐름을 변경하지 않고 프로덕션 트래픽을 수동적으로 채점하려면 대신 [모니터](/ko/products/wandb/weave/guides/evaluation/monitors)를 사용하세요.

모니터와 달리 가드레일은 애플리케이션의 제어 흐름에 영향을 주므로 코드 변경이 필요합니다. 하지만 가드레일의 모든 Scorer 결과는 Weave 데이터베이스에 자동으로 저장되므로, 별도의 설정 없이도 가드레일이 모니터 역할을 함께 수행합니다. 원래 어떤 방식으로 사용되었는지와 관계없이 과거 Scorer 결과를 분석할 수 있습니다.

<Note>
  Weave TypeScript SDK는 가드레일 설정에 필요한 도구를 지원하지 않습니다.
</Note>

<h3 id="optimize-your-weave-guardrail-performance">
  Weave 가드레일 성능 최적화
</h3>

가드레일은 애플리케이션의 제어 흐름을 중단하고 응답의 진행 방향을 바꿀 수 있으므로, 너무 복잡하면 성능에 영향을 줄 수 있습니다. 최상의 성능을 위해 다음 권장 사항을 따르세요:

* 가드레일 로직을 최소화하고 빠르게 유지하세요.
* 일반적인 결과를 캐시하세요.
* 무거운 외부 API 호출을 피하세요.
* 반복되는 초기화 비용을 피하기 위해 가드레일을 메인 함수 외부에서 초기화하세요.

가드레일을 메인 함수 외부에서 초기화하는 것은 특히 다음 경우에 중요합니다:

* Scorer가 ML 모델을 로드할 때
* 지연 시간이 중요한 로컬 LLM을 사용할 때
* Scorer가 네트워크 연결을 유지할 때
* 트래픽이 많은 애플리케이션이 있을 때

<h2 id="example-create-a-guardrail-using-a-built-in-moderation-scorer">
  예시: 기본 제공 moderation scorer를 사용하여 가드레일 만들기
</h2>

다음 예시는 OpenAI의 GPT-4o mini 모델에 사용자 프롬프트를 보냅니다. 그런 다음 모델의 응답을 [OpenAI의 moderation API](https://platform.openai.com/docs/guides/moderation)로 전달하여 LLM의 응답에 유해하거나 독성 있는 콘텐츠가 포함되어 있는지 평가합니다. 모델의 응답은 가드레일 함수(`generate_safe_response()`)로 전달되며, 이 함수는 `OpenAIModerationScorer`를 사용하여 LLM의 원래 응답을 검사합니다. 이어서 함수 로직은 OpenAI의 평가 응답에서 `passed` 필드의 boolean 값을 확인하고, 이 값에 따라 애플리케이션의 응답 방식이 결정됩니다.

```python lines {28-45} theme={"system"}
import weave
import openai
from weave.scorers import OpenAIModerationScorer
import asyncio

# Weave 초기화
weave.init("your-team-name/your-project-name")

# OpenAI 클라이언트 초기화
client = openai.OpenAI()  # OPENAI_API_KEY 환경 변수 사용

# 모더레이션 Scorer 초기화
moderation_scorer = OpenAIModerationScorer()

# OpenAI에 프롬프트 전송
@weave.op
def generate_response(prompt: str) -> str:
    response = client.chat.completions.create(
        model="gpt-4o-mini",
        messages=[
            {"role": "system", "content": "You are a helpful assistant."},
            {"role": "user", "content": prompt}
        ],
        max_tokens=200
    )
    return response.choices[0].message.content

# 가드레일 함수로 응답의 유해성 검사
async def generate_safe_response(prompt: str) -> str:
    """Generate a response with content moderation guardrail."""
    # 결과와 Call 객체를 함께 조회
    result, call = generate_response.call(prompt)
    
    # 사용자에게 반환하기 전에 모더레이션 Scorer 적용
    score = await call.apply_scorer(moderation_scorer)
    print("This is the score object:", score)
    
    # 콘텐츠가 플래그 지정되었는지 확인
    if not score.result.get("passed", True): 
        categories = score.result.get("categories", {})
        flagged_categories = list(categories.keys()) if categories else []
        print(f"Content blocked. Flagged categories: {flagged_categories}")
        return "I'm sorry, I can't provide that response due to content policy restrictions."
    
    return result

# 예시 실행
if __name__ == "__main__":
    
    prompts = [
        "What's the capital of France?",
        "Tell me a funny fact about dogs.",
    ]
    
    for prompt in prompts:
        print(f"\nPrompt: {prompt}")
        response = asyncio.run(generate_safe_response(prompt))
        print(f"Response: {response}")
```

LLM-as-a-judge Scorer를 사용할 때 점수화 프롬프트에서 Op의 변수를 참조할 수 있습니다. 예를 들어 "`{ground_truth}`를 기준으로 `{output}`이(가) 정확한지 평가하세요."와 같이 작성할 수 있습니다. 자세한 내용은 [프롬프트 변수](/ko/products/wandb/weave/guides/evaluation/scorers#access-variables-from-your-ops-in-scoring-prompts)를 참조하세요.

<h2 id="example-create-a-guardrail-using-a-custom-scorer">
  예시: 맞춤형 Scorer를 사용하여 가드레일 만들기
</h2>

다음 예시는 LLM 응답에서 이메일 주소, 전화번호, 사회보장번호 등의 개인 식별 정보(PII)를 감지하는 맞춤형 가드레일을 만듭니다. 이를 통해 생성된 콘텐츠에 민감한 정보가 노출되는 것을 방지합니다. `generate_safe_response` 함수는 맞춤형 `PIIDetectionScorer`를 적용합니다.

```python lines {14-39, 57-69} theme={"system"}
import weave
import openai
import re
import asyncio
from weave import Scorer

weave.init("your-team-name/your-project-name")

client = openai.OpenAI()

class PIIDetectionScorer(Scorer):
    """Detects PII in LLM outputs to prevent data leaks."""
    
    @weave.op
    def score(self, output: str) -> dict:
        """
        Check for common PII patterns in the output.
        
        Returns:
            dict: Contains 'passed' (bool) and 'detected_types' (list)
        """
        detected_types = []
        
        # 이메일 패턴
        if re.search(r'\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b', output):
            detected_types.append("email")
        
        # 전화번호 패턴(미국 형식)
        if re.search(r'\b\d{3}[-.]?\d{3}[-.]?\d{4}\b', output):
            detected_types.append("phone")
        
        # SSN 패턴
        if re.search(r'\b\d{3}-\d{2}-\d{4}\b', output):
            detected_types.append("ssn")
        
        return {
            "passed": len(detected_types) == 0,
            "detected_types": detected_types
        }

# 최적의 성능을 위해 함수 외부에서 Scorer를 초기화합니다
pii_scorer = PIIDetectionScorer()

@weave.op
def generate_response(prompt: str) -> str:
    """Generate a response using an LLM."""
    response = client.chat.completions.create(
        model="gpt-4o-mini",
        messages=[
            {"role": "system", "content": "You are a helpful assistant."},
            {"role": "user", "content": prompt}
        ],
        max_tokens=200
    )
    return response.choices[0].message.content

async def generate_safe_response(prompt: str) -> str:
    """Generate a response with PII detection guardrail."""
    result, call = generate_response.call(prompt)
    
    # PII 감지 Scorer 적용
    score = await call.apply_scorer(pii_scorer)
    
    # PII가 감지되면 응답 차단
    if not score.result.get("passed", True):
        detected_types = score.result.get("detected_types", [])
        return f"I cannot provide a response that may contain sensitive information (detected: {', '.join(detected_types)})."
    
    return result

# 사용 예시
if __name__ == "__main__":
    prompts = [
        "What's the weather like today?",
        "Can you help me contact someone at john.doe@example.com?",
        "Tell me about machine learning.",
    ]
    
    for prompt in prompts:
        print(f"\nPrompt: {prompt}")
        response = asyncio.run(generate_safe_response(prompt))
        print(f"Response: {response}")
```

<h2 id="integrate-weave-with-aws-bedrock-guardrails">
  Weave를 AWS Bedrock Guardrails와 통합하기
</h2>

AWS에서 이미 콘텐츠 정책을 관리하고 있다면 `BedrockGuardrailScorer`를 사용하여 Weave에서 해당 정책을 적용할 수 있습니다. 이 Scorer는 AWS Bedrock Guardrails를 사용하여 설정된 정책에 따라 콘텐츠를 탐지하고 필터링합니다.

Bedrock Guardrails 인테그레이션을 설정하려면 먼저 다음이 필요합니다.

* Bedrock 액세스 권한이 있는 AWS 계정
* [AWS Bedrock 콘솔에서 설정한 가드레일](https://docs.aws.amazon.com/bedrock/latest/userguide/guardrails-components.html)
* `boto3` [Python 패키지](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/s3.html)

Bedrock 클라이언트는 직접 생성할 필요가 없으며, Weave가 자동으로 생성합니다. 리전을 지정하려면 Scorer의 `bedrock_runtime_kwargs` 매개변수에 리전 값을 전달하세요.

AWS Bedrock에서 가드레일을 생성하는 예시는 [Bedrock guardrails 노트북](https://github.com/aws-samples/amazon-bedrock-samples/blob/main/responsible_ai/bedrock-guardrails/guardrails-api.ipynb)을 참조하세요.

다음 예시에서는 사용자에게 결과를 반환하기 전에 생성된 텍스트가 AWS Bedrock Guardrails 정책을 준수하는지 검사합니다.

```python theme={"system"}
import weave
from weave.scorers.bedrock_guardrails import BedrockGuardrailScorer

weave.init("your-team-name/your-project-name")

guardrail_scorer = BedrockGuardrailScorer(
    guardrail_id="your-guardrail-id",
    guardrail_version="DRAFT",
    source="INPUT",
    bedrock_runtime_kwargs={"region_name": "us-east-1"}
)

@weave.op
def generate_text(prompt: str) -> str:
    # 여기에 텍스트 생성 로직을 작성하세요
    return "Generated text..."

async def generate_safe_text(prompt: str) -> str:
    result, call = generate_text.call(prompt)

    score = await call.apply_scorer(guardrail_scorer)

    if not score.result.passed:
        if score.result.metadata.get("modified_output"):
            return score.result.metadata["modified_output"]
        return "I cannot generate that content due to content policy restrictions."

    return result
```
