#!/usr/bin/env python3 """ Anti-AI Detector - 去AI化工具 支持中文、英文和小红书风格优化 """ import re import os import sys import argparse from pathlib import Path from typing import Dict, List, Tuple class AntiAIDetector: """去AI化检测器""" def __init__(self): self.init_cn_patterns() self.init_en_patterns() self.init_xhs_patterns() # ==================== 中文AI痕迹模式 ==================== def init_cn_patterns(self): """初始化中文AI检测模式""" self.cn_patterns = { # 标志性短语 "值得注意的是": ["需要关注的是", "关键点在于", ""], "我们可以看到": ["从数据看", "实际情况是", ""], "换句话说": ["也就是说", "简单来说", ""], "不难发现": ["可以看出", "", ""], "显而易见": ["很明显", "显然", ""], "众所周知": ["大家都知道", "", ""], "综上所述": ["总结来说", "", ""], "归根结底": ["根本原因是", "说到底", ""], "由此可见": ["这说明", "", ""], # 结构模式 "首先": ["第一", "开始", ""], "其次": ["第二", "然后", ""], "最后": ["最终", "", ""], "总而言之": ["总的来说", "", ""], # 过度修饰 "非常": ["很", "挺", ""], "极其": ["很", "特别", ""], "毫无疑问": ["确实", "", ""], "一定程度上": ["", "", ""], # 模板化表达 "随着...的发展": ["", "", ""], "在当今社会": ["", "", ""], "引起了广泛关注": ["", "", ""], "具有重要的意义": ["", "", ""], } self.cn_structures = [ # 排比结构 (r'不仅[^,]+,而且[^,]+,还[^。]+', "避免三重排比"), (r'一方面[^,]+,另一方面[^,]+', "减少固定结构"), # 过渡词堆砌 (r'首先.*?其次.*?最后.*?(综上所述|总而言之)', "去除模板化结构"), # 学术腔 (r'从[^,]+角度(来看|分析|出发)', "口语化表达"), (r'基于[^,]+(的)?(背景|基础|之上)', "简化表达"), ] # ==================== 英文AI痕迹模式(Stop Slop)==================== def init_en_patterns(self): """初始化英文AI检测模式(基于Stop Slop)""" self.en_patterns = { # 标志性短语 "Here's the thing": ["The point is", "Fact is", ""], "Here's the deal": ["The reality is", "", ""], "Let that sink in": ["", "", ""], "The uncomfortable truth is": ["Truth is", "", ""], "The reality is": ["", "", ""], "This matters because": ["Because", "", ""], "What matters is": ["", "", ""], "Full stop": ["", "", ""], "Period": ["", "", ""], "Let me be clear": ["", "", ""], "I'm going to be honest": ["", "", ""], "Make no mistake": ["", "", ""], # 过度使用的动词 "navigate": ["handle", "deal with", "work through"], "unpack": ["explain", "break down", ""], "leverage": ["use", "take advantage of", ""], "delve": ["explore", "look at", ""], "dive into": ["explore", "examine", ""], "peel back the layers": ["examine", "analyze", ""], # 固定结构 "Not because": ["Not from", "", ""], "But because": ["But from", "", ""], "That's it": ["", "", ""], "That's the": ["", "", ""], "And that's okay": ["", "", ""], # 过度修饰 "In today's world": ["Today", "Now", ""], "In the digital age": ["", "", ""], "Rapidly evolving": ["changing", "", ""], "Fast-paced": ["busy", "", ""], # 模糊表达 "It's important to note": ["Note", "", ""], "It's worth mentioning": ["", "", ""], "As mentioned earlier": ["", "", ""], } self.en_structures = [ # "Not because X. Because Y." (r'Not because[^.]+\. Because[^.]+\.', "合并为一句"), # "[Noun]. That's it. That's the [thing]." (r'(\w+)\. That\'s it\. That\'s the[^.]+\.', "简化表达"), # 三重形容词 (r'\w+, \w+, and \w+ (landscape|environment|space)', "减少形容词"), # 过度使用hedging (r'arguably|potentially|likely|generally|typically', "直接表达"), ] # ==================== 小红书风格优化 ==================== def init_xhs_patterns(self): """初始化小红书风格检测模式""" self.xhs_patterns = { # 去除营销感 "强烈推荐": ["推荐", "我觉得", ""], "必买": ["值得买", "可以考虑", ""], "神器": ["好用", "不错", ""], "绝绝子": ["很好", "不错", ""], "YYDS": ["很棒", "", ""], "宝藏": ["好", "不错", ""], "闭眼入": ["推荐", "", ""], "天花板": ["很好", "顶级", ""], # 去模板化 "今天给大家分享": ["分享", "说说", ""], "姐妹们": ["大家", "", ""], "干货": ["内容", "", ""], "码住": ["收藏", "记住", ""], "抄作业": ["参考", "", ""], # 过度emoji提示 "emoji堆砌": ["适量使用emoji", "", ""], "标签堆砌": ["减少标签", "", ""], } self.xhs_structures = [ # 过于规整的排版 (r'^[0-9]+[.、\s]', "避免过于规整的序号"), (r'✅|❌|⚠️|⭐|🌟{3,}', "emoji过多"), (r'#[^#\s]+#[^#\s]+#[^#\s]+', "标签过多"), ] # ==================== 检测方法 ==================== def detect_cn(self, text: str) -> List[Tuple[str, str, List[str]]]: """检测中文AI痕迹""" findings = [] for pattern, replacements in self.cn_patterns.items(): if pattern in text or re.search(pattern.replace('...', '.*?'), text): findings.append(("phrase", pattern, replacements)) for pattern, suggestion in self.cn_structures: matches = re.findall(pattern, text, re.DOTALL) if matches: findings.append(("structure", pattern, [suggestion])) return findings def detect_en(self, text: str) -> List[Tuple[str, str, List[str]]]: """检测英文AI痕迹""" findings = [] text_lower = text.lower() for pattern, replacements in self.en_patterns.items(): if pattern.lower() in text_lower: findings.append(("phrase", pattern, replacements)) for pattern, suggestion in self.en_structures: matches = re.findall(pattern, text, re.IGNORECASE) if matches: findings.append(("structure", pattern, [suggestion])) return findings def detect_xhs(self, text: str) -> List[Tuple[str, str, List[str]]]: """检测小红书风格问题""" findings = [] for pattern, replacements in self.xhs_patterns.items(): if pattern in text: findings.append(("xhs_phrase", pattern, replacements)) for pattern, suggestion in self.xhs_structures: matches = re.findall(pattern, text, re.MULTILINE) if matches: findings.append(("xhs_structure", pattern, [suggestion])) # 检测emoji密度 emoji_count = len(re.findall(r'[\U0001F600-\U0001F64F\U0001F300-\U0001F5FF\U0001F680-\U0001F6FF\U0001F1E0-\U0001F1FF]', text)) if emoji_count > 5: findings.append(("emoji_density", f"{emoji_count}个emoji", ["建议减少到3-5个"])) return findings # ==================== 处理方法 ==================== def humanize_cn(self, text: str, aggressive: bool = False) -> str: """中文去AI化""" result = text # 替换标志性短语 replacements = { "值得注意的是": "", "我们可以看到": "", "不难发现": "", "显而易见": "很明显", "众所周知": "大家都知道", "综上所述": "总结来说", "归根结底": "说到底", "由此可见": "这说明", "换句话说": "也就是说", } for old, new in replacements.items(): if new: result = result.replace(old, new) else: # 删除或根据上下文调整 result = result.replace(old + ",", "") result = result.replace(old + ",", "") # 简化过渡词 result = re.sub(r'首先[,,]?', "第一,", result) result = re.sub(r'其次[,,]?', "第二,", result) result = re.sub(r'最后[,,]?', "最后,", result) # 去除过度修饰 result = re.sub(r'非常([的地])', r'很\1', result) result = re.sub(r'极其([的地])', r'特别\1', result) # 去除模板化开头 result = re.sub(r'随着[^,]+的发展[,,]', "", result) result = re.sub(r'在当今社会[,,]', "", result) if aggressive: # 更激进的优化 result = re.sub(r'[,,]+', ",", result) # 合并多个逗号 result = re.sub(r'。+', "。", result) # 合并多个句号 return result.strip() def humanize_en(self, text: str, aggressive: bool = False) -> str: """英文去AI化(基于Stop Slop)""" result = text # 替换标志性短语 replacements = { r"Here's the thing[:,.]*\s*": "", r"Here's the deal[:,.]*\s*": "", r"Let that sink in[:,.]*\s*": "", r"The uncomfortable truth is[:,.]*\s*": "", r"Let me be clear[:,.]*\s*": "", r"I'm going to be honest[:,.]*\s*": "", r"Make no mistake[:,.]*\s*": "", r"Full stop[.]*": ".", r"Period[.]*": ".", # 过度使用的动词 r"navigate\s+(the\s+)?": "handle ", r"unpack\s*": "explain ", r"leverage\s*": "use ", r"delve\s+(into\s+)?": "explore ", r"dive into\s*": "explore ", } for pattern, replacement in replacements.items(): result = re.sub(pattern, replacement, result, flags=re.IGNORECASE) # 简化结构 result = re.sub(r'Not because([^,.]+)[,.]\s*Because([^,.]+)[,.]', r'Not from\1, but from\2.', result, flags=re.IGNORECASE) result = re.sub(r"(\w+)\.\s*That's it\.\s*That's the[^.]+\.", r'\1 is what matters.', result, flags=re.IGNORECASE) # 去除过度修饰 result = re.sub(r'In today\'s world[,\s]*', '', result, flags=re.IGNORECASE) result = re.sub(r'In the digital age[,\s]*', '', result, flags=re.IGNORECASE) result = re.sub(r'rapidly evolving', 'changing', result, flags=re.IGNORECASE) result = re.sub(r'fast-paced', 'busy', result, flags=re.IGNORECASE) # 简化hedging result = re.sub(r'It\'s important to note that\s*', '', result, flags=re.IGNORECASE) result = re.sub(r'It\'s worth mentioning that\s*', '', result, flags=re.IGNORECASE) if aggressive: # 去除更多学术腔 result = re.sub(r'arguably\s*[,]*\s*', '', result, flags=re.IGNORECASE) result = re.sub(r'potentially\s*[,]*\s*', '', result, flags=re.IGNORECASE) return result.strip() def humanize_xhs(self, text: str) -> str: """小红书风格优化""" result = text # 替换营销词汇 replacements = { "强烈推荐": "推荐", "必买": "值得买", "闭眼入": "推荐", "神器": "好用", "绝绝子": "很好", "YYDS": "很棒", "宝藏": "不错", "天花板": "顶级", "干货": "内容", "码住": "收藏", "抄作业": "参考", } for old, new in replacements.items(): result = result.replace(old, new) # 简化称呼 result = result.replace("姐妹们", "大家") result = result.replace("集美们", "大家") result = result.replace("宝子们", "大家") # 优化emoji分布(保留但不过度) # 如果emoji过多,提示用户手动调整 # 减少标签堆砌 result = re.sub(r'#{3,}', '#', result) # 去除过于规整的序号 result = re.sub(r'^\d+[.、]\s*', '', result, flags=re.MULTILINE) return result.strip() def auto_detect_and_humanize(self, text: str) -> Tuple[str, str]: """自动检测语言并去AI化""" # 简单语言检测 chinese_chars = len(re.findall(r'[\u4e00-\u9fff]', text)) english_chars = len(re.findall(r'[a-zA-Z]', text)) if chinese_chars > english_chars: # 中文为主 return self.humanize_cn(text), "zh" else: # 英文为主 return self.humanize_en(text), "en" def analyze(self, text: str) -> Dict: """全面分析文本的AI痕迹""" cn_findings = self.detect_cn(text) en_findings = self.detect_en(text) xhs_findings = self.detect_xhs(text) return { "cn_findings": cn_findings, "en_findings": en_findings, "xhs_findings": xhs_findings, "cn_score": len(cn_findings), "en_score": len(en_findings), "xhs_score": len(xhs_findings), "total_risk": len(cn_findings) + len(en_findings) + len(xhs_findings), } def main(): """命令行入口""" parser = argparse.ArgumentParser(description='去AI化工具') parser.add_argument('text', nargs='?', help='输入文本') parser.add_argument('-f', '--file', help='输入文件') parser.add_argument('-o', '--output', help='输出文件') parser.add_argument('-t', '--type', choices=['zh', 'en', 'xhs', 'auto'], default='auto', help='处理类型') parser.add_argument('-a', '--aggressive', action='store_true', help='激进模式') parser.add_argument('--analyze', action='store_true', help='仅分析不处理') args = parser.parse_args() detector = AntiAIDetector() # 获取输入文本 if args.file: with open(args.file, 'r', encoding='utf-8') as f: text = f.read() elif args.text: text = args.text else: print("请提供文本或使用-f指定文件") return # 分析模式 if args.analyze: result = detector.analyze(text) print("=" * 50) print("AI痕迹分析报告") print("=" * 50) print(f"中文AI痕迹: {result['cn_score']} 处") print(f"英文AI痕迹: {result['en_score']} 处") print(f"小红书风格问题: {result['xhs_score']} 处") print(f"总体风险: {result['total_risk']} 处") print("\n详细发现:") for finding in result['cn_findings'][:5]: print(f" [CN] {finding[1]}") for finding in result['en_findings'][:5]: print(f" [EN] {finding[1]}") return # 处理模式 if args.type == 'auto': result, lang = detector.auto_detect_and_humanize(text) print(f"检测到语言: {lang}") elif args.type == 'zh': result = detector.humanize_cn(text, args.aggressive) elif args.type == 'en': result = detector.humanize_en(text, args.aggressive) elif args.type == 'xhs': result = detector.humanize_xhs(text) # 输出结果 if args.output: with open(args.output, 'w', encoding='utf-8') as f: f.write(result) print(f"结果已保存到: {args.output}") else: print("\n" + "=" * 50) print("处理结果:") print("=" * 50) print(result) if __name__ == '__main__': main()