Guardrails(护栏/安全防线)
一句话概括: 给你的 AI 智能体(Agent)装上"安全安检门",让它不乱说话、不泄露隐私、不做危险操作。
什么是 Guardrails?
Guardrails 就像是你给 AI 智能体请的"安保团队"。它会在智能体执行任务的关键节点上进行检查和过滤,确保:
- 不会泄露敏感信息(比如用户的身份证号、银行卡号)
- 不会被人恶意"套话"(Prompt 注入攻击)
- 不会输出不当或有害的内容
- 遵守公司规章制度和法律合规要求
- 输出质量过关、不胡编乱造
打个比方: 想象一个银行柜台。客户(用户)提交请求,柜员(AI Agent)处理业务。Guardrails 就是银行里的保安+监控+审批流程------客户进来先安检(输入检查),柜员办事过程中有监控(中间检查),大额转账还要经理签字(人工审批),最后给客户的回执也要复核(输出检查)。
怎么实现 Guardrails?------中间件(Middleware)
Guardrails 是通过一个叫 中间件(Middleware) 的机制来实现的。中间件就像"过滤器",可以安插在智能体执行流程的不同位置:
- 智能体启动前(Before Agent):检查用户的输入是否合法
- 智能体完成后(After Agent):检查 AI 的输出是否安全
- 模型调用/工具调用的前后:检查每一步操作是否合规
文档中配了一张中间件流程图,形象地展示了请求从"进入"到"输出"要经过哪些"关卡"。
两种实现方式:确定性 vs 模型驱动
| 方式 | 通俗解释 | 优点 | 缺点 |
|---|---|---|---|
| 确定性护栏(Deterministic) | 就像"关键词过滤"或"正则匹配"------写死规则,命中就拦截 | 快、省钱、结果可预测 | 不够灵活,可能漏掉"换个说法"的违规 |
| 模型驱动护栏(Model-based) | 再请一个 AI 来"审查"另一个 AI 的输出 | 能理解语义,抓得住"拐弯抹角"的违规 | 更慢、更贵 |
打个比方: 确定性护栏就像机场的金属探测门------你带了金属就响;模型驱动护栏就像安检员用 X 光机看你的行李箱------能分辨出是钥匙还是刀具。
LangChain 既提供了内置的护栏 (开箱即用),也提供了灵活的中间件系统让你自己造。
内置护栏(Built-in Guardrails)
1. PII 检测(隐私信息检测)
PII = Personally Identifiable Information(个人身份信息),就是能识别一个人身份的数据,比如邮箱、信用卡号、IP 地址等。
什么时候用?
- 医疗/金融类应用(合规要求,不能把病人/客户的隐私传给 AI 模型)
- 客服机器人(日志里不能留下用户的真实信息)
- 任何涉及敏感数据的应用
检测到 PII 后怎么处理?有 4 种策略:
| 策略 | 通俗解释 | 举例 |
|---|---|---|
redact(涂黑) |
直接把敏感信息替换成一个标签 | john@example.com → [REDACTED_EMAIL] |
mask(遮挡) |
只露出一部分,其余用星号代替 | 5105-1051-0510-5100 → ****-****-****-5100 |
hash(哈希) |
用算法把原文变成一串乱码,但同样的输入永远得到同样的乱码 | john@example.com → a8f5f167... |
block(拦截) |
直接报错,不让继续执行 | 抛出异常,程序中断 |
代码示例通俗解读:
python
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=[
# 第1道关卡:用户输入里的邮箱,直接涂黑
PIIMiddleware("email", strategy="redact", apply_to_input=True),
# 第2道关卡:用户输入里的信用卡号,只留后4位
PIIMiddleware("credit_card", strategy="mask", apply_to_input=True),
# 第3道关卡:如果发现API密钥,直接报错中断!
PIIMiddleware(
"api_key",
detector=r"sk-[a-zA-Z0-9]{32}", # 自定义正则:匹配sk-开头的32位字符串
strategy="block",
apply_to_input=True,
),
],
)
通俗理解: 这就像给 AI 的"输入窗口"装了三层滤网:第一层把邮箱涂掉,第二层把信用卡号打码,第三层如果发现 API 密钥就直接拒绝服务。
⚠️ 特别注意(Note 部分):
如果你设置了 apply_to_output=True(也检查 AI 的输出),那么 PII 中间件还会自动过滤流式输出 (streaming)中的内容------包括文字的逐字输出、工具调用的参数、工具返回的结果等。这个功能需要 langchain >= 1.3.2 版本。
内置能识别的 PII 类型:
| 类型 | 说明 |
|---|---|
email |
电子邮箱地址 |
credit_card |
信用卡号(会用 Luhn 算法验证真伪,不会误报) |
ip |
IP 地址 |
mac_address |
网卡的 MAC 地址 |
url |
网址链接 |
配置参数一览(通俗版):
| 参数 | 通俗解释 | 默认值 |
|---|---|---|
pii_type |
你要抓哪种隐私信息 | 必填 |
strategy |
抓到后怎么处理(涂黑/遮挡/哈希/拦截) | redact(涂黑) |
detector |
自定义检测规则(比如自己写正则表达式) | 用内置规则 |
apply_to_input |
要不要检查用户发来的消息 | True(检查) |
apply_to_output |
要不要检查 AI 回复的消息 | False(不检查) |
apply_to_tool_results |
要不要检查工具返回的结果 | False(不检查) |
2. Human-in-the-Loop(人工审批)
通俗解释: 有些高风险操作,AI 不能自己做主,必须暂停下来等人类点头才能继续。就像公司里报销超过 1 万块需要经理签字一样。
适用场景:
- 转账/付款等金融操作
- 删除或修改生产数据库
- 对外发送邮件/通知
- 任何"搞砸了后果很严重"的操作
代码示例通俗解读:
python
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={
"send_email": True, # 发邮件?必须人工审批!
"delete_database": True, # 删数据库?必须人工审批!
"search": False, # 搜索?自动放行,不用审批
}
),
],
checkpointer=InMemorySaver(), # 必须配一个"记忆存储器"来保存暂停时的状态
)
# 第一步:用户说"发邮件给团队"
# → AI 准备好邮件,但暂停!等人类审批
result = agent.invoke(
{"messages": [{"role": "user", "content": "Send an email to the team"}]},
config={"configurable": {"thread_id": "some_id"}} # 必须给个线程ID,用来"记住"暂停在哪
)
# 第二步:人类看了邮件内容,觉得OK,点击"批准"
# → AI 继续执行,把邮件发出去
result = agent.invoke(
Command(resume={"decisions": [{"type": "approve"}]}), # 告诉AI:"批准了,继续!"
config={"configurable": {"thread_id": "some_id"}} # 同一个线程ID,才能接上之前暂停的地方
)
通俗比喻: 就像网购下单------你选好商品(AI 准备好操作),点"确认支付"前会弹出确认框(暂停等审批),你点了"确认"(人工批准),订单才真正提交(AI 继续执行)。thread_id 就像是你的"购物车编号",保证你回来确认时还是同一笔订单。
自定义护栏(Custom Guardrails)
内置护栏不够用?你可以自己造!LangChain 提供了两种方式:
- 类语法(Class syntax) :写一个继承自
AgentMiddleware的类 - 装饰器语法(Decorator syntax) :用
@before_agent或@after_agent装饰一个函数
两种写法效果一样,只是风格不同。
Before Agent 护栏(执行前拦截)
通俗解释: 在 AI 开始干活之前,先检查用户的请求合不合法。就像进 nightclub 之前先查身份证。
适合做的事:
- 身份验证(你有权使用这个 AI 吗?)
- 频率限制(你今天已经问了 100 次了,明天再来)
- 关键词过滤(你的问题里有违禁词,直接拒绝)
代码逻辑通俗解读(以关键词过滤为例):
python
class ContentFilterMiddleware(AgentMiddleware):
"""关键词黑名单过滤器"""
def __init__(self, banned_keywords: list[str]):
self.banned_keywords = [kw.lower() for kw in banned_keywords]
# 把黑名单关键词全转成小写,方便后面比对
@hook_config(can_jump_to=["end"]) # 告诉系统:我有权直接跳到"结束"
def before_agent(self, state, runtime):
# 1. 取出用户发的第一条消息
first_message = state["messages"][0]
content = first_message.content.lower()
# 2. 逐个检查黑名单关键词
for keyword in self.banned_keywords:
if keyword in content:
# 3. 命中了!直接返回一条拒绝消息,并跳到"end"结束流程
return {
"messages": [{"role": "assistant", "content": "您的请求包含不当内容,请重新表述。"}],
"jump_to": "end" # 关键!直接跳到终点,AI 根本不会处理这个请求
}
# 4. 没命中任何关键词,返回 None 表示"放行"
return None
打个比方: 这就像小区门口的保安,你进门时他看一眼你的脸------如果在"黑名单"上,直接拦下;不在,就放行。而且你压根儿就进不了小区(AI 完全不会处理你的请求),省了资源。
关键知识点:
@hook_config(can_jump_to=["end"]):这个装饰器告诉系统,你的方法有能力"直接跳到终点",不让 AI 继续执行。return None表示"没问题,放行";返回一个 dict 表示"有问题,按我说的处理"。"jump_to": "end"是最强拦截------直接结束整个流程。
After Agent 护栏(执行后审查)
通俗解释: AI 干完活了,但在把结果交给用户之前,再找"审查员"看一眼。就像工厂的产品出厂前要过质检。
适合做的事:
- 用另一个 AI 模型判断回复是否安全
- 检查回复质量(有没有胡编乱造)
- 最终合规扫描
代码逻辑通俗解读(以 AI 安全审查为例):
python
class SafetyGuardrailMiddleware(AgentMiddleware):
"""用一个"审查AI"来检查"工作AI"的回复是否安全"""
def __init__(self):
self.safety_model = init_chat_model("gpt-5.4-mini")
# 请一个"小AI"(便宜、快的模型)当审查员
@hook_config(can_jump_to=["end"])
def after_agent(self, state, runtime):
# 1. 拿到AI最后的回复
last_message = state["messages"][-1]
# 2. 让"审查AI"判断这个回复安不安全
safety_prompt = f"""评估以下回复是否安全合适。
只回答 'SAFE'(安全)或 'UNSAFE'(不安全)。
回复内容:{last_message.content}"""
result = self.safety_model.invoke([{"role": "user", "content": safety_prompt}])
# 3. 如果不安全,把回复替换成拒绝消息
if "UNSAFE" in result.content:
last_message.content = "我无法提供该回复,请重新表述您的请求。"
return None
打个比方: 这就像一个餐厅,厨师(主 AI 模型)做好了一道菜,但在端给客人之前,要经过传菜窗口旁的食品卫生检查员(审查 AI)。如果检查员说"这菜有问题",就直接换成一盘"抱歉,这道菜做不了"的提示牌端出去。
组合多层护栏(Combine Multiple Guardrails)
通俗解释: 护栏不是只能装一道,你可以像"洋葱"一样一层一层地装,每一层管一件事。
代码通俗解读:
python
agent = create_agent(
model="gpt-5.5",
tools=[search_tool, send_email_tool],
middleware=[
# 🔒 第1层:关键词黑名单(最快、最省钱,在最前面拦截明显违规)
ContentFilterMiddleware(banned_keywords=["hack", "exploit"]),
# 🔒 第2层:隐私信息保护(输入时涂黑邮箱,输出时也涂黑邮箱)
PIIMiddleware("email", strategy="redact", apply_to_input=True),
PIIMiddleware("email", strategy="redact", apply_to_output=True),
# 🔒 第3层:人工审批(发邮件前必须人类确认)
HumanInTheLoopMiddleware(interrupt_on={"send_email": True}),
# 🔒 第4层:AI安全审查(最后用AI模型检查回复是否安全)
SafetyGuardrailMiddleware(),
],
)
打个比方: 就像机场安检的流程------
- 第1层:门口查护照(身份验证/关键词过滤)→ 没护照直接走人
- 第2层:行李过 X 光机(PII 检测)→ 发现液体拿出来
- 第3层:登机口核实机票(人工审批)→ 没问题才让登机
- 第4层:飞行途中空乘巡视(AI 安全审查)→ 确保一切正常
执行顺序很重要: 中间件按照数组中的顺序依次执行。把"快且便宜"的放前面(关键词匹配),"慢且贵"的放后面(AI 审查),这样大多数违规在早期就被拦下,节省资源。
额外资源(Additional Resources)
文档最后提供了一些延伸学习链接:
| 资源 | 说明 |
|---|---|
| Middleware 文档 | 中间件的完整使用指南 |
| Middleware API 参考 | 中间件的 API 接口文档 |
| Human-in-the-loop | 人工审批工作流的详细实现 |
| 测试 Agents | 如何测试你的安全机制是否有效 |
全文总结(一张图看懂 Guardrails)
用户输入
│
▼
┌──────────────────────────────┐
│ 第1层:Before Agent │ ← 关键词过滤、身份验证(确定性,快)
│ (执行前拦截) │
└──────────────┬───────────────┘
│ 放行
▼
┌──────────────────────────────┐
│ 第2层:PII 检测(输入) │ ← 邮箱涂黑、信用卡打码
└──────────────┬───────────────┘
│
▼
┌──────────────────────────────┐
│ 🤖 AI Agent 执行任务 │ ← 调用模型、使用工具
│ (中间可能触发人工审批) │ ← Human-in-the-loop 暂停等批准
└──────────────┬───────────────┘
│
▼
┌──────────────────────────────┐
│ 第3层:PII 检测(输出) │ ← 防止AI在回复中泄露隐私
└──────────────┬───────────────┘
│
▼
┌──────────────────────────────┐
│ 第4层:After Agent │ ← AI审查AI,检查回复安全性(模型驱动,慢)
│ (执行后审查) │
└──────────────┬───────────────┘
│
▼
返回给用户
核心思想: 像洋葱一样层层防护,既用"快而便宜"的规则做第一道筛子,也用"慢而聪明"的 AI 做最后把关,关键操作还要让人类拍板------确保 AI 应用安全、合规、可靠。