LangChain 安全防护体系——护栏、人机交互与多层防御架构

本文为「AI Agent 技术系列」第 5 篇。在 LangChain 工程化(第 4 篇)基础上,深入安全防护这一个切面。

一、主题定义与背景

AI Agent 的三大失控风险

不给 Agent 上锁,就像把公司大门钥匙交给陌生人。生产环境中的 AI Agent 面临三类核心风险:

风险类型 表现 后果
权限越界 Agent 擅自执行未授权操作,如删除数据库、发送未经审批的邮件 数据丢失、业务中断
数据泄露 Agent 回复中包含个人身份信息(PII),如邮箱、信用卡号、身份证号 合规违规、信誉损失
合规风险 Agent 输出不当内容或违反行业法规 法律风险、监管处罚

护栏的正式定义

LangChain 官方文档对护栏的定义 [1]:

“守卫(Guardrails)通过在您的智能体执行的关键点验证和过滤内容,帮助您构建安全、合规的 AI 应用。它们可以在问题发生前检测敏感信息、强制执行内容策略、验证输出并防止不安全行为。”

护栏的核心机制是中间件拦截——不是魔法,而是在 Agent 执行流程的关键节点插入检查点。

2024-2025 年 AI Agent 安全态势

随着 Agent 在生产环境的大规模部署,安全问题日益突出 [2]:

  • Prompt 注入攻击成为最常见的攻击向量
  • 多起 AI Agent 导致的数据泄露事件被报道
  • EU AI Act 等法规对 AI 系统提出明确的安全合规要求
  • OWASP 发布 LLM 应用 Top 10 安全风险清单

二、核心技术原理与架构设计

2.1 护栏中间件拦截模型

护栏就卡在 Agent 执行流程的三个关键节点上:

flowchart LR
    A[用户请求] --> B[beforeModel<br/>前置拦截]
    B --> C[Agent 执行<br/>LLM 推理]
    C --> D[工具调用拦截<br/>权限控制]
    D --> E[afterModel<br/>输出验证]
    E --> F[返回用户]

    B -.->|违规则跳过| F
    D -.->|违规则阻止| F
    E -.->|违规则替换| F
拦截点 职责 典型用途
beforeModel 在 Agent 处理前拦截 身份验证、内容过滤、阻止不当请求
工具调用拦截 控制 Agent 能做什么 限制哪些工具可用、哪些数据能访问
afterModel 在输出返回前验证 PII 脱敏、内容安全审查

2.2 内置护栏一:HITL 人机交互

HITL 的核心思想:让 AI 在关键操作前「停下来」,等待人类审核与批准。

三模块架构

flowchart LR
    A[Agent<br/>智能助手] -->|敏感操作| B[Interrupt<br/>检查站]
    B -->|暂停等待| C[Decision<br/>审核界面]
    C -->|批准/拒绝/编辑| A
模块 职责 类比
Agent(智能助手) 使用各种工具完成任务 有能力的员工
Interrupt(检查站) 敏感操作时自动暂停 公司的审批流程
Decision(审核界面) 展示操作详情,收集人类决策 审批表单

完整实现(基于 humanInTheLoopMiddleware):

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
56
57
58
59
60
61
62
63
64
65
66
67
import { createAgent, tool, humanInTheLoopMiddleware } from "langchain";
import { ChatOpenAI } from "@langchain/openai";
import { MemorySaver } from "@langchain/langgraph";
import { z } from "zod";

// 步骤 1:创建工具
const writeFile = tool(
async ({ file_path, content }) => `已写入 ${file_path}`,
{
name: "write_file",
description: "写入文件到指定路径",
schema: z.object({
file_path: z.string(),
content: z.string(),
}),
}
);

const executeSql = tool(
async ({ query }) => `执行: ${query}`,
{
name: "execute_sql",
description: "执行 SQL 查询",
schema: z.object({ query: z.string() }),
}
);

const readData = tool(
async ({ data_source }) => `读取 ${data_source} 的数据`,
{
name: "read_data",
description: "读取数据",
schema: z.object({ data_source: z.string() }),
}
);

// 步骤 2:设置审批规则并创建 Agent
const model = new ChatOpenAI({
model: "qwen3.6-plus",
configuration: {
baseURL: "https://dashscope.aliyuncs.com/compatible-mode/v1",
apiKey: process.env.DASHSCOPE_API_KEY,
},
});

const agent = createAgent({
model,
tools: [writeFile, executeSql, readData],
middleware: [
humanInTheLoopMiddleware({
interruptOn: {
// 完全审核:可批准 / 拒绝 / 编辑参数
write_file: { allowedDecisions: ["approve", "edit", "reject"] },
// 严格审核:只允许批准 / 拒绝,不能修改参数
execute_sql: {
allowedDecisions: ["approve", "reject"],
description: "🚨 SQL 执行需要 DBA 审批",
},
// 安全操作,无需审核
read_data: false,
},
descriptionPrefix: "工具执行待审批",
}),
],
// HITL 必须启用 checkpointer,用于暂停/恢复状态
checkpointer: new MemorySaver(),
});

步骤 3:处理中断与恢复执行

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
import { Command } from "@langchain/langgraph";
import { HumanMessage } from "langchain";

const config = { configurable: { thread_id: crypto.randomUUID() } };

// 运行 Agent,直到命中中断
const result = await agent.invoke(
{ messages: [new HumanMessage("帮我删除测试数据库中的过期数据")] },
config
);

// 检测到中断 → 展示审核界面
if (result.__interrupt__?.length) {
const { actionRequests, reviewConfigs } = result.__interrupt__[0].value;

console.log("⚠️ 敏感操作待审批:");
console.log(`工具: ${actionRequests[0].name}`);
console.log(`参数: ${JSON.stringify(actionRequests[0].args)}`);

// 收集人类决策(批准 / 拒绝 / 编辑)
const decisions = await promptForDecisions(actionRequests, reviewConfigs);

// 恢复 Agent 执行
const finalResult = await agent.invoke(
new Command({ resume: { decisions } }),
config
);
console.log(finalResult.messages.at(-1)?.content);
}

完整工作流

1
2
3
4
5
6
7
8
9
用户请求: "帮我删除测试数据库中的过期数据"

AI 准备: 执行 SQL: DELETE FROM logs WHERE date < "2024-01-01"

🛑 系统暂停: 操作类型=执行SQL,风险提示=需要DBA批准

人类审核: 选择「编辑」→ 修改为 DELETE FROM logs WHERE date < "2023-01-01"

AI 完成: 成功删除过期数据,共清理 1000 条记录

2.3 内置护栏二:PII 个人数据保护

自动检测对话中的个人信息,从源头防泄露。

5 类内置检测

PII 类型 检测方式 示例
邮箱地址 正则 + 域名校验 user@company.com
信用卡号 Luhn 算法校验 4532-1234-5678-9010
IP 地址 IPv4/IPv6 格式 192.168.1.1
MAC 地址 格式校验 aa:bb:cc:dd:ee:ff
URL 链接 协议 + 域名 https://example.com

使用方式

1
2
3
4
5
6
7
8
9
10
import { createAgent, piiMiddleware } from "langchain";

const agent = createAgent({
model,
tools,
middleware: [
piiMiddleware("email"), // 遮盖邮箱:user@***.com
piiMiddleware("credit_card"), // 替换信用卡:[REDACTED_CC]
],
});
策略 行为 适用场景
Mask(遮盖) 只显示部分,如 1234---5678 需要部分可见的场景
Redact(替换) 替换为 [REDACTED_EMAIL] 标记 完全隐藏但保留标记
Hash(哈希) 转为不可逆哈希值,不影响匹配 需要去重但不泄露原文
Block(阻止) 检测到直接抛异常,完全阻止 严格禁止的场景

还可自定义检测规则,比如检测 API 密钥格式 sk-xxx...

2.4 自定义护栏:createMiddleware 钩子

当内置护栏不够用时,用 createMiddleware 自己写 [3]:

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
import { createAgent, createMiddleware } from "langchain";
import { AIMessage } from "langchain";

// Agent 前护栏:关键词过滤
const keywordFilter = createMiddleware({
name: "KeywordFilter",
beforeModel: ({ state }) => {
const lastMessage = state.messages[state.messages.length - 1];
if (containsSensitiveWord(lastMessage.content)) {
// 返回消息直接跳过 Agent 执行,进入结束流程
return {
messages: [new AIMessage({ content: "请求包含敏感词,已被拦截" })],
};
}
// 返回 undefined 表示继续执行
},
});

// Agent 后护栏:内容安全评估(用 AI 检查 AI)
const contentSafety = createMiddleware({
name: "ContentSafety",
afterModel: ({ state }) => {
const lastMessage = state.messages[state.messages.length - 1];
if (isUnsafe(lastMessage.content)) {
return {
messages: [new AIMessage({ content: "无法提供该回复,请重新提问" })],
};
}
},
});

// 注册到 Agent
const agent = createAgent({
model,
tools,
middleware: [keywordFilter, contentSafety],
});

关键机制beforeModel / afterModel 返回消息后,该消息会直接作为输出返回,跳过后续 Agent 执行流程 [3]。

注意:LangChain v1 中中间件钩子名称为 beforeModel / afterModel(v0 中为 preModelHook / postModelHook),迁移时需更新 [3]。


三、实际应用场景与最佳实践

场景一:金融系统大额转账审批

使用 interrupt 函数实现工具内部的动态审批:

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
import { tool } from "langchain";
import { interrupt } from "@langchain/langgraph";
import { z } from "zod";

const transferMoney = tool(
async ({ account, amount }) => {
// 金额超过 10000 触发人工审批
if (amount > 10000) {
const approval = await interrupt({
operation: "银行转账",
account,
amount,
risk_level: "HIGH",
message: `转账 ¥${amount} 到账户 ${account},需要经理审批`,
});

if (approval.decision === "approved") {
return `转账成功:¥${amount}${account}`;
} else if (approval.decision === "rejected") {
return "转账已被拒绝";
} else if (approval.decision === "edited") {
const newAmount = approval.params.amount;
return `转账成功(已修改):¥${newAmount}${account}`;
}
}
// 小额直接执行
return `转账成功:¥${amount}${account}`;
},
{
name: "transfer_money",
description: "转账到指定账户",
schema: z.object({
account: z.string(),
amount: z.number(),
}),
}
);

场景二:内容发布平台 PII 脱敏

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
import { createAgent, createMiddleware, piiMiddleware } from "langchain";

const piiProtection = createMiddleware({
name: "PIIProtection",
afterModel: ({ state }) => {
// PII 中间件自动处理后返回脱敏结果
const lastMessage = state.messages[state.messages.length - 1];
const sanitized = sanitizePII(lastMessage.content, {
email: "mask",
credit_card: "redact",
ip: "hash",
phone: "mask",
});
if (sanitized !== lastMessage.content) {
return {
messages: [new AIMessage({ content: sanitized })],
};
}
},
});

// 应用于内容发布 Agent
const publishingAgent = createAgent({
model,
tools: [writeArticle, publishToCms, sendNotification],
middleware: [piiProtection],
});

多层组合防御架构

多个护栏按顺序叠加,一层一层过滤:

flowchart TD
    A[用户输入] --> B[第一层:输入过滤<br/>关键词拦截 + 身份验证]
    B --> C[第二层:PII 保护<br/>自动遮盖信用卡、邮箱等]
    C --> D[第三层:人工审批<br/>敏感工具需要人点头]
    D --> E[第四层:输出验证<br/>AI 检查 AI 的回复是否安全]
    E --> F[返回用户]
1
2
3
4
5
6
7
8
9
10
11
// 构建多层防护体系
const multiLayerAgent = createAgent({
model,
tools: [writeFile, executeSql, sendEmail, readData],
middleware: [
inputFilter, // 第一层:输入关键词过滤
piiMiddleware("email"), // 第二层:PII 自动脱敏
hitlApproval, // 第三层:敏感操作人工审批
outputValidation, // 第四层:输出安全验证
],
});

没有唯一的正确答案——根据业务场景灵活组合,才是最佳方案。


四、常见挑战与解决方案

挑战 表现 解决方案
护栏规则过多影响性能 每次请求经过多层检查,延迟增加 分层拦截 + 短路返回(违规即停)
HITL 审批延迟导致用户体验差 用户等待人工审批时无反馈 异步通知 + 超时策略 + 状态查询
PII 检测误报率高 正常内容被误判为 PII 自定义规则 + 白名单机制
护栏配置复杂 规则分散,难以管理 集中配置文件 + 环境分离
审计追溯困难 出事后无法定位是哪一层漏过 每层记录拦截日志 + LangSmith trace

短路返回示例

1
2
3
4
5
6
7
8
9
10
11
12
13
function layeredCheck(state: AgentState): AIMessage | undefined {
const checks = [identityCheck, keywordCheck, rateLimitCheck];

for (const check of checks) {
const result = check(state);
if (result.blocked) {
// 短路返回,跳过后续检查
return new AIMessage({ content: result.message });
}
}
// 全部通过,返回 undefined 继续 Agent 执行
return undefined;
}

五、行业趋势与前沿进展

AI Agent 安全合规框架

2024-2025 年,多个 AI 安全合规框架出台:

框架 发布方 核心要求
EU AI Act 欧盟 高风险 AI 系统必须有人工监督和透明度要求
NIST AI RMF 美国国家标准与技术研究院 AI 风险管理框架,强调 Govern/Map/Measure/Manage
OWASP LLM Top 10 OWASP LLM 应用十大安全风险清单

LangChain 的护栏机制与这些框架高度契合——HITL 满足”人工监督”要求,PII 保护满足”透明度”要求 [1]。

Guardrails 竞品对比

框架 定位 优势 与 LangChain 护栏的关系
LangChain Guardrails Agent 执行流程护栏 与 LangGraph 深度集成 内置,开箱即用 [1]
Guardrails AI 结构化输出验证 50+ 内置验证器,支持自动修复 可作为 afterModel 钩子集成 [4]
NeMo Guardrails NVIDIA 出品,对话级护栏 强大的对话流程控制 独立方案,可与 LangChain 并存 [5]

趋势:Guardrails AI 和 NeMo Guardrails 已宣布集成合作 [4]——NeMo Guardrails 平台 + Guardrails AI 验证器,可自动调整 LLM 无效输出或重新提示。

AI 安全评估基准

AI 安全评估正在标准化:

  • PurpleLlama(Meta):LLM 安全评估工具集
  • AILuminate:AI 系统安全基准测试
  • LangSmith Evals:LangChain 生态内置的评估工具,可对护栏效果进行持续评估 [6]

结论

LangChain 安全防护体系的核心可归纳为三层:

  1. 内置护栏,开箱即用:PII 数据保护和人在回路(HITL),通过 piiMiddlewarehumanInTheLoopMiddleware 即可配置
  2. 自定义护栏,灵活扩展:通过 createMiddleware 编写 beforeModel / afterModel 钩子,控制任何执行节点
  3. 多层组合,纵深防御:多个护栏按顺序叠加,构建从输入到输出的完整安全链

安全是 AI 工程化的基石,不是可选项。从”能用”到”安全地用”,护栏机制是必经之路。


参考资料

[1] LangChain 守卫(Guardrails)官方文档. 2026-05-27

[2] AI Agent Harness Engineering 安全防护方案. 2026

[3] LangChain Middleware Overview. 2026-06

[4] Guardrails AI and NVIDIA NeMo Guardrails 集成. 2026-05-08

[5] NeMo Guardrails GitHub

[6] LangSmith: AI Agent & LLM Observability Platform. 2026