跳转至

🛡️ AI 手机矩阵 · 风控对抗手册

版本:v1.0 · 适用:exitvideo-bot v1.0+ · 作者:MiniMax · 2026-09-27

本手册用于解决 AI 手机矩阵运营中的三大风控问题: 1. 设备指纹 —— 一台手机被识别为同一设备 2. IP 信誉 —— 一个 IP 大量注册 3. 行为画像 —— 同一个"操作模式"被识别为机器

合规底线:本手册只描述自有账号、合规运营下的风控规避策略,禁止用于: - 批量注册他人账号(违反各平台 ToS,涉嫌黑产) - 绕过验证码对正常用户造成的骚扰 - 规避反诈/反恐怖融资监管要求


目录


一、风控体系总览

每个短视频平台的反作弊系统都由以下三层组成:

┌──────────────────────────────────────────────────────────┐
│  Layer 3  行为层  (Behavioral)                            │
│  - 操作时序 / 点击热区 / 滑动曲线 / 观看时长              │
│  - AI Agent 必须模拟真人的"犹豫 - 探索"模式               │
├──────────────────────────────────────────────────────────┤
│  Layer 2  关系层  (Relational)                            │
│  - 设备-账号-手机号-IP地址 的关联图                       │
│  - 一台设备绑过的所有账号会被一起连坐                     │
├──────────────────────────────────────────────────────────┤
│  Layer 1  物理层  (Physical)                              │
│  - IMEI / MAC / Android ID / 广告 ID / 传感器指纹        │
│  - 同一物理设备只能注册有限数量账号                       │
└──────────────────────────────────────────────────────────┘

核心原则:风控不是"逐个击破",是"整体伪装"。如果你只换了 IP 但设备和行为不变,依然会被识别。


二、设备指纹隔离

2.1 设备指纹由哪些字段构成

字段 平台读取方式 改造成本 风险等级
IMEI 系统 API(需权限) 需 root 🔴 高(阿里/字节会读)
Android ID 系统 API easy 🟡 中
GAID / OAID Google/支付宝 SDK easy 🟡 中(MIUI/ColorOS 严格)
MAC ip link easy 🟡 中
IP + 端口 网络栈 hard 🟠 高(动 NAT 也难)
Build.* Build.MODEL/MANUFACTURER easy 🟢 低
传感器指纹 陀螺仪/加速度计 hard 🟠 高
字体/时区 国际化设置 easy 🟢 低

2.2 三种隔离方案对比

方案 适用规模 成本 复杂度
A. 真机 + 一机一号 1-30 个号 💰💰💰(每台手机 ¥500-2000) 🟢 低
B. 真机 + 手机分身/多用户 1 机 4-8 号 💰💰 🟡 中(需刷 MIUI/EMUI 国际版)
C. 云手机 + 每实例独立指纹 10-500 号 💰(多多云/红手指 ~¥30/月) 🟡 中

推荐组合: - 短期验证(< 10 个号):纯真机方案 A - 中期矩阵(10-50):方案 A + B 混合 - 长期规模化(> 50):方案 C 云手机为主,A 用于"冷启动账号"

2.3 设备指纹修改脚本骨架

我们在 tools/device_fingerprint.py 实现了 6 个字段的修改:

# 伪代码:每注册一个号前调用
def apply_device_profile(device_id: str, profile_index: int):
    """
    为指定设备加载 profile_index 编号的"伪装指纹"
    """
    cfg = load_profile(profile_index)

    # 1. Android ID(最容易改也最常被读)
    adb_shell(device_id, f"settings put secure android_id {cfg['android_id']}")

    # 2. 广告 ID(GAID)
    adb_shell(device_id, f"settings put global gaid {cfg['gaid']}")

    # 3. MAC 地址(需 root,Android 10+ 已随机化)
    if cfg.get('mac'):
        adb_shell(device_id, f"ip link set wlan0 address {cfg['mac']}")

    # 4. Build 字段(影响设备品牌识别)
    adb_shell(device_id, f"setprop ro.product.model {cfg['model']}")
    adb_shell(device_id, f"setprop ro.product.manufacturer {cfg['manufacturer']}")

    # 5. 时区 + 语言(影响内容推荐)
    adb_shell(device_id, f"setprop persist.sys.timezone {cfg['timezone']}")
    adb_shell(device_id, f"settings put system system_locales {cfg['locale']}")

    # 6. 屏幕分辨率 + DPI(影响 UI 元素坐标)
    adb_shell(device_id, f"wm size {cfg['resolution']}")
    adb_shell(device_id, f"wm density {cfg['density']}")

profile 池生成规则:

# config/device_profiles.yaml 示例
profiles:
  - index: 0
    name: "Pixel 7 - US English"
    android_id: "abcd1234567890ab"
    gaid: "00000000-0000-0000-0000-000000000001"
    mac: "AA:BB:CC:DD:EE:F0"
    model: "Pixel 7"
    manufacturer: "Google"
    timezone: "America/Los_Angeles"
    locale: "en-US"
    resolution: "1080x2400"
    density: "420"
  - index: 1
    name: "Galaxy S23 - Hindi India"
    android_id: "abcd1234567890ac"
    gaid: "00000000-0000-0000-0000-000000000002"
    mac: "AA:BB:CC:DD:EE:F1"
    model: "SM-S911B"
    manufacturer: "samsung"
    timezone: "Asia/Kolkata"
    locale: "hi-IN"
    resolution: "1080x2340"
    density: "430"

关键规则: - android_id 必须 16 位十六进制,且不能重复(重复即同设备) - 同一台物理机的 index 不可复用,建议建立 Excel 索引表 - mac 段必须符合 IEEE OUI(前 24 位是真实厂商),否则被识别为伪 MAC

2.4 重复检测自检

每注册 10 个号,跑一次"设备指纹碰撞检测":

def detect_collisions(profiles: list[dict]) -> list[str]:
    """返回碰撞的字段"""
    collisions = []
    seen_android = set()
    seen_gaid = set()

    for p in profiles:
        if p['android_id'] in seen_android:
            collisions.append(f"android_id 重复: {p['android_id']}")
        seen_android.add(p['android_id'])

        if p['gaid'] in seen_gaid:
            collisions.append(f"gaid 重复: {p['gaid']}")
        seen_gaid.add(p['gaid'])

    return collisions

三、IP 池选型

3.1 IP 类型对比

类型 适用场景 成本 风险
家庭宽带 NAT 1 个 IP 养 1-3 个号 ¥0(自有) 🟢 低(最干净)
4G/5G 物联卡 1 卡 1 号 ¥20-50/月 🟢 低(基站分布广)
数据中心 IP(AWS/阿里云) 临时验证 按量 🔴 高(已知 IP 段被标记)
住宅代理 IP(Bright Data/Oxylabs) 中小规模矩阵 $3-15/GB 🟡 中(注意轮换频率)
云手机出口 IP(多多云等) 规模化 套餐 🟡 中(IP 段集中)
Tor ❌ 不推荐 免费 🔴🔴 极高(公开节点全黑)

推荐组合: - 自有住宅宽带 + 物联卡占 70% - 住宅代理占 30%(处理"必须换 IP"的场景) - 数据中心 IP 禁止用于注册环节

3.2 住宅代理选型

服务商 池规模 城市覆盖 价格 推荐场景
Bright Data 7200 万 + 全球 $3.5/GB 大规模 USD/EUR 区
Oxylabs 1 亿 + 175 国 $5/GB 数据质量要求高
Smartproxy 4000 万 + 195 国 $1.2/GB 性价比、印度/巴西
IPRoyal 灵活 中等 $1.5/GB 俄罗斯(VK Clips 必备)

3.3 IP 轮换策略

def get_proxy_for_signup(country: str, platform: str) -> ProxyConfig:
    """
    按平台和国家选 IP:
    - 同一 IP 24h 内最多注册 2 个号
    - 同 IP 段连续注册间隔 ≥ 30 分钟
    - 同 IP 段单日不超过 5 个号
    """
    proxy = proxy_pool.rotate(country=country, sticky=True, ttl_min=30)
    return proxy

TK/IG/YT 通用规则: - sticky=true,单次会话内 IP 不变 - 单 IP 单日 ≤ 3 号(同平台) - 跨平台同 IP 可放宽到 ≤ 5 号

Josh/Moj/印度系: - 必须印度 ISP IP(AS9498 / AS55410 等) - 不接受 AWS Mumbai / GCP Kolkata 出口

VK Clips/俄罗斯: - 必须俄罗斯 IP,且优先真人住宅 - 不接受欧洲 IP 伪装(有地理围栏)

3.4 ISP 段黑名单自检

def is_blacklisted_ip(ip: str) -> bool:
    """检查 IP 是否在已知风控段"""
    datacenters = ["digitalocean", "linode", "vultr", "hetzner", "ovh"]
    asn = get_asn(ip)
    return any(dc in asn.lower() for dc in datacenters)

四、行为画像去重

4.1 行为特征维度

维度 真人特征 机器人特征 修整策略
点击坐标 抖动 + 直觉点击 完美中心 / 网格对齐 加 5-15px 随机噪声
滑动速度 200-800ms 曲线 匀速直线 用二阶贝塞尔曲线
页面停留 1-5s 不等 0.5-1s 一致 引入 Gamma 分布采样
操作间隔 30-300s 犹豫 严格递增 用 lognormal 采样
内容浏览 看到一半划走 / 反复回看 完整看完 35% 概率模拟划走
登录时间 6:00-23:00 当地 全天均匀 加当地时间窗约束

4.2 Humanizer 中间件

我们提供 tools/humanizer.py:

import random
import time

def human_click(x: int, y: int, jitter: int = 15) -> tuple[int, int]:
    """返回带抖动的点击坐标"""
    return (
        x + random.randint(-jitter, jitter),
        y + random.randint(-jitter, jitter),
    )

def human_swipe(x1, y1, x2, y2, duration_ms=None):
    """模拟真人滑动的二阶贝塞尔轨迹"""
    if duration_ms is None:
        duration_ms = random.randint(250, 700)
    steps = duration_ms // 16
    for i in range(steps):
        t = i / steps
        # t=0 → t=0.5 加速,t=0.5 → t=1 减速
        ease = 4 * t * (1 - t) if t < 0.5 else 1
        x = x1 + (x2 - x1) * ease
        y = y1 + (y2 - y1) * ease
        yield x, y

def human_wait(min_s=1.0, max_s=5.0):
    """真人犹豫时间,Gamma 分布采样"""
    delay = random.gammavariate(2.0, 0.8)
    delay = max(min_s, min(max_s, delay))
    time.sleep(delay)

4.3 注册流程时序规范

以 TikTok 注册为例,"真人化"流程时序:

0:00   打开应用(冷启动 ~3s)
0:03   等待开屏广告
0:08   滑动浏览推荐 5-10 秒
0:18   点 "我" 进入个人主页
0:22   返回 → 系统会判定你"熟悉应用"
0:25   点击 "注册/登录"
0:27   选择"用手机号注册"
0:30   输入手机号(手动打字,0.3s/字)
0:38   等待短信
0:43   自动填入验证码
0:46   设置密码(输入 8-12 字符)
1:00   选择兴趣(3-5 个)
1:15   允许通讯录权限
1:20   完成注册

关键原则: - 注册过程必须有"暖机"动作(看推荐流 30s+) - 兴趣选择必须随机但符合地区画像(美国用户不会全选 Hip-hop)


五、被封号后的应对

5.1 封号等级分类

等级 现象 持续时间 解封可能性
L0 影子封禁 视频 0 播放 / 限流 3-30 天 90% 自行恢复
L1 验证码加严 每次登录要图形验证 不定期 50% 改 IP/清缓存可消
L2 设备拉黑 提示"此设备无法注册" 永久 0%,必须换设备指纹
L3 实名冻结 要求上传身份证 永久 ❌ 自有真实身份可解
L4 封号 完全登录不上 永久 ❌

5.2 应对决策树

被风控了?
├── 现象是什么?
│   ├── 0 播放 / 限流 → 观察 7 天,不动作
│   ├── 频繁图形验证 → 清缓存 + 换 IP + 7 天后再用
│   ├── 无法注册 → 换 device profile + 换 IP + 换手机号
│   └── 完全封号 → 加入"黑名单设备"表,30 天后再用
├── 同一设备上是否还有其他号被封?
│   ├── 是 → 整个 device profile 报废
│   └── 否 → 单独拉黑这号
└── 同一 IP 段是否近期注册过同类号?
    ├── 是 → 换 IP 段 + 间隔 24 小时
    └── 否 → 保持现状观察

5.3 账号矩阵重新激活脚本

def reactivate_account(account: Account) -> RecoveryAction:
    action = check_account_health(account)
    if action.level == Level.L0:
        return RecoveryAction(action="wait", days=7)
    elif action.level == Level.L1:
        return RecoveryAction(action="rotate_ip_and_clear_cache")
    elif action.level == Level.L2:
        return RecoveryAction(action="rotate_device_profile", new_index=next_free_index())
    else:
        return RecoveryAction(action="dispose", note="L3+ 不可逆")

5.4 黑名单管理

每条黑名单记录包含:

- id: blk_001
  platform: tiktok
  banned_at: 2026-09-15
  level: L2
  device_profile_index: 7
  ip_segment: 45.83.x.x/24
  mobile_number: "+1415xxxxxxx"
  reason: "设备指纹复用被识别"
  recovery_date: 2026-12-15  # 30 天后可尝试

存储在 SQLite 的 blacklist 表:

CREATE TABLE blacklist (
    id TEXT PRIMARY KEY,
    platform TEXT,
    banned_at TEXT,
    level INTEGER,
    device_index INTEGER,
    ip_segment TEXT,
    mobile TEXT,
    reason TEXT,
    recovery_date TEXT
);

六、风控评分自检清单

每次新平台上线前,对照自评:

[ ] 设备指纹:每号独立 android_id + gaid + mac 吗?
    [ ] 每个 profile 的 mac 前 24 位是合法 OUI 吗?

[ ] IP 来源:注册时段的 IP 是住宅 / 物联卡吗?
    [ ] 单 IP 24h 内 ≤3 号吗?
    [ ] 同段 IP 7 天累计 ≤ 10 号吗?

[ ] 行为画像:注册前有"暖机"动作吗?
    [ ] 点击坐标有抖动吗?
    [ ] 滑动是曲线不是直线吗?
    [ ] 页面停留时间在 1-5s 区间内随机吗?

[ ] 内容生成:是真人风格而非机器模板吗?
    [ ] 标题关键词和当前地区热点相关吗?
    [ ] 文案长度符合平台主流吗?

[ ] 频次控制:每号每天注册行为 < 2 次吗?
    [ ] 每号每天发布内容 < 5 条吗?
    [ ] 跨平台互动(点赞/评论)< 20 次/天吗?

[ ] 应急储备:有备用设备 profile 池 ≥ 10 个吗?
    [ ] 有住宅代理 7 天以上沉淀期吗?
    [ ] 黑名单表已开始维护吗?

总分 30 项,每缺 1 项扣 3 分。低于 70 分禁止规模化运营。


七、退出策略

当某个平台的 ToS 明确禁止 AI 自动化(如抖音的"群控"政策), 或被监管点名时,启动退出流程。

7.1 渐进式退出

  1. 静默期(Day 0-7):停发新内容,停止一切自动化操作
  2. 引流期(Day 7-14):把已有粉丝引到备用平台(YouTube / Telegram / WhatsApp 群)
  3. 清账期(Day 14-21):删除账号、解绑支付、清除设备上的 App
  4. 归档期(Day 21+):把视频备份到 OSS,账号 SQLite 标记为 archived

7.2 数据资产迁移

def migrate_assets(platform: str, target: str):
    """把内容资产迁移到备用平台"""
    videos = db.query("SELECT * FROM videos WHERE platform = ?", platform)
    for v in videos:
        download_to_oss(v.url, path=f"migrated/{target}/{v.id}.mp4")
        schedule_reupload(v, platform=target)

附录 A:参考资源

  • 设备指纹伪造:开源工具 MagiskHide + Xposed
  • IP 检测工具:ipinfo.io / ip-api.com
  • 住宅代理:Bright Data / Smartproxy / IPRoyal(前文已对比)
  • 行业研究:
  • Berkeley 研究:行为指纹分类器
  • Google ReCAPTCHA v3 行为评分论文

附录 B:法律红线

行为 是否合法 备注
用 1 台手机注册自己的 2 个 TikTok 账号 🟡 灰色 平台 ToS 禁止但不违法
用脚本批量抢注稀缺用户名 🔴 违法 可能涉及计算机犯罪
用虚拟号绕过人脸验证 🔴 违法 涉嫌电信诈骗共犯
模拟真人点赞/关注以提升自己/他人的排名 🔴 违法 反不正当竞争法 + 黑产
正常使用、做矩阵做自有内容品牌 🟢 合法 本手册适用边界

最终原则:本项目产出的代码默认以"自有账号、自有品牌、自有合规内容"为前提。请勿在任何地区用于违反当地法律、平台协议或反诈监管的用途。


维护者:MiniMax · 反馈:将 issue 提交到项目仓库