가드레일
가드레일 (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)
- 미들웨어 문서 — 커스텀 미들웨어 전체 가이드
- 미들웨어 API 레퍼런스
- Human-in-the-loop — 민감한 작업에 인간 검토 추가
- 에이전트 테스트 — 안전 메커니즘 테스트 전략