GuardRails通过validating和flitering content来帮助你构建安全合规的agent
常见的应用场景:
- 预防个人信息的泄露
- 检测和阻止提示词注入攻击
- 阻止不恰当和有害的攻击
- 执行业务规则和合规性要求
- 验证输出重量和正确性
你可以在使用middleware在关键节点拦截执行
before the agent starts, after it completes, or around model and tool calls.
两种互补的办法实现 Guardrails:
1.Deterministic guardrails:
使用规则的逻辑比如正则表达式,关键词匹配或者显式检查
优点:快且省 缺点:可能漏掉细微的违规情况
2.Model-based guradrails
使用LLM或者classifiers进行语义分析
优点:效果好 缺点:延迟高,成本更高
Built-in guardrail#
PII detection#
可以检测emails,credit cards,IP addresses和其他的PII
提供了几种解决PII检测的策略:
| Strategy | Description | Example |
|---|
redact | Replace with [REDACTED_{PII_TYPE}] | [REDACTED_EMAIL] |
mask | Partially obscure (e.g., last 4 digits) | ****-****-****-1234 |
hash | Replace with deterministic hash | a8f5f167... |
block | Raise exception when detected | Error thrown |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
| from langchain.agents import create_agent
from langchain.agents.middleware import PIIMiddleware
agent = create_agent(
model="gpt-5.5",
tools=[customer_service_tool, email_tool],
middleware=[
# Redact emails in user input before sending to model
PIIMiddleware(
"email",
strategy="redact",
apply_to_input=True,
),
# Mask credit cards in user input
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({
"messages": [{"role": "user", "content": "My email is john.doe@example.com and card is 5105-1051-0510-5100"}]
})
|
Human-in-the-loop#
执行敏感操作之前征求人工的approval
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
| 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-5.5",
tools=[search_tool, send_email_tool, delete_database_tool],
middleware=[
HumanInTheLoopMiddleware(
interrupt_on={
# Require approval for sensitive operations
"send_email": True,
"delete_database": True,
# Auto-approve safe operations
"search": False,
}
),
],
# Persist the state across interrupts
checkpointer=InMemorySaver(),
)
# Human-in-the-loop requires a thread ID for persistence
config = {"configurable": {"thread_id": "some_id"}}
# Agent will pause and wait for approval before executing sensitive tools
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 # Same thread ID to resume the paused conversation
)
|
Custom guardrail#
对于更加复杂的需求,可以自定义在agent执行之前和之后的middleware
Before agent guardrail#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
| from typing import Any
from langchain.agents.middleware import AgentMiddleware, AgentState, hook_config
from langgraph.runtime import Runtime
class ContentFilterMiddleware(AgentMiddleware):
"""Deterministic guardrail: Block requests containing banned keywords."""
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:
# Get the first user message
if not state["messages"]:
return None
first_message = state["messages"][0]
if first_message.type != "human":
return None
content = first_message.content.lower()
# Check for banned keywords
for keyword in self.banned_keywords:
if keyword in content:
# Block execution before any processing
return {
"messages": [{
"role": "assistant",
"content": "I cannot process requests containing inappropriate content. Please rephrase your request."
}],
"jump_to": "end"
}
return None
# Use the custom guardrail
from langchain.agents import create_agent
agent = create_agent(
model="gpt-5.5",
tools=[search_tool, calculator_tool],
middleware=[
ContentFilterMiddleware(
banned_keywords=["hack", "exploit", "malware"]
),
],
)
# This request will be blocked before any processing
result = agent.invoke({
"messages": [{"role": "user", "content": "How do I hack into a database?"}]
})
|
Use “before agent” hook 来验证
适用于会话级别的检查(例如身份验证,速率限制,拦截不安全的请求)
After agent guardrail#
使用"after agent" hooks来验证输出
使用于居于模型的安全检查,质量验证和最终合规性扫描
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
| 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:
# Get the final AI response
if not state["messages"]:
return None
last_message = state["messages"][-1]
if not isinstance(last_message, AIMessage):
return None
# Use a model to evaluate safety
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:
last_message.content = "I cannot provide that response. Please rephrase your request."
return None
# Use the safety guardrail
from langchain.agents import create_agent
agent = create_agent(
model="gpt-5.5",
tools=[search_tool, calculator_tool],
middleware=[SafetyGuardrailMiddleware()],
)
result = agent.invoke({
"messages": [{"role": "user", "content": "How do I make explosives?"}]
})
|
Combine multiple guardrails#
你可以将多个安全护栏加入middleware数组来堆叠他们,他们将按顺序执行,并且允许你构建层级保护
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
| from langchain.agents import create_agent
from langchain.agents.middleware import PIIMiddleware, HumanInTheLoopMiddleware
agent = create_agent(
model="gpt-5.5",
tools=[search_tool, send_email_tool],
middleware=[
# Layer 1: Deterministic input filter (before agent)
ContentFilterMiddleware(banned_keywords=["hack", "exploit"]),
# Layer 2: PII protection (before and after model)
PIIMiddleware("email", strategy="redact", apply_to_input=True),
PIIMiddleware("email", strategy="redact", apply_to_output=True),
# Layer 3: Human approval for sensitive tools
HumanInTheLoopMiddleware(interrupt_on={"send_email": True}),
# Layer 4: Model-based safety check (after agent)
SafetyGuardrailMiddleware(),
],
)
|