这一页回答什么
本页介绍 X For You 信息流的架构组成、组件连接方式以及单次推荐请求的完整阶段。本页是系统架构的总览入口,其他页面展开介绍各个子系统。
核心结论
- 系统包含两条路径。请求路径在用户打开 For You 时实时运行,负责候选召回、水合、过滤、打分、选择与混排。标签路径持续在后台运行,内容理解模型与规则引擎持续评估帖子和账号并写入安全标签(
README.md:99-185、:186-250)。 - 两条路径在可见性过滤阶段汇合。请求路径选出候选帖子后,
VFCandidateHydrator向可见性过滤服务查询每条候选帖子。可见性过滤服务读取标签路径写入的安全标签,返回展示、添加提示、添加遮罩或丢弃四种动作之一(home-mixer/candidate_hydrators/vf_candidate_hydrator.rs:53-130)。 - 排序与可见性逻辑解耦。排序阶段决定候选帖子的排列顺序。可见性过滤阶段决定候选帖子是否具备展示资格。两个阶段属于不同服务,使用不同输入,遵循不同规则(
README.md:492-494)。 - 请求路径采用两层嵌套流水线。外层
ForYouCandidatePipeline混排候选帖子、广告与功能模块。内层PhoenixCandidatePipeline负责候选帖子的召回、过滤、打分与选择(home-mixer/candidate_pipeline/for_you_candidate_pipeline.rs:219-234、phoenix_candidate_pipeline.rs:237-556)。 - 候选来自四类来源:Thunder(关注账号的近期帖)、Phoenix 召回、SimClusters 以及热门帖子列表(
README.md:83)。内层流水线共装配 9 个候选源,其中 3 个在开源配置中默认关闭(详见 home-mixer 编排层)。 - 系统采用单个排序模型搭配多个后处理组件。Phoenix 模型预测候选帖子在多种行为上的发生概率。
VMRanker将各行为概率加权计算为基础分,执行冷启动调整,随后调用 vm-ranker 服务完成重排(home-mixer/scorers/vm_ranker.rs:59-140)。 - 代码库参数默认值由定时脚本同步自线上主值(
README.md:432、home-mixer/params/param.rs:1)。本文档称之为“开源默认值”,线上实验组可能采用不同配置。
请求路径
flowchart TB
REQ([For You 请求]) --> QB["QueryBuilder<br/>用户数据 + feature switches"]
QB --> OQ["外层 Query 水合<br/>served history / 请求时间戳"]
OQ --> OS
subgraph OUTER["外层 ForYouCandidatePipeline"]
OS["7 个源:ScoredPosts / 广告 / Who to Follow<br/>Prompt / PushToHome / Frame / 问卷"]
BL["BlenderSelector<br/>帖子与广告混排,插入模块"]
OS --> BL
end
OS -. "ScoredPostsSource 调用" .-> IQ
subgraph INNER["内层 PhoenixCandidatePipeline"]
IQ["21 个 Query 水合器<br/>互动序列 / 关注 / 屏蔽 / Bloom"] --> SRC["9 个候选源"]
SRC --> HYD["15 个候选水合器"]
HYD --> PRE["21 个预打分过滤器"]
PRE --> SC["5 个打分器<br/>Phoenix / 沉浸视频 / VMRanker / 页级重排 ×2"]
SC --> TOP["TopKScoreSelector 取 50"]
TOP --> PH["10 个选后水合器<br/>含可见性查询"]
PH --> PF["5 个选后过滤器<br/>VF / 附属 VF / 会话去重"]
end
SRC -. 站内 .-> TH[(Thunder)]
SRC -. 站外 .-> PR["Phoenix 召回 / SimClusters / 热门帖子"]
SC -. 打分 .-> PX[Phoenix 排序]
SC -. 重排 .-> VM[vm-ranker]
PH -. 查询 .-> VF[visibility-filtering]
PF --> BL
BL --> SE["side effect<br/>写 served history / 缓存 / 日志"]
BL --> RESP([For You 信息流,至多 48 项])
各阶段组件数量以 Commit 2e2295b 的装配配置为准(phoenix_candidate_pipeline.rs:285-543、for_you_candidate_pipeline.rs:210-263)。历史版本曾装配 15 个 Query 水合器、6 个候选源、10 个候选水合器、14 个预打分过滤器、3 个打分器、6 个选后水合器与 3 个选后过滤器。
| 阶段 | 职责 | 详见 |
|---|---|---|
| 请求适配 | 校验用户身份,拉取用户数据,评估实验开关,构造查询对象 | home-mixer 编排层 |
| Query 水合 | 补全用户互动序列、关注列表、屏蔽列表与已读历史 | home-mixer 编排层 |
| 候选源 | 并发调用 Thunder、热门帖子列表、SimClusters 与 Phoenix 召回等源拉取候选 | home-mixer 编排层 |
| 候选水合 | 补全帖子正文、媒体元数据、作者信息、引用帖、语言与互动计数 | 端到端数据流 |
| 预打分过滤 | 剔除重复帖子、过期帖子、作者本人的帖子、屏蔽/静音账号帖子及已展示历史 | 过滤流水线 |
| 打分 | Phoenix 预测各行为概率,执行加权打分、冷启动调整与重排 | 打分与排序 |
| 选择 | 按打分结果截取前 50 条候选帖子 | 候选选择与成型 |
| 选后水合与过滤 | 查询可见性与品牌安全裁定,剔除不可见帖子与重复会话,截断至 35 条 | 过滤流水线 |
| 混排 | 插入广告、Who to Follow 推荐与 Prompt 模块 | 广告混排 |
| side effect | 推荐结果返回后,异步写入已展示历史、刷新缓存并上报日志 | candidate-pipeline 框架 |
标签路径
flowchart TB
subgraph CU["1 内容理解 · 持续运行,不在请求路径上"]
GX["grox<br/>文本与媒体分类器"]
MM["media-model-proxy<br/>图像与视频模型"]
CL["clip<br/>图文嵌入"]
AG["agatha<br/>屏蔽与举报相对点赞的比例"]
BD["bdsm<br/>不真实行为"]
UC["user-cred-v2<br/>关注与互动图上的 PageRank"]
end
subgraph LR["2 打标签规则"]
SCW["scarecrow + botmaker<br/>事件触发的规则"]
AES["abuse-enforcement-service<br/>按账号分数打标签、验证或封禁"]
AGG["safety-label-user-agg<br/>按帖子标签给账号打标签"]
end
CU --> LR
LR --> ST[("3 标签存储")]
ST --> VFS["4 visibility-filtering<br/>ALLOW / NOTICE / INTERSTITIAL / DROP"]
VFS --> PSF["5 选后过滤<br/>VFFilter / AncillaryVFFilter"]
PSF --> FEED([For You 信息流])
- 内容理解:帖子维度由 grox、media-model-proxy 与 clip 生成分类概率与嵌入向量;账号维度由 agatha、bdsm 与 user-cred-v2 计算账号信用分(
README.md:189-200)。 - 打标签规则:scarecrow 运行内嵌的 botmaker 规则引擎,在事件触发时执行条件规则并打上对应标签;abuse-enforcement-service 读取账号信用分,决定执行打标签、发起人机验证或封禁账号,申诉推翻的处置在冷却期内不再重复执行;safety-label-user-agg 根据账号下帖子累积的安全标签为账号本身打标签(
README.md:202-214)。 - 存储写入:系统将生成的标签持久化写入存储服务,供请求路径实时读取。
- 可见性过滤:可见性过滤服务针对“用户-帖子”对返回展示裁定。规则除读取安全标签外,还会校验用户关系(屏蔽、静音、关注状态)、账号状态(受保护、封禁、停用)、订阅状态、用户偏好设置与访问国家。部分安全规则仅对站外推荐生效(
README.md:220-237)。 - 选后过滤:home-mixer 剔除被判定为 DROP 的帖子;若帖子的祖先帖子、引用帖或转发原帖被判定为 DROP,系统同样剔除该帖子。被判定为添加提示(NOTICE)或添加遮罩(INTERSTITIAL)的帖子继续保留在信息流中,客户端负责具体渲染(
README.md:239-250)。
标签路径还在两处逻辑中接入请求路径:在选后水合阶段,AdsBrandSafetyVfHydrator 读取安全标签以计算品牌安全裁定(详见 广告混排);在召回索引构建阶段,phoenix-rankall-strato 在帖子写入召回索引前预先查询可见性过滤服务(README.md:290)。
组件一览
编排与框架
| 组件 | 语言 | 职责 | 详见 |
|---|---|---|---|
home-mixer/ |
Rust | For You 服务进程:负责流水线装配、参数解析与外部 gRPC 服务暴露 | home-mixer 编排层 |
candidate-pipeline/ |
Rust | 流水线框架:定义核心组件 trait 与阶段执行器 | candidate-pipeline 框架、CandidatePipeline trait |
候选来源
| 组件 | 语言 | 职责 | 详见 |
|---|---|---|---|
thunder/ |
Rust | 在内存中缓存近期帖子,检索并返回关注账号发布的帖子 | Thunder 站内帖子内存库、Thunder Kafka 摄入 |
phoenix/ 召回 |
Python / JAX + Rust | 将用户与帖子编码为向量,检索并返回与用户兴趣最相近的候选帖子 | Phoenix 召回 |
simclusters/ |
Scala | 基于用户互动行为将账号与帖子聚类为社区簇,利用社区簇发现候选帖子 | SimClusters |
home-mixer/sources/popular_posts_source.rs |
Rust | 维护全站共享的近期热门帖子列表 | home-mixer 编排层 |
召回索引
| 组件 | 语言 | 职责 | 详见 |
|---|---|---|---|
phoenix-rankall/ |
Rust | 维护供 Phoenix 召回查询的帖子索引,随事件流实时更新 | Phoenix RankAll 召回索引 |
phoenix-rankall-strato/ |
Strato | 索引事件处理层:在帖子写入召回索引前预先查询可见性过滤服务 | Phoenix RankAll 召回索引 |
排序
| 组件 | 语言 | 职责 | 详见 |
|---|---|---|---|
phoenix/ 排序 |
Python / JAX + Rust | 预测用户对每条候选帖子产生各类行为的概率,包含模型训练与合成数据生成逻辑 | Phoenix 排序模型、Phoenix 训练 |
xai-value-model/ |
Rust | 将各项行为预测概率按设定权重累加计算为综合得分 | 打分与排序 |
vm-ranker/ |
Rust | VMRanker 调用的重排服务:基于行列式点过程与向量相似度执行多样性重排 |
VM Ranker |
内容理解
| 组件 | 语言 | 职责 | 详见 |
|---|---|---|---|
grox/ |
Python | 帖子发布后异步运行:评估垃圾内容、成人、暴力等分类概率,提取文本与图像特征向量 | Grox 服务架构、Grox 内容分类器、多模态帖子嵌入器 |
media-model-proxy/ |
Scala | 图像与视频多媒体模型服务:检测成人内容、暴力血腥、仇恨符号、内容主题与已知媒体匹配 | 媒体模型 |
clip/ |
Python | 训练图文多模态嵌入模型,下游分类器复用其生成的媒体嵌入向量 | 媒体模型 |
adult-content/ |
Python | 训练与校准成人媒体分类模型 | 媒体模型 |
pnsfwmedia/ |
Python | 结合 CLIP 媒体嵌入向量与账号信用分识别成人媒体内容 | 媒体模型 |
agatha/ |
Scala | 离线批处理任务:统计账号被屏蔽、举报与被点赞的相对比例,为账号打上对应标签 | 账号信号 |
bdsm/ |
Python + Rust | 分析账号随时间推移的行为序列,识别虚假互动与滥用行为 | 账号信号 |
user-cred-v2/ |
Scala | 在关注图与互动网络上运行 PageRank 算法,计算账号可信度得分 | 账号信号 |
可见性过滤与标签
| 组件 | 语言 | 职责 | 详见 |
|---|---|---|---|
visibility-filtering/ |
Rust | 判定指定帖子能否展示给目标用户;业务规则注册于 rules/registry.rs |
可见性过滤 |
visibility-filtering-client/ |
Rust | 供调用方集成的客户端库,定义帖子安全标签数据类型 | 可见性过滤 |
safety-label-source/ |
Rust | 可见性过滤读取帖子安全标签的客户端库,提供本地缓存能力(safety-label-source/source.rs:62-75,README 组件表未列出) |
可见性过滤 |
takedowns/ |
Scala | 产出供可见性规则判断使用的内容下架原因列表 | 可见性过滤 |
scarecrow/ |
Scala | 监听事件流并执行打标签规则,底层规则引擎基于 botmaker 构建 | 标签规则 |
botmaker/ |
Java + Scala | 规则引擎系统:包含领域专用规则语言、编译器与执行运行时 | 标签规则 |
botmaker-rules/ |
规则文件 | scarecrow 运行时加载的业务规则集;为防止规则被对抗绕过,部分规则未在开源库中公开 | 标签规则 |
safety-label-user-agg/ |
Strato | 根据账号名下帖子累计的安全标签,汇总生成账号级标签 | 标签规则 |
abuse-enforcement-service/ |
Rust | 根据账号模型信用分执行打标签、要求人机验证或封禁账号 | 处置服务 |
abuse-ledger-service/ |
Rust | 记录并查询账号是否处于申诉生效后的处置冷却期 | 处置服务 |
under-the-hood/ |
Scala + Strato + TSX | 生成面向单个账号的标签透明度报告 | Under the Hood 透明度工具 |
语言列按目录内源文件扩展名统计,phoenix/ 的 Rust 部分属于推理服务层(README.md:300)。
流水线十阶段
无论内层还是外层流水线,执行顺序均由流水线框架中的 execute_stages() 统一编排(candidate-pipeline/candidate_pipeline.rs:126-179):
| # | 阶段 | 执行方式 |
|---|---|---|
| 1 | Query 水合 | 并行 |
| 2 | 依赖型 Query 水合 | 并行 |
| 3 | 候选源 | 并行 |
| 4 | 候选水合 | 并行 |
| 5 | 预打分过滤 | 顺序 |
| 6 | 打分 | 顺序 |
| 7 | 选择 | 单次 |
| 8 | 选后水合 | 并行 |
| 9 | 选后过滤 | 顺序 |
| 10 | side effect | 后台并行 |
框架并发执行无依赖任务以降低请求耗时;过滤与打分阶段依赖前置计算结果,因此采用顺序执行。详见 candidate-pipeline 框架。
外部依赖
内层流水线在 prod() 方法中并发初始化数十个客户端连接(phoenix_candidate_pipeline.rs:558-995):社交图服务、帖子实体服务、Gizmoduck 用户服务、可见性过滤服务、Strato、Redis、Kafka、用户行为聚合服务、互动计数服务、SimClusters ANN、SID 召回服务及 vm-ranker 服务。mock() 方法使用替身对象装配结构相同的测试流水线(phoenix_candidate_pipeline.rs:996-1110)。上述服务均为 X 内部基础设施,整套在线推荐服务无法脱离内部网络独立运行。Phoenix 属于例外情况:它附带训练代码、推理代码与合成数据生成器,支持端到端运行小模型示例(README.md:460),详见 run_pipeline。
设计决策
| 决策 | 理由 |
|---|---|
| 请求路径与标签路径分离 | 内容理解计算开销大,在后台异步完成;请求路径仅读取预存标签以降低耗时 |
| 排序与可见性分离 | 排序模型仅决定展示顺序,可见性过滤独立决定展示资格,两套逻辑独立演进与审计(README.md:492-494) |
| 外层混排与内层排序分层设计 | 帖子单品排序与多内容形态组装解耦,支持分别独立迭代 |
| 召回过滤初筛、排序模型精排 | 召回阶段以低计算成本将全网候选缩减至千级,精排阶段再使用高开销模型精细打分 |
| 统一流水线框架 | 框架集中实现阶段顺序、并发调度、错误控制与链路追踪,业务组件仅需关注单一职责 |
| 参数默认值同步线上主值 | 保证开源配置默认值贴近线上实际运行参数(README.md:432) |
常见问题
Q:外层流水线为什么没有打分器?
A:外层流水线的候选帖子由 ScoredPostsSource 提供,该数据源内部已执行完整的 PhoenixCandidatePipeline 排序流程。外层流水线仅负责将打分完毕的候选帖子与广告、推荐模块组装混排(for_you_candidate_pipeline.rs:336-354)。
Q:单条候选帖子的最终排序分如何计算?
A:Phoenix 模型预测用户产生各类互动行为的概率,打分器将各行为概率加权求和得出基础分。权重放大的是“当前请求用户发生该行为的预测概率”,而非帖子历史上已累积的互动计数(README.md:370)。详见 打分与排序。
Q:被打上安全标签的帖子是否一定会被删除?
A:不一定。可见性过滤服务依据规则将标签映射为四种动作之一,仅当裁定为 DROP 时才丢弃帖子。部分规则仅对站外推荐生效,同一条帖子仍可展示给作者的关注者(README.md:220-237)。详见 可见性过滤。
源码锚点
README.md:99-250—— 请求路径与标签路径candidate-pipeline/candidate_pipeline.rs:126-179—— 十阶段编排home-mixer/candidate_pipeline/for_you_candidate_pipeline.rs:189-273—— 外层流水线home-mixer/candidate_pipeline/phoenix_candidate_pipeline.rs:237-556—— 内层流水线home-mixer/candidate_hydrators/vf_candidate_hydrator.rs:53-130—— 两条路径的汇合点home-mixer/scorers/vm_ranker.rs:59-140—— 加权、冷启动与重排
相关页面
- For You 是怎么工作的 —— 本页的白话版
- 五大组件 —— 组件的白话介绍
- 端到端数据流 —— 一条帖子从发布到被推荐
- home-mixer 编排层 —— 服务、流水线与候选源
- candidate-pipeline 框架 —— 十阶段框架
- 过滤流水线 —— 两道过滤
- 打分与排序 —— 打分器链
- 候选选择与成型 —— 选择与成型
- 广告混排 —— 外层广告混排
- 可见性过滤 —— 标签路径的终点
- 标签规则 —— 标签路径的规则层
- 开源版与线上版的差异 —— 哪些东西不在仓库里