에이전트를 위한 안전성 검사 및 콘텐츠 필터링 구현
Guardrails는 에이전트 실행의 주요 지점에서 콘텐츠를 검증하고 필터링함으로써 안전하고 규정을 준수하는 AI 애플리케이션을 구축하는 데 도움을 줍니다. 민감한 정보를 감지하고, 콘텐츠 정책을 시행하며, 출력을 검증하고, 문제가 발생하기 전에 안전하지 않은 동작을 방지할 수 있습니다.
일반적인 사용 사례는 다음과 같습니다:
- PII 유출 방지
- 프롬프트 인젝션 공격 감지 및 차단
- 부적절하거나 유해한 콘텐츠 차단
- 비즈니스 규칙 및 규정 준수 요구사항 시행
- 출력 품질 및 정확성 검증
전략적 지점에서 실행을 가로채기 위해 middleware를 사용하여 가드레일을 구현할 수 있습니다 - 에이전트가 시작하기 전, 완료된 후 또는 모델 및 도구 호출 주변에서 말이죠.
가드레일은 두 가지 상호 보완적인 접근 방식을 사용하여 구현할 수 있습니다:
두 가지 가드레일 접근 방식
결정론적 가드레일(Deterministic guardrails): 정규식 패턴, 키워드 매칭 또는 명시적 검사와 같은 규칙 기반 로직을 사용합니다. 빠르고 예측 가능하며 비용 효율적이지만, 미묘한 위반을 놓칠 수 있습니다.
모델 기반 가드레일(Model-based guardrails): LLM이나 분류기를 사용하여 의미론적 이해로 콘텐츠를 평가합니다. 규칙이 놓치는 미묘한 문제를 포착하지만, 더 느리고 비용이 많이 듭니다.
LangChain은 내장 가드레일(예: PII 감지, human-in-the-loop)과 두 접근 방식 중 하나를 사용하여 커스텀 가드레일을 구축하기 위한 유연한 미들웨어 시스템을 모두 제공합니다.
내장 가드레일
PII 감지
LangChain은 대화에서 개인 식별 정보(PII)를 감지하고 처리하기 위한 내장 미들웨어를 제공합니다. 이 미들웨어는 이메일, 신용카드, IP 주소 등과 같은 일반적인 PII 유형을 감지할 수 있습니다.
PII 감지 미들웨어는 규정 준수 요구사항이 있는 의료 및 금융 애플리케이션, 로그를 정리해야 하는 고객 서비스 에이전트, 그리고 일반적으로 민감한 사용자 데이터를 처리하는 모든 애플리케이션에 유용합니다.
PII 미들웨어는 감지된 PII를 처리하기 위한 여러 전략을 지원합니다:
| 전략 | 설명 | 예시 |
|---|---|---|
redact |
[REDACTED_TYPE]으로 교체 |
[REDACTED_EMAIL] |
mask |
부분적으로 가림 (예: 마지막 4자리) | ****-****-****-1234 |
hash |
결정론적 해시로 교체 | a8f5f167... |
block |
감지 시 예외 발생 | 오류 발생 |
from langchain.agents import create_agent
from langchain.agents.middleware import PIIMiddleware
agent = create_agent(
model="gpt-4o",
tools=[customer_service_tool, email_tool],
middleware=[
# 모델로 전송하기 전에 사용자 입력의 이메일을 삭제
PIIMiddleware(
"email",
strategy="redact",
apply_to_input=True,
),
# 사용자 입력의 신용카드 마스킹
PIIMiddleware(
"credit_card",
strategy="mask",
apply_to_input=True,
),
# API 키 차단 - 감지되면 오류 발생
PIIMiddleware(
"api_key",
detector=r"sk-[a-zA-Z0-9]{32}",
strategy="block",
apply_to_input=True,
),
],
)
# 사용자가 PII를 제공하면 전략에 따라 처리됩니다
result = agent.invoke({
"messages": [{"role": "user", "content": "My email is john.doe@example.com and card is 4532-1234-5678-9010"}]
})
내장 PII 유형 및 구성
내장 PII 유형:
email- 이메일 주소credit_card- 신용카드 번호 (Luhn 검증됨)ip- IP 주소mac_address- MAC 주소url- URL
구성 옵션:
| 매개변수 | 설명 | 기본값 |
|---|---|---|
pii_type |
감지할 PII 유형 (내장 또는 커스텀) | 필수 |
strategy |
감지된 PII 처리 방법 ("block", "redact", "mask", "hash") |
"redact" |
detector |
커스텀 감지 함수 또는 정규식 패턴 | None (내장 사용) |
apply_to_input |
모델 호출 전에 사용자 메시지 확인 | True |
apply_to_output |
모델 호출 후에 AI 메시지 확인 | False |
apply_to_tool_results |
실행 후 도구 결과 메시지 확인 | False |
PII 감지 기능에 대한 전체 세부 정보는 middleware 문서를 참조하세요.
Human-in-the-Loop
LangChain은 민감한 작업을 실행하기 전에 사람의 승인을 요구하는 내장 미들웨어를 제공합니다. 이것은 높은 위험성이 있는 결정에 대한 가장 효과적인 가드레일 중 하나입니다.
Human-in-the-loop 미들웨어는 금융 거래 및 이체, 프로덕션 데이터 삭제 또는 수정, 외부 당사자에게 통신 전송, 그리고 중요한 비즈니스 영향이 있는 모든 작업과 같은 경우에 유용합니다.
from langchain.agents import create_agent
from langchain.agents.middleware import HumanInTheLoopMiddleware
from langgraph.checkpoint.memory import InMemorySaver
from langgraph.types import Command
agent = create_agent(
model="gpt-4o",
tools=[search_tool, send_email_tool, delete_database_tool],
middleware=[
HumanInTheLoopMiddleware(
interrupt_on={
# 민감한 작업에 대한 승인 요구
"send_email": True,
"delete_database": True,
# 안전한 작업 자동 승인
"search": False,
}
),
],
# 중단 간에 상태 유지
checkpointer=InMemorySaver(),
)
# Human-in-the-loop은 지속성을 위해 스레드 ID가 필요합니다
config = {"configurable": {"thread_id": "some_id"}}
# 에이전트는 민감한 도구를 실행하기 전에 일시 중지되고 승인을 기다립니다
result = agent.invoke(
{"messages": [{"role": "user", "content": "Send an email to the team"}]},
config=config
)
result = agent.invoke(
Command(resume={"decisions": [{"type": "approve"}]}),
config=config # 일시 중지된 대화를 재개하기 위해 동일한 스레드 ID 사용
)
승인 워크플로우 구현에 대한 전체 세부 정보는 human-in-the-loop 문서를 참조하세요.
커스텀 가드레일
더 정교한 가드레일을 위해 에이전트가 실행되기 전이나 후에 실행되는 커스텀 미들웨어를 만들 수 있습니다. 이를 통해 검증 로직, 콘텐츠 필터링 및 안전성 검사를 완전히 제어할 수 있습니다.
Before Agent 가드레일
각 호출의 시작 부분에서 한 번 요청을 검증하기 위해 "before agent" 훅을 사용합니다. 이것은 인증, 속도 제한 또는 처리가 시작되기 전에 부적절한 요청을 차단하는 것과 같은 세션 수준 검사에 유용합니다.
클래스 구문
from typing import Any
from langchain.agents.middleware import AgentMiddleware, AgentState, hook_config
from langgraph.runtime import Runtime
class ContentFilterMiddleware(AgentMiddleware):
"""결정론적 가드레일: 금지된 키워드를 포함하는 요청을 차단합니다."""
def __init__(self, banned_keywords: list[str]):
super().__init__()
self.banned_keywords = [kw.lower() for kw in banned_keywords]
@hook_config(can_jump_to=["end"])
def before_agent(self, state: AgentState, runtime: Runtime) -> dict[str, Any] | None:
# 첫 번째 사용자 메시지 가져오기
if not state["messages"]:
return None
first_message = state["messages"][0]
if first_message.type != "human":
return None
content = first_message.content.lower()
# 금지된 키워드 확인
for keyword in self.banned_keywords:
if keyword in content:
# 모든 처리 전에 실행 차단
return {
"messages": [{
"role": "assistant",
"content": "I cannot process requests containing inappropriate content. Please rephrase your request."
}],
"jump_to": "end"
}
return None
# 커스텀 가드레일 사용
from langchain.agents import create_agent
agent = create_agent(
model="gpt-4o",
tools=[search_tool, calculator_tool],
middleware=[
ContentFilterMiddleware(
banned_keywords=["hack", "exploit", "malware"]
),
],
)
# 이 요청은 모든 처리 전에 차단됩니다
result = agent.invoke({
"messages": [{"role": "user", "content": "How do I hack into a database?"}]
})
데코레이터 구문
from typing import Any
from langchain.agents.middleware import before_agent, AgentState, hook_config
from langgraph.runtime import Runtime
banned_keywords = ["hack", "exploit", "malware"]
@before_agent(can_jump_to=["end"])
def content_filter(state: AgentState, runtime: Runtime) -> dict[str, Any] | None:
"""결정론적 가드레일: 금지된 키워드를 포함하는 요청을 차단합니다."""
# 첫 번째 사용자 메시지 가져오기
if not state["messages"]:
return None
first_message = state["messages"][0]
if first_message.type != "human":
return None
content = first_message.content.lower()
# 금지된 키워드 확인
for keyword in banned_keywords:
if keyword in content:
# 모든 처리 전에 실행 차단
return {
"messages": [{
"role": "assistant",
"content": "I cannot process requests containing inappropriate content. Please rephrase your request."
}],
"jump_to": "end"
}
return None
# 커스텀 가드레일 사용
from langchain.agents import create_agent
agent = create_agent(
model="gpt-4o",
tools=[search_tool, calculator_tool],
middleware=[content_filter],
)
# 이 요청은 모든 처리 전에 차단됩니다
result = agent.invoke({
"messages": [{"role": "user", "content": "How do I hack into a database?"}]
})
After Agent 가드레일
사용자에게 반환하기 전에 최종 출력을 한 번 검증하기 위해 "after agent" 훅을 사용합니다. 이것은 모델 기반 안전성 검사, 품질 검증 또는 완전한 에이전트 응답에 대한 최종 규정 준수 스캔에 유용합니다.
클래스 구문
from langchain.agents.middleware import AgentMiddleware, AgentState, hook_config
from langgraph.runtime import Runtime
from langchain_core.messages import AIMessage
from langchain.chat_models import init_chat_model
from typing import Any
class SafetyGuardrailMiddleware(AgentMiddleware):
"""모델 기반 가드레일: LLM을 사용하여 응답 안전성을 평가합니다."""
def __init__(self):
super().__init__()
self.safety_model = init_chat_model("gpt-4o-mini")
@hook_config(can_jump_to=["end"])
def after_agent(self, state: AgentState, runtime: Runtime) -> dict[str, Any] | None:
# 최종 AI 응답 가져오기
if not state["messages"]:
return None
last_message = state["messages"][-1]
if not isinstance(last_message, AIMessage):
return None
# 모델을 사용하여 안전성 평가
safety_prompt = f"""Evaluate if this response is safe and appropriate.
Respond with only 'SAFE' or 'UNSAFE'.
Response: {last_message.content}"""
result = self.safety_model.invoke([{"role": "user", "content": safety_prompt}])
if "UNSAFE" in result.content:
return {
"messages": [{
"role": "assistant",
"content": "I cannot provide that response. Please rephrase your request."
}],
"jump_to": "end"
}
return None
# 안전성 가드레일 사용
from langchain.agents import create_agent
agent = create_agent(
model="gpt-4o",
tools=[search_tool, calculator_tool],
middleware=[SafetyGuardrailMiddleware()],
)
result = agent.invoke({
"messages": [{"role": "user", "content": "How do I make explosives?"}]
})
데코레이터 구문
from langchain.agents.middleware import after_agent, AgentState, hook_config
from langgraph.runtime import Runtime
from langchain_core.messages import AIMessage
from langchain.chat_models import init_chat_model
from typing import Any
safety_model = init_chat_model("gpt-4o-mini")
@after_agent(can_jump_to=["end"])
def safety_guardrail(state: AgentState, runtime: Runtime) -> dict[str, Any] | None:
"""모델 기반 가드레일: LLM을 사용하여 응답 안전성을 평가합니다."""
# 최종 AI 응답 가져오기
if not state["messages"]:
return None
last_message = state["messages"][-1]
if not isinstance(last_message, AIMessage):
return None
# 모델을 사용하여 안전성 평가
safety_prompt = f"""Evaluate if this response is safe and appropriate.
Respond with only 'SAFE' or 'UNSAFE'.
Response: {last_message.content}"""
result = safety_model.invoke([{"role": "user", "content": safety_prompt}])
if "UNSAFE" in result.content:
return {
"messages": [{
"role": "assistant",
"content": "I cannot provide that response. Please rephrase your request."
}],
"jump_to": "end"
}
return None
# 안전성 가드레일 사용
from langchain.agents import create_agent
agent = create_agent(
model="gpt-4o",
tools=[search_tool, calculator_tool],
middleware=[safety_guardrail],
)
result = agent.invoke({
"messages": [{"role": "user", "content": "How do I make explosives?"}]
})
여러 가드레일 결합
미들웨어 배열에 추가하여 여러 가드레일을 쌓을 수 있습니다. 순서대로 실행되어 계층화된 보호를 구축할 수 있습니다:
from langchain.agents import create_agent
from langchain.agents.middleware import PIIMiddleware, HumanInTheLoopMiddleware
agent = create_agent(
model="gpt-4o",
tools=[search_tool, send_email_tool],
middleware=[
# 레이어 1: 결정론적 입력 필터 (before agent)
ContentFilterMiddleware(banned_keywords=["hack", "exploit"]),
# 레이어 2: PII 보호 (모델 전후)
PIIMiddleware("email", strategy="redact", apply_to_input=True),
PIIMiddleware("email", strategy="redact", apply_to_output=True),
# 레이어 3: 민감한 도구에 대한 사람의 승인
HumanInTheLoopMiddleware(interrupt_on={"send_email": True}),
# 레이어 4: 모델 기반 안전성 검사 (after agent)
SafetyGuardrailMiddleware(),
],
)
추가 자료
- Middleware 문서 - 커스텀 미들웨어에 대한 완전한 가이드
- Middleware API 참조 - 완전한 API 참조
- Human-in-the-loop - 민감한 작업에 대한 사람의 검토 추가
- Testing agents - 안전성 메커니즘 테스트를 위한 전략
출처: https://docs.langchain.com/oss/python/langchain/guardrails
Langchain v1.0
- LangChain 개요
- LangChain v1
- LangChain v1 마이그레이션 가이드
- LangChain 설치
- QuickStart
- Philosophy
- Agents
- Models
- Messages
- Tools
- Short-term memory
- Streaming
- Middleware
- Structured output
Guardrails- Runtime
- Context Engineering
- Model Context Protocol (MCP)
- Human-in-the-loop
- Multi-agent
- Retrieval
- Long-term memory
- Studio
- Test
- Deploy
- Agent Chat UI
- Observability
