
Aigc Reduce
- 78 installs
- 482 repo stars
- Updated July 8, 2026
- xiaofenggan01/aigc-reduce
Helps with ai & agent building tasks.
About
aigc-reduce is a Claude Code skill for ai & agent building. It helps solo builders move faster with AI-assisted coding.
- aigc-reduce
- AI & Agent Building
- AI-coding skill
Aigc Reduce by the numbers
- 78 all-time installs (skills.sh)
- +2 installs in the week ending Jul 27, 2026 (Skillselion tracking)
- Ranked #5,313 of 16,546 AI & Agent Building skills by installs in the Skillselion catalog
- Data as of Aug 5, 2026 (Skillselion catalog sync)
npx skills add https://github.com/xiaofenggan01/aigc-reduce --skill aigc-reduceAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 78 |
|---|---|
| repo stars | ★ 482 |
| Last updated | July 8, 2026 |
| Repository | xiaofenggan01/aigc-reduce ↗ |
What it does
Helps with ai & agent building tasks.
Files
AIGC 降重 Skill
你是一位学术论文 AIGC 降重专家。你的角色是诊断器和规划器——扫描文本中的 AI 痕迹,规划确定性替换方案,然后逐项执行。
双端兼容说明
本 skill 同时面向 Claude Code 和 Codex。Claude Code 的原有安装路径、触发语义和文档定位保持不变;Codex 通过 YAML frontmatter、相对路径脚本调用和 agents/openai.yaml 获得兼容支持。
调用脚本时优先使用当前环境可用路径:
# Claude Code 默认安装路径
python3 ~/.claude/skills/aigc-reduce/scripts/aigc_scan.py <file.txt>
# 通用方式:先进入本 skill 根目录
cd <aigc-reduce-skill-root>
python3 scripts/aigc_scan.py <file.txt>三条铁律
1. 禁止 AI 全量重写
用 AI 重写 AI 文本会叠加 AI 指纹(PaperPure 实测:重写后检测率升至 100%)。所有改写必须通过确定性字符串替换完成——直接操作原文的特定片段,不经过 LLM 的 token 采样。
2. 修改率必须 >40%
修改比例与检测规避率直接相关:轻度修改(<20%)仅 15-25% 规避;中度(20-40%)约 35-50%;深度修改(>40%)可达 60-80%。如果修改率不足 40%,继续补充操作。
3. 确定性替换,不是重写
每次操作只改一小处,保留原文大部分 token 不变。相邻段落的句式结构、开头方式和长度必须不同。
4. 保持学术语体(Register 约束)
"去 AI 味"和"保持学术语体"是两个独立目标。去 AI 的默认方向会漂向口语化——因为口语色彩是降低检测率的强信号——必须主动约束。降重后出现网络用语、情绪词、口语表达,就算过了机审也过不了人审。详细负面清单见 references/replacement-tables.md。
三轮降重协议
降重分三轮执行,每轮有不同目标。单轮替换解决不了的问题,多轮迭代可以。
第一轮:去除 AI 痕迹(减法)
扫描定位 → 词级替换 → 句级重构 → 段落调整
1. 运行扫描脚本:
python3 ~/.claude/skills/aigc-reduce/scripts/aigc_scan.py <file.txt>
# 或在本 skill 根目录执行:
python3 scripts/aigc_scan.py <file.txt>2. 估算修改量,确保总修改率 >40%:
| 操作层级 | 贡献 | 主要手段 |
|---|---|---|
| 词级替换 | 10-15% | 模板词、AI 高频词、动词的系统性替换 |
| 句级重构 | 15-20% | 语序重组、长句拆分、被动改主动、主语更换 |
| 段落调整 | 10-15% | 对称段长打破、段间过渡 |
详细替换表见 references/replacement-tables.md。替换表中有 中文 AI 高频词清单,这些词在 AI 生成文本中出现频率远高于人类文本,必须全部替换。
对 docx 文件通过 python-docx 定位段落并替换文本。每处替换使用不同的替代词。
第二轮:注入人类特征(加法)
核心洞察(源自 humanizer skill):只去除 AI 痕迹是不够的。干净但毫无灵魂的文本和 AI 文本一样容易被检测。必须主动注入人类写作特征。
在第一轮修改率达标的基础上,对每个段落做以下检查和补充:
节奏工程(提高突发性):
- 检查每段的句子长度分布,如果长度过于均匀(CV < 0.4),必须调整
- 将部分长句(50 字+)拆为短句(15-25 字),制造"长短交错"的节奏感
- 在连续的中等长度句子之间插入一个极短句(10 字以内)
- 目标:让 CV 提升到 0.45 以上
不确定性和主观性注入:
- 在数据陈述后加入作者的不确定性表达:"推测…""猜测…""我们倾向于认为…"
- 在结论处加入复杂性的承认:"不过这一推断还需要更多数据支持"
- 用"笔者认为""我们的判断是"替代客观陈述的语气
- 每段最多加 1-2 句,不要过度
具体化操作细节(如果原文缺少):
- 在实验数据段落中加入 1 句操作观察
- 加入参数波动范围("反应时间浮动 ±15 min")
- 加入异常值说明("第 3 批数据偏高,疑因环境温度波动")
声音校准(如果用户提供了参考文本):
- 分析用户提供的其他论文/段落的写作风格
- 提取特征:平均句长、过渡词偏好、段落长度、常用表达
- 在改写中匹配这些特征,而不是用通用模板
第三轮:Anti-AI 审计(自检)
审视修改后的文本,回答:"这段话为什么看起来还像 AI 写的?"
逐项排查(详细说明见 references/ai-patterns.md):
- [ ] 重要性膨胀?(删掉"重要""关键"后含义不变?)
- [ ] 同义词轮换?(同一概念被叫了 3 个以上名字?)
- [ ] 三板斧?(连续出现"A、B和C"三件套?)
- [ ] 空洞结论?("具有良好的应用前景"?)
- [ ] 公式化挑战段?("尽管…但仍存在局限性"?)
- [ ] 模糊归因?("有研究表明"无引用?)
- [ ] 悬浮式分析?(一句话挂了 2+ 个"从而/进而"?)
- [ ] 段落长度过于均匀?句式结构过于整齐?
- [ ] 节奏是否单调?(所有句子长度差不多?)
对剩余痕迹做确定性替换。如果发现普遍性问题,回到第一轮或第二轮补充操作。
终扫验证
再次运行扫描脚本,对比各维度指标变化。验证修改率是否 >40%。可在免费平台验证:腾讯朱雀 https://matrix.tencent.com/ai-detect/ai_gen_txt
改写示例
原文(AI 痕迹明显):
SPI和KC含量的增加导致凝胶的L*显著降低(P<0.05),归因于两方面,首先,由于SPI本身呈黄绿色、KC呈浅黄色,浓度升高使凝胶内有色物质总量增加。此外,蛋白质分子的聚集及交联度增加会增强对光线的吸收,降低反射光线强度。上述结果一致表明,蛋白与多糖浓度的变化显著影响复合凝胶的色泽。
第一轮后(去除 AI 痕迹):
SPI和KC用量增大的同时,L*值出现了明显下降(P<0.05)。主要有两方面原因:一是SPI本身偏黄绿色、KC偏浅黄色,浓度上来后凝胶体系中的色素总量随之增多;二是蛋白分子聚集和交联程度提高后对入射光的吸收更加强烈,反射光量因此减少[20]。把以上几组数据放在一起看,蛋白和多糖的用量变化对凝胶外观颜色产生了不可忽视的影响。
第二轮后(注入人类特征 — 注意最后两句的节奏变化和主观性):
SPI和KC用量增大的同时,L*值出现了明显下降(P<0.05)。主要有两方面原因:一是SPI本身偏黄绿色、KC偏浅黄色,浓度上来后凝胶体系中的色素总量随之增多。二是蛋白分子聚集和交联程度提高后对入射光的吸收更加强烈,反射光量因此减少[20]。这个趋势在重复测试中很稳定。把以上几组数据放在一起看,蛋白和多糖的用量变化确实改变了凝胶的外观颜色,不过两者各自的贡献比例还需要进一步拆解。
第三轮后(Anti-AI 审计 — 检查无剩余问题):
(如果第二轮后没有发现剩余 AI 痕迹,第三轮无需修改。)
检测平台注意
- PaperPure:灵敏度极高,AI 全量重写被判 100%。只能确定性替换,修改率 >40%
- 知网 3.0:准确率 98.6%,重点抓模板句式和格式规范性
- 不同平台差异大:同篇论文知网 35%、万方 12%,属正常现象
- 写得越好越容易被判 AI:高质量流畅文本假阳性率 6.5%,有口语化瑕疵的仅 1.8%
参考文档
references/replacement-tables.md— 词级/句级/段落级替换表 + 中文 AI 高频词清单references/ai-patterns.md— 10 种深度 AI 痕迹识别模式references/detection-principles.md— 主流检测器技术原理与弱点scripts/aigc_scan.py— 自动化 AI 特征扫描脚本(7 维度)
MIT License
Copyright (c) 2026
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
interface:
display_name: "AIGC Reduce"
short_description: "Scan and reduce academic AI-writing traces"
default_prompt: "Use $aigc-reduce to scan this academic text for AI-writing traces and propose deterministic edits."
policy:
allow_implicit_invocation: true
MIT License
Copyright (c) 2026
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
AIGC Reduce
降低学术论文 AIGC 查重率的 Claude Code Skill,同时增量兼容 Codex。
基于知网 3.0、万方、PaperPass、PaperPure 等主流检测器的技术原理,结合 humanizer skill(源自 Wikipedia "Signs of AI writing")的 AI 痕迹识别方法论,通过三轮降重协议(去除痕迹 → 注入人类特征 → 自检审计)让文本呈现「人类写作」的统计特征。
安装
Claude Code
Claude Code 是本 skill 的原始目标环境,推荐安装到:
git clone https://github.com/xiaofenggan01/aigc-reduce.git ~/.claude/skills/aigc-reduce安装后,当你在 Claude Code 中提到「降 AI 味」「降 AIGC 率」「去 AI 检测」等关键词时,该 skill 会自动触发。
Codex
Codex 可安装到 Codex 可发现的 skills 目录:
git clone https://github.com/xiaofenggan01/aigc-reduce.git ~/.agents/skills/aigc-reduce如果你的环境使用 $CODEX_HOME/skills:
git clone https://github.com/xiaofenggan01/aigc-reduce.git "$CODEX_HOME/skills/aigc-reduce"Codex 通过 SKILL.md frontmatter 识别触发条件,通过 agents/openai.yaml 读取 UI 元数据。Claude Code 可以忽略 agents/openai.yaml。
为什么需要这个工具?
AIGC 检测器已经在各大高校强制使用。但检测技术存在根本性局限:
- 写得好 = 判 AI? 高质量流畅论文假阳性率 6.5%,有口语化瑕疵的论文仅 1.8%
- 跨平台结果不一致: 同一篇论文知网 AI 率 35%,万方仅 12%
- 术语密集型论文受害: 术语密度 >20% 时假阳性率 8-12%
- 检测器依赖浅层特征: DPO 训练可使检测准确率下降 60%
核心思路:不是帮人作弊,而是帮本来是人写的论文降低被误判的风险。
三条铁律
1. 禁止 AI 全量重写 — AI 重写 AI 文本 = 叠加 AI 指纹(PaperPure 实测:重写后检测率升至 100%) 2. 修改率必须 >40% — 轻度修改(<20%)仅 15-25% 规避率,深度修改(>40%)可达 60-80% 3. 确定性替换 — 每次只改一小处,不经过 LLM 的 token 采样
三轮降重协议
第一轮:去除 AI 痕迹(减法)
扫描文本 → 词级替换 → 句级重构 → 段落调整,确保修改率 >40%。
替换操作覆盖三个层级:
- 词级(10-15%):模板词、72 个中文 AI 高频词、动词的系统性替换
- 句级(15-20%):语序重组、长句拆分、被动改主动、主语更换
- 段落级(10-15%):对称段长打破、段间过渡、语义注入
第二轮:注入人类特征(加法)
源自 humanizer skill 的核心洞察:只去除 AI 痕迹不够,干净但无灵魂的文本和 AI 文本一样容易被检测。
- 节奏工程:故意制造长短句交错,目标突发性 CV > 0.45
- 不确定性注入:"推测…""猜测…""不过还需要更多数据支持"
- 操作细节补充:加入实验观察、参数波动、异常说明
- 声音校准:如果用户提供参考文本,分析并匹配其写作风格
第三轮:Anti-AI 审计(自检)
审视文本,回答"这段话为什么还像 AI 写的?",逐项排查 10 种深度 AI 痕迹模式:
1. 重要性膨胀("至关重要""不可忽视") 2. 同义词轮换(同一概念被叫了 3 个以上名字) 3. 三板斧强迫症(连续出现"A、B和C"三件套) 4. 系词回避(AI 不用"是",偏用"作为/体现/代表") 5. 模糊归因("有研究表明"无引用) 6. 公式化挑战段("尽管…但仍存在局限性") 7. 悬浮式分析(一句话挂了 2+ 个"从而/进而") 8. 空洞结论("具有良好的应用前景") 9. 破折号过度使用 10. 虚假范围("从宏观到微观")
自动化扫描
内置 aigc_scan.py 脚本,自动扫描文本的 7 个 AI 特征维度:
python3 scripts/aigc_scan.py your_paper.txt| 维度 | 对应检测器 |
|---|---|
| 模板句式密度 | 知网语义指纹 |
| 突发性 CV | GPTZero 核心算法 |
| 段落对称性 | 知网格式规范性校验 |
| 嵌套编号 | 统计检测 |
| 冒号并列 | 知网逻辑断层检测 |
| 被动语态 | Turnitin 句式特征分析 |
| 标点规律 | 万方 BERT 语义分析 |
文件结构
aigc-reduce/
├── SKILL.md # Skill 核心(120行,渐进式披露 Level 2)
├── README.md # 本文件
├── agents/
│ └── openai.yaml # Codex UI 元数据,Claude Code 可忽略
├── references/
│ ├── replacement-tables.md # 替换表 + 72 词中文 AI 高频词清单
│ ├── ai-patterns.md # 10 种深度 AI 痕迹识别模式
│ └── detection-principles.md # 检测器技术原理与弱点
└── scripts/
└── aigc_scan.py # 自动化扫描脚本(7 维度)检测器参考数据
国内产品
| 产品 | 综合准确率 | 假阳性率 | 核心检测维度 |
|---|---|---|---|
| 知网 3.0 | 98.6% | 1.2% | 语义指纹、格式规范性 |
| 万方 | ~95% | ~3% | 多模型融合 |
| PaperPass | ~97% | 0.3% | 语言风格一致性 |
国际产品
| 产品 | 综合准确率 | 假阳性率 | 中文支持 |
|---|---|---|---|
| Turnitin | 98%(英文)/ 85%(中文) | 2.1% | 一般 |
| GPTZero | 90-99% | 16% | 良好 |
| Copyleaks | 99%+ | 未公开 | 良好 |
致谢
方法论综合了以下来源的实证研究:
- 《论文AIGC查重检测方法与原理深度研究报告》(2026-05)
- Wikipedia "Signs of AI writing"(WikiProject AI Cleanup 维护)
- Humanizer skill — AI 痕迹识别 + 二次自检方法论
- LINUX DO 论坛社区验证的 Prompt 工程
- 微博博主"厄加特特"的句式变换方法论
- 火山引擎开发者社区发布的降重 Prompt
- GitHub 开源项目:BypassAIGC、Humanizer-zh、humanize-chinese
- PaperPure 实测反馈
License
MIT
深度 AI 痕迹识别
源自 Wikipedia "Signs of AI writing" 指南(WikiProject AI Cleanup 维护),
针对中文学术写作做了本地化适配。这些模式超出了统计检测范畴,
即使困惑度和突发性正常,仍可能被深度学习检测器捕捉。
1. 重要性膨胀(Significance Inflation)
AI 给普通事实加上"重大意义"包装。
高危词: "至关重要""不可忽视""深远影响""具有重要价值""为…提供了重要参考""标志着""开启了新篇章"
识别: 删掉"重要""关键""显著"后含义不变 → 这些修饰是 AI 添加的膨胀内容。
处理: 删除膨胀修饰,或替换为具体数据。
- "对食品工业具有重要意义" → "在植物基仿生食品开发中有应用潜力"
- "为该领域提供了重要的理论依据" → "为配方设计提供了参考"
2. 同义词轮换(Synonym Cycling)
AI 因 repetition penalty 过度替换同义词,人类通常全文统一使用一个术语。
检测:
- 同一对象被交替称为"凝胶""胶体""水凝胶""复合物"
- 同一指标被交替称为"硬度""坚实度""抗变形能力"
- 同一操作被交替称为"测定""检测""分析""表征"
处理: 核心术语全文统一。如果原文已经统一,不要人为制造轮换。
3. 三板斧强迫症(Rule of Three)
AI 强迫把论点凑成三个一组。
检测:
- "XXX、YYY和ZZZ" 且三项长度相近
- "不仅A,而且B,甚至C" 的三段递进
- 每个段落恰好讨论三个要点
处理: 将部分三件套拆为两件或四件。
4. 系词回避(Copula Avoidance)
AI 不用简单的"是",偏用复杂系动词。
检测:
- "作为…的代表" → 就是"是…的代表"
- "体现了…" → 就是"是…"
- "扮演着…的角色" → 就是"是…"
处理: 该用"是"的地方就用"是"。
5. 模糊归因(Vague Attributions)
检测:
- "有研究表明" 无引用编号
- "学界普遍认为" 无出处
- "众所周知" 无佐证
- "相关研究指出" 无具体文献
处理: 要么删掉模糊归因,要么给出具体引用。
6. 公式化挑战段(Formulaic Challenges Section)
检测:
- "尽管取得了…成果,但本研究仍存在一定的局限性"
- "未来的研究可以进一步探讨…"
- 这些段落在大量论文中几乎一模一样
处理: 用具体、自然的叙述替代模板。
- "本实验只在实验室条件下测试了三种浓度,工业化生产中的表现还需进一步验证"
7. 悬浮式分析(Superficial -ing Analyses)
AI 在陈述事实后附加悬挂式短语,制造虚假分析深度。
检测:
- 一句话末尾挂了 2 个以上的"从而/进而/由此"
- "…从而实现了…进而促进了…"
处理: 将悬挂短语独立成句,或删掉不提供实质信息的部分。
- "KC浓度升高增强了氢键交联,从而使凝胶由疏松网络向致密网络转变"
- → "KC浓度升高后,氢键交联更密集。凝胶从松散网络转变为紧密结构。"
8. 空洞结论(Generic Positive Conclusions)
检测:
- "具有良好的应用前景"
- "为…提供了理论和实验依据"
- "具有重要的理论价值与现实意义"
- 这些表述可以套用到任何论文
处理: 替换为具体判断。
- "具有良好的应用前景" → "该配比下凝胶硬度接近动物性食品实测值,可作为素毛肚原型材料"
9. 破折号过度使用(Em Dash Overuse)
检测: 一段话中出现 2 个以上"——"
处理: 大部分破折号替换为逗号、句号或括号。一段话最多保留 1 个。
10. 虚假范围(False Ranges)
检测:
- "从宏观到微观""从理论到实践""从基础研究到工程应用"
- "涵盖了从A到B的各个方面"
处理: 直接列举实际覆盖的范围,或删掉。
AIGC 检测技术原理深度解析
数据来源:《论文AIGC查重检测方法与原理深度研究报告》(2026-05)
---
目录
---
一、AIGC 检测的技术背景
AIGC 检测与传统的抄袭检测(文本比对)本质不同。抄袭检测是在已有数据库中搜索相同或相似的文本片段;而 AIGC 检测需要在语义层面区分人类创作与机器生成内容——即使文本在字面上完全原创,检测器也需要判断它是"人写的"还是"AI 写的"。
从研究范畴看,AIGC 检测已从最初的二分类问题(人类 vs 机器)发展为更细粒度的任务:
| 子任务 | 说明 |
|---|---|
| 整篇判别 | 判断全文是人类撰写还是机器生成 |
| 局部化检测 | 定位到具体哪些句子/片段由 AI 生成 |
| 多模型溯源 | 判断内容由哪个具体模型生成(GPT-4?Claude?Gemini?) |
| 对抗鲁棒性检测 | 检测经过人工修改后的 AI 内容 |
关键时间节点
| 时间 | 事件 |
|---|---|
| 2023 年 1 月 | GPTZero 发布,首个商业化 AI 检测工具 |
| 2023 年 7 月 | OpenAI 关闭其 AI 文本分类器(准确率仅 26%),标志第一代检测技术失败 |
| 2024-2025 年 | 基于 RoBERTa/DeBERTa 的深度学习检测成为主流 |
| 2025 年 | 知网 3.0 上线(准确率 98.6%);国内高校大规模采用 AIGC 检测 |
| 2025 年 | 意大利团队证明 DPO 训练可使检测准确率下降 60% |
| 2026 年 3 月 | TTP-Detect 黑盒水印检测框架发布 |
---
二、三大技术路线
2.1 主动水印技术
原理: 在 AI 生成内容的生成阶段嵌入隐蔽的标识信息,后续通过特定检测算法识别 AI 来源。不依赖文本统计特征分析,而是通过调整 token 的概率分布嵌入可验证签名。
KGW 算法(Kirchenbauer et al., 2023)
当前主流水印技术的基础算法:
1. 在模型生成第 t 个 token 时,利用第 t-1 个 token 的 ID + 哈希密钥 → 生成"绿名单"(Green List) 2. 引导模型优先从绿名单中选择 token(提高采样概率) 3. 不显著影响生成质量的前提下嵌入水印 4. 检测时:持有密钥的检测器复现绿名单,统计文本中绿名单 token 比例,若显著高于随机预期 → 判定带水印
SynthID Text(Google DeepMind, 2024.10)
最新一代水印技术的代表:
- 对每个生成位置,从概率分布中采样多个候选 token
- 用密钥控制的评分函数对候选排序
- 选择既满足语义连贯又满足水印模式的 token
- 已整合至 Gemini 模型,声称即使文本被裁剪、改写,水印仍然有效
- 局限:短文本、翻译文本、事实性回答表现较差
弱点
| 攻击方式 | 效果 |
|---|---|
| Bias-Inversion Rewriting Attack (BIRA) | 抑制含水印 token 的 logit 概率,削弱水印信号 |
| 人工深度修改(修改 >40%) | 假阴性率 60-80%,水印检测成功率大幅下降 |
| 黑盒场景限制 | 传统水印检测需要密钥(白盒),第三方难以验证 |
---
2.2 被动统计检测
原理: AI 生成文本与人类文本在统计特征上存在系统性差异。大语言模型倾向选择"最合理"的下一个词,导致低困惑度、低突发性、过度语义连贯。
核心指标
困惑度(Perplexity) — 衡量语言模型对文本的"惊讶程度"
- 数学定义:对于含 n 个 token 的文本序列,困惑度 = 各位置条件概率倒数的 n 次几何平均
- AI 文本困惑度低(模型选择概率最高的 token,文本高可预测)
- 人类文本困惑度高(个性化表达、非标准用法、创造性措辞)
- Turnitin 以困惑度分析为核心指标之一
突发性(Burstiness) — 衡量句子长度/句式/词汇的变化程度
- 人类写作:短句长句交错、简单句复杂句混合、词汇使用波动大
- AI 文本:句子长度分布均匀、句式结构规整、"过于完美"的一致性
- GPTZero 核心算法 = 困惑度 + 突发性联合分析
其他统计特征:
| 特征类别 | 具体指标 | AI 文本特征 |
|---|---|---|
| 词汇特征 | 词频分布、搭配模式、专业术语密度 | 搭配模式过于工整 |
| 句法特征 | 从句数量、被动语态比例、标点使用模式 | 被动语态过多、全角标点排列整齐 |
| 语义连贯性 | 段落间逻辑过渡、论证深度 | 严格"总-分-总"框架、过度使用过渡词 |
弱点
- 统计特征容易被针对性改写规避(调整句子长度、插入个性化表达)
- 对专业术语密集型、高度规范化的文本误判率高
- 随着生成模型进化(GPT-4o 等展现更强多样性),统计特征的区分效力在下降
---
2.3 深度学习判别
原理: 利用 BERT、RoBERTa、DeBERTa、ELECTRA 等预训练模型,通过大规模标注数据学习人类文本与机器文本在语义层面的细微差异。能捕捉更深层语义结构、逻辑连贯性和语境依赖性。
主流检测模型
| 模型 | 特点 | 检测应用 |
|---|---|---|
| RoBERTa | 移除 NSP 任务、动态掩码、更大训练批次 | 训练为二分类器,提取上下文特征输出概率分布 |
| DeBERTa | 分离注意力机制(语义内容与位置信息分别编码) | 捕捉"表面连贯但深层逻辑薄弱"的 AI 特征 |
| ELECTRA | 生成器-判别器架构,"替换 token 检测"任务 | 识别 AI 文本中的"不自然" token 模式,检测修改后内容鲁棒性强 |
典型框架
- ImBD(Imitate Before Detect)(复旦大学, 2025):基于 DeBERTa,引入风格感知机制(Style-CPC),检测 GPT-3.5/GPT-4 修改文本准确率提升 15-20%,仅需 1000 样本 + 5 分钟训练即可达到 0.9449 AUROC
- 局部化检测:序列标注问题,输出每个位置的 AI 生成概率,Turnitin 提供段落级标注 + 置信度
弱点
1. 跨模型泛化:在 GPT-3.5 上训练后,难以识别 Claude/Gemini/Llama 生成的文本 2. 对抗鲁棒性:DPO 训练可使准确率下降 60% 3. 可解释性差:"黑箱"判别,难以直观解释判别依据
---
三、主流商业检测产品
国内产品
| 产品 | 综合准确率 | 假阳性率 | 假阴性率 | 核心技术 |
|---|---|---|---|---|
| 知网 3.0 | 98.6% | 1.2% | 1.5% | 语义指纹(模板句式、逻辑断层、数据模糊)+ 格式规范性校验 |
| 万方 | ~95% | ~3% | ~5% | 多模型融合(GPT 特征 + BERT 语义 + XGBoost) |
| PaperPass | ~97% | 0.3%(官方) | 未公开 | 语言风格一致性、论证逻辑递进性 |
| PaperYY / 维普 / 格子达 | 各异 | 各异 | 各异 | 功能大同小异,训练数据与阈值不同 |
国际产品
| 产品 | 综合准确率 | 假阳性率 | 中文支持 | 核心技术 |
|---|---|---|---|---|
| Turnitin | 98%(英文)/ 85%(中文) | 2.1% | 一般 | 机器学习分类模型 + 多维特征分析 |
| GPTZero | 90-99%(AI 文本) | 16%(人类文本) | 良好 | 困惑度 + 突发性联合分析 |
| Copyleaks | 99%+ | 未公开 | 良好 | 多语言检测 + API |
| Originality.ai | 99% | 未公开 | 一般 | 独立第三方验证 |
知网 3.0 的"语义指纹"模块
知网针对以下 AI 文本特征进行模式识别:
1. 模板化句式 — "基于…分析""通过实验验证""综上所述""具有重要的理论价值与现实意义" 2. 逻辑断层 — 段落间缺乏自然过渡,叙事跳跃 3. 数据模糊性表述 — "据统计""相关研究表明""一般认为",无具体来源 4. 标准化标题层级 — 过于规整的章节编号 5. 参考文献格式错误 — 格式规范性校验
跨平台检测结果差异
同一篇论文在不同平台的检测结果可能差异巨大:
| 平台 | AI 率 |
|---|---|
| 知网 | 35% |
| 维普 | 18% |
| 万方 | 12% |
差异来源于各平台的检测算法、训练数据和阈值设置不同。
---
四、检测器的弱点与高误判场景
假阳性高发场景(人工文本被误判为 AI)
| 文本类型 | 假阳性率 | 原因 |
|---|---|---|
| 专业术语密集型(术语密度 >20%) | 8-12% | 规范表达与 AI 特征相似 |
| 引用密集型(引用 >30%) | 12.3% | 引用格式被视为"标准化痕迹",引用内容可能被 AI 学习过 |
| 文献综述 | 9.2% | "A 认为…B 指出…"的罗列式写法,缺乏批判性串联 |
| 研究方法部分 | 7.5% | 结构固定、用语规范 |
| 高质量流畅文本 | 6.5% | "完美输出"特征与 AI 生成高度重合 |
| 有口语化不规范处的文本 | 1.8% | 反而因"不完美"降低了 AI 特征 |
反直觉发现
写得越好,越容易被判 AI。 逻辑清晰、表达流畅的高质量论文假阳性率 6.5%,而包含语法小瑕疵、个人化表达的论文仅 1.8%。
写得越规范,越容易被判 AI。 文献综述、法律文书等模板化写作的假阳性率高达 9%。
语言偏见
非英语母语者的作文更容易被误判为 AI 生成(加州大学伯克利分校 D-Lab 研究)。
---
五、对抗性改写效果
修改程度与检测规避
| 修改程度 | 假阴性率 | 技术手段 |
|---|---|---|
| 轻度修改 (<20%) | 15-25% | 同义词替换、语序调整、标点修改 |
| 中度修改 (20-40%) | 35-50% | 句式重构、增加细节、加入个人化引导词 |
| 深度修改 (>40%) | 60-80% | 语义重构、加入作者判断、打破模板结构 |
核心结论: 修改比例 >40% 时假阴性率高达 60-80%。这意味着 AI 初稿 + 大量人工改写是当前最有效的降重手段。
DPO 训练攻击
意大利研究团队(2025)发现:使用直接偏好优化(DPO)训练模型生成"更像人类"的文本(调整句子长度分布、词汇多样性、标点模式),仅需约 7000 样本进行一轮训练,即可使顶尖检测器的准确率从 76% 骤降至 40%,准确率下降高达 60%。
这一发现揭示了当前检测器过度依赖浅层语言特征(句子长度、词汇多样性、标点使用模式)的根本性脆弱。
反检测方法分类
| 方法类型 | 原理 | 降检测率效果 |
|---|---|---|
| 表层改写 | 同义词替换、语序调整、句式重构、标点修改 | 10-30% |
| 语义重构 | 在保持原意前提下重构句子结构和论证逻辑,加入个人化引导词 | 30-60% |
| 对抗性重写(DPO) | 训练模型学习人类写作风格特征,生成统计特征接近人类的文本 | 高达 60% |
---
六、攻防博弈的动态演进
博弈循环
检测技术升级 → 反检测方法进化 → 检测器再次升级 → ...- 第一代(统计检测)→ 被针对性改写轻易规避
- 第二代(深度学习检测)→ 被 DPO 训练有效欺骗
- 第三代(水印技术)→ 被 BIRA 攻击和人工修改削弱
未来检测方向
1. 多模态融合:结合写作过程数据(编辑历史、输入速度、修改痕迹) 2. 局部化检测:精确定位到具体句子,并解释判别依据 3. 因果推理增强:从因果关系层面判别内容原创性,而非仅看表层统计特征 4. "标识+检测+披露"三位一体:2025.9.1 中国《人工智能生成合成内容标识办法》施行
根本性结论
完全依靠技术手段无法彻底解决 AIGC 检测问题。随着生成模型不断进化,AI 文本与人类写作的差距在缩小。未来的 AIGC 治理需要技术检测与制度规范协同发力。
替换表参考
本文件由 SKILL.md 按需加载,包含所有替换操作的详细规则。
一、词级替换
每处替换必须使用不同的替代词,不能全文统一替换。
1. 模板连接词
- "此外" → "另一方面" / "另一组数据则显示" / 直接删除 / "从另一角度看"
- "与此同时" → "另一方面" / "同时" / "结合前文来看"
- "综上所述" → 删除 / 改为具体判断 / "把以上结论放在一起看"
- "需要指出的是" → "值得注意的是" / "值得说明的是" / 直接删除
- "研究发现" / "研究表明" → "实验表明" / "数据呈现" / "从结果来看" / "测试结果显示"
- "分析认为" → "推测" / "可能的原因是" / "据此推断" / "这一现象说明"
- "具体而言" → "从数据来看" / "进一步分析发现" / "拆开来看"
- "值得注意的是" → "有意思的是" / "特别之处在于" / "一个细节是"
2. "XX了"高危句式
- "揭示了" → "指向了" / "表明" / "体现了"
- "探讨了" → "考察了" / "分析了" / "梳理了"
- "验证了" → "确认了" / "证明了" / "实测结果表明"
- "构建了" → "建立了" / "搭建了" / "设计出"
- "展示了" → "呈现了" / "反映了" / "体现了"
- "证实了" → "确认了" / "实测支持了"
- "导致了" → "造成了" / "引发了" / "使得"
- "表明了" → "显示出" / "意味着" / "提示"
3. 动词替换
- "显著" → "明显" / "大幅" / "可观地"
- "增加" → "上升" / "提高" / "攀升" / "增长"
- "降低" → "下降" / "减小" / "削弱" / "回落"
- "提升" → "增强" / "改善" / "优化"
- "影响" → "改变" / "调控" / "左右"
- "反映" → "体现" / "呈现" / "揭示"
- "促进" → "推动" / "驱动" / "有利于"
- "抑制" → "限制" / "阻碍" / "约束"
- "归因于" → "来源于" / "主要在于" / "原因之一是"
- "认为" → "判断" / "推测" / "倾向于"
4. 形容词/副词替换
- "显著" → "明显" / "大幅" / "可观地"
- "明显" → "显著" / "清晰可见"
- "进一步" → "更深入地" / 删除
- "有效" → "切实" / "确实"
- "整体" → "全局来看" / "汇总来看"
- "相对" → "比较" / "一定程度上"
- "基本" → "总体上" / "大致"
5. 句式模式
- "归因于两方面,首先…其次…" → "主要有两方面原因:一是…二是…"
- "上述结果一致表明" → "把以上结论放在一起看" / "综合这几组数据"
- "与…相比" → "对比…" / "相较于…"
- "…的影响达到了显著水平" → "…带来的变化具有统计意义"
- "这说明…" → "背后的逻辑是…" / "意味着…"
二、句级重构
6. 语序重组
- "研究某某领域的某某事物" → "对某某领域的某某事物进行研究"
- "选择某个方式针对某个事物研究,从而得出某个结论" → "为了得出某个结论,选择某个事物作为研究对象"
- "A 导致 B" → "B 的出现与 A 密切相关"
- "X 具有 Y 特性" → "Y 是 X 的一个重要特征"
7. 拆长句为短句
- 50 字以上的单句在合适位置断开,加句号
- "由于A,且B,因此C" → "A 和 B 同时存在。在这种条件下,C 自然发生。"
8. 被动改主动
- "被测定为" → "测得"
- "被观察到" → "观察到"
- "被认为是" → "通常看作"
- "已被证实" → "已有研究支持"
9. 主语更换
- "实验结果显示" → "从数据中可以看到" / "各组数据对比后不难发现"
- "研究表明" → "已有文献记录" / "多篇论文的数据指向"
- "本研究发现" → "从实验结果中可以提取出"
- "结果显示" → "对比各组数据后"
10. 排比/并列结构拆解
(1)…(2)…(3)…→ 改为自然叙述A:…;B:…;C:…→ 拆成独立叙述- "首先…其次…最后…" → 删除序号标记,改为自然衔接
三、段落级调整
11. 打破对称段长
连续 3 段以上长度相近时,将其中一段扩写(插入操作观察、补充数据细节)或精简(合并冗余表述)。
12. 段间过渡
- "这一发现也引出了下一个问题:"
- "与前述力学性能相对应的,是"
- "从结构表征转向功能评价,"
13. 语义注入(仅用于高风险段落)
在数据和结论之间插入实验细节:
- 操作观察:"过程中发现粉料容易结团,需分次加水"
- 参数波动:"反应时间浮动 ±15 min"
- 异常说明:"第 3 批数据偏高,疑因环境温度波动"
加入作者判断(1 句):
- "这一现象值得注意"
- "实际应用中需权衡"
具体化模糊表述:
- 删除"据统计""相关研究表明",给出具体数值或来源
14. 专项针对
- 文献综述:避免"A 认为…B 指出…C 提出…"的并列,改为有主次、有批判的叙评结合
- 结论与展望:避免对称列举,合并叙述,加入对实际约束的讨论
- 实验方法:加入实操视角表述
中文 AI 高频词清单
源自 humanizer skill 的 AI Vocabulary 模式,针对中文学术论文适配。
这些词在 AI 生成文本中出现频率远高于人类文本。必须全部替换。
最高优先级(几乎只出现在 AI 文本中)
| AI 高频词 | 替换为 |
|---|---|
| 值得注意的是 | 有意思的是 / 特别之处在于 / 一个细节是 / 删除 |
| 至关重要 | 关键 / 必要 / 不可少 |
| 深入探讨 | 仔细考察 / 详细分析 / 梳理 |
| 系统性 | 全面 / 整体 / 综合的 |
| 全方位 | 各方面 / 多角度 |
| 多维度 | 多个方面 / 从不同角度看 |
| 深度剖析 | 仔细分析 / 拆解 |
| 高度契合 | 吻合 / 一致 / 相符 |
| 紧密结合 | 结合 / 联系 |
| 有机融合 | 结合 / 融合 / 整合 |
| 无缝衔接 | 衔接 / 过渡 |
| 稳步提升 | 逐步提高 / 慢慢上升 |
| 持续优化 | 改进 / 调整 |
| 全面提升 | 整体提高 / 改善 |
| 显著提升 | 明显增强 / 大幅改善 |
| 不可或缺 | 必需 / 离不开 |
| 举足轻重 | 重要 / 关键 |
| 源源不断 | 持续 / 不断 |
| 深远影响 | 长期影响 / 重要影响 |
| 广泛关注 | 关注 / 重视 |
高优先级(AI 使用频率远高于人类)
| AI 高频词 | 替换为 |
|---|---|
| 此外 | 另一组数据显示 / 从另一角度看 / 删除 |
| 与此同时 | 同时 / 另一方面 |
| 综上所述 | 把以上结论放在一起看 / 删除 |
| 需要指出的是 | 值得说明的是 / 删除 |
| 研究表明 | 实验表明 / 数据呈现 / 从结果来看 |
| 分析认为 | 推测 / 据此推断 / 可能的原因是 |
| 具体而言 | 从数据来看 / 拆开来看 |
| 具体来说 | 细看各组数据 / 从细节来看 |
| 显著 | 明显 / 大幅 / 可观地 |
| 有效 | 切实 / 确实 |
| 进一步 | 更深入地 / 删除 |
| 整体 | 全局来看 / 汇总来看 |
| 从而 | 进而 / 因此 / 由此 |
| 进而 | 因此 / 由此 / 所以 |
| 由此 | 因此 / 所以 |
| 确保 | 保证 / 使 |
| 旨在 | 为了 / 目的是 |
| 赋予 | 给 / 带来 |
| 提升 | 提高 / 增强 / 改善 |
| 优化 | 改进 / 调整 |
| 阐述 | 说明 / 解释 |
| 阐明 | 说明 / 解释清楚 |
| 揭示 | 显示 / 指向 |
| 凸显 | 突出 / 显示出 |
| 彰显 | 显示 / 体现 |
| 展现 | 表现 / 呈现 |
| 助力 | 帮助 / 有利于 |
| 赋能 | 支持 / 帮助 |
| 协同 | 配合 / 共同 |
| 融合 | 结合 / 混合 |
| 探索 | 尝试 / 研究 / 考察 |
| 梳理 | 整理 / 回顾 |
| 践行 | 实施 / 执行 |
| 聚焦 | 关注 / 集中于 |
| 锚定 | 围绕 / 基于 |
中优先级(需要结合语境判断)
| AI 高频词 | 替换为 |
|---|---|
| 归因于 | 来源于 / 主要在于 |
| 呈现 | 表现出 / 显示出 |
| 反映 | 体现 / 折射 |
| 促进 | 推动 / 有利于 |
| 抑制 | 限制 / 阻碍 |
| 导致 | 造成 / 引发 |
| 证实 | 确认 / 验证 |
| 具备 | 有 / 具有 |
| 体现 | 表现 / 反映 |
| 蕴含 | 包含 / 含有 |
| 涵盖 | 包括 / 覆盖 |
| 着眼于 | 关注 / 从…出发 |
| 立足于 | 基于 / 以…为基础 |
| 致力于 | 致力于 / 专注于 / 专门做 |
| 倾向于 | 偏向 / 更愿意 |
| 致力于 | 专注于 / 专门做 |
口语化/网络用词负面清单
源自 humanize-chinese 的 style_signals 模块。
这些词绝对不能出现在降重后的学术论文中。 降重不是口语化。
禁止出现的网络用语
"yyds""绝绝子""破防""emo""cpu""拿捏""整活""有梗""无语""离谱""逆天""炸裂""社死""摆烂""崩了""手感""搞定""踩坑""翻车"
禁止出现的情绪词
"愤怒""兴奋""崩溃""爽""恶心""气死""乐死""笑死""烦躁""郁闷"
禁止出现的口语化表达
"说实话""坦白讲""老实说""不瞒你说""说白了""讲真""反正""大概齐""差不多就是""这事的难度""不得不考虑的一环"
Register 约束原则
"去 AI 味"和"保持学术语体"是两个独立目标。去 AI 的默认方向会漂向口语化(因为口语色彩是降低 AI 检测率的强信号),必须主动约束。学术论文的 register 底线:
- 可以:加入作者判断、操作细节、不确定性表达、节奏变化
- 不可以:网络用语、情绪词、口语化固定搭配、过于随意的句式
破折号和从句规则
破折号(——)密度
一段话中最多出现 1 个破折号。超过 1 个必须替换为逗号、句号或括号。
AI 使用破折号的频率远高于人类。humanize-chinese 的阈值:每 100 句话中破折号不超过 1 个。
"不仅X而且Y"类从句堆砌
以下模式是 AI 强特征,必须拆解:
| AI 模式 | 处理方式 |
|---|---|
| "不仅…而且…更…" | 只保留核心论点,删掉堆砌 |
| "虽然…但是…同时…" | 二选一,不要三重转折 |
| "一方面…另一方面…总的来说…" | 删掉总结句 |
| "既有…也有…更有…" | 只保留两个层次 |
| "优点…缺点…总体" | 分别讨论,不要总括 |
| "随着…的发展,在当今…时代" | 直接删掉这个开头 |
对称论述检测
AI 特别喜欢两面论述、过度平衡。如果连续两段都是"虽然A好,但B也好"的结构,必须打破其中一段的对称性。
学术论文 AI 短语清单
源自 humanize-chinese 的 academic_patterns 模块。
这些短语几乎只出现在 AI 生成的学术论文中,必须全部替换。
最高优先级(出现即判定为 AI)
- "本文旨在" → "本研究聚焦于" / "本文着重" / "本文尝试"
- "具有重要的理论意义和实践价值" → "在学理与应用两个层面均有所推进"
- "进行了深入分析" → "作了较为细致的考察" / "做了逐层剖析"
- "具有广阔的应用前景" → "在应用层面仍有可拓展的空间"
- "奠定了坚实的基础" → "打下了一定的基础" / "在基础层面做了铺垫"
- "提供了重要的参考价值" → "对相关研究有所启发"
- "引起了广泛关注" → "逐渐进入研究者的视野"
- "发挥着重要作用" → "在其中起到了关键的支撑"
- "取得了显著的成效" → "收到了一定的效果"
- "有待进一步研究" → "仍有继续追问的空间"
高优先级
- "鉴于此" → "基于上述考虑"
- "对此进行了系统的" → "对此做了逐步推进的研究"
- "进行了有益的探索" → "在这一方向上迈出了一步"
- "开辟了新的途径" → "探索出一条可能的路径"
- "做出了重要贡献" → "在该领域有所推进"
- "成为学术界研究的热点" → "在学界引发了持续的讨论"
- "有着不可忽视的作用" → "其作用不宜低估"
- "前景广阔" → "后续仍有拓展余地"
数据描述模板(AI 强特征)
- "数据显示" → "从数据来看" / "数据层面反映出"
- "数据表明" → "数据所呈现的趋势是"
- "从表中可以看出" → "观察该表" / "表中所列数据反映出"
- "从图中可以看出" → "对照该图" / "图中曲线显示"
- "如图所示" → "参见下图" / "图中呈现的规律是"
- "由表可知" → "梳理表中数据后发现"
- "实验结果表明" → "实验所得结果指向"
- "统计结果表明" → "统计分析给出的结论是"
- "分析结果显示" → "分析结果提示"
过度确定性语气(AI 缺少学术留白)
- "必然" → "大概率" / "在多数情况下会"
- "毫无疑问" → "应当承认" / "较为确定的是"
- "毋庸置疑" → "可以说" / "较为明确的是"
- "势必" → "很可能" / "有较大概率"
- "必将" → "预计将" / "有望"
- "无一例外" → "在绝大多数情况下"
- "绝对" → "在很大程度上"
高危句式快速排查清单
改写前先搜索这些模式:
句式类
- "揭示了""探讨了""验证了""构建了""展示了""证实了""凸显了" — "XX了"后跟长句是 AI 强特征
- "和""或""与""同""、" 串联的超长复合句 — 拆短
连接词类
- "首先…其次…最后…"
- "此外""与此同时""综合来看""综上所述""需要指出的是"
- 全部删除或替换
"了"字清理
- 搜索"了",删除不必要的口语化"了"
- "升高了 20%"这种正常用法保留
#!/usr/bin/env python3
"""
AIGC 特征扫描器 — 检测学术论文中的 AI 生成痕迹
基于知网 3.0 / 万方 / PaperPass 的检测原理,扫描以下维度:
1. 模板句式密度
2. 句子长度均匀度(突发性)
3. 嵌套编号模式
4. 冒号并列结构
5. 被动语态比例
6. 段落长度对称性
7. 模糊表述密度
8. 标点符号规律性
用法: python aigc_scan.py <file.txt> [--json] [--threshold 0.5]
"""
import re
import sys
import json
import argparse
from collections import Counter
from pathlib import Path
# ─── 模板句式库 ───
TEMPLATE_PATTERNS = [
# 段落开头模板
r'^(综上所述[,,])',
r'^(基于.{2,10}(分析|研究|探讨))',
r'^(通过.{2,15}(验证|实验|研究|测定))',
r'^(随着.{2,20}(发展|进步|深入))',
r'^(近年来[,,])',
r'^(在.{2,20}(背景下|条件下|过程中))',
r'^(本研究[旨在对通过])',
r'^(目前[,,])',
r'^(当前[,,])',
r'^(因此[,,])',
r'^(由此可见[,,])',
r'^(总而言之[,,])',
# 过渡词冗余
r'(此外[,,])',
r'(另外[,,])',
r'(与此同时[,,])',
r'(值得注意的是[,,])',
r'(需要指出的是[,,])',
# 模糊表述
r'(据统计[,,])',
r'(相关研究表明[,,])',
r'(一般认为[,,])',
r'(具有重要的.{2,10}(意义|价值|作用))',
r'(具有广阔的应用前景)',
r'(为.{2,20}(提供了|奠定了).{2,10}(基础|依据|参考))',
]
# 被动语态标记
PASSIVE_MARKERS = [
r'被.{1,15}(测定|检测|验证|确认|证明|发现|计算)',
r'由.{1,15}(进行|完成|测定|检测|计算)',
r'经.{1,15}(测定|检测|计算|分析)',
r'通过.{1,15}(测定|检测|验证|实验|计算)',
r'采用.{1,15}(进行|测定|检测)',
]
# 嵌套编号模式
NESTED_NUM_PATTERN = re.compile(r'[((](\d+)[))]')
# 冒号并列模式
COLON_LIST_PATTERN = re.compile(r'[::]\s*.+?[;;]\s*.+?[;;]')
# 全角标点
FULLWIDTH_PUNCT = set(',。!?;:、""''()【】《》')
def load_text(filepath: str) -> str:
"""读取文本文件"""
path = Path(filepath)
if not path.exists():
print(f"错误: 文件不存在 — {filepath}", file=sys.stderr)
sys.exit(1)
if path.suffix == '.txt':
return path.read_text(encoding='utf-8')
else:
# 尝试读取纯文本
return path.read_text(encoding='utf-8')
def split_paragraphs(text: str) -> list[str]:
"""按段落拆分"""
paras = re.split(r'\n\s*\n', text.strip())
return [p.strip() for p in paras if p.strip()]
def split_sentences(text: str) -> list[str]:
"""按句子拆分"""
sentences = re.split(r'[。!?!?\n]', text)
return [s.strip() for s in sentences if s.strip() and len(s.strip()) > 5]
def count_template_matches(text: str) -> dict:
"""统计模板句式命中"""
hits = []
for pattern in TEMPLATE_PATTERNS:
matches = re.findall(pattern, text, re.MULTILINE)
if matches:
hits.extend(matches if isinstance(matches[0], str) else [m[0] if isinstance(m, tuple) else m for m in matches])
return {
'count': len(hits),
'density_per_1000': len(hits) / max(len(text), 1) * 1000,
'matches': hits[:20] # 最多展示 20 条
}
def count_passive_markers(text: str) -> dict:
"""统计被动语态"""
total = 0
for pattern in PASSIVE_MARKERS:
total += len(re.findall(pattern, text))
sentence_count = max(len(split_sentences(text)), 1)
return {
'count': total,
'per_sentence': round(total / sentence_count, 3)
}
def analyze_burstiness(paragraphs: list[str]) -> dict:
"""分析突发性(句子长度变化程度)"""
all_sent_lengths = []
for para in paragraphs:
sents = split_sentences(para)
for s in sents:
all_sent_lengths.append(len(s))
if len(all_sent_lengths) < 3:
return {'score': 0, 'avg_len': 0, 'std_len': 0, 'risk': '数据不足'}
avg_len = sum(all_sent_lengths) / len(all_sent_lengths)
variance = sum((l - avg_len) ** 2 for l in all_sent_lengths) / len(all_sent_lengths)
std_len = variance ** 0.5
# 变异系数 = 标准差 / 均值。AI 文本通常 CV < 0.3
cv = std_len / max(avg_len, 1)
if cv < 0.25:
risk = '高风险 — 句子长度过于均匀,典型 AI 特征'
elif cv < 0.35:
risk = '中风险 — 句子变化度偏低'
elif cv < 0.5:
risk = '低风险'
else:
risk = '正常 — 句子长度变化丰富'
return {
'avg_len': round(avg_len, 1),
'std_len': round(std_len, 1),
'cv': round(cv, 3),
'risk': risk
}
def analyze_para_symmetry(paragraphs: list[str]) -> dict:
"""分析段落长度对称性"""
para_lens = [len(p) for p in paragraphs]
if len(para_lens) < 3:
return {'risk': '段落数不足', 'symmetrical_count': 0}
# 检测连续 3 段以上长度相近(偏差 < 20%)
symmetrical_runs = []
current_run = 0
for i in range(1, len(para_lens)):
deviation = abs(para_lens[i] - para_lens[i-1]) / max(para_lens[i-1], 1)
if deviation < 0.2:
current_run += 1
else:
if current_run >= 2: # 连续 3 段
symmetrical_runs.append(current_run + 1)
current_run = 0
if current_run >= 2:
symmetrical_runs.append(current_run + 1)
return {
'para_count': len(para_lens),
'avg_para_len': round(sum(para_lens) / len(para_lens), 1),
'symmetrical_runs': symmetrical_runs,
'risk': f'发现 {len(symmetrical_runs)} 处对称段落组(3段以上长度相近)' if symmetrical_runs else '未发现明显对称'
}
def count_nested_numbers(text: str) -> dict:
"""检测嵌套编号"""
matches = NESTED_NUM_PATTERN.findall(text)
return {
'count': len(matches),
'risk': f'检测到 {len(matches)} 处编号标记' if len(matches) > 3 else '正常'
}
def count_colon_lists(text: str) -> dict:
"""检测冒号并列结构"""
matches = COLON_LIST_PATTERN.findall(text)
return {
'count': len(matches),
'risk': f'检测到 {len(matches)} 处冒号并列结构' if len(matches) > 1 else '正常'
}
def analyze_punctuation(text: str) -> dict:
"""分析标点规律性"""
fullwidth_count = sum(1 for c in text if c in FULLWIDTH_PUNCT)
total_chars = max(len(text), 1)
# 统计逗号密度
comma_count = text.count(',') + text.count(',')
sentence_count = max(len(split_sentences(text)), 1)
commas_per_sentence = round(comma_count / sentence_count, 2)
# AI 文本通常逗号密度较高且均匀
return {
'fullwidth_punct_ratio': round(fullwidth_count / total_chars * 100, 2),
'commas_per_sentence': commas_per_sentence,
'risk': '高密度逗号可能是 AI 特征' if commas_per_sentence > 2.5 else '正常'
}
def scan(text: str) -> dict:
"""完整扫描"""
paragraphs = split_paragraphs(text)
sentences = split_sentences(text)
return {
'summary': {
'total_chars': len(text),
'total_paragraphs': len(paragraphs),
'total_sentences': len(sentences),
},
'template_phrases': count_template_matches(text),
'passive_voice': count_passive_markers(text),
'burstiness': analyze_burstiness(paragraphs),
'para_symmetry': analyze_para_symmetry(paragraphs),
'nested_numbers': count_nested_numbers(text),
'colon_lists': count_colon_lists(text),
'punctuation': analyze_punctuation(text),
}
def print_report(result: dict):
"""打印人类可读报告"""
s = result['summary']
tp = result['template_phrases']
pv = result['passive_voice']
b = result['burstiness']
ps = result['para_symmetry']
nn = result['nested_numbers']
cl = result['colon_lists']
pu = result['punctuation']
print("=" * 60)
print(" AIGC 特征扫描报告")
print("=" * 60)
print(f"\n文本概况: {s['total_chars']} 字符, {s['total_paragraphs']} 段, {s['total_sentences']} 句")
print(f"\n{'─' * 40}")
print(" [1] 模板句式")
print(f" 命中: {tp['count']} 处 (密度: {tp['density_per_1000']:.2f}/千字)")
if tp['matches']:
print(f" 示例: {tp['matches'][:5]}")
print(f" 风险: {'⚠️ 偏高' if tp['count'] > 3 else '✅ 正常'}")
print(f"\n{'─' * 40}")
print(" [2] 被动语态")
print(f" 被动标记: {pv['count']} 处 ({pv['per_sentence']}/句)")
print(f" 风险: {'⚠️ 偏高,建议改主动' if pv['per_sentence'] > 0.3 else '✅ 正常'}")
print(f"\n{'─' * 40}")
print(" [3] 句子长度变化(突发性)")
print(f" 平均句长: {b['avg_len']} 字, 标准差: {b['std_len']}")
print(f" 变异系数 CV: {b['cv']}")
print(f" 风险: {b['risk']}")
print(f"\n{'─' * 40}")
print(" [4] 段落对称性")
print(f" 平均段长: {ps['avg_para_len']} 字")
print(f" 风险: {ps['risk']}")
print(f"\n{'─' * 40}")
print(" [5] 嵌套编号")
print(f" 编号标记: {nn['count']} 处")
print(f" 风险: {nn['risk']}")
print(f"\n{'─' * 40}")
print(" [6] 冒号并列结构")
print(f" 并列结构: {cl['count']} 处")
print(f" 风险: {cl['risk']}")
print(f"\n{'─' * 40}")
print(" [7] 标点规律")
print(f" 全角标点占比: {pu['fullwidth_punct_ratio']}%")
print(f" 每句逗号数: {pu['commas_per_sentence']}")
print(f" 风险: {pu['risk']}")
# 综合评分
risk_count = 0
if tp['count'] > 3: risk_count += 1
if pv['per_sentence'] > 0.3: risk_count += 1
if b.get('cv', 1) < 0.35: risk_count += 1
if ps.get('symmetrical_runs', []): risk_count += 1
if nn['count'] > 3: risk_count += 1
if pu['commas_per_sentence'] > 2.5: risk_count += 1
print(f"\n{'=' * 60}")
print(f" 综合风险: {'🔴 高' if risk_count >= 4 else '🟡 中' if risk_count >= 2 else '🟢 低'}")
print(f" 触发维度: {risk_count}/7")
print(f" 建议: {'需要多轮深度改写' if risk_count >= 4 else '局部调整即可' if risk_count >= 2 else '风险较低,微调即可'}")
print("=" * 60)
def main():
parser = argparse.ArgumentParser(description='AIGC 特征扫描器')
parser.add_argument('file', help='待扫描的文本文件 (.txt)')
parser.add_argument('--json', action='store_true', help='输出 JSON 格式')
parser.add_argument('--threshold', type=float, default=0.5, help='风险阈值(保留)')
args = parser.parse_args()
text = load_text(args.file)
result = scan(text)
if args.json:
print(json.dumps(result, ensure_ascii=False, indent=2))
else:
print_report(result)
if __name__ == '__main__':
main()