← 返回首页

JmsAI-Auditor

轻量级现代 AI 内容审核框架

Version 1.x.x

📖 快速开始

什么是 JmsAI-Auditor?

JmsAI-Auditor 是一个基于大语言模型的智能内容审核框架,提供了可配置、高可靠、易扩展的 AI 审核解决方案。 它支持同步/异步执行、拦截器机制、失败重试等功能,适用于 UGC 社区、电商平台、社交网络等内容审核场景。

💡 核心理念
  • 配置驱动:审核规则与代码解耦
  • 高可靠性:内置重试机制,对抗 API 不稳定性
  • 异步优先:原生支持并发执行
  • 高可扩展性:拦截器机制提供灵活定制
  • 基于 jms-http:享受装饰器模式、限流控制等基础设施

第一个 AI 审核程序

// ① 创建配置 AIAuditorConfiguration config = new GeneralConfiguration(); config.setModelName("doubao"); config.setModelId("your-model-id"); config.setAuthorization("Bearer YOUR_API_KEY"); config.setConfigurationName("config/auditor-config.json"); config.setPromptName("prompts/content-moderation.txt"); // ② 创建审核器 AIAuditor auditor = new AIAuditor(config); // ③ 执行审核(同步) String result = auditor.execute("这是一段待审核的文本"); // ④ 关闭资源 auditor.shutdownExecutor();
✅ 异步执行(推荐用于高并发)
auditor.asyncExecute("待审核文本", new AIAuditorCallback<String>() { @Override public String callback(HttpResponse response, Throwable e) { if (e != null) { logger.error("审核失败", e); return null; } return response.getBody(); } });

📦 核心组件

1. AIAuditor - AI 审核器门面

AIAuditor 是审核器的入口,负责配置解析、任务调度和资源管理。

// 创建审核器(自动创建线程池) AIAuditor auditor = new AIAuditor(configuration); // 或自定义线程池 ExecutorService executor = Executors.newFixedThreadPool(10); AIAuditor auditor = new AIAuditor(configuration, executor); // 同步执行 <T> T execute(String userInput); <T> T execute(String userInput, AIAuditorCallback<T> callback); <T> T execute(String userInput, AIAuditInterceptor interceptor); <T> T execute(String userInput, AIAuditorCallback<T> callback, AIAuditInterceptor interceptor); // 异步执行 void asyncExecute(String userInput, ...); // 关闭资源 auditor.shutdownExecutor();

2. AIAuditorConfiguration - 配置接口

AIAuditorConfiguration 定义了审核器的所有配置项,支持从文件或流加载。

方法 说明 默认值
getAuthorization() API 授权信息(如 Bearer Token) -
getModelId() 模型 ID -
getModelName() 模型名称(配置文件中的 key) -
getConfigurationName() 配置文件路径(classpath) -
getPromptName() 提示词文件路径(classpath) -
getRetryAfterFailureNumber() 失败重试次数 3
getConnectTimeout() 连接超时时间(毫秒) 5000
getReadTimeout() 读取超时时间(毫秒) 1800000 (30min)
getLogger() 日志记录器 AILogger
// Spring Boot 环境下的配置示例 @ConfigurationProperties(prefix = "jms.ai.auditor") public class GeneralConfigurationProperties implements AIAuditorConfiguration { private String authorization; private String modelId; private String configurationName; private String promptName; private String modelName; private Integer retryAfterFailureNumber; // ... getters and setters }

3. AIAuditInterceptor - 审核拦截器

在审核流程的关键节点插入横切关注点,实现流程控制。

public interface AIAuditInterceptor extends Interceptor { // 前置拦截:调用前校验 boolean preHandle(String text); // 后置拦截:响应修饰 HttpResponse postHandle(HttpResponse response); // 异常拦截:错误兜底 void exceptionHandle(Throwable e); } // 使用示例 auditor.execute(userInput, new AIAuditInterceptor() { @Override public boolean preHandle(String text) { // 敏感词预过滤 if (text.contains("敏感词")) { return false; // 中断审核 } return true; } @Override public HttpResponse postHandle(HttpResponse response) { // 审核结果格式化 return response; } @Override public void exceptionHandle(Throwable e) { // 转人工审核 logger.error("AI 审核失败,转人工", e); } });

4. AIAuditorCallback - 回调函数

处理异步执行的结果,支持泛型返回。

@FunctionalInterface public interface AIAuditorCallback<T> { T callback(HttpResponse result, Throwable e) throws Exception; } // 使用示例 auditor.asyncExecute(userInput, new AIAuditorCallback<AuditResult>() { @Override public AuditResult callback(HttpResponse response, Throwable e) { if (e != null) { throw new RuntimeException("审核失败", e); } JSONObject json = JSONObject.parseObject(response.getBody()); AuditResult result = new AuditResult(); result.setPass(json.getBoolean("pass")); result.setReason(json.getString("reason")); return result; } });

5. AIHttpClient - HTTP 客户端

基于 jms-http 的装饰器链,提供重试、限流等能力。

🔧 内部机制

AIHttpClient 使用单例模式,通过装饰器链组合多种功能:

  • AIRetryHttpDecorator:失败重试(梯度延迟:1s → 2s → 3s)
  • RateLimitDecorator:速率限制(防止触发 API 限流)

⚙️ 配置详解

配置文件结构(auditor-config.json)

{ "doubao": { "url": "https://ark.cn-beijing.volces.com/api/v3/chat/completions", "requestBody": "{\"model\":\"${modelId}\",\"messages\":[{\"role\":\"user\",\"content\":\"${prompt}${userInput}\"}]}" }, "deepseek": { "url": "https://api.deepseek.com/v1/chat/completions", "requestBody": "{\"model\":\"${modelId}\",\"messages\":[...]}" } }

提示词文件示例(content-moderation.txt)

你是一个内容审核助手。请判断以下用户输入是否包含违规内容: 1. 政治敏感 2. 色情低俗 3. 暴力恐怖 4. 广告营销 5. 人身攻击 如果包含违规内容,请返回 JSON:{"pass": false, "reason": "违规类型"} 如果不包含违规内容,请返回 JSON:{"pass": true, "reason": "合规"} 用户输入:

配置解析流程

// ① 读取配置文件和提示词文件 InputStream configStream = this.getClassLoader().getResourceAsStream(configurationName); InputStream promptStream = this.getClassLoader().getResourceAsStream(promptName); // ② 解析配置 JSON JSONObject configJson = JSONObject.parseObject(new String(bytes)); // ③ 读取提示词(逐行读取,用 \n 连接) BufferedReader reader = new BufferedReader(new InputStreamReader(promptStream)); ArrayList<String> lines = new ArrayList<>(); String line; while ((line = reader.readLine()) != null) { lines.add(line); } String prompt = String.join("\\n", lines); // ④ 提取模型配置 JSONObject modelConfig = configJson.getJSONObject(modelName); String url = modelConfig.getString("url"); String requestBody = modelConfig.getString("requestBody"); // ⑤ 替换占位符 requestBody = requestBody.replace("${modelId}", modelId) .replace("${prompt}", prompt);
⚠️ 注意事项
  • 配置文件和提示词文件必须存在于 classpath 或通过 InputStream 提供
  • 配置文件必须是合法的 JSON 格式
  • 模型配置中必须包含 urlrequestBody 属性
  • ${userInput} 会在运行时被替换为用户输入(自动转义)

💡 实战场景

场景 1:评论审核(同步)

@Service public class CommentService { @Autowired private AIAuditor auditor; public void submitComment(Long userId, String content) { // 执行 AI 审核 AuditResult result = auditor.execute(content, new AIAuditorCallback<AuditResult>() { @Override public AuditResult callback(HttpResponse response, Throwable e) { if (e != null) { throw new AuditException("审核失败", e); } JSONObject json = JSONObject.parseObject(response.getBody()); AuditResult result = new AuditResult(); result.setPass(json.getBoolean("pass")); result.setReason(json.getString("reason")); return result; } }); if (!result.isPass()) { throw new AuditException("评论包含违规内容:" + result.getReason()); } // 审核通过,保存评论 commentRepository.save(new Comment(userId, content)); } }

场景 2:批量审核(异步)

public class BatchAuditor { private final AIAuditor auditor; private final CountDownLatch latch; public BatchAuditor(AIAuditor auditor) { this.auditor = auditor; this.latch = new CountDownLatch(0); } public void auditBatch(List<String> texts) { latch = new CountDownLatch(texts.size()); for (String text : texts) { auditor.asyncExecute(text, new AIAuditorCallback<AuditResult>() { @Override public AuditResult callback(HttpResponse response, Throwable e) { try { // 处理结果... AuditResult result = parseResult(response, e); saveResult(text, result); return result; } finally { latch.countDown(); } } }); } // 等待所有审核完成 try { latch.await(); } catch (InterruptedException e) { Thread.currentThread().interrupt(); } } }

场景 3:多级审核(拦截器链)

public class MultiLevelAuditInterceptor implements AIAuditInterceptor { @Override public boolean preHandle(String text) { // 第 1 级:敏感词过滤 if (containsSensitiveWords(text)) { logger.warn("包含敏感词:" + text); return false; } // 第 2 级:长度检查 if (text.length() > 10000) { logger.warn("文本过长:" + text.length()); return false; } return true; // 继续 AI 审核 } @Override public HttpResponse postHandle(HttpResponse response) { // 后处理:结果缓存 cacheResult(response); return response; } @Override public void exceptionHandle(Throwable e) { // 降级策略:转人工审核 logger.error("AI 审核失败,转人工", e); transferToManualReview(e); } } // 使用 auditor.execute(userInput, new MultiLevelAuditInterceptor());

场景 4:Spring Boot 集成(完整指南)

① 添加依赖

<!-- Maven 依赖 --> <dependency> <groupId>com.jms</groupId> <artifactId>jmsAIAuditor-spring-boot-starter</artifactId> <version>1.x.x</version> </dependency>

② 配置文件(application.yml)

# application.yml jms: ai: auditor: # API 授权信息 authorization: "Bearer YOUR_API_KEY" # 模型 ID model-id: "your-model-id" # 配置文件路径(classpath) configuration-name: "config/auditor-config.json" # 提示词文件路径(classpath) prompt-name: "prompts/content-moderation.txt" # 模型名称(配置文件中对应的 key) model-name: "doubao" # 失败重试次数(可选,默认 3) retry-after-failure-number: 3 # 连接超时时间(可选,默认 5000ms) connect-timeout: 5000 # 读取超时时间(可选,默认 30min) read-timeout: 1800000

③ 自动装配原理

🔧 Starter 工作机制
  • @ConfigurationProperties:自动绑定 yml 配置到 Java 对象
  • @EnableAutoConfiguration:通过 spring.factories 自动加载配置类
  • @ConditionalOnMissingBean:如果用户自定义了 Bean,则使用用户的(支持覆盖)
  • AIAuditorConfigurationContainer:配置容器,解决属性传递问题
// 核心自动配置类 @Configuration @EnableConfigurationProperties(GeneralConfigurationProperties.class) public class AIAuditorSpringConfiguration { @Bean @ConditionalOnMissingBean public AIAuditorConfiguration getAIAuditorConfiguration(...) { // 从容器创建配置 return new AIAuditorConfiguration() {...}; } @Bean @ConditionalOnMissingBean public AIAuditor getAIAuditor(AIAuditorConfiguration configuration) { // 创建审核器实例 return new AIAuditor(configuration); } }

④ 注入使用(推荐方式)

@Service public class ContentAuditService { // 直接注入 AIAuditor @Autowired private AIAuditor auditor; public AuditResult auditContent(String content) { // 同步执行 return auditor.execute(content, new AIAuditorCallback<AuditResult>() { @Override public AuditResult callback(HttpResponse response, Throwable e) { if (e != null) { logger.error("AI 审核失败", e); throw new AuditException("审核服务异常", e); } JSONObject json = JSONObject.parseObject(response.getBody()); AuditResult result = new AuditResult(); result.setPass(json.getBoolean("pass")); result.setReason(json.getString("reason")); return result; } }); } }

⑤ 自定义配置(高级用法)

// 如果需要自定义配置(覆盖默认配置) @Configuration public class CustomAIAuditorConfig { @Bean public AIAuditorConfiguration customConfiguration() { return new AIAuditorConfiguration() { @Override public String getAuthorization() { // 从环境变量或密钥管理系统获取 return System.getenv("AI_API_KEY"); } @Override public String getModelId() { return "custom-model-id"; } // ... 其他配置 }; } @Bean public AIAuditor customAuditor(AIAuditorConfiguration config) { // 自定义线程池 ExecutorService executor = new ThreadPoolExecutor( 10, // 核心线程数 50, // 最大线程数 60L, TimeUnit.SECONDS, new LinkedBlockingQueue<>(1000) ); return new AIAuditor(config, executor); } }
✅ Spring Boot 集成的优势
  • 零样板代码:无需手动创建 AIAuditor 实例
  • 配置外部化:yml 配置文件管理,环境切换方便
  • 生命周期管理:Spring 容器自动管理资源销毁
  • 依赖注入:直接使用@Autowired,测试友好
  • 可覆盖性:通过@ConditionalOnMissingBean 支持自定义

⑥ 多环境配置(Nacos 集成)

# application-dev.yml(开发环境) jms: ai: auditor: authorization: "Bearer dev-api-key" model-id: "dev-model" model-name: "doubao-dev" # application-prod.yml(生产环境) jms: ai: auditor: authorization: "Bearer prod-api-key" model-id: "prod-model" model-name: "doubao-prod" retry-after-failure-number: 5 # 生产环境增加重试次数 read-timeout: 3600000 # 60 分钟,处理长文本
🌐 Nacos 配置中心集成

如果使用 Nacos 作为配置中心,只需在 Nacos 控制台配置上述 yml 内容, 应用启动时会自动拉取对应环境的配置。环境切换通过 Nacos 命名空间实现,无需修改代码。

🔍 用户输入预处理

在发送给大模型之前,会自动对用户输入进行转义,确保 JSON 格式正确:

字符 转义后 说明
" \" 双引号
\ \\ 反斜杠
\n \\n 换行符
\r \\r 回车符
\t \\t 制表符
✅ 好处
  • 防止 JSON 格式错误
  • 避免特殊字符导致的解析失败
  • 无需调用方手动转义

⚠️ 注意事项

❌ 常见错误
  • 忘记调用 shutdownExecutor() → 线程泄漏
  • 配置文件不存在 → 启动时抛异常
  • 模型配置缺少必需属性 → 解析失败
  • 在拦截器中抛出异常 → 导致后续流程中断
✅ 最佳实践
  • 应用关闭前调用 auditor.shutdownExecutor()
  • 使用 Spring Boot Starter 自动管理生命周期
  • 在拦截器的 exceptionHandle 中实现降级策略
  • 高并发场景使用异步执行
  • 配置合理的超时时间(连接 5s,读取 30min)

资源管理示例

// ✅ 手动管理 AIAuditor auditor = new AIAuditor(config); try { AuditResult result = auditor.execute(content); } finally { auditor.shutdownExecutor(); } // ✅ Spring Boot(推荐) @Autowired private AIAuditor auditor; // 容器自动管理生命周期

异常处理

try { AuditResult result = auditor.execute(content); } catch (AIAuditorException e) { // AI 审核器异常(已包装) logger.error("AI 审核失败", e); } catch (Exception e) { // 其他异常 logger.error("未知错误", e); }

🎯 总结

JmsAI-Auditor 的优势

核心组件回顾

组件 职责 关键特性
AIAuditor 审核器门面 配置解析、同步/异步执行、资源管理
AIAuditorConfiguration 配置接口 双层配置分离、支持文件/流加载
AIAuditInterceptor 拦截器 preHandle/postHandle/exceptionHandle
AIAuditorCallback<T> 回调函数 泛型返回、支持异步处理
AIHttpClient HTTP 客户端 单例模式、装饰器链、重试 + 限流
AIAuditorException 统一异常 继承 RuntimeException、四种构造方法

适用场景

🚀 快速上手口诀

一配置(Configuration)、二创建(AIAuditor)、三执行(execute)
同步异步随意选,拦截器来把关
回调函数处理结果,异常兜底要写好
配置驱动规则变,不用改代码
Spring Boot 更省心,开箱即用
Nacos 管环境,切换不麻烦

查看 API 文档