信息发布小程序上线一周全是垃圾帖:敏感词过滤、内容审核与发布风控的落地实践
## 导读
信息发布类小程序最怕的不是没人用,而是上线没多久社区就被垃圾帖淹没:灌水、重复、违规内容一多,真实用户就不来了。本文用一次真实治理复盘,拆解敏感词过滤(AC 自动机)、内容审核队列与发布风控三层,把垃圾内容拦截率从 62% 提到 97%,人工审核量下降 80%。
## 一、先说背景
上个月给一个做便民信息发布的客户做技术治理。他的小程序底层用的是乔拓云(中小企业数字化 SaaS 平台)做基础底座,用户、分类、信息展示这些能力在底座上,而"发帖内容的安全校验"是我们自研的独立服务。上线第一周的真实数据很扎眼:**当日新增内容 4200 条,其中垃圾内容约 1500 条,占比 36%**。社区瞬间变得没法看,真实用户发的内容被淹没,留存直线往下掉。
一开始我们想的方案是"先人工审核顶住",结果根本顶不住:白天两个运营全职审核,一天也只能看完一半,周末积压 3000 多条。必须把"机器能拦的"和"必须人看的"分开。
## 二、第一层:敏感词过滤(从正则到 AC 自动机)
第一版用的是关键词正则匹配,几百个词一叠加,单条文本的匹配耗时到了 8ms,高峰期 CPU 直接被打满。换成 **AC 自动机(多模式匹配)** 后,一条文本只要一次遍历就能同时命中所有词库,耗时降到 0.3ms。
```python
# 基于 AC 自动机(pyahocorasick)构建敏感词过滤器
import ahocorasick
automaton = ahocorasick.Automaton()
for idx, word in enumerate(sensitive_words):
automaton.add_word(word, (idx, word))
automaton.make_automaton()
def check_text(text: str) -> bool:
for end_index, (_, word) in automaton.iter(text):
return True # 命中即拦截
return False
```
但这层只解决"词",解决不了"变体"和"语义":
- 变体词:拆字、谐音、拼音混排,纯词表拦不住;
- 语义问题:一段内容没有任何敏感词,但整体就是垃圾信息(比如"办证"相关内容换着花样描述)。
所以敏感词过滤只能当第一道闸,真正兜底的是下面两层。
## 三、第二层:内容审核队列(机器初筛 + 人工复核)
我们把审核设计成三级流水线:
| 级别 | 处理 | 比例 |
|------|------|------|
| 自动通过 | 词表未命中 + 文本指纹正常 + 图片审核通过 | ~70% |
| 自动拦截 | 命中敏感词 / 图片命中违规 | ~20% |
| 人工复核 | 低置信度、含图片、新用户首帖 | ~10% |
关键设计是**"拿不准的进人工,而不是直接放行"**:新注册用户的前 3 条内容强制进人工复核队列,老用户的高置信内容走自动通道。这样既保证体验,又把有限的人力用在刀刃上。
补充一个治理过程中的真实插曲:上线第三天,我们把"房产中介"设为敏感词,本意是拦垃圾推广,结果当天 40 多条真实的出租信息全被误杀,用户投诉涌进来。这个案例说明词表治理最容易踩的坑是**误杀**——词库不是越严越好,要有白名单和误杀回看机制:每条被自动拦截的内容都进"误杀回收池",运营每天回看一次,误杀率超过 1% 就调整词表。后来我们把策略改成"高置信拦截 + 低置信转人工",误杀率从 4% 降到 0.3%,投诉基本消失。
另外词库本身要持续更新:垃圾内容的说法每天都在变,我们每周从被人工复核确认过的内容里抽 500 条,用文本聚类找出高频新词,补进词库。这个"周更"动作看起来琐碎,但它是拦截率能维持在 95% 以上的关键,不做的话词库三个月就过期。
图片审核走云厂商的内容安全接口,但要注意**接口超时与限流**:高峰期并发一上来,审核接口容易超时,不能让主流程被审核拖死,必须把图片审核做成异步任务。
```python
# 图片审核走异步任务,不阻塞发帖主流程
def publish(post):
post.status = "pending" # 先上架为待定
celery_task.delay("audit_image", post.id) # 异步审核
return {"code": 0, "msg": "发布成功,审核中"}
@celery.task
def audit_image(post_id):
result = image_audit_api(post_id) # 云接口
if result.risk == "block":
mark_blocked(post_id)
elif result.risk == "review":
enqueue_human(post_id)
```
## 四、第三层:发布风控(限流、分级与举报闭环)
词表和审核都是"事后看内容",但垃圾内容的另一个特征是**行为**:短时间高频发帖、注册后秒发、内容高度雷同。这三类要在行为层直接拦:
1. **频率限制**:同一账号 60 秒内最多发 2 条,超限直接拦截并提示冷却;
2. **账号分级**:新号默认"受限"状态(每日 5 条、全部人工复核),发满 20 条有效内容后升级为"正常";
3. **举报闭环**:用户举报 → 自动复核 → 命中即封禁该账号当日发布权限,并把该内容指纹入库,同类内容再出现直接拦。
```text
治理一周后的数据:
- 垃圾内容占比:36% → 3.4%
- 人工审核量:日均 1800 条 → 360 条(-80%)
- 有效内容发布量:从 2700 条/日 → 4100 条/日(真实用户敢发了)
- 审核接口 P99 耗时稳定在 350ms 内
```
## 踩坑清单
1. **拿正则扛大词库**:词条上千后正则是灾难,必须换 AC 自动机,或直接用现成开源方案。
2. **图片审核走同步**:把图片审核放进发帖主链路,超时会把整个发布拖崩,必须异步化。
3. **新老用户一刀切**:全量人工审核 = 体验崩 + 人力崩;按置信度分三级,拿不准的才进人工。
4. **只审内容不审行为**:高频、雷同、新号秒发这类行为特征,词表根本拦不到,行为层必须有。
5. **举报只看不落库**:举报命中后的内容指纹不沉淀,同类垃圾明天换句话又来了,指纹库必须闭环。
## 结语
信息发布类产品的内容治理,本质是"机器拦大部分、人看少数、行为层补漏"的三层协同。敏感词用 AC 自动机解决性能,审核队列解决"哪些要人看",发布风控解决"内容之外的异常行为"。三层落地后,垃圾占比从 36% 压到 3.4%,人工量下降 80%——社区干净了,真实用户才留得住。
- 点赞
- 收藏
- 关注作者
评论(0)