가드레일

가드레일 (Guardrails)

에이전트가 사용자에게 그냥 응답만 하면 좋겠지만, 실제로는 마음에 걸리는 요소가 많아요. 민감한 개인정보가 입력되면? 위험한 요청이 들어오면? LangChain에서는 이런 것들을 **가드레일(guardrails)**이라는 개념으로 처리해요. 쉽게 말해, 에이전트의 실행 경로 곳곳에 안전망을 설치해 두는 거예요. 이번 페이지에서는 그 안전망을 어떻게 만드는지 살펴볼게요.

출처: LangChain 공식 문서 — guardrails

가드레일 구현 방식

가드레일은 미들웨어(middleware)를 사용해서 구현해요. 미들웨어를 쓰면 에이전트가 시작되기 전, 완료된 후, 모델 호출 전후, 도구 호출 전후 같은 전략적인 지점에서 실행을 가로챌 수 있어요.

가드레일을 만드는 방법은 크게 두 가지 접근이 있어요.

접근 방식 장단점
결정적 가드레일 (Deterministic) 정규식(regex), 키워드 매칭, 명시적 검사 같은 규칙 기반 빠르고 예측 가능하며 비용이 낮지만, 미묘한 위반을 놓칠 수 있어요
모델 기반 가드레일 (Model-based) LLM이나 분류기로 의미를 이해하며 평가 규칙이 놓치는 미묘한 문제를 잡지만 느리고 비용이 더 들어요

LangChain은 두 접근 모두에 대응할 수 있도록, 내장 가드레일(예: PII 감지, human-in-the-loop)과 유연한 커스텀 미들웨어 시스템을 함께 제공해요.

내장 가드레일 (Built-in guardrails)

PII 감지 (PII detection)

LangChain은 대화에서 개인식별정보(PII, Personally Identifiable Information)를 감지하고 처리하는 내장 미들웨어를 제공해요. 이 미들웨어는 이메일, 신용카드, IP 주소 같은 흔한 PII 유형을 감지할 수 있어요.

PII 감지 미들웨어는 이런 곳에 특히 유용합니다:

  • 규정 준수가 필요한 의료·금융 애플리케이션
  • 로그를 정화(sanitize)해야 하는 고객 서비스 에이전트
  • 민감한 사용자 데이터를 다루는 모든 애플리케이션

PII 미들웨어는 감지된 PII를 처리하는 여러 전략을 지원해요.

전략 설명 예시
redact [REDACTED_{PII_TYPE}]로 교체 [REDACTED_EMAIL]
mask 부분적으로 가림 (예: 마지막 4자리) ****-****-****-1234
hash 결정적 해시로 교체 a8f5f167...
block 감지되면 예외 발생 에러 발생

apply_to_output=True를 설정하면 PIIMiddleware가 등록된 스트림 트랜스포머를 통해 스트리밍 출력(텍스트 델타, 도구 호출 인자, 도구 출력, 상태 스냅샷)도 함께 가립니다. langchain>=1.3.2가 필요해요. 자세한 내용은 미들웨어에 트랜스포머 등록 문서를 참고하세요.

        PIIMiddleware(
            "credit_card",
            strategy="mask",
            apply_to_input=True,
        ),
        # Block API keys - raise error if detected
        PIIMiddleware(
            "api_key",
            detector=r"sk-[a-zA-Z0-9]{32}",
            strategy="block",
            apply_to_input=True,
        ),
    ],
)

# When user provides PII, it will be handled according to the strategy
result = agent.invoke({

내장 PII 유형:

  • email — 이메일 주소
  • credit_card — 신용카드 번호 (Luhn 검증)
  • ip — IP 주소
  • mac_address — MAC 주소
  • url — URL

구성 옵션:

매개변수 설명 기본값
pii_type 감지할 PII 유형 (내장 또는 커스텀) 필수
strategy 감지된 PII 처리 방식 ("block", "redact", "mask", "hash") "redact"
apply_to_input 모델 호출 전에 사용자 메시지 검사 True

커스텀 가드레일 (Custom guardrails)

내장 미들웨어만으로 부족하다면, 직접 미들웨어를 만들어 가드레일을 구현할 수 있어요. 크게 에이전트 전(Before agent) 가드레일과 에이전트 후(After agent) 가드레일로 나뉘어요.

Before agent 가드레일

에이전트가 작업을 시작하기 전에 요청을 검사하는 방식이에요. 클래스 문법과 데코레이터 문법 두 가지로 작성할 수 있어요.

from typing import Any

from langchain.agents.middleware import AgentMiddleware, AgentState, hook_config
from langgraph.runtime import Runtime

class ContentFilterMiddleware(AgentMiddleware):
@before_agent(can_jump_to=["end"])
def content_filter(state: AgentState, runtime: Runtime) -> dict[str, Any] | None:
    """Deterministic guardrail: Block requests containing banned keywords."""
# Use the custom guardrail
from langchain.agents import create_agent

agent = create_agent(
    model="gpt-5.5",
    tools=[search_tool, calculator_tool],
    middleware=[content_filter],
)

After agent 가드레일

에이전트가 응답을 만든 뒤에, 그 응답이 안전한지 LLM으로 평가하는 방식이에요.

from langchain.agents.middleware import AgentMiddleware, AgentState, hook_config
from langgraph.runtime import Runtime
from langchain.messages import AIMessage
from langchain.chat_models import init_chat_model
from typing import Any

class SafetyGuardrailMiddleware(AgentMiddleware):
    """Model-based guardrail: Use an LLM to evaluate response safety."""

    def __init__(self):
        super().__init__()
        self.safety_model = init_chat_model("gpt-5.4-mini")

    @hook_config(can_jump_to=["end"])
    def after_agent(self, state: AgentState, runtime: Runtime) -> dict[str, Any] | None:
from typing import Any

safety_model = init_chat_model("gpt-5.4-mini")

@after_agent(can_jump_to=["end"])
def safety_guardrail(state: AgentState, runtime: Runtime) -> dict[str, Any] | None:

여러 가드레일 조합하기

가드레일은 여러 개를 겹쳐 쌓을 수도 있어요. 각각 다른 레이어를 담당하게 쌓으면 더 견고해져요.

        HumanInTheLoopMiddleware(interrupt_on={"send_email": True}),

        # Layer 4: Model-based safety check (after agent)
        SafetyGuardrailMiddleware(),
    ],
)

추가 자료 (Additional resources)

더 알아보기 (Learn more)