𝕏(推特)「为你推荐」信息流的完整链路:候选从哪来、Transformer 怎么打分、安全系统如何决定一条帖子能不能被看见 —— 基于 xai-org/x-algorithm 2026 年 8 月开源版本,按行业通用的「召回 → 粗排 → 精排 → 重排 → 混排」漏斗术语讲解。
先建立参照系。今天各家信息流产品 —— 抖音/TikTok、小红书、YouTube、Instagram Reels —— 的推荐系统,基本都收敛到同一套级联排序架构(cascade ranking):用一层比一层重的模型,把候选量级一级级压下来,让最贵的模型只算最少的帖子。下面这块面板把「量级」和「延迟」放在同一个状态里:上半是漏斗(每层看到多少条),下半是同一状态下的延迟瀑布(每步花多少毫秒)。我们的主角是一条叫 №4711 的帖子,它会在后面每张图里出现。
粗排存在的理由:让重模型只看到最少的帖子。总延时 = 最长的那根串行链。
各层职责一句话:召回负责「别漏」(高召回率,宁滥勿缺),粗排负责「省钱」(轻模型控制精排算力),精排负责「排准」(重模型逐条预估),重排负责「好看」(多样性与业务规则),混排负责「营收与生态」(广告与运营内容)。各家叫法略有差异:粗排也叫轻排 / L1,精排也叫 L2 / Heavy Ranker。
同一条漏斗的「系统视角」:用右上角的引导视图,按「候选漏斗 / 特征与历史 / 广告并行」逐条看。
面板下半就是延迟预算的分账。用户下拉刷新的忍耐上限决定了体感总延时:典型请求(P50)约 400ms,尾部(P99)可到 800ms;服务端排序预算按 P99 设,约 300ms。三个让账面 ≠ 体感的机制,都能在面板上亲手验证:
反过来读,这张分账表就是架构的成因:精排在关键路径上只分到约 100ms,所以必须单卡毫秒级(把精排模型切到 Transformer 再关掉粗排,看它怎么把预算撑破);召回只分到约 50ms,所以必须亚线性(双塔 + ANN)。带着这个参照系,下一讲看 𝕏 的实际实现 —— 它与范式的几处偏离,恰恰是最值得学的部分。
每次下拉刷新 For You,都由信息流服务 𝕏-Home Mixer(Rust)现场组装一条时间线。它构建在 candidate-pipeline 框架上,把工作拆成标准化的阶段 —— 来源、水合、过滤、打分、选择、副作用 —— 能并行的阶段并行执行。对照上一讲的经典漏斗,𝕏 的链路是 召回 → 精排 → 重排 → 混排,外加水合与两道过滤 —— 注意少了粗排,后面会解释为什么。先看全景,后面各讲逐段展开:
排序决定顺序,可见性决定能否展示 —— 两条线直到 ⑦ 才相遇。
home-mixer/params/param.rs,官方用 cron 脚本把仓库默认值同步为线上生产值。把讲义里的九个阶段落到真实服务上:上排是离线的打标签路径,下排是每次请求走的路;节点上的 SRC 标记直接链到 x-algorithm 的源码文件。
| 行业环节 | 英文 | 本系统对应 |
|---|---|---|
| 召回 | Candidate Retrieval | 𝕏-Thunder(关注内)· 𝕏-Phoenix 召回 · 𝕏-SimClusters(关注外) |
| 粗排 | Pre-ranking / Light Ranking | 没有独立粗排层 —— 召回已把量级压到数千,规则过滤到数百后精排直接吃下 |
| 精排 | (Heavy) Ranking | 𝕏-Phoenix 排序模型:pointwise 多目标互动预估 |
| 融合 | Score Fusion / Value Model | RankingScorer 加权求和 + 三项调整 |
| 重排 | Re-ranking | 𝕏-VMRanker:DPP 多样性重排;同作者打散 |
| 混排 | Blending | Blending Pipeline:广告、推荐关注等非帖子内容的插入 |
| 特征水合 | Feature Hydration | Query / Candidate Hydrators(①③ 两个阶段) |
| 内容安全 | Trust & Safety | visibility-filtering + 打标签链路(第 5 讲) |
唯一「对不上」的环节值得琢磨:多数大厂在召回和精排之间放一个轻量粗排模型,先把几千条筛到几百条再上重模型。𝕏 用「强召回 + 规则过滤」直接对接精排 —— 候选隔离让精排打分可缓存(第 6 讲),重模型吃几百条的成本可以接受,粗排层就省了。
记住一个贯穿全课的分工:排序决定顺序,可见性决定能否展示。第 ⑤ 步的模型只管「你有多可能喜欢它」;第 ⑦ 步引用的是另一套完全独立的内容安全系统(第 5 讲),两者输入不同、规则不同、服务也不同。
三条召回通道(retrieval channels)并行取货:
两个值得停下来品的细节:
use_user_embedding=False)。系统几乎完全用「你最近互动过什么」来表示你 —— 你的兴趣画像每天都在被你自己的行为改写,而不是固化在一个学出来的 ID 嵌入里。进入精排(ranking)的每条帖子,由 𝕏-Phoenix 排序模型(一个 Transformer,读你的行为序列作上下文)做多目标互动预估(multi-task engagement prediction),逐条(pointwise)输出约二十种行为各自的概率:点赞、回复、转发、引用、分享、各类点击、停留时长、关注作者,以及负反馈(negative feedback)类的「不感兴趣」、静音、拉黑、举报。然后 RankingScorer 用一行融合公式(score fusion / value model)合成最终分:
最终分 = Σ ( 权重i × P(行为i) )
下面是仓库 2026-08 快照里 param.rs 的部分真实默认权重(线上以配置系统为准,官方用 cron 把生产值回写到仓库):
| 行为 | 权重 | 行为 | 权重 |
|---|---|---|---|
| 回复 | +5.0 | 举报 | −234.0 |
| 引用 | +5.0 | 静音作者 | −58.8 |
| 关注作者 | +4.0 | 不感兴趣 | −43.2 |
| 分享 | +2.0 | 拉黑作者 | −31.2 |
| 转发 | +1.0 | 无停留 | −0.02 |
| 点赞 | +0.5 | 停留时长(连续值) | +0.004 |
| 点击 | +0.4 | 停留(二值) | +0.05 |
常见误读权重乘的是你自己的预测概率,不是原始互动数。看到举报权重是点赞的 468 倍,就推出「1 个举报抵消 468 个赞」是错的 —— 举报本来就是比点赞罕见得多的行为,概率基线低几个数量级,大权重只是让这个稀有信号有机会影响排序。README 和代码注释都专门澄清了这一点。
权重是价格,不是选票:一次稀有的举报,能压过一堆便宜的点赞。
融合之后还有三个业务调整,再进入重排(re-ranking):
模型说「你会喜欢」,不代表就能给你看。这部分对应行业里的内容安全 / 信任与安全(Trust & Safety)体系:一条帖子能否展示,由可见性过滤服务 visibility-filtering 独立裁决,依据是一整条持续运行的打标签链路 —— 内容理解(content understanding)模型给帖子和账号打分,规则引擎写入安全标签(safety labels);它不在请求路径上,请求来时只做读取:
visibility-filtering/rules/registry.rs。排队员排顺序,门卫查名单:拨动「关注」,裁决翻转,队伍顺序纹丝不动。
registry.rs 的规则顺序查名单。「仅对推荐生效」的规则只在观看者未关注作者时才会 drop;成人媒体标签给出 INTERSTITIAL,与是否关注无关。一个精细的设计:有一组规则只对「推荐」生效 —— 仅当帖子来自你未关注的账号时才可能 drop(比如高召回率抓到的疑似垃圾内容),同一条帖子对关注者照常展示。系统宁可少推荐,也不轻易在粉丝面前隐藏内容。
配套的透明度工具「Under the Hood」让每个人查看自己账号和帖子上影响可见性的标签统计 —— 部分规则文件(如 𝕏-Grox 的提示词、部分 𝕏-Botmaker 规则)为防对抗没有开源,官方以「代码 + 可查询的结果」组合来补足透明度。
candidate-pipeline 把阶段类型标准化,执行与监控和业务逻辑分离,加一路召回通道或一个过滤器都是插件式的。这次开源和 2023 年那次的最大区别:𝕏-Phoenix 目录里是真实的生产训练与推理代码(JAX 训练 + Rust gRPC 推理引擎),配了确定性的合成数据生成器和单卡 nano 配置(home_direct_packed_nano 精排、xrecsys_two_tower_nano 召回),几分钟就能在一张 GPU 上端到端跑通:训练 → 出 checkpoint → 用生产同款引擎对外服务。入口见 phoenix/QUICKSTART.md 与 phoenix/TRAINING.md。
The full path of 𝕏 (Twitter)'s For You feed: where candidates come from, how a Transformer scores them, and how a separate safety system decides whether a post can be shown at all — based on the August 2026 open-source release of xai-org/x-algorithm, told in the industry's standard Retrieval → Pre-ranking → Ranking → Re-ranking → Blending vocabulary.
First, a frame of reference. Today's feed products — TikTok/Douyin, Xiaohongshu, YouTube, Instagram Reels — have converged on the same cascade ranking architecture: a chain of progressively heavier models, each cutting the candidate count by an order of magnitude or two, so the most expensive model only ever sees the fewest posts (Chinese shorthand for the layers: 召回 / 粗排 / 精排 / 重排 / 混排). The panel below keeps "how many" and "how long" in one state: the top half is the funnel (what each layer sees), the bottom half is the latency waterfall of that same state (what each step costs). Our protagonist is a post called №4711; it appears in every figure from here on.
Pre-ranking is what makes the heavy ranker affordable. Total latency is the longest serial chain.
Each layer in one line: retrieval must not miss (high recall — err on the side of too many), pre-ranking saves money (a light model protects the heavy model's compute), ranking gets the order right (heavy model, per-item prediction), re-ranking makes it pleasant (diversity and business rules), and blending pays the bills and feeds the ecosystem (ads and editorial content). Names vary by company: pre-ranking is also called light ranking / L1, ranking is L2 / the heavy ranker.
The same funnel as a system map: use the guided views top-right to walk the candidate funnel, the feature path and the parallel ads auction one at a time.
The bottom half of the panel is the latency budget, itemised. A user's patience on pull-to-refresh caps perceived end-to-end latency: a typical request (P50) lands around 400 ms, the tail (P99) can reach 800 ms; the server-side ranking budget is set at P99, about 300 ms. Three reasons the ledger differs from what users feel — each can be verified by hand on the panel:
Read backwards, this ledger is the architecture's cause: ranking gets about 100 ms on the critical path, so it must run in milliseconds on one GPU (set the model to Transformer, then switch pre-ranking off, and watch it break the budget); retrieval gets about 50 ms, so it must be sublinear (two-tower + ANN). With this frame in hand, the next lecture looks at 𝕏's real implementation — the places where it departs from the paradigm are the most instructive parts.
Every pull-to-refresh of For You is assembled on the spot by the feed service 𝕏-Home Mixer (Rust). It is built on the candidate-pipeline framework, which splits the work into standardized stages — sources, hydrators, filters, scorers, selectors, side effects — and runs independent stages in parallel. Against the cascade from Lecture 1, 𝕏's path is Retrieval → Ranking → Re-ranking → Blending, plus hydration and two rounds of filtering — note the missing pre-ranking layer; we'll come back to why. The big picture first; later lectures expand each segment:
Ranking decides the order; visibility decides who gets in at all — the two lines only meet at ⑦.
home-mixer/params/param.rs, and a cron job syncs the repository defaults to production values.The nine stages of the lecture landed on real services: the labeling path on top runs offline, the request path below runs per request; the SRC badges on each node open the x-algorithm source files.
| Industry stage | 中文 | In this system |
|---|---|---|
| Retrieval | 召回 | 𝕏-Thunder (in-network) · 𝕏-Phoenix retrieval · 𝕏-SimClusters (out-of-network) |
| Pre-ranking | 粗排 | No separate pre-ranking layer — retrieval already brings the count to thousands; rule filters take it to hundreds and ranking consumes them directly |
| Ranking | 精排 | 𝕏-Phoenix ranking model: pointwise multi-task engagement prediction |
| Fusion | 融合 | RankingScorer weighted sum + three adjustments |
| Re-ranking | 重排 | 𝕏-VMRanker: DPP diversity re-ranking; author scatter |
| Blending | 混排 | Blending pipeline: inserting ads, Who to Follow and other non-post items |
| Feature hydration | 特征水合 | Query / candidate hydrators (stages ① and ③) |
| Trust & Safety | 内容安全 | visibility-filtering + the labeling path (Lecture 5) |
The one stage that doesn't line up deserves a pause: most large platforms put a light pre-ranking model between retrieval and ranking to cut thousands down to hundreds before the heavy model runs. 𝕏 wires strong retrieval plus rule-based filtering straight into ranking — candidate isolation makes ranking scores cacheable (Lecture 6), the heavy model can afford a few hundred posts, and the pre-ranking layer is simply skipped.
One division of labour runs through the whole course: ranking decides the order; visibility decides whether a post can be shown at all. The model in stage ⑤ only answers "how likely are you to like this"; stage ⑦ consults an entirely separate Trust & Safety system (Lecture 5) with different inputs, different rules and different services.
Three retrieval channels fetch in parallel:
Two details worth savouring:
use_user_embedding=False). The system represents you almost entirely by what you engaged with recently — your interest profile is rewritten daily by your own behaviour, not frozen into a learned ID embedding.Each post entering ranking(精排) is scored by the 𝕏-Phoenix ranking model — a Transformer that reads your action sequence as context — with multi-task engagement prediction, pointwise, producing probabilities for roughly twenty actions: like, reply, repost, quote, share, various clicks, dwell time, follow author, plus negative-feedback actions — not interested, mute, block, report. RankingScorer then combines them with a one-line fusion formula (score fusion / value model):
Final score = Σ ( weighti × P(actioni) )
Some real default weights from param.rs in the 2026-08 snapshot (production reads them from a config system; a cron job writes production values back into the repository):
| Action | Weight | Action | Weight |
|---|---|---|---|
| Reply | +5.0 | Report | −234.0 |
| Quote | +5.0 | Mute author | −58.8 |
| Follow author | +4.0 | Not interested | −43.2 |
| Share | +2.0 | Block author | −31.2 |
| Repost | +1.0 | Not dwelled | −0.02 |
| Like | +0.5 | Dwell time (continuous) | +0.004 |
| Click | +0.4 | Dwell (binary) | +0.05 |
Common misreadingWeights multiply your own predicted probabilities, not raw engagement counts. Seeing that report's weight is 468× like's and concluding "one report cancels 468 likes" is wrong — reporting is a far rarer action than liking, its probability baseline is orders of magnitude lower, and the large weight simply lets that rare signal move the ranking at all. Both the README and the code comments spell this out.
Drag the sliders to set the model's predicted probability of each action for you on this post, and watch the final score move. Weights are the real defaults from param.rs.
Weights are prices, not votes: one rare report can outweigh a pile of cheap likes.
After fusion come three business adjustments, then re-ranking:
The model saying "you'd like this" doesn't mean you get to see it. This is the industry's Trust & Safety layer: whether a post can be shown is decided independently by the visibility-filtering service visibility-filtering, based on a continuously running labeling path — content-understanding models score posts and accounts, and a rule engine writes safety labels. None of it runs on the request path, which only reads:
visibility-filtering/rules/registry.rs.The queue sets the order, the bouncer checks the list: flip "follows", the verdict flips, the queue does not move.
registry.rs. The "recommendations only" rules drop a post only when the viewer does not follow the author; the adult-media label yields INTERSTITIAL regardless of following.A subtle design: one set of rules applies only to recommendations — a post can be dropped only when it comes from an account you don't follow (e.g. suspected spam caught at high recall); the same post is shown to followers as usual. The system would rather recommend less than hide content from a creator's own followers.
A companion transparency tool, Under the Hood, lets anyone see aggregate statistics of the visibility-affecting labels on their account and posts. Some rule files (𝕏-Grox's prompts, some 𝕏-Botmaker rules) are withheld to resist gaming; the stated position is that code plus queryable outcomes together make up the transparency.
candidate-pipeline standardizes stage types and separates execution and monitoring from business logic; adding a retrieval channel or a filter is a plug-in.The biggest difference from the 2023 open-sourcing: the 𝕏-Phoenix directory holds the real production training and serving code (JAX training plus a Rust gRPC serving engine), with deterministic synthetic-data generators and single-GPU nano configs (home_direct_packed_nano for ranking, xrecsys_two_tower_nano for retrieval). In minutes on one GPU you can run it end to end: train → checkpoint → serve with the same engine production uses. Start at phoenix/QUICKSTART.md and phoenix/TRAINING.md.