基于 Spring Boot 构建企业级内容安全过滤服务:DFA + AC 自动机 + AI 语义审核架构设计
categories:
- Java
- Spring Boot
tags: - 内容安全
- 敏感词过滤
- DFA
- AC自动机
- Redis
- AI审核
- 若依
- 芋道
基于 Spring Boot 构建企业级内容安全过滤服务:DFA + AC 自动机 + AI 语义审核架构设计
技术栈:JDK 8 · Spring Boot 2.7 · 原生 MyBatis · Redis / RabbitMQ(可选)
工程名:content-security
适用场景:若依 / 芋道 / 自研 Spring Boot 业务系统的评论、帖子、昵称、私信等内容审核
一、背景与问题
在 UGC(用户生成内容)场景中,评论、帖子、昵称、私信都可能出现违规内容。
很多团队一开始会用「敏感词列表 + contains」或拷贝一段 DFA 工具类快速上线,随后就会遇到这些问题:
- 性能不够:词库到十万级后,简单遍历或重复匹配延迟明显上升
- 变形绕过:拼音、谐音、插符号、全半角混用导致漏杀
- 误杀严重:如「枪」误伤「水枪」「玩具枪」
- 词库难运维:改词要发版重启,多实例难以同步
- 只有关键词,没有语义:如「我要让他消失」没有敏感词,但可能有威胁语义
- 缺少闭环:没有审核记录、没有人工复核、无法持续优化词库
因此,内容安全不应只是一个工具方法,而应沉淀为企业级基础能力服务 / 可嵌入组件。
二、建设目标
本方案希望同时满足:
| 目标 | 说明 |
|---|---|
| 高性能 | 内存自动机匹配,支撑高频检测 |
| 高准确 | 归一化 + 白名单 + 分级策略 + AI 语义 |
| 可运维 | 词库热更新,不必重启 |
| 可接入 | Starter 嵌入 + Feign/RPC 两种方式 |
| 可闭环 | 自动检测 → 人工审核 → 词库优化 |
| 易落地 | 兼容若依 / 芋道主数据源,支持零配置 H2 兜底 |
一句话:
同步只负责判定,异步负责沉淀;配置能省则省,中间件能借则借。
三、总体架构设计
3.1 逻辑架构
3.2 分层职责
| 层级 | 职责 |
|---|---|
| 接入层 | Starter 进程内调用,或 Feign/HTTP 远程调用 |
| 检测层 | 归一化、DFA/AC 匹配、风险动作决策 |
| 策略层 | 白名单、分级、场景规则、AI 融合 |
| 运营层 | 词库管理、审核工单、发布热更新 |
| 基础设施 | MySQL/H2、Redis、RabbitMQ、本地线程池 |
3.3 工程模块
content-security
├── content-security-api # DTO / 枚举 / Feign 契约
├── content-security-core # 归一化 + DFA/AC 引擎
├── content-security-starter # Spring Boot 自动装配(嵌入式)
├── content-security-service # 独立检测服务(默认 8088)
└── content-security-admin # 词库与审核管理(默认 8089)
四、核心检测链路
一次完整检测建议固定为以下流水线:
原始文本
→ 文本归一化(繁简/全半角/去干扰符/大小写等)
→ 白名单快速放行(可选)
→ DFA 匹配(法律禁止词 / 高频词)
→ AC 匹配(社区词 / 扩展大词库)
→ 风险聚合(取最高风险 / 最严动作)
→(可选)AI 语义复核
→ 返回结果 + 异步侧效应(自动学习 / 审计落库)
关键设计:
- 同步路径只做内存判定,保证低延迟
- 写库、学习、审计走异步削峰,避免高并发打爆数据库
- 异步通道可自动探测:
RabbitMQ → Redis List → 本地线程池
五、文本归一化设计
用户绕过敏感词的常见手段:
- 繁体 / 异体字
- 全角字符
- 大小写混写
- 插入符号:
傻@@B、毒*品 - 拼音与数字谐音:
sb、4b
因此在匹配前必须统一做归一化,例如:
| 处理项 | 目的 |
|---|---|
| 转小写 | 统一英文匹配 |
| 全角转半角 | 统一符号与字母 |
| 去除无干扰符 | 还原紧凑词 |
| 繁简转换(可选) | 降低字形变形 |
| 空白压缩 | 避免插空格绕过 |
工程中由 TextNormalizer 完成。注意:
- 返回结果中建议同时保留 原文 与 归一化文本,便于审计回溯
- 打码替换尽量基于原文位置映射,避免用户看到错位替换
六、能力边界与设计原则
6.1 本方案覆盖的能力
- 高性能敏感词匹配(DFA + AC)
- 风险分级与处理动作(PASS / REPLACE / REVIEW / BLOCK)
- 词库分级、分类与白名单
- Redis 热更新与多实例同步
- Starter / Feign 双接入
- 场景自动学习入库
- 人工审核闭环
- AI 语义审核扩展位
- 高并发异步削峰
6.2 设计原则
| 原则 | 落地 |
|---|---|
| 判定与沉淀分离 | 检测同步,学习/审计异步 |
| 规则优先、模型兜底 | 明确违规直接拦,隐含语义再走 AI |
| 配置可省略 | 无主库表时自动 H2,有主库表则复用 DataSource |
| 中间件可借用 | 主项目已有 MQ/Redis 则自动启用削峰通道 |
| 业务少接口 | 业务主要调 /security/check,不必再调入库接口 |
6.3 本文后续结构
- 七~十一:匹配算法、词库分级、库表、热更新、工程结构
- 十二~十七:接入方式、检测接口、误杀漏杀、AI、审核闭环、性能优化
- 十八~二十四:部署架构、若依/芋道集成、选型总结、扩展与终章
(第一部分结束)
七、敏感词匹配算法设计
敏感词匹配是整个内容安全服务的核心模块。
根据词库规模、访问频率以及业务场景,本方案采用:
- DFA 自动机
- AC 自动机
两种算法组合。
7.1 DFA 自动机设计
7.1.1 DFA 介绍
DFA(Deterministic Finite Automaton),即确定有限状态自动机。
核心思想:将敏感词转换成状态转移结构。
例如敏感词:违规
构建状态:
开始
|
违
|
规
|
结束
匹配时逐字符进行状态转移;如果达到结束状态,则表示命中敏感词。
7.1.2 DFA 特点
优势:
- 查询速度快
- 内存占用较低
- 匹配稳定
适用于:
- 小规模敏感词库
- 高频检测场景
例如法律禁止词库(约 5000~10000 条),采用 DFA 即可满足性能要求。
7.2 AC 自动机设计
7.2.1 AC 自动机介绍
AC 自动机(Aho-Corasick Automaton)是一种多模式字符串匹配算法。
它通过:
- Trie 树
- Fail 失败指针
- 状态转移
实现一次扫描匹配多个关键词。
7.2.2 AC 自动机构建过程
例如词库:
- 违法
- 违规
- 违规内容
首先构建 Trie 树(示意):
root
/ \
违 违
| |
法 规
|
内
|
容
然后建立失败指针。匹配文本时,只需要扫描一次。
7.2.3 AC 自动机优势
相比逐个关键词匹配:
| 方式 | 复杂度直觉 |
|---|---|
| 传统 | 文本 × 敏感词数量 |
| AC | 文本一次扫描 |
因此适合 10 万+,乃至百万级敏感词库。
7.3 DFA + AC 组合方案
生产环境推荐:不是二选一,而是组合使用。
整体流程:
策略建议:
| 词库类型 | 算法 |
|---|---|
| 法律禁止词 | DFA |
| 高频违规词 | DFA |
| 社区违规词 | AC |
| 扩展词库 | AC |
| 语义风险词 | AI |
工程落地时,可在 content-security-core 中分别实现 DfaMatcher / AcMatcher,由 SensitiveEngine 统一调度。
八、敏感词库分级设计
敏感词不能简单维护一个列表,需要按照风险等级管理。
8.1 风险等级定义
| 等级 | 类型 | 处理方式 |
|---|---|---|
| 5 | 法律禁止词 | 直接拦截 |
| 4 | 严重违规词 | 拒绝发布 |
| 3 | 社区违规词 | 替换或屏蔽 |
| 2 | 争议词 | 人工审核 |
| 1 | 普通风险词 | 记录分析 |
8.2 敏感词分类
建议分类:
| 分类 | 含义 |
|---|---|
LEGAL |
法律风险 |
VIOLENCE |
暴力内容 |
PORN |
低俗色情 |
ABUSE |
辱骂攻击 |
AD |
广告垃圾 |
POLITICAL |
政治风险 |
8.3 处理策略设计
根据等级决定动作,例如:
法律禁止词
- 风险:
HIGH - 处理:
BLOCK - 结果:内容禁止发布
社区违规词
- 风险:
MEDIUM - 处理:
REPLACE - 示例:输入
xxxx→ 输出****
争议词
- 风险:
UNKNOWN/MEDIUM - 处理:
REVIEW - 结果:进入人工审核
九、敏感词数据库设计
9.1 敏感词表
表名:sensitive_word
CREATE TABLE sensitive_word
(
id BIGINT PRIMARY KEY COMMENT '主键',
word VARCHAR(100) COMMENT '敏感词',
category VARCHAR(50) COMMENT '敏感分类',
level INT COMMENT '风险等级',
action VARCHAR(20) COMMENT '处理动作',
status TINYINT COMMENT '启用状态',
create_time DATETIME,
update_time DATETIME
);
字段说明:
| 字段 | 说明 |
|---|---|
| id | 主键 |
| word | 敏感词 |
| category | 分类 |
| level | 风险等级 |
| action | 处理方式 |
| status | 是否启用 |
| create_time | 创建时间 |
| update_time | 更新时间 |
9.2 白名单表
用于降低误杀。
表名:sensitive_word_white
CREATE TABLE sensitive_word_white
(
id BIGINT PRIMARY KEY,
word VARCHAR(100),
remark VARCHAR(255),
status TINYINT,
create_time DATETIME
);
例如:
- 敏感词:
枪 - 白名单:
水枪、玩具枪、游戏枪械
检测时先判断白名单,命中白名单则放行。
十、敏感词库热更新设计
敏感词库不能写死在代码中,否则新增一词就要经历:
修改代码 → 重新编译 → 重新部署 → 重启服务
效率极低。因此采用:
MySQL
↓
Redis
↓
内存 DFA / AC 自动机
10.1 词库更新流程
10.2 Redis 发布订阅
频道示例:content:security:word:update
发布消息:
{
"version": "20260810",
"type": "WORD_UPDATE"
}
服务监听后重载:
public void reloadMatcher() {
// 1. 重新加载词库
// 2. 构建 DFA / AC
// 3. 替换旧 Matcher 对象
}
配置示例(本工程):
content:
security:
load-from-redis: false
redis-refresh-enabled: true
redis-words-key: content:security:words
redis-channel: content:security:word:update
十一、Spring Boot 工程设计
项目名称:content-security
整体结构:
content-security
├── content-security-core
├── content-security-api
├── content-security-service
├── content-security-admin
└── content-security-starter
11.1 core 模块
负责:
- DFA 实现
- AC 实现
- 文本归一化
- 匹配模型
结构示意:
core
├── matcher
│ ├── DfaMatcher.java
│ └── AcMatcher.java
├── normalize
│ └── TextNormalizer.java
└── model / engine
├── SensitiveEngine.java
└── ...
11.2 api 模块
定义统一 DTO / Feign 契约,例如:
public interface ContentSecurityFeignClient {
ApiResponse<CheckResult> check(CheckRequest request);
}
11.3 service 模块
负责:
- HTTP 内容检测
- 审计记录
- 对外提供独立服务(默认端口 8088)
核心调用链:
Controller
→ ContentCheckService
→ SensitiveWordService
→ SensitiveEngine(归一化 + DFA/AC + 风险计算)
十二、业务系统接入方案
为了支持若依、芋道以及其他 Spring Boot 项目快速接入,设计两种接入模式:
- Maven Starter
- RPC / Feign 接口
12.1 Maven Starter 方式
适用于:
- 同一个 Java 技术体系
- 对性能要求较高
- 内网业务系统
例如若依:
ruoyi-system
|
content-security-starter
引入依赖:
<dependency>
<groupId>com.janelee</groupId>
<artifactId>content-security-starter</artifactId>
<version>1.0.0-SNAPSHOT</version>
</dependency>
Starter 自动装配后,业务直接调用:
@Resource
private SensitiveWordService sensitiveWordService;
public void comment(String content) {
CheckResult result = sensitiveWordService.check(content);
if (!result.isPass()) {
throw new RuntimeException("内容违规");
}
}
Starter 优点
| 优点 | 说明 |
|---|---|
| 无网络调用 | 进程内执行 |
| 响应快 / 延迟低 | 适合高频检测 |
Starter 缺点
| 缺点 | 说明 |
|---|---|
| 每服务加载词库 | 内存有成本 |
| 升级需重新发布 | 版本跟随业务 |
12.2 RPC / Feign 方式
适用于:
- 多业务系统共享
- 微服务架构
- 多语言调用
架构:
若依服务
|
Feign
|
内容安全服务
|
Redis / MySQL
Feign 接口:
@FeignClient(name = "content-security-service", path = "/security")
public interface ContentSecurityFeignClient {
@PostMapping("/check")
ApiResponse<CheckResult> check(@RequestBody CheckRequest request);
}
RPC 优点 / 缺点
| 优点 | 缺点 |
|---|---|
| 统一管理词库 | 增加网络调用 |
| 服务独立升级 | 需要服务治理 |
十三、内容检测接口设计
统一接口:
POST /security/check
请求参数:
{
"content": "用户输入内容",
"bizType": "comment"
}
字段说明:
| 字段 | 说明 |
|---|---|
| content | 检测文本 |
| bizType | 业务场景(如 comment / post / nickname) |
返回结果示意:
{
"code": 0,
"message": "success",
"data": {
"pass": false,
"riskLevel": "HIGH",
"action": "BLOCK",
"hits": [
{
"word": "xxx",
"category": "LEGAL",
"level": 5
}
]
}
}
健康检查:
GET /security/health
十四、误杀和漏杀问题解决方案
敏感词过滤系统最大的挑战,往往不是「检测不到」,而是:
如何保证准确率,同时减少误杀。
生产环境需要多层策略。
14.1 白名单机制
例如敏感词 枪,但 水枪、玩具枪、游戏枪械 属于正常内容。
检测流程:
敏感词命中
|
↓
查询白名单
|
-----------
| |
存在 不存在
| |
放行 风险处理
14.2 上下文判断
关键词本身不一定代表风险。
| 文本 | 判断 |
|---|---|
| 黑客攻击服务器 | 风险较高 |
| 游戏攻击力提升 | 通常正常 |
因此需要结合:
- 前后文
- 业务场景(
bizType) - 用户行为
14.3 变形词识别
用户可能使用拼音、数字、同音字、特殊符号,例如:
sb4b傻比傻B
建立扩展词库链路:
原始词 → 拼音 → 同音替换 → 数字映射
本工程通过 TextNormalizer + 场景自动学习 降低变形漏杀:检测命中后,可按场景自动把新词 / 变形紧凑词入库,无需业务再调单独入库接口。
十五、AI 语义审核设计
关键词匹配只能解决「明确违规」,无法解决隐含语义风险。
例如:
我要让他消失
没有敏感词,但可能存在威胁语义。因此增加 AI 语义审核。
15.1 AI 审核流程
建议:先规则,后模型;高风险关键词直接拦截,不浪费模型调用。
15.2 AI 模型选择
方案一:第三方审核服务
- 优点:上线快、效果成熟
- 缺点:调用成本、数据安全需评估
方案二:自建模型
例如 BERT / RoBERTa / 大语言模型:
用户文本
↓
模型推理
↓
风险概率
↓
规则融合
↓
审核结果
十六、人工审核闭环设计
企业级内容安全不能只有自动检测,必须建立:
检测 → 审核 → 优化
闭环。
16.1 审核记录表
表名:security_audit_record
CREATE TABLE security_audit_record
(
id BIGINT PRIMARY KEY,
content TEXT,
risk_level VARCHAR(20),
hit_words VARCHAR(500),
biz_type VARCHAR(50),
biz_id VARCHAR(64),
review_status VARCHAR(20),
reviewer VARCHAR(50),
create_time DATETIME
);
字段说明:
| 字段 | 说明 |
|---|---|
| content | 原始内容 |
| risk_level | 风险等级 |
| hit_words | 命中词 |
| review_status | 审核状态 |
| reviewer | 审核人员 |
管理端可提供:
GET /admin/audits:审核列表POST /admin/audits/review:人工复核
十七、性能优化设计
内容安全接口通常属于高频接口(例如评论可达很高 QPS),需要重点优化。
17.1 自动机常驻内存
错误方式:
请求 → 查询数据库 → 匹配
问题:数据库压力大、延迟高。
正确方式:
服务启动 → 加载词库 → 构建自动机 → 内存匹配
17.2 AtomicReference 无锁更新
词库更新时不能影响正在处理的请求,采用:
AtomicReference<Matcher>
更新流程:
旧 Matcher
↓
构建新 Matcher
↓
AtomicReference 替换
↓
请求自动使用最新版本
17.3 Redis 缓存设计
Redis 保存词库与版本,例如:
content:security:wordscontent:security:words:version
服务启动:
Redis / DB → 加载词库 → 构建 DFA/AC → 开始服务
17.4 高并发侧效应削峰(本工程补充)
检测本身走内存同步;自动学习、审计写库走异步通道,自动探测:
RabbitMQ → Redis List → 本地线程池
避免高并发把数据库打满。
content:
security:
concurrency:
channel: auto
local:
core-size: 4
max-size: 16
queue-capacity: 10000
十八、生产部署架构设计
内容安全服务通常属于基础能力服务,需要满足:
- 高可用
- 高并发
- 可扩展
- 快速更新
因此推荐服务集群部署。
18.1 单体部署方案
小规模业务:
适用于:用户量较少、内部系统、测试环境。
18.2 集群部署方案
生产环境推荐:
优势:
- 水平扩展
- 故障隔离
- 支持高并发
- 词库热更新可多实例同步
十九、与若依、芋道框架集成方案
目前企业 Java 项目大量采用若依、芋道,两者均基于 Spring Boot,可以快速集成。
19.1 若依框架接入方式
方案一:公共组件方式
例如放入 ruoyi-common:
<dependency>
<groupId>com.janelee</groupId>
<artifactId>content-security-starter</artifactId>
<version>1.0.0-SNAPSHOT</version>
</dependency>
业务代码:
@Resource
private SensitiveWordService sensitiveWordService;
public void saveComment(String content) {
CheckResult result = sensitiveWordService.check(content);
if (!result.isPass()) {
throw new RuntimeException("内容违规");
}
}
接入主库时:
- 执行
sql/mysql/schema.sql - 复用若依
application-druid.yml,不必再写一遍 JDBC storage.mode=auto自动探测业务表
方案二:微服务 RPC 方式
ruoyi-system
|
Feign
|
content-security-service
适用于若依 Spring Cloud 版本。
19.2 芋道框架接入方式
芋道基于 Spring Boot + Spring Cloud Alibaba,推荐独立部署:
yudao-server / 业务服务
|
OpenFeign / Dubbo / Gateway
|
content-security-service
二十、技术选型总结
| 模块 | 技术方案 |
|---|---|
| 开发框架 | Spring Boot 2.7 |
| JDK | Java 8 |
| ORM | 原生 MyBatis |
| 微服务 | Spring Cloud Alibaba(可选) |
| RPC | OpenFeign / Dubbo |
| 数据库 | MySQL / PostgreSQL / Oracle / SQLServer / H2 |
| 缓存 | Redis(可选) |
| 配置中心 | Nacos(可选) |
| 消息削峰 | RabbitMQ / Redis List / 本地线程池 |
| 文本匹配 | DFA + AC 自动机 |
| AI 审核 | BERT / LLM / 第三方(可选) |
| 部署 | Docker / Kubernetes |
二十一、完整技术架构总结
最终整体架构:
一句话概括:
同步只负责判定,异步负责沉淀;配置能省则省,中间件能借则借。
二十二、方案优势总结
相比传统敏感词过滤方案,本方案具有以下优势:
1. 高性能
采用 DFA + AC 自动机,避免大量字符串遍历;检测路径常驻内存。
2. 高准确性
通过文本归一化、白名单、上下文判断、AI 语义分析,降低误杀与漏杀。
3. 高扩展性
支持多业务接入、Starter / Feign 双模式、微服务架构。
4. 动态更新
词库更新无需重启服务:
管理员修改 → MySQL → Redis → 自动机刷新 → 实时生效
5. 工程友好
- 零配置可用(H2 兜底)
- 复用若依 Druid 主数据源
- 高并发侧效应自动走 MQ / Redis / 本地线程池
二十三、未来扩展方向
内容安全不仅限于文本,未来可以扩展:
23.1 图片审核
支持 OCR 文字识别、图片涉黄 / 违规识别:
图片 → OCR → 文本检测 → 风险判断
23.2 视频审核
视频 → 抽帧 → OCR / 视觉模型 → 内容审核
23.3 音频审核
例如直播语音:
音频 → ASR → 文本审核 → 风险判断
23.4 用户风险画像
结合历史违规次数、举报记录、审核结果、用户行为,形成用户风险评分。
例如:
- 违规次数:10
- 举报次数:5
- 风险等级:HIGH
二十四、总结
一个完整的内容安全系统,并不是简单维护一个敏感词列表。
真正企业级内容安全方案,需要结合:
- 高性能匹配算法
- 文本归一化
- 多级敏感词库
- 风险等级控制
- 动态词库更新
- AI 语义理解
- 人工审核闭环
- 高并发削峰与可运维部署
本文设计了一套基于 Spring Boot 的内容安全过滤服务。通过:
DFA + AC 自动机 + Redis 热更新 + AI 语义审核 + 人工审核闭环
形成一个稳定、高效、可扩展的企业级内容安全基础能力。
该方案可以作为:
- 若依公共组件
- 芋道基础服务
- Spring Cloud 内容安全微服务
为企业应用提供统一、安全、可靠的内容审核能力。
参考标签
SpringBoot Java 微服务 内容安全 敏感词过滤 DFA AC自动机 Redis RabbitMQ AI审核 若依 芋道 SpringCloud
更多推荐


所有评论(0)