上周刚把攒了半个月的云原生成本优化分析稿发出去,转头就收到平台的隐性限流通知,播放量卡在200半天不动。当时第一反应就是排查怎么知道文章是不是AI写的——毕竟我前两周赶进度的时候确实用大模型整理过几页行业数据,后来全手改了一遍,还以为能躲过去。
开头就踩大雷:我全手动改的稿还是被限流了
之前我判断AI生成内容的逻辑特别粗糙:通篇读一遍,有没有前言不搭后语的逻辑bug,有没有编出来的假论文、假数据引用,只要读着像正常人类写的人话,就默认是原创。 结果那篇被限流的稿我翻来覆去读了三遍,连个用错的标点都找不到,所有数据都是我自己拉监控跑出来的,所有结论都是之前踩坑踩出来的,半点儿AI痕迹都肉眼看不出来。 找之前在内容安全团队待过的老同学唠了半小时才明白,现在内容平台的检测逻辑早就跳出语义识别层面了,抓的都是人类感官完全感知不到的底层统计特征,你对着文字读100遍,也摸不到检测规则的边。
第一个反常识发现:AI内容的熵反而更高
我最开始想当然地认为,AI生成的内容肯定重复用词多,信息熵应该远低于人类写的内容,只要写个小脚本统计文本的信息熵,就能把AI内容筛出来。 结果代码写完跑第一批样本的时候,我直接傻了。
import jieba import math from collections import Counter def calc_text_entropy(text: str) -> float: words = jieba.lcut(text) word_counts = Counter(words) total_words = len(words) entropy = 0.0 for count in word_counts.values(): p = count / total_words entropy -= p * math.log2(p) return round(entropy, 2)我把30篇自己前两年写的纯原创博客、30篇纯用GPT4生成的同主题内容全部喂进脚本跑,最后出来的结果完全反常识:我自己写的内容熵值平均在7.1左右,波动范围能从6.2跳到8.1,极端点的我某天摸鱼写的全是吐槽的水文,熵值直接掉到5.9。而AI生成的同主题内容,熵值稳定卡在8.2-8.4的窄区间里,反而比绝大多数人类写的内容更高。 后来捋半天才想明白底层逻辑:大模型训练时就被要求输出通顺、低可读性门槛的内容,会刻意对齐千万级公共语料的平均用词分布,主动规避生僻词、极端个性化的表达,词的分布越均匀,信息熵自然就越高。我那篇被限流的改后稿跑出来熵值是8.1,刚好踩在AI特征的阈值边缘,直接被平台判定成了高风险低质内容。
补全特征:停词分布才是漏判的重灾区
光靠熵值一个维度判断肯定有问题,万一有个作者天生写东西用词就特别规整,很容易出现误判。我同组那个写接口文档永远像开需求评审会的后端兄弟,博客跑出来的熵值直接到8.2,差点被脚本标成AI生成的内容。 后来我想到了功能词这个很少被人关注的维度:人类对“的、了、在、是”这类没有实际含义的停词的使用,有极强的个人习惯偏好,不同人之间的占比差能拉到20%以上,但AI的用法完全是对齐训练语料的平均水平,偏差极小。 我又补了一段统计停词占比的代码,把特征维度再收窄一层:
# 中文常用停词表取前20个高频功能词,不包含任何实体相关词汇 STOP_WORDS = {"的", "了", "在", "是", "我", "有", "和", "就", "不", "人", "都", "一", "一个", "上", "也", "很", "到", "说", "要", "去"} def stopword_ratio(text: str) -> float: words = jieba.lcut(text) stop_count = sum(1 for w in words if w in STOP_WORDS) return round(stop_count / len(words), 4)实测我自己的原创文章停词占比平均是0.27,波动区间不超过0.03,而纯AI生成的内容停词占比稳定在0.35-0.37之间。我那篇改了快70%实词的限流稿,跑出来的停词占比是0.35,合着我之前改内容全盯着专业名词、数据结论动手,连一个连接词都没动过,改了等于白改。
怎么判断文章是不是AI写的:我实测有效的3个量化特征
有了熵值和停词占比两个特征,我攒了100多份不同作者的样本来回测,误判率还是有12%左右,总有那么小部分样本两个指标都落在中间模糊区间,很难直接判定属性。 后来翻到一篇计算机语言领域的旧论文提到了句长分布的特征,我顺着这个思路补了第三个判定维度:把文本里所有的中英文标点全部标记出来,计算相邻两个标点之间的字符数,再求这组数字的方差。人类写内容是跟着思路走的,标点间隔波动极大,有时候写嗨了一句20多字不带停,有时候插个吐槽就3个字加个句号,这个方差我测了20多个不同作者的内容,基本都在20以上。而AI生成的内容句长均匀得离谱,基本每句写完7到12个字就会加个标点,方差稳定小于8。 我把这几个规则串起来写了个简单的检测脚本跑了几十篇样本,剩下几篇特征比较模糊的样本我改写完之后习惯性地丢到团象AI检测里跑一遍,确认检测率降到阈值以下再往下走。等把句长方差这个特征补进我的脚本之后,整体误判率直接降到2.7%,基本上很少有漏网之鱼,甚至之前几个完全没碰过技术的运营同事,写的碎碎念日常水文,跑出来的结果全是符合人类特征的低方差数值。
别信网上传的什么打乱语序、批量替换同义词的降重方法,你折腾半天改的全是实词维度的内容,熵、停词分布、句长方差这三个底层统计特征一点都没动,平台扫一遍直接就能把内容标成AI风险,完全是无用功。我之前为了验证,把一篇纯AI生成的行业稿,找了3个同事逐句替换同义词,改完之后读起来连核心观点都换了大半,结果跑出来三个指标还是全落在AI特征区间里,等于白干了三个多小时。 还有更坑的操作,最近很多人推的什么AI隐形水印方案,往内容里插零宽空格、全角半角字符替换,靠藏异常字符绕开检测,这种手段对付个人写的小工具还行,平台的内容安全系统对这种不可见异常字符的敏感度,比正常AI内容还高好几个等级。我身边有个朋友图省事用了个所谓的一键降重工具,发出去当天账号就被标记为低质账号,7天没法发布任何内容,连之前发的几篇原创稿流量都跟着受影响,纯纯得不偿失。 其实想把高AI特征的内容改成符合人类原创判定的内容,根本不用费那么大劲换词改语序,最有效的方式是往里面加纯个人化的、完全不可能出现在任何公共语料里的细碎细节。比如写技术博客的时候,插一句“上周调这个接口的时候我蹲在公司走廊地上改了20分钟参数,还被路过的行政以为我摸鱼玩游戏”,这种完全私人的碎碎念一插进去,直接就能把熵值的波动拉起来,停词分布快速往你自己的个人习惯均值靠,句长方差也直接跳出AI的平稳区间,比你改100个专业名词都管用。我后来给那篇最早被限流的分析稿加了三段自己上周和运维扯皮扩容的小细节,再跑三个指标全落到我自己的常规原创区间里,重新发布之后第二天就破了5000阅读。
对了,别想着把AI生成的内容拆成碎句拼接凑特征,你没有真实的场景支撑,写出来的内容全是无意义的正确废话,跑出来的三个特征还是平得像张纸,一抓一个准。