黑话垃圾标题防不住?多层漏斗策略从规则到分类一次讲透
先说一个真实到让人头疼的场景:你负责的内容社区或投稿后台,突然出现一条新内容,标题是“招来站务算我炸单✌︎ ॑꒳ ॑✌︎”。你盯着它看了十秒钟,第一反应是“这是什么黑话?”第二反应是“这好像不是正常人写出来的”。如果你做过站务管理,大概会熟练地把这类内容归为垃圾信息,然后点删除。但问题在于,这样的标题每天会出现几十个变体,今天把“站务”换成“版务”,明天把“炸单”换成“炸蛋”,后天再加上一堆不可见字符。你手动删得过来吗?
我见过不少站点管理员,最初都是纯人肉审核,上午还行,下午眼睛就开始花了,一周之后看到任何带表情符号的标题都手抖。这不是个人能力问题,而是审核任务本身就不适合靠人肉硬扛。更麻烦的是,垃圾文本的制造者也在进步,他们不写完整句子,不重复同样内容,而是用各种分词、谐音、emoji 和 Unicode 变体绕过关键词。真正对抗的不是某一个具体标题,而是一套不断变化的“语言”。
所以我先把结论放在前面:面对“招来站务算我炸单”这类无意义、黑话化、高变体的垃圾标题,想要靠一个关键词黑名单打天下基本不可能。更稳妥的做法是搭一套“规则过滤 + 指纹去重 + 文本分类 + 人工复核”的多层漏斗,让每层只解决一部分问题,相互兜底。这既是工程问题,也是运营问题。这篇文章就按照“先理解问题,再设计流程,再落地参数,最后排查踩坑”的顺序,把这套思路完整拆开。
1. 先看懂站务审核为什么会被无意义标题打穿
1.1 垃圾消息为什么偏爱黑话和奇怪字符
如果你拦过广告、外链或推广内容,会发现它们有明显的模板特征,比如“加微信”“全网最低”“点击链接”。这类内容只要维护一批关键词,基本能挡掉大部分。可真正让人头疼的是“招来站务算我炸单”这种:它既没有链接,也没有明显的广告词,甚至像一句无绪的暗语。
垃圾文本制造者其实很聪明,他们知道系统会做关键词屏蔽,所以故意把字词拆散、替换同音字、插入 emoji 或零宽字符。例如把“客服”写成“客 服”,把“加群”写成“➕ 群”,再把一些随机字组合在一起。从语义上看,这些文本毫无意义,但从数据上看,它们和正常标题的字符分布差异很大。也就是说,垃圾内容不依赖“读懂”,而是依赖“像垃圾”这件事本身。
你不需要知道“炸单”具体指什么,只需要知道:如果一个标题包含大量异常字符、高比例表情符号、或者字词之间缺少连贯语义,它大概率不是正常用户想发布的内容。这也是规则引擎能起效的地方。
1.2 站务场景里的三类典型垃圾内容
我把常见的垃圾内容粗略分成三类,分别对应不同的识别策略:
- 模板化广告:包含微信号、二维码、外链域名、诱导话术。这类内容最容易识别,关键词加正则就够了。
- 批量低质文本:同一个文本反复发布,或者改几个字发布几十次。这类内容适合用文本指纹做相似度去重。
- 黑话化垃圾:像“招来站务算我炸单”一样,表面上没有明显广告要素,但字符分布异常、语义混乱。这类内容需要交给分类模型或更复杂的特征工程。
前两类是基础设施,第三类是你要长期对抗的主力。很多站点只做了关键词过滤,结果被第三类打得措手不及,因为黑话是不停变化的,你不可能穷举所有变体。所以我们需要把“语义理解”交给模型,而不是靠死记硬背。
1.3 人肉审核为什么不可持续
有人会说,“我有两个兼职审核员,每天手动看一遍就好”。如果每天只有几十条内容,人肉审核确实没问题。但当内容量增长到上千条,管理员需要在“误删正常内容”和“漏放垃圾内容”之间做选择时,心理压力会非常大。
还有一个更隐蔽的问题:人的判断标准不稳定。同一个标题,周一你可能觉得是垃圾,周三你心情好就放行了;或者不同审核员之间的尺度不一致。这种不一致会导致用户投诉,也会让垃圾制造者有机可乘——他们只要尝试几次,就能摸清你的审核规律。
人肉审核适合作为最后的兜底,但不合适作为第一道关卡。机器先过滤掉 90% 的明显垃圾,再把剩下的 10% 交给人工处理,这才是可持续的协作方式。
2. 搭建垃圾标题识别系统的整体思路:从单规则到多层漏斗
2.1 一个最小可用的规则引擎
先别急着上机器学习。任何一套审核系统都应该从最简单、最可解释的规则开始。规则引擎的价值不是准确率,而是“稳定”:只要标题命中规则,就一定会被处理,不会像模型一样出现概率波动。
最小规则集可以包含四类:
这个规则很简单,但已经能接住一部分明显垃圾。注意正则里的字符集要结合你的站点语言和常见特殊符号调整,比如 emoji 也属于特殊符号,但要单独处理。
规则引擎的关键不是“写得多”,而是“别误杀”。如果某个规则会命中很多正常标题,宁可把规则调严,也不要直接删掉。因为误删一个正常帖子,比漏放十个垃圾帖子更容易引发用户流失。
2.2 加入文本指纹与相似度匹配
黑名单规则能拦截固定模式,但拦不住“改一个字再发一遍”。文本指纹就是用来做“近似去重”的。
一种常见的做法是把标题标准化后计算哈希,然后在数据库里查找过去一段时间内是否出现过相同或高度相似的指纹。实现时不需要等“完全一样”,可以用 SimHash 或 MinHash 来算相似度,但最小可用版本也可以先用简单的“归一化后完全匹配”。
比如把标题里的 emoji、标点、空格全部去掉,统一转小写,然后算 MD5:
如果数据库里已经存在同一个指纹,说明这条内容之前出现过,可以直接进入待审核队列,甚至直接拦截。但要注意:垃圾制造者也会做“变形”,比如在中间插入一个随机字,让哈希完全不同。这时候需要用 SimHash 计算海明距离,而不是精确匹配。不过 SimHash 的工程实现要更复杂,建议先用小规模精确匹配跑通,再根据垃圾量决定是否升级。
2.3 引入分类模型时的训练样本怎么准备
当规则和指纹都拦不住时,语义层面的垃圾就得靠分类模型。但是“分类模型”听起来高大上,其实训练样本的准备工作才是决定成败的地方。
你不需要一开始就搞一个大而全的模型。先收集过去 30 天被人工标记为垃圾的标题,再随机取同样数量的正常标题,打上 0/1 标签,训练一个二分类器。文本表示可以从简单的 TF-IDF 开始,选词维度控制在几万以内,模型用逻辑回归或朴素贝叶斯。这个组合在中小规模数据上已经够用。
训练样本的注意点:
- 正负样本比例不要严重失衡。垃圾内容可能只占 1%,但你喂给模型的时候要保持接近 1:1,否则模型会倾向把所有内容都预测为正常。
- 对“黑话化文本”要单独标注。如果你只标注了带链接的垃圾,模型就学不会识别“招来站务算我炸单”这种无链接垃圾。
- 保留一份验证集。为了调阈值,你需要验证集,不要用训练集里的样本来评估效果。
2.4 人工复核闭环:永远保留兜底
机器再强,也不应该给“绝对删除”的权限。更稳妥的流程是分级别处理:
- 规则或模型判定“明显垃圾”的内容,直接拦截或进回收站。
- 判定“疑似垃圾”的内容,先进待审核队列,由人工判断。
- 人工审核的结果要回流到训练数据里,定期更新模型。
也就是说,人工不是被机器替代,而是和机器形成闭环。机器负责把 1000 条内容压缩成 50 条“需要人看”的候选,人只需要看这 50 条。这样既保证效率,又避免模型误杀。
3. 关键参数与工程细节:先跑通,再优化
3.1 预处理:别让字符编码坑了你
你拿到的标题不是干净的字符串,里面可能包含全角空格、零宽字符、emoji、繁体中文、大小写混写。如果不做预处理,同一个标题会因为字符形式不同而产生不同的特征。
我推荐的预处理步骤:
- 统一转小写。
- 全角字符转半角(比如
A转A)。 - 去除零宽字符(
\u200b、\u200c、\u200d等)。 - 根据业务需求决定是否去除 emoji。
- 对繁体中文做可选的转简体处理。
注意:“去除 emoji”不是必须的,因为 emoji 本身可能是特征。比如正常标题很少会有连续三个表情符号,而垃圾标题经常会用表情来吸引注意。你可以把 emoji 统计数量作为特征,而不是直接删掉。
3.2 特征设计:字符熵、emoji 占比、重复度
当规则判不出“像不像垃圾”时,就要让特征来表达“像不像”。这里介绍三个非常有效的特征,全部基于字符统计,不需要额外依赖。
字符熵:描述字符串的混乱程度。正常标题“今天天气不错适合跑步”的信息熵较低,而“招来站务算我炸单✌︎ ॑꒳ ॑✌︎”因为混入大量奇怪符号,熵会显著偏高。计算方式可以用 Python 的collections.Counter:
emoji 占比:统计 emoji 字符数在全文字符数中的比例。比例超过 0.2 就已经很可疑。
连续重复度:或叫重复字符比例。正常文本一般不会出现连续五个相同字符,但垃圾文本会为了绕过检测而故意重复。
这三个特征加在一起,已经能分出一部分“语义混乱”的内容。如果某条标题同时满足高熵、高 emoji 占比、高重复度,它几乎没有可能是正常内容。
3.3 阈值选择:不能只看准确率,要看召回和误杀成本
很多人调模型只看准确率,比如“准确率 95%”,听起来很高。但在垃圾过滤场景里,如果垃圾只占 1%,你把所有内容都预测为正常,准确率也有 99%。所以你真正要关注的是:
- 对垃圾内容的召回率:100 条垃圾至少拦下多少?
- 对正常内容的误杀率:100 条正常内容有多少被误判?
- 人工审核队列的占用率:如果疑似项太多,人工依然会很累。
合适策略是:先设定一个“宁可多召回、不可漏放”的高嫌疑阈值,把疑似项都送人工;再用一个更严格的“直接删除”阈值,只处理置信度极高的垃圾。这样可以把误杀风险控制在很小范围。
3.4 实时性与批处理的选择
站务审核有的是实时拦截,比如发帖时立刻判断;有的是批处理,比如每天跑一次脚本,把当天可疑内容集齐后让审核员处理。
- 如果站点内容量不大,实时判断更友好,用户发完马上有反馈。
- 如果内容量大且需要复杂模型,可以用消息队列做异步处理,先发布,后台再抽检,发现问题再下架。
实时方案和批处理方案的代码结构差很多。初期建议先做批处理,把日志和疑似列表输出到一张表里,验证效果后再逐步迁移到实时接口。不要一开始就追求毫秒级,稳定性比速度更重要。
4. 真实链路中的坑:排查顺序与错误定位
4.1 现象:为什么明明设了规则,垃圾还是溜进来
一个常见场景:你已经配好了关键词、指纹和模型,后台依然每天出现不少漏网垃圾。这时候不要急着加更多规则,先按顺序排查。
排查顺序通常是:
- 先看漏网内容长什么样,是模板广告还是黑话变体。
- 再看它是否通过了所有过滤层,还是某些层根本没执行。
- 最后看是输入问题,还是参数问题,还是流程问题。
4.2 从输入排查:编码、全角半角、零宽字符
很多垃圾标题在后台看起来正常,但在字符层面已经“包装”过了。比如标题里藏了零宽空格,视觉上完全看不出,但正则匹配时就不等于普通空格。如果规则里写了“过滤空白字符”,而垃圾制造者用了零宽空格,规则就失效了。
排查方法是把漏网标题的 Unicode 码点打印出来,看是否有 \u200b、\u200c、\ufeff 这类控制字符。有的话就在预处理阶段统一剥离。这一步虽然琐碎,但往往能解决一半的“规则失效”问题。
4.3 从模型排查:样本分布、过拟合、阈值漂移
如果规则没问题,但模型预测概率普遍偏低,大概率是训练样本分布和线上实际数据不一致。比如你只标注了“纯英文垃圾”,但线上垃圾是中英混杂,模型自然学不到。
还有一种情况是“阈值漂移”:上线时阈值 0.8 效果很好,三个月后线上内容风格变化了,正常用户也开始用更多网络梗和表情,模型仍然按旧阈值判断,导致误杀升高。解决办法是定期抽样评估,重新调阈值或更新模型,而不是让模型“一劳永逸”。
4.4 从流程排查:审核队列是否被绕过、日志是否缺失
最后要确认管道没有被绕过。比如你只在发布接口做了过滤,但用户通过编辑接口二次上传标题,编辑接口没走同一个过滤逻辑,垃圾就溜进去了。或者在批处理流程中,某个异常导致日志没有写入,后续无法追踪。
排查时先看日志链路:一条垃圾内容从提交到展示,经过了哪些环节,每个环节是否都有记录。如果某个环节没有日志,说明那里可能存在盲区。补日志虽然不增加“效果”,但能快速定位问题,长期价值很高。
5. 这套方案在什么场景下适用,在什么场景下别用
5.1 适合:中小型论坛、评论区、投稿系统、站内信
这套“规则 + 指纹 + 分类 + 人工复核”的漏斗,最适合内容量在每天几千到几万条、且以短文本为主的中小型站点。它的成本控制在一个可接受范围内,不需要专门的算法团队,一个人加上一台普通服务器就能运行。
具体场景包括:
- 论坛帖子标题过滤。
- 文章评论区的广告刷屏。
- 用户投稿时的内容初筛。
- 站内信里的批量骚扰信息。
这些场景的文本通常较短,特征比较鲜明,而且都有“可以接受误杀后申诉”的容错空间。
5.2 不适合:内容量极小或需要复杂语义判断的站
如果你每天只有几十条内容,搭建这套系统反而增加维护成本。这时候直接让人肉审核,或者只用一个简单的关键词黑名单,效率更高。
另外,如果你的需求是“判断一个标题是否优质、是否吸引人”,这就不是垃圾过滤模型能解决的问题。优质内容往往需要理解领域知识、语境甚至审美,目前的规则和分类模型处理不了。别指望这套方案能帮你写标题,它只负责把明显的垃圾挡在外面。
5.3 如果要做长期运营,还需要补上什么
长期运营中最容易被忽视的三块拼图:
- 内容处置策略:拦截之后是直接删除、进回收站,还是让用户申诉?建议先进回收站,保留 7 天。
- 统计报表:每周看垃圾量、拦截率、误杀率、人工复核耗时,这些数据能告诉你系统是否在退化。
- 策略版本管理:规则和模型参数不是一次设完就结束。每次修改都要记录版本,方便出问题时回滚。
这三块不是“选装”,而是把审核系统当成一个长期服务来运营的必要条件。
回到开头那个标题:“招来站务算我炸单✌︎ ॑꒳ ॑✌︎”。它看起来荒诞,但反过来说明了一个趋势:垃圾内容正在越来越“非人化”,它们不再追求语义通顺,而是用各种变体绕过机械规则。站务审核的长期解法,不会是一份万能黑名单,也不会是一个永远不更新的模型,而是一套能把“机器批量过滤”和“人工判断”有效结合起来的流程。先跑通最小闭环,再逐步增加指纹和模型,最后用日志和报表把经验固化下来。你会发现,真正让你轻松的,不是某一次精准拦截,而是这套系统能跟着垃圾变化一起迭代。