SafeGuardAdvisor 安全审查

SafeGuardAdvisor 类是一个关键内容安全审查组件,用于在 AI 生成内容(如聊天回复、文本生成)时进行实时风险检测(如暴力、仇恨言论、隐私泄露等),确保输出符合安全策略。

  

核心功能

SafeGuardAdvisor 类的核心功能如下:

敏敏感词校验

SafeGuardAdvisor 可精准识别并拦截含敏感词的用户输入,有效规避因信息处理不当导致的系统风险。敏感词库支持按需定制与动态更新,确保对各类敏感信息的识别与处理始终精准高效。

请求拦截

当用户提交的内容触发敏感词机制时,SafeGuardAdvisor 会即时拦截该请求,终止后续大模型调用流程。这一机制既能减少不必要的计算资源消耗,也能从源头防范因处理敏感信息引发的潜在安全隐患。

合规性保障

通过敏感词校验与请求拦截的协同作用,SafeGuardAdvisor 助力系统在用户信息处理环节严格遵循相关法律法规及行业标准,显著提升系统合规水平,降低因违规操作导致的法律风险。

  

工作原理

SafeGuardAdvisor 类的工作原理如下:

(1)请求拦截

当用户向系统提交请求时,SafeGuardAdvisor 类会首先对该请求进行拦截。对请求中的文本内容进行敏感词校验,以判断是否存在敏感信息。

(2)敏感词识别

SafeGuardAdvisor 类使用预定义的敏感词库对请求中的文本进行匹配。如果发现文本中包含敏感词,则触发敏感词机制。

(3)请求处理

如果请求被识别为包含敏感信息,SafeGuardAdvisor 类会立即对该请求进行拦截,并返回相应的错误信息或提示。如果请求不包含敏感信息,则允许其继续传递至后续的 Advisor 组件或聊天模型进行处理。

 

构造方法

SafeGuardAdvisor 和其他 Advisor 不同,提供了两个公开的构造方法,如下:

public SafeGuardAdvisor(List<String> sensitiveWords) {
    this(sensitiveWords, DEFAULT_FAILURE_RESPONSE, DEFAULT_ORDER);
}

public SafeGuardAdvisor(List<String> sensitiveWords, String failureResponse, int order) {
    Assert.notNull(sensitiveWords, "Sensitive words must not be null!");
    Assert.notNull(failureResponse, "Failure response must not be null!");
    this.sensitiveWords = sensitiveWords;
    this.failureResponse = failureResponse;
    this.order = order;
}

参数说明:

  • sensitiveWords  敏感词列表,用于内容审查。在 SafeGuardAdvisor 的后续处理中,系统会检查输入内容是否包含这些敏感词,若包含则触发安全机制。

  • failureResponse  当检测到敏感词时返回的失败响应信息。当用户输入包含敏感词时,系统会直接返回此消息,而非继续处理请求。默认值为:

private static final String DEFAULT_FAILURE_RESPONSE = 
    "I'm unable to respond to that due to sensitive content. Could we rephrase or discuss something else?";
  • order  设置该 Advisor 的执行顺序。在多个 Advisor 共存的场景中,order 值越小,优先级越高。例如,若有多个拦截器,order 决定了它们的执行顺序。默认为 0,如下:

private static final int DEFAULT_ORDER = 0;

注意,除了使用上述公开构造方法创建 SafeGuardAdvisor 外,还可以使用静态方法 builder() 来创建:

public static Builder builder() {
    return new Builder();
}

builder() 方法将返回 SafeGuardAdvisor.Builder 对象,SafeGuardAdvisor.Builder  定义如下:

public static final class Builder {
    // 敏感词
    private List<String> sensitiveWords;
    // 错误返回信息
    private String failureResponse = DEFAULT_FAILURE_RESPONSE;
    // 执行顺序
    private int order = DEFAULT_ORDER;
    
    private Builder() {
    }
    //...
}

  

简单使用

下面示例,将通过 SafeGuardAdvisor 类的 sensitiveWords() 方法,将“账号”、“密码”和“电话号码”关键字作为敏感词。当我们输入中涉及这些敏感词,服务将终止请求大模型,而是直接返回错误提示信息。

创建配置

在 resources 目录下创建名为 application.yml 的配置文件,如下:

spring:
  application:
    name: springai_demo1
  # AI配置
  ai:
    # openai相关配置
    openai:
      # 基础地址
      base-url: https://api.xty.app
      # AI KEY
      api-key: sk-vHTHX8D3wNZBfRya8***********2BeB8A23e48AbB600
      # 聊天模型配置
      chat:
        options:
          model: gpt-3.5-turbo
      # 图片模型配置
      image:
        options:
          # 需要高级接口
          model: dall-e-3
    chat:
      memory:
        # 会话历史持久化
        repository:
          jdbc:
            # 启动时不自动执行初始化SQL脚本,手动创建数据表
            initialize-schema: never
      client:
        # true 开启,自动注入 ChatClient,false 关闭,需要手动创建 ChatClient
        enabled: true

# 日志配置
logging:
  charset:
    console: UTF-8
  level:
    root: info
    org.springframework.ai: debug

创建配置类

使用 @Configuration 注解创建名为 AiConfig 的配置类,用来配置 SafeGuardAdvisor,以及设置敏感词。如下:

package com.hxstrive.springai.springai_openai.advisor_SafeGuardAdvisor.config;

import org.springframework.ai.chat.client.advisor.SafeGuardAdvisor;
import org.springframework.ai.chat.client.advisor.SimpleLoggerAdvisor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.List;

/**
 * AI配置
 * @author Administrator
 */
@Configuration
public class AiConfig {

    @Bean
    public SafeGuardAdvisor safeGuardAdvisor() {
        return SafeGuardAdvisor.builder()
                // 设置铭感词,避免敏感词被记录到聊天历史中
                .sensitiveWords(List.of("账号", "密码", "电话号码")).build();
    }

    @Bean
    public SimpleLoggerAdvisor simpleLoggerAdvisor() {
        return new SimpleLoggerAdvisor(); // 默认配置
    }

}

注意,你可以尝试将敏感词存放到配置文件、数据库等中。

创建 Controller

创建名为 AIController 的 Controller,将上面创建的 SafeGuardAdvisor 注入进来,然后通过 ChatClient 的 defaultAdvisors() 方法添加到 Advisor 链中。如下:

package com.hxstrive.springai.springai_openai.advisor_SafeGuardAdvisor.controller;

import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.client.advisor.SafeGuardAdvisor;
import org.springframework.ai.chat.client.advisor.SimpleLoggerAdvisor;
import org.springframework.ai.chat.memory.ChatMemory;
import org.springframework.ai.chat.model.ChatModel;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class AIController {

    @Autowired
    private ChatModel chatModel;

    @Autowired
    private SimpleLoggerAdvisor simpleLoggerAdvisor;

    @Autowired
    private SafeGuardAdvisor safeGuardAdvisor;


    @GetMapping("/ai/simple")
    public String completion(@RequestParam("userText") String userText) {
        // 构建 RAG advisor 时需要完成 vectorStore 初始化
        ChatClient chatClient = ChatClient.builder(chatModel)
                .defaultSystem("使用中文进行回复")
                .defaultAdvisors(
                        simpleLoggerAdvisor,
                        safeGuardAdvisor
                )
                .build();

        // conversationId 区分不同对话,定位对应的历史记录
        String conversationId = "sessionId-20250708204548";
        return chatClient.prompt()
                // 运行时设置会话ID参数
                .advisors(advisor -> {
                    advisor.param(ChatMemory.CONVERSATION_ID, conversationId);
                })
                .user(userText)
                .call()
                .content();
    }

}

运行&验证

启动应用程序,浏览器访问 http://localhost:8080/ai/simple 接口,问“张三的银行卡密码”,如下:

SafeGuardAdvisor 安全审查

由于提的问题涉及了“密码”敏感词,后端直接返回如下信息:

I'm unable to respond to that due to sensitive content. 
Could we rephrase or discuss something else?
由于内容敏感,我无法回应这个问题。我们可以换一种说法,或者讨论其他事情吗?

如果将问题改为“张三”,回复如下:

SafeGuardAdvisor 安全审查

上图正常回复了内容,因为没有涉及敏感关键字。

当然,我们可以通过 failureResponse() 自定义设置触发敏感词响应的内容,如下:

@Bean
public SafeGuardAdvisor safeGuardAdvisor() {
    return SafeGuardAdvisor.builder()
            // 设置铭感词,避免敏感词被记录到聊天历史中
            .sensitiveWords(List.of("账号", "密码", "电话号码"))
            // 设置触发敏感关键词响应的内容
            .failureResponse("由于内容敏感,我无法回应这个问题。我们可以换一种说法,或者讨论其他事情吗?")
            .build();
}

再次运行程序,问“张三的银行卡密码”,效果如下图:

SafeGuardAdvisor 安全审查

上图成功返回了自定义的提示信息。

说说我的看法
全部评论(
没有评论
关于
本网站专注于 Java、数据库(MySQL、Oracle)、Linux、软件架构及大数据等多领域技术知识分享。涵盖丰富的原创与精选技术文章,助力技术传播与交流。无论是技术新手渴望入门,还是资深开发者寻求进阶,这里都能为您提供深度见解与实用经验,让复杂编码变得轻松易懂,携手共赴技术提升新高度。如有侵权,请来信告知:hxstrive@outlook.com
其他应用
公众号