Skip to content

处置与标签聚合

abuse-enforcement-service 读取模型分数后打标签、发挑战或封禁;申诉保护期;safety-label-source 供应标签;safety-label-user-agg 按帖子标签给账号打标签;下架原因的合并

Updated

这一页回答什么

  • abuse-enforcement-service/(下称处置服务)读取什么输入,按什么规则决定打标签、发挑战还是封禁。
  • abuse-ledger-service/ 的“申诉保护期”是什么,怎样阻止重复处置。
  • safety-label-source/ 怎样把帖子标签提供给可见性过滤。
  • safety-label-user-agg/ 怎样根据一个账号最近帖子的标签,给该账号打标签。
  • takedowns/ 怎样合并帖子级和账号级的下架原因。

打标签规则 由事件驱动;本页的系统则基于模型分数或帖子标签的累计。

核心结论

  1. 处置服务按规则表从上到下匹配,取第一条为真的规则(abuse-enforcement-service/service-lib/src/rules.rs:311-332)。用户与帖子各有一张规则表,规则写在 YAML 中。文件注释写明“从 GrowthBook 动态配置镜像,最后同步 2026-10-20”(abuse-enforcement-service/service-lib/rules/enforcement_user.yaml:1)。
  2. 动作只有六种: 封禁账号(临时或永久)、加账号标签、加帖子标签、Arkose 挑战、验证码、活体检测(abuse-enforcement-service/service-lib/src/decision.rs:1-24)。
  3. 最常见的处置是加 SpamHighRecall 账号标签,有效 7 天或 30 天。 带这个标签的账号,其帖子在站外推荐中被丢弃(见 可见性过滤)。
  4. 用户表的最后一条是兜底封禁:act_suspend,条件为 true,动作是临时封禁,策略为 PlatformManipulation(enforcement_user.yaml:184-189)。测试代码强制它必须在最后(rules.rs:1227-1228)。
  5. 处置服务先跳过粉丝数高和可信度分高的账号。 开源 YAML 中的阈值是占位值 12.34(enforcement_user.yaml:19-33)。代码中另有一道写死的粉丝上限检查(abuse-enforcement-service/service-lib/src/safety_checks.rs:158-175)。
  6. 申诉推翻过的处置不会被自动重做。 处置服务在封禁或加特定标签前,向 abuse-ledger-service 查询有效保护期;开源默认关闭这道检查(abuse-enforcement-service/service-lib/src/overturn_hold.rs:150-162)。
  7. 帖子标签累计到一定数量,账号也会被打标签。 默认规则:最近 5 条帖子中至少 3 条带 NSFW_HIGH_PRECISION(60 天内)时,账号获得 NSFW_HIGH_PRECISION 标签,有效 7 天(safety-label-user-agg/postToUserLabelRules.strato:395-426)。

abuse-enforcement-service:读取分数,执行处置

输入

  • 来自 Kafka 的评分事件 ScoreResult(xai_abuse_proto::enforcement,abuse-enforcement-service/service-lib/src/facts.rs:5、:145-170)。规则读取其中的 score.labels。BDSM 也定义了同名消息(bdsm/proto/abuse_inference.proto:80),二者是否为同一定义,源码未说明。BDSM 结果汇写出的 enforcement_cusp_*、enforcement_threshold_reached 与处置规则引用的标签名一致。
  • 账号与帖子事实:是否存在、是否已封禁/停用、现有标签、粉丝数、可信度分(cred.score、cred.is_high)、是否在允许名单中(facts.rs:215、abuse-enforcement-service/service-lib/src/allowlist.rs:10)。
  • topic_labels 配置决定哪些 Kafka 主题、带哪些标签的事件进入处置(abuse-enforcement-service/service-lib/src/config.rs:50-55)。该配置文件不在仓库中。

用户规则表(开源默认值)

顺序 规则 id 条件 结果
1 user_in_allowlist 在允许名单 跳过
2 user_not_found 账号不存在 跳过
3 high_follower_count 粉丝数 ≥ 12.34(占位值) 跳过
4 pagerank_skipped cred.is_high 或可信度分 ≥ 12.34(占位值) 跳过
5 anchor_campaign_suspend / _cse 评分标签含对应值 临时封禁(平台操纵)/ 永久封禁(CSE)
6 anchor_campaign_user anchor_campaign_user 加 SpamHighRecall(无 TTL)
7 panda_reports_embedding_v10_rough_spam、act_bb1_*_suspend 对应标签 临时封禁
8 act_bb1_*_bounce 对应标签 SpamHighRecall 30 天 + 活体检测
9 act_liveness_check_and_spam_high_recall_7d / act_spam_high_recall_7d 对应标签 SpamHighRecall 7 天(前者加活体检测)
10 act_add_llm_slop_label llm_slop_user,且账号尚无 SpamHighRecall SpamHighRecall 7 天
11 act_add_majority_poster_label SpamEmbeddingMajorityPoster,且尚无该标签 SpamHighRecall 30 天
12 act_spam_liveness_check spam_liveness_check_required 活体检测
13 already_suspended / already_deactivated 已封禁 / 已停用 跳过
14 act_cusp_arkose / _captcha / _liveness BDSM 临界挑战标签,且没有 enforcement_threshold_reached 对应挑战
15 act_impersonation_scam_suspend impersonation_scam_classifier_v1_suspend 临时封禁
16 act_suspend true 临时封禁

依据:abuse-enforcement-service/service-lib/rules/enforcement_user.yaml:5-189。TTL 换算:604800000 ms = 7 天,2592000000 ms = 30 天。

BDSM 的 enforcement_threshold_reached 没有专门规则。带这个标签的事件跳过第 14 行,落到第 16 行,即临时封禁(依规则表推断)。

帖子规则表(开源默认值)

规则 id 条件 结果
post_in_allowlist / user_in_allowlist / user_not_found 名单或不存在 跳过
high_follower_count / pagerank_skipped 作者粉丝或可信度高(占位值),且事件未要求跳过此检查 跳过
act_add_llm_slop_post_label llm_slop_post 帖子标签 RiskyHighVizReply,30 天
act_add_gibberish_post_label gibberish_post 帖子标签 SpamHighRecall,30 天
act_add_fast_reply_spam_post_label fast_reply_spam_post 帖子标签 SpamHighRecall,30 天
anchor_campaign_post / act_add_spam_embedding_ptos_distilled_label 对应标签 帖子标签 SpamHighRecall(无 TTL)
act_suspend_ncmec_reported_content_author cse_reports_embedding_v2 作者永久封禁(CSE)
post_no_actionable_label true 跳过

依据:abuse-enforcement-service/service-lib/rules/enforcement_post.yaml:3-82。帖子表的兜底动作是跳过,不是封禁。

带 SpamHighRecall 标签的帖子在站外推荐中被丢弃(visibility-filtering/rules/tweet_rules.rs:944-949)。RiskyHighVizReply 只在通知级别中使用(visibility-filtering/rules/levels.rs:217)。

处置前的检查

flowchart TD
    E["评分事件 ScoreResult"] --> R["规则表: 第一条为真"]
    R -- "skip" --> X["不处置"]
    R -- "act" --> C["粉丝上限检查"]
    C -- "超上限" --> X
    C -- "未超" --> H{"需要查申诉保护期?"}
    H -- "否" --> A["执行动作"]
    H -- "是" --> L["abuse-ledger-service 查询"]
    L -- "有有效保护期" --> X
    L -- "无" --> A
  • 粉丝上限:规则 very_high_follower_count,条件为 cred.follower_count >= 12345.67。超过上限时,处置服务把所有决定改成跳过,允许名单和账号不存在两种决定除外(safety_checks.rs:158-175、rules.rs:291-309)。该数值形似占位值,生产值未公开(推测)。
  • 申诉保护期见下一节。

abuse-ledger-service:申诉保护期

  • 该服务只读一张表 ledger.enforcement_holds。查询条件:用户 id 匹配、未清除、未过期,且动作是封禁,或动作是加标签且标签在请求列表中(abuse-ledger-service/src/sql.rs:3-7)。
  • 返回的保护记录包含 action_kind、label、head(模型头)、expires_at、case_group_id、reason(abuse-ledger-service/src/repo.rs:15-25)。
  • 处置服务按以下方式调用它(abuse-enforcement-service/service-lib/src/overturn_hold.rs):
    • 接口为 /v1/holds/lookup,默认超时 200 ms,正结果缓存 60 秒(:24-33)。
    • 模式有 off / shadow / enforce 三种,开源默认为 off。默认只检查封禁,不检查标签(:150-162、:396-406)。
    • enforce 模式下命中保护期时,处置服务跳过动作,并把状态记为 hold_overturned(:1709-1710)。
    • 永久封禁只受指定案件组的保护期或人工(manual)保护期约束(:408-415)。
  • 保护期时长:上游 README 写明“按申诉队列设定的固定时长”(上游 README 组件表 abuse-ledger-service/ 一行)。写入保护期的代码不在仓库中。

safety-label-source:标签读取层

VF 通过 safety-label-source 读取帖子的 SafetyLabelMap(visibility-filtering/server_deps.rs:39-40、:148)。

层 参数(开源默认值) 锚点
进程内缓存 每条 TTL 10 秒 safety-label-source/source.rs:13
Dragonfly 缓存 键前缀 sls:;写入 TTL 24 小时;30 秒、90 秒两档刷新 safety-label-source/dragonfly.rs:25-38
Manhattan 存储 超时 200 ms,重试 1 次,扫描上限 512 safety-label-source/mh_client.rs:11-13
  • 标签可以带过期时间 expires_at_msec。读取时,safety-label-source 剔除过期标签(safety-label-source/source.rs:35-54、:138-140)。打标签规则中的 7 天、14 天 TTL 靠这一步生效。
  • 远端不可用时,safety-label-source 走降级路径(source.rs:130-134)。

safety-label-user-agg:按帖子给账号打标签

flowchart LR
    K["Kafka: vf_tweet_safety_labels_event_prod"] -- "延迟 10 分钟转发" --> P["Processor"]
    P --> T{"新加的标签是否触发规则?"}
    T -- "是" --> U["取作者状态: nsfw 标记 / 高 PageRank / 灰标 / 现有标签"]
    U --> S["扫描作者最近 N 条帖子的标签"]
    S --> M{"满足计数条件?"}
    M -- "是" --> W["写 Gizmoduck 账号标签, 带 TTL"]
  • 输入:帖子标签事件流。Processor 只处理“新加”(Applied)事件;转发延迟 10 分钟,SLO 最大延迟 20 分钟(safety-label-user-agg/safetyLabelToUserLevelAggregationV2Forwarder.strato:3-21、safetyLabelToUserLevelAggregationV2Processor.strato:14-19)。
  • 规则来自功能开关 safety_understanding_post_to_user_label_rules。开关缺省时,Processor 使用代码中的默认 JSON(postToUserLabelRules.strato:360-432)。
  • 规则结构:触发标签 → 排除条件 → 若干条件,每个条件含 (窗口条数, 最少命中条数, 最大帖龄, 是否只看带媒体帖, 标签选择器) → 账号标签与 TTL(postToUserLabelRules.strato:6-47)。
  • 可写的账号标签只有 POSSIBLY_NSFW_ACCOUNT 与 NSFW_HIGH_PRECISION(postToUserLabelRules.strato:96-99)。
  • 配置上限:最多 10 条规则;窗口 ≤ 10;最少命中 ≤ 11;帖龄 ≤ 60 天;TTL ≤ 7 天(postToUserLabelRules.strato:100-107)。
  • 帖子扫描:Processor 从作者主页时间线倒序取帖;遇到转发时,取原帖的标签(safetyLabelToUserLevelAggregationV2Processor.strato:59-87)。
  • 写入时,byUser 与 source 都记为 "Grox"(safetyLabelToUserLevelAggregationV2Processor.strato:91-106)。

默认有两条规则:

规则 id 触发标签 条件 账号标签 排除 锚点
possibly_nsfw_account NSFW_HIGH_PRECISION、SOFT_NSFW 最近 10 条中至少 11 条带其一 POSSIBLY_NSFW_ACCOUNT,7 天 nsfw 用户、nsfw 管理员标记、高 PageRank 或灰标、已有同类标签 postToUserLabelRules.strato:363-394
nsfw_high_precision NSFW_HIGH_PRECISION 最近 5 条中至少 3 条带该标签,帖龄 ≤ 60 天 NSFW_HIGH_PRECISION,7 天 nsfw 管理员标记、已有该标签 postToUserLabelRules.strato:395-426

possibly_nsfw_account 的默认条件“10 条中至少 11 条”永远无法满足,因此这条规则默认等于关闭(依代码推断)。VF 的账号标签枚举中也没有 POSSIBLY_NSFW_ACCOUNT(visibility-filtering/models/author.rs:20-37)。

NSFW_HIGH_PRECISION 账号标签会触发站外推荐丢弃(visibility-filtering/rules/author_rules.rs:176-181)。结果是:一个账号最近 5 条帖子中有 3 条被判为高精度成人内容时,接下来 7 天它的所有帖子都不会出现在非关注者的推荐中。

takedowns:下架原因合并

  • 帖子的 takedownReasons = 帖子自身原因 + 作者账号的原因。系统只在帖子的 hasTakedown 为真时查询(takedowns/tweet-entity-service/TakedownReasonsTransform.scala:19-72)。
  • Gizmoduck 读取账号级原因时,先去掉“不执行”的部分:全部 DMCA,国家码为 xy 的法律请求和未注明原因,国家码为 xx/xy 的第三方举报(takedowns/gizmoduck/RedactUnenforcedTakedownsFilter.scala:64-81)。因此,账号级的版权下架不会波及该账号的所有帖子。
  • VF 怎样按国家使用这些原因,见 可见性过滤 的“国家下架与法律下架(takedown)”一节。

设计决策

决策 理由
规则放在 YAML 中,由动态配置下发 处置策略可以快速调整,不必发版
用户表以封禁兜底,帖子表以跳过兜底 推测:进入用户处置流的事件已经过上游模型和主题筛选;帖子事件只在标签明确时才处置
先检查名单、粉丝数、可信度分 减少对高影响力账号的自动误判
申诉保护期独立成服务,且只读 处置服务只需要“能不能做”的答案;写入走人工申诉流程
标签带 TTL,读取时过滤过期标签 自动化标签到期自然失效,不依赖清理任务
账号聚合规则有硬上限 防止配置错误导致大面积给账号打标签

源码锚点

  • abuse-enforcement-service/service-lib/src/rules.rs:287-332 —— 第一条为真的规则
  • abuse-enforcement-service/service-lib/src/decision.rs:1-24 —— 动作种类
  • abuse-enforcement-service/service-lib/rules/enforcement_user.yaml:5-189 —— 用户规则
  • abuse-enforcement-service/service-lib/rules/enforcement_post.yaml:3-82 —— 帖子规则
  • abuse-enforcement-service/service-lib/src/safety_checks.rs:158-175 —— 粉丝上限
  • abuse-enforcement-service/service-lib/src/overturn_hold.rs:150-162、:396-415 —— 申诉保护期门
  • abuse-ledger-service/src/sql.rs:3-7 —— 保护期查询
  • safety-label-source/source.rs:13-54 —— 本地缓存与过期过滤
  • safety-label-user-agg/postToUserLabelRules.strato:96-107、:360-428 —— 聚合规则上限与默认规则
  • takedowns/gizmoduck/RedactUnenforcedTakedownsFilter.scala:64-81 —— 不执行的账号级下架

相关页面

Type to search…

↑↓ navigate↵ selectEsc close