引言
在当今的内容创作领域,评论区是博主与读者互动的重要场所。然而,随着网站流量的增长,评论管理面临着两大挑战:内容安全审核 和及时回复读者。传统的人工审核方式效率低下,而忽视读者评论又会影响互动体验。
本文将详细介绍如何基于 Spring Boot 构建一套完整的 AI 智能评论审核与自动回复系统,实现评论的自动审核、敏感内容过滤、智能回复生成等功能。
体验地址:https://www.hqxiaozou.top/about
效果预览

一、系统架构概览
1.1 整体架构
┌─────────────────────────────────────────────────────────────────┐
│ 前端展示层 │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ 评论提交 │ │ 状态轮询 │ │ AI回复展示 │ │
│ └──────────────┘ └──────────────┘ └──────────────┘ │
└─────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────┐
│ 控制层 (Controller) │
│ ┌──────────────────┐ ┌──────────────────┐ │
│ │ CommentController│ │ AiCommentController│ │
│ │ (评论CRUD) │ │ (AI管理接口) │ │
│ └──────────────────┘ └──────────────────┘ │
└─────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────┐
│ 服务层 (Service) │
│ ┌──────────────────┐ ┌──────────────────┐ ┌──────────────┐ │
│ │ AiCommentService │ │ AiCommentTask │ │ CommentService│ │
│ │ (审核/回复核心) │ │ (异步任务调度) │ │ (评论基础) │ │
│ └──────────────────┘ └──────────────────┘ └──────────────┘ │
└─────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────┐
│ AI 服务层 │
│ ┌──────────────────┐ ┌──────────────────┐ │
│ │ 内容审核 API │ │ 回复生成 API │ │
│ │ (多模态支持) │ │ (上下文感知) │ │
│ └──────────────────┘ └──────────────────┘ │
└─────────────────────────────────────────────────────────────────┘
1.2 核心功能模块
| 模块 | 功能描述 | 技术要点 |
|---|---|---|
| 本地预筛选 | 敏感词快速过滤 | 正则表达式缓存 |
| AI 内容审核 | 智能识别违规内容 | 多模态模型支持 |
| AI 自动回复 | 生成个性化回复 | 上下文感知生成 |
| 状态管理 | 评论生命周期管理 | 状态机设计 |
| 异步处理 | 高并发评论处理 | @Async + 线程池 |
| 实时推送 | 前端状态同步 | 轮询机制 |
二、核心功能实现
2.1 评论审核状态机
系统采用清晰的状态流转设计:
java
public enum CommentAuditStatus {
PENDING(0, 0, "待审核"), // 初始状态
APPROVED(1, 1, "已通过"), // 审核通过
REJECTED(0, 4, "已拒绝"), // 审核拒绝
AI_REPLYING(0, 2, "AI回复中"), // 正在生成回复
AI_REPLIED(1, 3, "已回复"), // 已完成回复
AI_REPLY_FAILED(0, 5, "AI回复失败"); // 回复生成失败
}
状态流转图:
┌─────────┐ 提交评论 ┌─────────┐
│ 用户 │ ─────────────▶ │ PENDING │
└─────────┘ └────┬────┘
│
┌─────────────────┼─────────────────┐
▼ ▼ ▼
┌─────────┐ ┌──────────┐ ┌─────────┐
│APPROVED │ │ REJECTED │ │AI_REPLY │
│(通过) │ │ (拒绝) │ │_FAILED │
└────┬────┘ └──────────┘ └─────────┘
│
▼
┌───────────┐
│AI_REPLYING│
└─────┬─────┘
│
▼
┌──────────┐
│ AI_REPLIED│
│ (已回复) │
└──────────┘
2.2 双层审核机制
为了提高审核效率并降低成本,系统采用本地预筛选 + AI 深度审核的双层架构:
第一层:本地敏感词预筛选
java
// 敏感词正则表达式缓存(初始化时编译)
private List<Pattern> sensitivePatterns;
@PostConstruct
public void initSensitivePatterns() {
List<String> words = aiCommentProperties.getSensitiveWords();
if (words != null) {
sensitivePatterns = words.stream()
.map(word -> Pattern.compile(Pattern.quote(word),
Pattern.CASE_INSENSITIVE | Pattern.UNICODE_CASE))
.collect(Collectors.toList());
}
}
// 快速匹配
private boolean containsSensitiveWords(String content) {
if (sensitivePatterns == null || content == null) return false;
return sensitivePatterns.stream()
.anyMatch(pattern -> pattern.matcher(content).find());
}
优势:
- 响应时间 < 1ms
- 不消耗 AI API 调用额度
- 可拦截明显的违规内容
第二层:AI 智能审核
java
@Override
public AiCommentAuditResult auditComment(Comments comment) {
// 1. 本地预筛选
if (containsSensitiveWords(content)) {
return AiCommentAuditResult.reject("包含敏感内容", "SENSITIVE_WORD", 1.0);
}
// 2. AI 深度审核
String prompt = buildAuditPrompt(content, nickname, emojis);
String response = callAiApi(prompt, auditModel, 200, 0.3);
return parseAuditResponse(response);
}
AI 审核 Prompt 设计:
java
private String buildAuditPrompt(String content, String nickname, Set<String> emojis) {
return String.format("""
你是一位专业的内容审核员,请对以下评论进行审核。
评论内容:%s
用户昵称:%s
包含表情:%s
请从以下维度评估:
1. 是否包含政治敏感内容
2. 是否包含色情、暴力内容
3. 是否包含广告、垃圾信息
4. 是否包含人身攻击、侮辱性语言
5. 是否与文章主题相关
请以 JSON 格式返回:
{
"approved": true/false,
"confidence": 0.0-1.0,
"reason": "拒绝原因(如拒绝)",
"violationType": "违规类型"
}
""", content, nickname, emojis);
}
2.3 多模态内容审核(表情识别)
系统创新性地支持对评论中的表情图片进行审核:
java
// 提取评论中的表情
Set<String> emojis = EmojiImageUtils.extractEmojisFromContent(content);
// 如果有表情且启用了多模态,转换图片为 Base64
if (aiCommentProperties.isEnableMultimodal() && !emojis.isEmpty()) {
List<String> emojiImages = emojis.stream()
.map(EmojiImageUtils::convertEmojiToBase64)
.filter(Objects::nonNull)
.collect(Collectors.toList());
// 调用多模态模型
response = callMultimodalAiApi(prompt, emojiImages,
aiCommentProperties.getMultimodalModel(), 200, 0.3);
}
技术亮点:
- 使用
google/gemma-3-27b-it等多模态模型 - 支持图文联合理解
- 可识别不当表情使用
2.4 上下文感知的 AI 回复
AI 回复不仅基于评论内容,还结合文章上下文生成:
java
@Override
public AiReplyResult generateReply(Comments originalComment,
String articleTitle,
String articleContent) {
// 构建上下文感知的 Prompt
String prompt = buildReplyPrompt(
originalComment.getContent(),
articleTitle,
articleContent,
aiCommentProperties.getReplyStyle()
);
String response = callAiApi(prompt, replyModel, 500, 0.7);
return parseReplyResponse(response);
}
回复风格配置:
yaml
ai:
comment:
reply-style: friendly # 可选: friendly, professional, humorous
不同风格的 Prompt 示例:
java
private String getStyleInstruction(String style) {
return switch (style.toLowerCase()) {
case "professional" -> "以专业、严谨的态度回复,使用正式的语言风格";
case "humorous" -> "以幽默、轻松的方式回复,适当使用网络流行语";
default -> "以友好、热情的态度回复,像朋友一样交流";
};
}
三、异步处理架构
3.1 为什么需要异步处理?
AI API 调用通常需要 1-3 秒,如果同步处理:
- 用户提交评论后需要长时间等待
- 高并发时容易阻塞线程池
- 影响用户体验
3.2 Spring @Async 实现
java
@Service
public class AiCommentTaskServiceImpl implements AiCommentTaskService {
@Async("aiCommentExecutor")
@Override
public CompletableFuture<Void> asyncProcessComment(Integer commentId) {
return CompletableFuture.runAsync(() -> {
try {
aiCommentService.processComment(commentId);
} catch (Exception e) {
log.error("异步处理评论失败: commentId={}", commentId, e);
}
});
}
}
3.3 线程池配置
java
@Configuration
public class AsyncConfig {
@Bean("aiCommentExecutor")
public Executor aiCommentExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(5);
executor.setMaxPoolSize(20);
executor.setQueueCapacity(100);
executor.setThreadNamePrefix("ai-comment-");
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
executor.initialize();
return executor;
}
}
3.4 批量处理优化
java
@Override
public CompletableFuture<Void> asyncProcessComments(List<Integer> commentIds) {
List<CompletableFuture<Void>> futures = commentIds.stream()
.map(this::asyncProcessComment)
.toList();
// 等待所有任务完成
return CompletableFuture.allOf(futures.toArray(new CompletableFuture[0]));
}
四、前端实时状态同步
4.1 轮询机制设计
javascript
const CONFIG = {
POLL_INTERVAL: 3000, // 3秒轮询一次
MAX_POLL_COUNT: 60 // 最多轮询3分钟
};
function startPolling(commentId, commentData) {
let pollCount = 0;
const pollTimer = setInterval(async () => {
pollCount++;
if (pollCount > CONFIG.MAX_POLL_COUNT) {
clearInterval(pollTimer);
return;
}
const status = await fetchCommentStatus(commentId);
updateCommentUI(status);
// 状态已终态,停止轮询
if ([STATUS.APPROVED, STATUS.REJECTED, STATUS.AI_REPLIED]
.includes(status.code)) {
clearInterval(pollTimer);
}
}, CONFIG.POLL_INTERVAL);
}
4.2 状态 UI 展示
javascript
function renderPendingComment(data, tempId) {
return `
<div class="comment pending" id="${tempId}">
<div class="content">
<span class="author">${data.nickname}</span>
<div class="text">${data.content}</div>
<div class="status-badge">
<i class="spinner"></i> 审核中...
</div>
</div>
</div>
`;
}
function updateCommentApproved(commentId) {
$(`#pending-${commentId}`)
.removeClass('pending')
.addClass('approved')
.find('.status-badge')
.html('<i class="check"></i> 已通过');
}
function addAiReply(commentId, replyContent) {
const replyHtml = `
<div class="ai-reply">
<div class="ai-badge">🤖 AI 助手</div>
<div class="text">${replyContent}</div>
</div>
`;
$(`#comment-${commentId}`).append(replyHtml);
}
五、定时任务与补偿机制
5.1 定时任务设计
java
@Component
public class AiCommentScheduledTask {
/**
* 每5分钟处理待审核评论
*/
@Scheduled(fixedRate = 5 * 60 * 1000)
public void processPendingComments() {
List<Comments> pendingComments = commentsMapper
.selectByAuditStatus(CommentAuditStatus.PENDING);
pendingComments.forEach(comment ->
aiCommentTaskService.asyncProcessComment(comment.getId())
);
}
/**
* 每30分钟重试失败评论
*/
@Scheduled(fixedRate = 30 * 60 * 1000)
public void reprocessFailedComments() {
List<Comments> failedComments = commentsMapper
.selectByAuditStatus(CommentAuditStatus.AI_REPLY_FAILED);
failedComments.forEach(comment ->
aiCommentService.reprocessFailedComment(comment.getId())
);
}
/**
* 每天凌晨2点清理过期拒绝评论
*/
@Scheduled(cron = "0 0 2 * * ?")
public void cleanExpiredRejectedComments() {
// 清理7天前的拒绝评论
commentsMapper.deleteExpiredRejected(7);
}
}
5.2 失败重试策略
java
@Override
public void reprocessFailedComment(Integer commentId) {
Comments comment = commentsMapper.selectById(commentId);
if (comment == null) return;
// 重置状态为待处理
comment.setAuditStatus(CommentAuditStatus.PENDING.getCode());
commentsMapper.updateById(comment);
// 重新触发处理流程
processComment(commentId);
}
六、配置管理
6.1 YAML 配置示例
yaml
ai:
comment:
# 功能开关
audit-enabled: true
reply-enabled: true
# API 配置
api-key: ${AI_API_KEY}
api-url: https://api.openai.com/v1/chat/completions
# 模型配置
model: gpt-3.5-turbo
audit-model: gpt-4o-mini # 审核专用模型
reply-model: gpt-3.5-turbo # 回复专用模型
multimodal-model: google/gemma-3-27b-it
# 生成参数
max-tokens: 500
temperature: 0.7
timeout: 30000
# 阈值配置
audit-confidence-threshold: 0.7
reply-quality-threshold: 0.6
# 本地过滤
enable-local-filter: true
sensitive-words:
- "敏感词1"
- "敏感词2"
# 回复风格
reply-style: friendly
# 多模态支持
enable-multimodal: true
6.2 配置属性类
java
@Data
@Component
@ConfigurationProperties(prefix = "ai.comment")
public class AiCommentProperties {
private boolean auditEnabled = true;
private boolean replyEnabled = true;
private String apiKey = "";
private String apiUrl = "https://api.openai.com/v1/chat/completions";
private String model = "gpt-3.5-turbo";
private String auditModel = "";
private String replyModel = "";
private int maxTokens = 500;
private double temperature = 0.7;
private int timeout = 30000;
private double auditConfidenceThreshold = 0.7;
private double replyQualityThreshold = 0.6;
private List<String> sensitiveWords;
private boolean enableLocalFilter = true;
private String replyStyle = "friendly";
private boolean enableMultimodal = true;
private String multimodalModel = "google/gemma-3-27b-it";
}
七、性能优化与监控
7.1 性能指标
| 指标 | 优化前 | 优化后 | 优化手段 |
|---|---|---|---|
| 单次审核耗时 | 2000-3000ms | 50-100ms | 本地预筛选 |
| 评论提交响应 | 3000ms+ | <100ms | 异步处理 |
| 并发处理能力 | 10 QPS | 100+ QPS | 线程池优化 |
| AI API 调用成本 | 100% | 30-40% | 本地过滤 |
7.2 日志与监控
java
@Slf4j
@Service
public class AiCommentServiceImpl implements AiCommentService {
@Override
public AiCommentAuditResult auditComment(Comments comment) {
long startTime = System.currentTimeMillis();
// ... 审核逻辑
long processingTime = System.currentTimeMillis() - startTime;
log.info("评论审核完成: commentId={}, approved={}, confidence={}, time={}ms",
comment.getId(), result.isApproved(), result.getConfidence(), processingTime);
return result;
}
}
7.3 关键指标统计
java
@Component
public class AiCommentMetrics {
private final AtomicInteger totalAudited = new AtomicInteger(0);
private final AtomicInteger approvedCount = new AtomicInteger(0);
private final AtomicInteger rejectedCount = new AtomicInteger(0);
private final AtomicLong totalProcessingTime = new AtomicLong(0);
public void recordAudit(boolean approved, long processingTime) {
totalAudited.incrementAndGet();
if (approved) {
approvedCount.incrementAndGet();
} else {
rejectedCount.incrementAndGet();
}
totalProcessingTime.addAndGet(processingTime);
}
public Map<String, Object> getStats() {
int total = totalAudited.get();
return Map.of(
"totalAudited", total,
"approvedRate", total > 0 ? (double) approvedCount.get() / total : 0,
"avgProcessingTime", total > 0 ? totalProcessingTime.get() / total : 0
);
}
}
八、安全与异常处理
8.1 降级策略
java
@Override
public AiCommentAuditResult auditComment(Comments comment) {
try {
// AI 审核逻辑
return performAiAudit(comment);
} catch (Exception e) {
log.error("AI审核失败,使用降级策略: commentId={}", comment.getId(), e);
// 降级:默认通过,但置信度较低
return AiCommentAuditResult.success(0.5);
}
}
8.2 API 限流保护
java
@Component
public class AiApiRateLimiter {
private final RateLimiter rateLimiter = RateLimiter.create(10.0); // 每秒10个请求
public boolean tryAcquire() {
return rateLimiter.tryAcquire();
}
}
8.3 敏感信息保护
yaml
# 使用环境变量存储 API Key
ai:
comment:
api-key: ${AI_API_KEY:}
九、总结与展望
9.1 核心亮点
- 双层审核架构:本地预筛选 + AI 深度审核,兼顾效率与准确性
- 多模态支持:创新性地支持表情图片审核
- 上下文感知回复:结合文章内容生成高质量回复
- 异步处理:保证用户体验的同时处理高并发
- 实时状态同步:前端轮询机制实现状态实时展示
- 完善的补偿机制:定时任务确保失败任务最终完成
9.2 未来优化方向
- WebSocket 推送:替代轮询,进一步降低延迟
- 模型微调:基于历史数据微调专用审核模型
- 多语言支持:扩展至英文、日文等多语言评论
- 情感分析:识别评论情感倾向,优先回复负面情绪
- 智能去重:合并相似评论的回复
参考资料
本文基于实际项目经验编写,代码示例均来自生产环境。如有问题欢迎交流讨论。