护栏 (Guardrails)
护栏帮助你构建安全、合规的 AI 应用,通过在智能体执行的关键点验证和过滤内容。它们可以检测敏感信息、执行内容策略、验证输出,并在问题发生前防止不安全行为。
常见用例包括:
- 防止 PII(个人身份信息)泄露
- 检测和阻止提示注入攻击
- 阻止不当或有害内容
- 执行业务规则和合规要求
- 验证输出质量和准确性
你可以使用中间件在战略性位置拦截执行来实现护栏 - 在智能体启动前、完成后,或围绕模型和工具调用。
护栏可以使用两种互补的方法实现:
确定性护栏:使用基于规则的逻辑,如正则表达式模式、关键词匹配或显式检查。快速、可预测且经济高效,但可能遗漏细微的违规行为。
基于模型的护栏:使用 LLM 或分类器进行语义理解来评估内容。可以捕获规则遗漏的细微问题,但速度较慢且成本较高。
LangChain 提供内置护栏(如 PII 检测、人机协作)以及用于构建自定义护栏的灵活中间件系统。
内置护栏
PII 检测
LangChain 提供内置中间件,用于检测和处理对话中的个人身份信息 (PII)。该中间件可以检测常见的 PII 类型,如电子邮件、信用卡、IP 地址等。
PII 检测中间件适用于以下场景:具有合规要求的医疗保健和金融应用、需要清理日志的客户服务智能体,以及任何处理敏感用户数据的应用。
PII 中间件支持多种处理检测到的 PII 的策略:
| 策略 | 描述 | 示例 |
|---|---|---|
redact |
替换为 [REDACTED_{PII_TYPE}] |
[REDACTED_EMAIL] |
mask |
部分遮蔽(如只显示最后4位) | ****-****-****-1234 |
hash |
替换为确定性哈希 | a8f5f167... |
block |
检测到时抛出异常 | 抛出错误 |
import { createAgent, piiRedactionMiddleware } from "langchain";
const agent = createAgent({
model: "gpt-4o",
tools: [customerServiceTool, emailTool],
middleware: [
// 在发送到模型前脱敏用户输入中的邮箱
piiRedactionMiddleware({
piiType: "email",
strategy: "redact",
applyToInput: true,
}),
// 遮蔽用户输入中的信用卡号
piiRedactionMiddleware({
piiType: "credit_card",
strategy: "mask",
applyToInput: true,
}),
// 阻止 API 密钥 - 检测到时抛出错误
piiRedactionMiddleware({
piiType: "api_key",
detector: /sk-[a-zA-Z0-9]{32}/,
strategy: "block",
applyToInput: true,
}),
],
});
// 当用户提供 PII 时,将根据策略进行处理
const result = await agent.invoke({
messages: [{
role: "user",
content: "我的邮箱是 test@example.com,信用卡号是 5105-1051-0510-5100"
}]
});
内置 PII 类型
email- 电子邮件地址credit_card- 信用卡号(Luhn 验证)ip- IP 地址mac_address- MAC 地址url- URL 地址
配置选项
| 参数 | 描述 | 默认值 |
|---|---|---|
piiType |
要检测的 PII 类型(内置或自定义) | 必填 |
strategy |
如何处理检测到的 PII | "redact" |
detector |
自定义检测器正则表达式 | 使用内置 |
applyToInput |
在模型调用前检查用户消息 | true |
applyToOutput |
在模型调用后检查 AI 消息 | false |
applyToToolResults |
执行后检查工具结果消息 | false |
人机协作
LangChain 提供内置中间件,用于在执行敏感操作前要求人工批准。这是高风险决策最有效的护栏之一。
人机协作中间件适用于以下场景:金融交易和转账、删除或修改生产数据、向外部方发送通信,以及任何具有重大业务影响的操作。
import { createAgent, humanInTheLoopMiddleware } from "langchain";
import { MemorySaver, Command } from "@langchain/langgraph";
const agent = createAgent({
model: "gpt-4o",
tools: [searchTool, sendEmailTool, deleteDatabaseTool],
middleware: [
humanInTheLoopMiddleware({
interruptOn: {
// 敏感操作需要批准
send_email: { allowAccept: true, allowEdit: true, allowRespond: true },
delete_database: { allowAccept: true, allowEdit: true, allowRespond: true },
// 安全操作自动批准
search: false,
}
}),
],
checkpointer: new MemorySaver(),
});
// 人机协作需要线程 ID 以进行持久化
const config = { configurable: { thread_id: "some_id" } };
// 智能体将暂停并等待批准后再执行敏感工具
let result = await agent.invoke(
{ messages: [{ role: "user", content: "给团队发送一封邮件" }] },
config
);
// 批准后恢复执行
result = await agent.invoke(
new Command({ resume: { decisions: [{ type: "approve" }] } }),
config // 使用相同的线程 ID 恢复暂停的对话
);
提示:查看人机协作文档了解实现批准工作流的完整详情。
自定义护栏
对于更复杂的护栏,你可以创建在智能体执行前后运行的自定义中间件。这让你可以完全控制验证逻辑、内容过滤和安全检查。
智能体前护栏
使用"智能体前"钩子在每次调用开始时验证请求一次。这对于会话级别的检查很有用,如身份验证、速率限制或在任何处理开始前阻止不当请求。
import { createMiddleware, AIMessage } from "langchain";
const contentFilterMiddleware = (bannedKeywords: string[]) => {
const keywords = bannedKeywords.map(kw => kw.toLowerCase());
return createMiddleware({
name: "ContentFilterMiddleware",
beforeAgent: {
hook: (state) => {
// 获取第一条用户消息
if (!state.messages || state.messages.length === 0) {
return;
}
const firstMessage = state.messages[0];
if (firstMessage._getType() !== "human") {
return;
}
const content = firstMessage.content.toString().toLowerCase();
// 检查禁用关键词
for (const keyword of keywords) {
if (content.includes(keyword)) {
// 在任何处理前阻止执行
return {
messages: [
new AIMessage(
"我无法处理包含不当内容的请求。请重新表述您的请求。"
)
],
jumpTo: "end",
};
}
}
return;
},
canJumpTo: ['end']
}
});
};
// 使用自定义护栏
import { createAgent } from "langchain";
const agent = createAgent({
model: "gpt-4o",
tools: [searchTool, calculatorTool],
middleware: [
contentFilterMiddleware(["hack", "exploit", "malware"]),
],
});
// 此请求将在任何处理前被阻止
const result = await agent.invoke({
messages: [{ role: "user", content: "如何 hack 进入数据库?" }]
});
智能体后护栏
使用"智能体后"钩子在返回用户前验证最终输出一次。这对于基于模型的安全检查、质量验证或对完整智能体响应的最终合规扫描很有用。
import { createMiddleware, AIMessage, initChatModel } from "langchain";
const safetyGuardrailMiddleware = () => {
const safetyModel = initChatModel("gpt-4o-mini");
return createMiddleware({
name: "SafetyGuardrailMiddleware",
afterAgent: {
hook: async (state) => {
// 获取最终的 AI 响应
if (!state.messages || state.messages.length === 0) {
return;
}
const lastMessage = state.messages[state.messages.length - 1];
if (lastMessage._getType() !== "ai") {
return;
}
// 使用模型评估安全性
const safetyPrompt = `评估此响应是否安全和适当。
仅回复 'SAFE' 或 'UNSAFE'。
响应: ${lastMessage.content.toString()}`;
const result = await safetyModel.invoke([
{ role: "user", content: safetyPrompt }
]);
if (result.content.toString().includes("UNSAFE")) {
return {
messages: [
new AIMessage(
"我无法提供该响应。请重新表述您的请求。"
)
],
jumpTo: "end",
};
}
return;
},
canJumpTo: ['end']
}
});
};
// 使用安全护栏
import { createAgent } from "langchain";
const agent = createAgent({
model: "gpt-4o",
tools: [searchTool, calculatorTool],
middleware: [safetyGuardrailMiddleware()],
});
组合多个护栏
你可以通过将多个护栏添加到中间件数组来堆叠它们。它们按顺序执行,允许你构建分层保护:
import { createAgent, piiRedactionMiddleware, humanInTheLoopMiddleware } from "langchain";
const agent = createAgent({
model: "gpt-4o",
tools: [searchTool, sendEmailTool],
middleware: [
// 第1层:确定性输入过滤器(智能体前)
contentFilterMiddleware(["hack", "exploit"]),
// 第2层:PII 保护(模型前后)
piiRedactionMiddleware({
piiType: "email",
strategy: "redact",
applyToInput: true,
}),
piiRedactionMiddleware({
piiType: "email",
strategy: "redact",
applyToOutput: true,
}),
// 第3层:敏感工具需要人工批准
humanInTheLoopMiddleware({
interruptOn: {
send_email: { allowAccept: true, allowEdit: true, allowRespond: true },
}
}),
// 第4层:基于模型的安全检查(智能体后)
safetyGuardrailMiddleware(),
],
});