📖 快速开始
什么是 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 |
@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;
}
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);
JSONObject configJson = JSONObject.parseObject(new String(bytes));
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 格式
- 模型配置中必须包含
url 和 requestBody 属性
${userInput} 会在运行时被替换为用户输入(自动转义)
💡 实战场景
场景 1:评论审核(同步)
@Service
public class CommentService {
@Autowired
private AIAuditor auditor;
public void submitComment(Long userId, String content) {
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) {
if (containsSensitiveWords(text)) {
logger.warn("包含敏感词:" + text);
return false;
}
if (text.length() > 10000) {
logger.warn("文本过长:" + text.length());
return false;
}
return true;
}
@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 集成(完整指南)
① 添加依赖
<dependency>
<groupId>com.jms</groupId>
<artifactId>jmsAIAuditor-spring-boot-starter</artifactId>
<version>1.x.x</version>
</dependency>
② 配置文件(application.yml)
jms:
ai:
auditor:
authorization: "Bearer YOUR_API_KEY"
model-id: "your-model-id"
configuration-name: "config/auditor-config.json"
prompt-name: "prompts/content-moderation.txt"
model-name: "doubao"
retry-after-failure-number: 3
connect-timeout: 5000
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 {
@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";
}
✅ Spring Boot 集成的优势
- 零样板代码:无需手动创建 AIAuditor 实例
- 配置外部化:yml 配置文件管理,环境切换方便
- 生命周期管理:Spring 容器自动管理资源销毁
- 依赖注入:直接使用@Autowired,测试友好
- 可覆盖性:通过@ConditionalOnMissingBean 支持自定义
⑥ 多环境配置(Nacos 集成)
jms:
ai:
auditor:
authorization: "Bearer dev-api-key"
model-id: "dev-model"
model-name: "doubao-dev"
jms:
ai:
auditor:
authorization: "Bearer prod-api-key"
model-id: "prod-model"
model-name: "doubao-prod"
retry-after-failure-number: 5
read-timeout: 3600000
🌐 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();
}
@Autowired
private AIAuditor auditor;
异常处理
try {
AuditResult result = auditor.execute(content);
} catch (AIAuditorException e) {
logger.error("AI 审核失败", e);
} catch (Exception e) {
logger.error("未知错误", e);
}
🎯 总结
JmsAI-Auditor 的优势
- ✅ 易用性:简洁的 API,快速集成
- ✅ 高可靠性:内置重试机制,对抗 API 不稳定性
- ✅ 高扩展性:拦截器机制提供灵活定制
- ✅ 异步优先:原生支持并发执行
- ✅ 配置驱动:审核规则与代码解耦
- ✅ 基于 jms-http:享受装饰器模式、限流控制等基础设施
- ✅ Spring Boot 友好:starter 模块实现开箱即用,零样板代码
- ✅ 多环境支持:完美集成 Nacos 配置中心,环境隔离方便
核心组件回顾
| 组件 |
职责 |
关键特性 |
AIAuditor |
审核器门面 |
配置解析、同步/异步执行、资源管理 |
AIAuditorConfiguration |
配置接口 |
双层配置分离、支持文件/流加载 |
AIAuditInterceptor |
拦截器 |
preHandle/postHandle/exceptionHandle |
AIAuditorCallback<T> |
回调函数 |
泛型返回、支持异步处理 |
AIHttpClient |
HTTP 客户端 |
单例模式、装饰器链、重试 + 限流 |
AIAuditorException |
统一异常 |
继承 RuntimeException、四种构造方法 |
适用场景
- UGC 社区的内容合规性审核(评论、帖子、弹幕)
- 电商平台的商品描述审核
- 社交网络的敏感话题识别
- 在线教育平台的言论监管
- 需要对接多个大模型服务商的中间件层
- 对审核成功率有严格要求的生产环境
- Spring Boot 应用的快速集成(推荐)
- 基于 Nacos 的多环境部署场景
🚀 快速上手口诀
一配置(Configuration)、二创建(AIAuditor)、三执行(execute)
同步异步随意选,拦截器来把关
回调函数处理结果,异常兜底要写好
配置驱动规则变,不用改代码
Spring Boot 更省心,开箱即用
Nacos 管环境,切换不麻烦