#!/usr/bin/env python3 # -*- coding: utf-8 -*- """ 美业护肤科普口播 · 敏感词 / 合规机器初筛 整合自 content-reviewer 与 medical-content-compliance-auditor 两技能,按美业场景裁剪。 输出 markdown 审查报告(风险等级 + 法规依据 + 合规替换 + 结论三选一)。 用法: python compliance_scan.py --text "口播全文" python compliance_scan.py --file path/to/script.md python compliance_scan.py --file path/to/script.md --output report.md """ import argparse import sys from pathlib import Path # 词库: (词, 类别, 风险符号, 法规依据, 合规替换) WORD_LIST = [ # 绝对化用语 ("最好", "绝对化用语", "🟠", "《广告法》第9条", "适合 / 值得考虑"), ("最佳", "绝对化用语", "🟠", "《广告法》第9条", "合适"), ("第一", "绝对化用语", "🟠", "《广告法》第9条", "代表性 / 较早"), ("顶级", "绝对化用语", "🟠", "《广告法》第9条", "优质"), ("唯一", "绝对化用语", "🟠", "《广告法》第9条", "特色"), ("国家级", "绝对化用语", "🟠", "《广告法》第9条", "(删除)"), ("最安全", "绝对化用语", "🟠", "《广告法》第9条", "较安全"), ("最有效", "绝对化用语", "🟠", "《广告法》第9条", "较有效"), ("全球领先", "绝对化用语", "🟠", "《广告法》第9条", "行业先进"), # 治愈承诺 ("根治", "治愈承诺", "🔴", "《广告法》第17条 / 《医疗广告管理办法》", "改善"), ("治愈", "治愈承诺", "🔴", "《广告法》第17条 / 《医疗广告管理办法》", "改善"), ("根除", "治愈承诺", "🔴", "《广告法》第17条 / 《医疗广告管理办法》", "减少"), ("彻底消除", "治愈承诺", "🔴", "《广告法》第17条 / 《医疗广告管理办法》", "明显缓解"), ("永不复发", "治愈承诺", "🔴", "《广告法》第17条 / 《医疗广告管理办法》", "减少反复"), ("包治", "治愈承诺", "🔴", "《广告法》第17条 / 《医疗广告管理办法》", "辅助改善"), ("治好", "治愈承诺", "🔴", "《广告法》第17条 / 《医疗广告管理办法》", "改善"), # 保证性承诺 ("保证", "保证性承诺", "🟠", "《广告法》第9、25条", "有助于"), ("承诺", "保证性承诺", "🟠", "《广告法》第9、25条", "预期(疗效类承诺删除)"), ("100%", "保证性承诺", "🟠", "《广告法》第9、25条", "多数情况下"), ("无效退款", "保证性承诺", "🟠", "《广告法》第25条", "(删除)"), ("签约治疗", "保证性承诺", "🟠", "《广告法》第25条", "(删除)"), # 功效夸大·即时 ("一夜回春", "功效夸大·即时", "🟡", "《广告法》第28条(虚假宣传)", "逐步改善"), ("秒变", "功效夸大·即时", "🟡", "《广告法》第28条(虚假宣传)", "逐渐"), ("瞬间", "功效夸大·即时", "🟡", "《广告法》第28条(虚假宣传)", "逐渐"), ("奇效", "功效夸大·即时", "🟡", "《广告法》第28条(虚假宣传)", "效果"), ("神效", "功效夸大·即时", "🟡", "《广告法》第28条(虚假宣传)", "效果"), ("立竿见影", "功效夸大·即时", "🟡", "《广告法》第28条(虚假宣传)", "循序渐进、需要坚持"), ("立马见效", "功效夸大·即时", "🟡", "《广告法》第28条(虚假宣传)", "逐渐见效"), # 医疗功效越界(护肤品禁宣称) ("治疗", "医疗功效越界", "🟠", "《化妆品监督管理条例》/《广告法》", "护理 / 改善"), ("药用", "医疗功效越界", "🟠", "《化妆品监督管理条例》/《广告法》", "(删除)"), ("消炎", "医疗功效越界", "🟠", "《化妆品监督管理条例》/《广告法》", "舒缓"), ("杀菌", "医疗功效越界", "🟠", "《化妆品监督管理条例》/《广告法》", "洁净"), ("抗炎", "医疗功效越界", "🟠", "《化妆品监督管理条例》/《广告法》", "舒缓"), ("抗菌", "医疗功效越界", "🟠", "《化妆品监督管理条例》/《广告法》", "清洁"), ("医用", "医疗功效越界", "🟠", "《化妆品监督管理条例》/《广告法》", "(删除)"), ("药效", "医疗功效越界", "🟠", "《化妆品监督管理条例》/《广告法》", "(删除)"), # 患者证言·对比 ("术前术后", "患者证言·对比", "🔴", "《医疗广告管理办法》", "(删除,改用示意图)"), ("对比图", "患者证言·对比", "🔴", "《医疗广告管理办法》", "(删除,改用示意图)"), ("疗效见证", "患者证言·对比", "🔴", "《医疗广告管理办法》", "(删除)"), ("患者案例", "患者证言·对比", "🔴", "《医疗广告管理办法》", "(删除 / 脱敏)"), # 平台诱导风险 ("加微信", "平台诱导风险", "🟡", "抖音/小红书审核规则", "进店了解"), ("私信我", "平台诱导风险", "🟡", "抖音/小红书审核规则", "(删除)"), ("点击下方链接", "平台诱导风险", "🟡", "抖音/小红书审核规则", "(删除)"), ("限时优惠", "平台诱导风险", "🟡", "抖音/小红书审核规则", "活动期间优惠"), ("最低价", "平台诱导风险", "🟡", "抖音/小红书审核规则", "优惠价"), ("免费领", "平台诱导风险", "🟡", "抖音/小红书审核规则", "(删除)"), ("扫码", "平台诱导风险", "🟡", "抖音/小红书审核规则", "(删除)"), ] RISK_RANK = {"🔴": 4, "🟠": 3, "🟡": 2, "🟢": 1} CONCLUSION = { 4: "不予通过(存在极高违规,必须删除/替换后重检)", 3: "修改后通过(高)—— 须替换 🟠 项方可进入生成", 2: "修改后通过(中)—— 建议替换 🟡 项", 1: "修改后通过(低)—— 建议酌情优化", 0: "通过(未检出违禁词)", } def scan(text: str): hits = [] seen = set() for word, cat, risk, law, repl in WORD_LIST: if word in text and word not in seen: seen.add(word) hits.append({ "word": word, "cat": cat, "risk": risk, "law": law, "repl": repl, "count": text.count(word), }) hits.sort(key=lambda h: -RISK_RANK[h["risk"]]) return hits def build_report(text: str, hits: list) -> str: lines = [] lines.append("## 敏感词 / 合规检测报告\n") lines.append("### 内容类型") lines.append("抖音短视频口播文案(美业护肤科普)\n") lines.append("### 检测条目") if not hits: lines.append("\n> ✅ 未检出高危违禁词。\n") else: lines.append("") lines.append("| 违规点 | 原表述 | 风险等级 | 法规依据 | 合规替换 |") lines.append("|--------|--------|----------|----------|----------|") for h in hits: cnt = f"(×{h['count']})" if h["count"] > 1 else "" lines.append( f"| {h['cat']} | 「{h['word']}」{cnt} | {h['risk']} {('极高' if h['risk']=='🔴' else '高' if h['risk']=='🟠' else '中' if h['risk']=='🟡' else '低')} | {h['law']} | {h['repl']} |" ) lines.append("") max_rank = max((RISK_RANK[h["risk"]] for h in hits), default=0) lines.append("### 审查结论") lines.append(CONCLUSION[max_rank] + "\n") if hits: lines.append("### 建议") for i, h in enumerate(hits, 1): lines.append(f"{i}. 「{h['word']}」({h['cat']})→ 替换为「{h['repl']}」,规避对应风险。") lines.append(f"{len(hits)+1}. 修改后建议再跑一次本脚本确认无新增违禁词。") return "\n".join(lines) def main(): ap = argparse.ArgumentParser(description="美业口播敏感词/合规机器初筛") g = ap.add_mutually_exclusive_group(required=True) g.add_argument("--text", help="直接传入口播文本") g.add_argument("--file", help="传入文本/脚本文件路径(.txt/.md)") ap.add_argument("--output", help="将报告写入该文件(可选)") args = ap.parse_args() if args.text: text = args.text else: p = Path(args.file) if not p.exists(): print(f"[错误] 文件不存在: {args.file}", file=sys.stderr) sys.exit(2) text = p.read_text(encoding="utf-8") hits = scan(text) report = build_report(text, hits) print(report) if args.output: Path(args.output).write_text(report, encoding="utf-8") print(f"\n[已写入报告] {args.output}", file=sys.stderr) # 退出码:极高/高违规 → 非0,便于流程判断 max_rank = max((RISK_RANK[h["risk"]] for h in hits), default=0) sys.exit(0 if max_rank <= 2 else 1) if __name__ == "__main__": main()