如何用AI检测AI生成的文本?

使用Wikipedia社区策划的AI生成内容特征,用Python构建AI文本检测器

如何用AI检测AI生成的文本?
AI模型价格对比 | AI工具导航 | ONNX模型库 | Vibe Coding教程 | PLC在线仿真器 | Tripo 3D | Meshy AI | ElevenLabs | KlingAI | ArtSpace | Phot.AI | InVideo

自2022年11月ChatGPT推出以来,AI生成的内容持续涌入互联网。这正成为一个日益严重的问题,例如在教育领域,当学生提交AI生成的作业时。

这对Medium来说也是一个问题,因为其AI内容政策禁止付费墙文章中使用AI生成的写作[1]。

Medium是用于人类讲故事的,而非AI生成的写作。

同样,Wikipedia也在打击质量低劣的AI生成内容[2]。

LLM生成的文本通常违反Wikipedia的几项核心内容政策。因此,使用LLM生成或改写文章内容是被禁止的,除了对来自其他语言Wikipedia资料的基本复制编辑和翻译[…]

"WikiProject AI Cleanup"产生了一个社区编写的、最新的建议页面,列出了许多AI生成写作的特征,例如破折号的过度使用。

基于这个列表,我们将创建一个小应用程序,使用大语言模型(LLM)作为评判者来评估给定文本是否可能由AI生成或人类撰写。

1、AI文本检测的工作原理

检测文本是由人类还是AI撰写的并不容易。一个著名的例子包括AI检测软件将1776年的《独立宣言》标记为AI生成的概率高达98.51%[3]。

LLM在演进,所以写作风格随着每个新LLM版本的发布而变化。此外,人们可以通过使用特定的提示来避免某些明显的特征,或者通过改写句子来迷惑检测模型来避免AI写作检测。

1.1 AI文本检测系统的4种主要类型

检测AI生成的文本仍然是一个活跃的研究领域。如下图所示,检测方法可以分为四类。

根据研究,AI文本检测方法可以分为四类:水印技术、基于统计的检测器、基于神经网络的检测器和人工辅助方法。
  • 水印技术:LLM提供商在生成的文本中嵌入不可见的数字水印。例如,Google在其生成的图片、音频文件、文本和视频中嵌入SynthID水印。这些水印可用于检测AI生成的内容。
  • 基于统计的检测器:这些检测器分析不同的文本特征来检测AI生成文本中的统计模式。如果某个特征超过特定阈值,就被视为AI生成文本的证据。例如,我们可以使用LLM的logits(概率)来计算给定文本的似然度。
  • 基于神经网络的检测器:人类和AI生成的文本被用作训练数据来训练分类模型。
  • 人工辅助方法:人类的直觉、先验知识和分析技能被用来识别AI生成文本中典型的不一致或错误。

1.2 困惑度和突发性:AI检测器使用的流行信号

除了研究之外,许多AI检测工具专注于基于统计的检测,包括困惑度和突发性[5]。

困惑度是一种白盒统计量,使用LLM来衡量下一个词的概率。例如,给定文本"I would love a bowl of ___,"AI最可能预测的词是"soup"。

然而,人类作家可能会写更不可预测的内容,比如"I would love a bowl of the soup you made for my birthday last year." AI生成的文本往往困惑度较低,而人类生成的文本困惑度较高。

突发性衡量句子长度和结构的变化。AI生成的文本突发性较低,通常意味着中等句子长度和一致的结构。人类生成的文本则有更多变化。

现在,让我们看看两个目前可用的在线工具是如何工作的。

ZeroGPT如何标记AI编写的文本

ZeroGPT主要是一个"基于统计的检测器"。它分析给定文本的语言学和统计信号。这些信号包括token模式、突发性、熵和在混合数据集上训练的集成分类器特征。输出是一个整体分数和看起来像AI生成的突出段落[6]。

GPTZero如何检测AI生成的写作

GPTZero是使用最广泛的AI检测模型之一。最新版本属于"基于神经网络的检测器"类别。它使用一个深度学习AI模型,在各种流行LLM的人类编写文本数据和AI生成文本上进行训练。该模型对每个句子进行分类,并提供其由AI、人类或两者生成的概率[7, 8]。

2、Wikipedia的AI写作特征

AI生成内容已经成为最大的在线百科全书Wikipedia的一个问题。"WikiProject AI Cleanup"创建了一个建议页面,包含指示AI生成文本的特征列表[9]。

这是AI聊天机器人(如ChatGPT)典型的写作和格式惯例列表,真实示例取自Wikipedia文章、草稿、评论和其他内容。它是一份帮助检测Wikipedia上未披露的AI生成内容的现场指南:虽然某些特征可能广泛适用,但在非Wikipedia上下文中可能不适用。并非所有具有这些指标的文本都是AI生成的,因为驱动AI聊天机器人的大语言模型是在人类写作上训练的。

这个列表对于信息性写作(如Wikipedia文章)最有用,但也适用于Medium和其他地方的博客文章。它包含与文本内容、风格、格式等相关的特征,例如ChatGPT曾经痴迷的破折号(—)的过度使用。

当然,这些特征只是观察,不是文本由AI撰写的确定性证据。然而,多个特征的积累提供了强有力的证据。

我们将使用这个特征列表来创建一个应用程序,使用LLM作为评判者,根据每个特征/类别对给定文本进行评分。输出将是文本由AI生成的概率。这个AI文本检测模型属于"人工辅助方法"。它使用人类知识创建AI特征列表。

基本思想是使用1到5的量表独立评估每个类别,然后使用分数集合得出最终结论。

这个列表最大的优点是它是社区驱动的,并且不断更新。不需要训练一个会随着每个新LLM版本而过时的AI模型。相反,我们可以使用这个可适应的列表作为提示模板。

3、使用LLM-as-a-Judge构建AI文本检测器

我们将使用Google的Gemini LLM在Python中自动评估文本的AI写作特征。

首先,我们需要安装必要的Python包。

pip install google-genai==1.73.1 dotenv pyyaml

使用Wikipedia文章作为蓝图,我们可以将选定的内容复制到categories.yaml文件中。对于每个特征,我们定义一个name、一个description和一个examples列表。

生成的文件看起来像这样:

categories:
  - name: overuse_of_em_dashes
    description: >
      While human editors and writers often use em dashes (—), LLM output
      uses them more often than nonprofessional human-written text of the same
      genre, and uses them in places where humans are more likely to use commas,
      parentheses, colons, or (misused) hyphens (-) and en dashes (–). LLMs
      especially tend to use em dashes in a formulaic, pat way, often mimicking
      "punched up" sales-like writing by over-emphasizing clauses or
      parallelisms.
    examples:
      - You're right about one thing — we do seem to have different
        interpretations of what policy-based discussion entails.

这只是一个摘录。对于这个项目,我使用了以下类别

  • 对重要性、遗产和更广泛趋势的不当强调:AI写作经常夸大主题的重要性。例如,它可能使用"关键时刻"或"重大转变"等短语。
  • 肤浅的分析:AI倾向于插入肤浅的分析,通常在句子末尾添加现在分词("-ing")短语。
  • 宣传和广告式语言:LLM难以保持中立的语气。
  • "AI词汇"的高密度: delve, pivotal, key, …
  • 负面平行结构:不仅仅是X,而且是Y。
  • 三法则:"形容词、形容词、形容词"或"短语、短语和短语。"
  • 标题大小写:AI倾向于将章节标题中所有主要单词大写。
  • 破折号的过度使用:著名的——
  • 表情符号作为格式:🚨 AI喜欢表情符号,特别是在标题或列表中。🚨

使用yaml.safe_load(),我们可以从YAML文件中将内容作为Python字典导入:

import yaml

with open("categories.yaml") as f:
    data = yaml.safe_load(f)

CATEGORIES = data["categories"]

接下来,定义我们的LLM。我使用Google的Gemini 3.1 Flash Lite Preview模型。以下代码假设你在同一文件夹中有一个.env文件包含你的API密钥。你可以在Google AI Studio中为开发目的创建一个免费的API密钥。

import os

from dotenv import load_dotenv

load_dotenv()
assert os.getenv("GOOGLE_API_KEY"), "GOOGLE_API_KEY not found in environment"

使用Google的genai库,我们可以使用我们选择的Pydantic模型进行结构化的LLM调用。

from typing import Type, TypeVar

from google import genai
from google.genai import types
from pydantic import BaseModel

client = genai.Client()

T = TypeVar("T", bound=BaseModel)

def call_llm(prompt: str, response_model: Type[T]) -> T:
    """Make a structured LLM call conforming to the provided Pydantic model"""

    config = types.GenerateContentConfig(
        temperature=0.0,
        thinking_config=types.ThinkingConfig(thinking_level="minimal"),
        response_mime_type="application/json",
        response_json_schema=response_model.model_json_schema(),
    )

    response = client.models.generate_content(
        model="gemini-3.1-flash-lite-preview",
        contents=prompt,
        config=config,
    )

    text = response.text

    try:
        return response_model.model_validate_json(text)
    except Exception as e:
        raise ValueError(f"Invalid structured output:\n{text}") from e

我们将使用三个Pydantic类。首先,一个用于每个类别/特征的CategoryScore类,包含1到5的分数和一个推理字符串,为LLM提供额外的思考token并提供评分理由。

from pydantic import Field

class CategoryScore(BaseModel):
    reasoning: str
    score: int = Field(
        ...,
        ge=1,
        le=5,
        description="Score from 1 to 5, where 1 means 'not present at all' and 5 means 'very strongly present'",
    )

class AllCategoryResults(BaseModel):
    results: dict[str, CategoryScore]

class Verdict(BaseModel):
    reasoning: str
    ai_probability: int = Field(
        ...,
        ge=0,
        le=100,
        description="Estimated probability that the text was written by AI, from 0 to 100",
    )

AllCategoryResults类以结构化的方式聚合每个类别的分数。这将用作生成最终判定的输入。Verdict类是LLM的输出,提供文本是AI生成的0到100之间的概率。

score_category()函数从YAML文件中读取单个类别,并指示LLM如何评估提供的文本。目标是独立地对每个类别进行评分。

def score_category(category: dict, text: str) -> CategoryScore:
    examples_str = "\n".join(category["examples"])
    prompt = f"""
You are an expert linguistic evaluator. Your task is to assess whether the given text exhibits a specific writing pattern.
You must be precise, consistent, and conservative in your judgments. Do not overgeneralize or infer intent beyond the text.

## EVALUATION CATEGORY:
Name: {category["name"]}

Definition:
{category["description"]}

Examples (for calibration only, do NOT copy wording or assume exact matches are required):
{examples_str}

## SCORING GUIDELINES
Score from 1 to 5 based on how strongly the pattern is present:

1 = Not present at all
2 = Possibly present (weak or ambiguous signal)
3 = Moderately present (clear instance, but limited or isolated)
4 = Strongly present (multiple clear instances or a dominant pattern)
5 = Very strongly present (pervasive, defining characteristic of the text)

Important:
- Base your score ONLY on observable text features.
- Do NOT rely on assumptions about the author or intent.
- Do NOT penalize or reward general writing quality.
- The pattern must match the definition, not just vaguely resemble it.

## OUTPUT FORMAT:
Return JSON with:
- reasoning: brief explanation of your decision
- score: 1-5

## INPUT TEXT:
{text}
""".strip()

    return call_llm(prompt, CategoryScore)

final_verdict()函数使用所有类别的聚合分数来生成最终判定。我还添加了一个关于字数的简短提示,因为太短的文本不可靠,所以需要更强的证据。

def final_verdict(categories: AllCategoryResults, word_count: int) -> Verdict:
    prompt = f"""
You are an impartial judge. Your task is to estimate the probability that a text was written by an AI system.
You MUST base your decision strictly on the provided category scores and reasoning.

## INPUT CATEGORY SCORES:
Each category includes:
- a score from 1 (not present at all) to 5 (very strongly present)
- reasoning describing the evidence

{categories.model_dump_json(indent=2)}

## OUTPUT PROBABILITY GUIDELINES
Use these rough anchors for calibration:

- 0-20: little to no evidence of AI patterns
- 21-40: weak or sparse signals
- 41-60: mixed or moderate evidence
- 61-80: strong evidence across multiple categories
- 81-100: overwhelming and consistent AI-like patterns

When in doubt, favor the human-written hypothesis: unless the evidence is both strong and consistent, keep the probability close to 50 rather than assigning a high AI likelihood.

## LENGTH ADJUSTMENT RULES
Text length: {word_count} words
- <50 words: low reliability -> reduce confidence
- >=200 words: higher reliability -> increase confidence

## OUTPUT FORMAT:
Return JSON with:
- reasoning: brief explanation of your decision
- ai_probability: estimated probability from 0 to 100
""".strip()

    print(prompt)
    return call_llm(prompt, Verdict)

analyze_text()函数运行整个流程。它返回一个包含每个类别和最终判定的字典。

import json

input_text = "Insert input text here"
result = analyze_text(input_text)
print(json.dumps(result, indent=2))

4、使用Streamlit构建UI

如截图所示,我创建了一个带有Streamlit UI的小应用,其中有一个文本区域可以粘贴文本。后端调用analyze_text(text),结果字典用于向用户显示AI概率和推理。

更多详情请查看GitHub

5、结果:测试AI检测器

让我们用几个输入文本示例来测试应用。

测试1:独立宣言(0% AI)

首先,我测试了独立宣言,看看历史文档是否会被误判为AI。如下所示,文本的AI概率为0%。

然而,推理显示LLM识别出文本是独立宣言,这似乎严重影响了判断。但也许这是件好事。毕竟,LLM评判者足够智能,能够推理出历史文档应该被不同地评估。

独立宣言文本的AI概率为0%。

测试2:ChatGPT之前的维基百科文章(0% AI)

以下文本来自2022年1月2日的维基百科文章"Cat",比ChatGPT首次向公众发布早了几个月。因此,我假设这段文本完全由人类撰写。

ChatGPT之前的维基百科文章AI概率为10%。

测试3:100% AI生成的博客文章

我使用以下提示生成了100% AI编写的文本:

写一篇关于智能体AI的简短(300字)博客文章。

使用相同的提示,我用ChatGPT 5.3、Gemini 3和Qwen3.6-Plus生成了三个不同的AI编写文本。

所有三段文本都被判定为75%的AI概率。例如,以下是Qwen生成的文本:

AI生成的文本被检测为75%的概率。

6、AI检测器对比

我测试了GPTZero、ZeroGPT和QuillBot的AI文本检测模型,将我们的应用基于Wikipedia的AI写作特征进行了比较。

结果如下表所示。每个单元格显示给定文本由AI生成的概率。绿色单元格表示正确的检测,红色单元格表示不正确的检测。

从最好到最差:GPTZero,QuillBot,我们的应用,ZeroGPT

总体而言,我们的应用表现相当不错。GPTZero和QuillBot的概率更接近真实情况。特别是GPTZero在这个小实验中非常准确。

另一方面,ZeroGPT将所有内容标记为几乎100%的AI生成。这是危险的,因为这些误报可能被用来做出错误的指控。

7、结束语

在这个项目中,我们实现了LLM-as-a-judge概念,使用Wikipedia社区生成的AI生成写作特征列表自动评估文本。

我在两段人类编写的文本和三段AI生成的文本上测试了这个概念,取得了相当好的结果。

当然,还有一些可以改进的地方。首先,我没有实现Wikipedia列表中的所有规则。例如,"粗体的过度使用"是一个强指标,但在将简单文本复制粘贴到文本字段时不起作用。

也许还有其他优秀的AI指标列表,不专门针对Wikipedia文章。其他类别可以轻松添加到YAML配置文件中。例如在Medium上,我认为AI生成的封面图片和信息图是AI使用的强指标。

不幸的是,Wikipedia的AI特征列表可以通过提示LLM避免所有这些特征来被利用。这就是为什么仅依赖该列表不足以检测熟练的AI使用的原因。

检测AI写作的一个很好的解决方案是结合研究总结中AI文本检测工作原理的多个类别。Wikipedia列表是一种人工辅助方法。一个有价值的改进将是添加基于统计的方法。例如,可以评估困惑度和突发性作为额外的信号,使整体管道更加健壮和准确。


原文链接:How to Detect AI-Generated Text Using Signs of AI Writing

汇智网翻译整理,转载请标明出处