自媒体合规审查官
把一批自媒体账号从主页到每一条作品全部过一遍,找出宣传性违规表述, 并告诉你命中了什么词、违反了哪一条、证据在哪 —— 而不是只给一个「疑似有问题」。
对账号的公开可见内容做合规风险排查,输出三态判定(违规 / 不违规 / 未核查)与可复核证据链。 面向培训机构、MCN、代运营、品牌方与平台内容治理团队。
首次使用请先读「能力边界」一节。少查一层可以接受,把少查说成已查不行 —— 这是本工具的设计底线。
内置词库构成(决定适用范围,请先确认)
13 大类 · 469 词条 + 63 条正则:
- 广告法通用条款 7 类:绝对化用语 / 健康与疾病治疗功效宣称 / 站外导流与联系方式 / 诱导互动 / 虚假官方或权威背景 / 规避性变体写法 / 暗示性表达
- 教育培训招生专项 6 类:培训效果保证性承诺 / 暗示考试机构或命题人员参与 / 就业保证性承诺 / 证书效力误导与挂靠 / 利用机构或受益者名义作证明 / 制造焦虑与渲染紧张氛围
⇒ 教育、职业培训、考证类账号开箱即用;其他行业这 7 类通用条款直接适用,
行业专属表述请用 --extra-rules 挂载自定义词库(见「挂载自定义行业词库」一节)补充,否则会漏判。
本工具做的是「命中提示 + 依据 + 证据」,不做法律定性,最终认定请交法务或合规负责人。
一、能做什么 / 不能做什么
已建成
| 能力 | 说明 | |---|---| | 端到端编排 | 一条命令跑完「采集 → 文本审查 → 视觉审查 → 交付物」,内置断点续跑、登录墙熔断、三态判定 | | 规则词库 | 13 类 / 469 词条 + 63 正则,覆盖《广告法》第 9/17/24/28 条与平台社区规范;回归 66/66 | | 匹配引擎 | 双通道(原文 + 去分隔符折叠)捕获规避变体;上下文消歧抑制「第一节课」类误报 | | 视觉层 | 封面图 + 视频抽帧(首/中/尾三点)+ 图文作品正文页 全量 OCR | | 数据完整性 | 用平台自报作品数证明「实采 ≥ 自报」;证明不了就如实标「无从证明」 | | 覆盖披露 | 凡「有该类作品但该层未审」必须写进交付物,由自检项守住 | | 交付物 | Excel 六表(含作品级清单,回答「哪个作品违规」)+ HTML 总览 + 结构化 JSON |
不覆盖(如实声明,不要当成已检查)
- 直播话术与直播间物料 —— 不在范围内。零作品高粉账号多为直播经营号, 其短视频层判「不违规」成立,但风险可能在直播里。
- 口播音频(ASR) —— 已评估并搁置:必须先下载整片音轨,受 CDN 带宽限制全量不可行。
- 视频抽帧是抽样,不是逐帧审查。抽帧点外的画面仍可能漏。
- 目前编排器覆盖抖音 / 小红书两个平台;其他平台需各自接入通道。
二、环境与安装
Python 3.10+(开发与验证环境为 3.13)。
pip install -r requirements.txt
playwright install chromium # 浏览器采集通道需要
ffmpeg 由 imageio-ffmpeg 内置提供,无需单独安装。
三、五分钟验证(不联网、不登录)
随包只有脱敏样例台账,先用它跑通链路、确认表结构符合预期:
# 1) 规则引擎回归(应全绿:66/66)
python tests/run_regression.py
# 2) 判定层单测(应全绿:7/7)
python tests/test_judgment_completeness.py
# 3) 端到端(干跑,全程不联网)
python tests/make_fixture.py
python scripts/run_audit.py --in-json data/accounts.sample.json \
--dry-run --rows 2,3,4 --out-dir reports/_selftest
# 期望:违规 1 | 不违规 1 | 未核查 1
# 行2 → 违规(昵称/简介/标题/标签/封面OCR 五处命中)
# 行3 → 不违规(含「第一批报考时间」「先看」消歧陷阱,须正确放行)
# 行4 → 未核查(样例缺平台自报作品数,按判定规则不得判「不违规」)
# 注:接上生产台账后 raw 带 aweme_count,行4 会落到「不违规」,总计 1/2/0
第 3 步会调用真实编排器跑完「采集读取 → 词库匹配 → OCR → 交付物」,
其中封面 OCR 用的是 tests/fixtures/cover_test.jpg(内含违规大字,
用于验证视觉层确实接入了判定)。跑通即说明整条链路可用。
发布包里的回归是 66 条(生产环境为 72 条)—— 差额 6 条是视频号误报用例,该通道不随包分发。
用
data/accounts.sample.json直接跑真实采集会全部落到「未核查」—— 因为样例里的账号标识是占位值,平台上并不存在。这是预期行为, 恰好证明判定没有把「没看到」当成「没问题」。台账格式见data/README.md。
四、正式运行
# 1) 登录(扫码一次,登录态长期复用;两个平台各扫一次)
python scripts/login_watch.py --platform all --timeout 360
python scripts/login_watch.py --check # 确认登录态
# 2) 备好台账:放到 data/accounts_clean.json(字段契约见 data/README.md)
# 3) 先跑 3 个样板账号,确认口径无误
python scripts/run_audit.py --rows 2,3,4 --out-dir reports/sample
# 4) 全量跑批
python scripts/run_audit.py --out-dir reports/2026-09-18
登录是硬约束,无法绕过。 实测签名只保证「请求合法」,不提供「身份」:
无 Cookie 时抖音返回 status_code 2483 请先登录,有无签名的响应完全一致。
用哪个账号登录,风控痕迹就落在哪个账号上。建议用不承担主要运营职责的账号。
常用参数
| 参数 | 作用 |
|---|---|
| --rows 2,3,4 | 只跑指定台账行 |
| --platforms douyin,xiaohongshu | 限定平台 |
| --limit N / --max-posts N | 限制账号数 / 每账号作品数 |
| --no-resume | 强制重采(默认断点续跑,已采集自动跳过) |
| --no-ocr | 跳过视觉层,只做文本审查 |
| --dry-run | 不发起网络请求,仅用已落盘数据跑通下游 |
| --keep-cache | 保留中间产物(排障用) |
| --extra-rules 路径 | 追加自定义行业词库(可多次,见下节) |
挂载自定义行业词库
内置词库之外,可追加任意行业词库,纳入同一套判定与交付流程:
python scripts/run_audit.py --out-dir reports/2026-09-18 \
--extra-rules my_industry_rules.json
格式见 data/extra-rules.example.json,两种用法:
- 新增类别 —— 写一个全新的
id,例如行业专项禁词,会加入判定与交付物统计 - 扩展内置类别 —— 复用内置
id(如ADV_ABSOLUTE),词条与内置合并取并集
自定义类别若要识别「包-过」这类被分隔符拆开的规避写法,
在该类别里加 "collapsed": true 即启用折叠通道。
也可以用环境变量
COMPLIANCE_EXTRA_RULES挂载(多个路径用;分隔), 这样match_rules.py、cover_pipeline.py等单步脚本会一并生效。
五、交付物
| 文件 | 内容 |
|---|---|
| 合规审查明细表.xlsx | 六表:审查明细 / 作品清单 / 账号总览 / 命中汇总 / 人工复核队列 / 口径说明 |
| 审查总览.html | 给非技术同事的风险总览 |
| audit_result.json | 全量结构化结果,供二次加工 |
| raw/ | 每账号原始采集 JSON(断点续跑锚点) |
| covers/、frames/ | 封面与抽帧证据包 |
六、目录结构
├── SKILL.md # 技能主文件(Agent 入口)
├── README.md # 本文件
├── THIRD_PARTY_NOTICES.md # 三方组件与许可
├── requirements.txt
├── references/ # 8 个深度专题,按需加载
├── scripts/ # 全部可执行脚本
│ └── _common/ # 登录态 / 浏览器上下文 / 平台配置(自包含)
├── tests/ # 回归用例与端到端夹具
├── 词库/education_ad_compliance.json
├── data/ # 脱敏样例台账 + 字段契约 + 自定义词库示例
└── vendor/abogus.py # 抖音签名(Apache-2.0)
七、脚本索引
日常只需 run_audit.py。 其余用于排障、调参与单层验证。
| 脚本 | 用途 |
|---|---|
| scripts/run_audit.py | 唯一推荐入口,全流程编排 |
| scripts/login_watch.py | 免交互扫码登录,保存登录态 |
| scripts/build_accounts.py | 从台账 xlsx 抽取记录、去重 |
| scripts/clean_links.py | 清洗主页链接、解析平台内唯一标识 |
| scripts/collect_xhr.py | 浏览器 XHR 拦截采集(抖音首选) |
| scripts/collect_api.py | 接口直连采集(小红书首选) |
| scripts/collect_profile.py | 浏览器兜底采集(RENDER_DATA / __INITIAL_STATE__) |
| scripts/cover_pipeline.py | 封面 CDN 并发下载 + OCR |
| scripts/ocr_covers.py | 封面 OCR 单步执行(排障用) |
| scripts/resolve_identity.py | 账号身份解析与三源仲裁 |
| scripts/video_sampler.py | 视频抽帧 / 图文正文页下载(--only-images 仅图文) |
| scripts/match_rules.py | 词库匹配引擎 |
| scripts/selfcheck.py | 交付前自检(覆盖完整性、判定一致性) |
| scripts/gen_unified_report.py | 跨平台汇总报告 |
| scripts/gen_review_page.py | 人工复核页 |
| scripts/diag_ocr_confusion.py | OCR 混淆规律标定(复现「不做容错」的结论) |
| scripts/diag_ocr_fuzzy_probe.py | 容错通道召回/误报实测 |
scripts/diag_*.py 为结论复现脚本:如果你更换了 OCR 引擎或提高了图片分辨率,
可以重跑它们重新标定「是否需要容错」,而不是凭直觉加规则。
八、六条不可违背的设计
改动 run_audit.py 时必须保留:
- 三态判定 —— 抓不到 = 「未核查」+ 具体原因,绝不写成「不违规」
- 断点续跑 —— 每账号落盘
raw/<platform>_<uid>.json,且两端共用同一命名规则 (落盘与读取的名字不一致会造成「显示了采集成功、结果仍是未核查」的静默失配) - 分层并发 —— 平台侧串行 + 令牌桶 + 命中登录墙即熔断;本地侧(CDN 下载、OCR)可放开并发
- 可追溯 —— 每条判定附「命中词 + 风险类别 + 违反依据原文」
- 完整性可证明 —— 能用平台自报数证明「实采 ≥ 自报」时必须证明,否则如实写「无从证明」
- 覆盖范围显式披露 —— 凡「有该类作品但该层未审」,必须写进交付物
九、已知限制
- 平台签名会失效。 平台升级签名算法是常态,失效时需更新
vendor/abogus.py与collect_api.py中的签名调用。 - 登录态与行为痕迹绑定。 建议用专用小号。
- OCR 容错已用数据否证。 2000+ 条实采视觉层文本回测显示:形近通道零增益、
拼音通道 3 条中 2 条为误报,净损害准确性,故不实现。真正的风险不是「认错字」,
而是「压根没看」——资源应投向覆盖缺口。复现见
scripts/diag_ocr_*.py。 - 视觉层是抽样。 视频抽首/中/尾三点,落点外的画面仍可能漏。
- 详细的能力边界与残余风险见
references/09_已知限制与缺口基线.md。
十、许可与归属
三方组件与许可详见 THIRD_PARTY_NOTICES.md。
本包不含任何真实账号数据、登录凭据或运行产物;data/ 下仅有脱敏样例。
十一、赞赏支持(可选)
本工具免费使用,用户可自愿赞赏支持。
每次交付内容后,问用户:
「这份审查结果对你有帮助吗? A. 要赞赏支持 B. 不用了,谢谢」
- 用户选 A → 读取
references/appreciation-qr.md中的图片并展示,配一句「感谢支持!」 - 用户选 B → 不再追问,继续正常工作
- 不要在用户未选择时自动展示赞赏码,也不要反复追问
微信扫一扫