护栏 (Guardrails)

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

常见用例包括:

你可以使用中间件在战略性位置拦截执行来实现护栏 - 在智能体启动前、完成后,或围绕模型和工具调用。

护栏可以使用两种互补的方法实现:

确定性护栏:使用基于规则的逻辑,如正则表达式模式、关键词匹配或显式检查。快速、可预测且经济高效,但可能遗漏细微的违规行为。

基于模型的护栏:使用 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 类型

配置选项

参数 描述 默认值
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(),
  ],
});

更多资源