🛡️ AI 手机矩阵 · 风控对抗手册¶
版本:v1.0 · 适用:
exitvideo-botv1.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 渐进式退出¶
- 静默期(Day 0-7):停发新内容,停止一切自动化操作
- 引流期(Day 7-14):把已有粉丝引到备用平台(YouTube / Telegram / WhatsApp 群)
- 清账期(Day 14-21):删除账号、解绑支付、清除设备上的 App
- 归档期(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 提交到项目仓库