
X 算法拆解证据总表
本篇汇整 X 推荐算法开源项目的 58 项机器命题验证数据与源代码路径,逐行解析行为权重、过滤器管线与可见度规则。适合需要精确源代码依据、验证脚本与技术规格的工程师与研究人员参考。
xai-org / x-algorithm · HEAD a389166
每一条主张都附源代码位置与复现指令。所有数字由脚本实跑产生,非人工转录。
仓库 xai-org/x-algorithm(2026-08-13 更新) HEAD a389166f6cf5da70a286b568c87695d4dcdce3a1 规模 2,015 档 / 21 MB / 5 commits 判读 2026-08-14 验证 58 条机器命题,58 PASS / 0 FAIL 自验 注入错误期望值 → 正确产生 1 FAIL(闸门有效)
① 机器命题验证表
下表 58 条全部由 verify-all.sh 实跑产生,本页数值直接由该脚本输出转成表格, 没有经过人工抄写。脚本本体见附录。

| 项目 | 数值 | 说明 |
|---|---|---|
| PASS | 58 | — |
| FAIL | 0 | — |
| should-FAIL 反例验(注入错值必须被抓到) | 1 | — |
| 编号 | 命题 | 实测值 | 结果 |
|---|---|---|---|
| C01 | HEAD | a389166f6cf5da70a286b568c87695d4dcdce3a1 | PASS |
| C02 | param!区块数 | 183 | PASS |
| C03 | 文件总数 | 2015 | PASS |
| C04 | FavoriteWeight | 0.5 | PASS |
| C05 | ReplyWeight | 5.0 | PASS |
| C06 | RetweetWeight | 1.0 | PASS |
| C07 | ShareViaCopyLinkWeight | 20.0 | PASS |
| C08 | ReportWeight | -234.0 | PASS |
| C09 | MuteAuthorWeight | -58.8 | PASS |
| C10 | BlockAuthorWeight | -31.2 | PASS |
| C11 | NotInterestedWeight | -43.2 | PASS |
| C12 | NEW_USER_OON_WEIGHT_FACTOR | 0.00001 | PASS |
| C13 | NEW_USER_MIN_FOLLOWING | 5 | PASS |
| C14 | NEGATIVE_SCORES_OFFSET | 0.001 | PASS |
| C15 | MAX_POST_AGE(秒) | 172800 | PASS |
| C16 | NewUserAgeThresholdSecs缺省 | 0 | PASS |
| C17 | AuthorDiversityDecay | 0.5 | PASS |
| C18 | AuthorDiversityFloor | 0.25 | PASS |
| C19 | OonWeightFactor | 0.75 | PASS |
| C20 | 前置过滤器数 | 17 | PASS |
| C21 | 后置过滤器数 | 3 | PASS |
| C22 | filters档数(不含mod) | 27 | PASS |
| C23 | mod.rs声明数 | 26 | PASS |
| C24 | 未声明的filter | popular_topics_author_dedup_filter | PASS |
| C25 | 基本可见度规则数 | 28 | PASS |
| C26 | OON加码规则数 | 26 | PASS |
| C27 | 排序器取用预测头数(scores.* 去掉方法调用 .clone) | 26 | PASS |
| C28 | MinVideoDurationMs | 10_000 | PASS |
| C29 | EnableQuotedVqvDurationCheck | false | PASS |
| C30 | EnableInventoryHoldout | false | PASS |
| C31 | VMRankerSendHeadWeights | false | PASS |
| C32 | Rust侧bridge命中 | 0 | PASS |
| C33 | phoenix [:,:,4] 命中 | 0 | PASS |
| C34 | phoenix [:,:,2] 命中 | 0 | PASS |
| C35 | phoenix [:,:,3] 命中 | 0 | PASS |
| C36 | Rust用ContinuousActionName次数 | 2 | PASS |
| C37 | Rust 引用 DwellTime 的处数 | 2 | PASS |
| C38 | BRIDGE_PROBABILITY枚举值 | 4 | PASS |
| C39 | bridge开关设True次数 | 0 | PASS |
| C40 | 有损失的连续头种类数 | 1 | PASS |
| C41 | NUM_CONTINUOUS(参考实现) | 8 | PASS |
| C42 | DWELL_INDEX(参考实现) | 1 | PASS |
| C43 | history_seq_len | 1022 | PASS |
| C44 | num_layers | 8 | PASS |
| C45 | emb_size | 2560 | PASS |
| C46 | ActionName枚举项数 | 204 | PASS |
| C47 | PLACE_HOLDER占位数 | 8 | PASS |
| C48 | 两份proto是否相同 | same | PASS |
| C49 | ProfileClickWeight | 0.0 | PASS |
| C50 | DwellWeight | 0.0 | PASS |
| C51 | QuotedVqvWeight | 0.0 | PASS |
| C52 | ContClickDwellTimeWeight | 0.0 | PASS |
| C53 | ContActiveSecs5mResidualNormWeight | 0.0 | PASS |
| C54 | BidirectionalFollowDwellWeightBoost | 0.0 | PASS |
| C55 | BidirectionalFollowReplyWeightBoost | 15.0 | PASS |
| C56 | ContDwellTimeWeight | 0.004 | PASS |
| C57 | NotDwelledWeight | -0.02 | PASS |
| C58 | 名称含Weight的参数数 | 33 | PASS |
② 权重总表
来源 home-mixer/params/param.rs。逐块解析全档 183 个 param! 后筛出名称含 Weight 者共 33 个。其中 30 个是数值权重,全部列在下面三张表;另外三个不是单一数值,另外两个分列他处(DwellRegretGateWeights 见本节末、VMRankerSendHeadWeights 见第 ④ 节的开关表),另一个 PostUnexploredWeightInNetworkOnly 是布尔开关(param.rs:369-374,默认 true,限定探索加分只作用在关注内的帖子),不是权重值,故不列入权重表。数值为代码内置默认值,在线可由 feature switch 覆写。
抽取陷阱(我第一版就中了):这个文件同时存在多行与单行两种 param! 写法。 只扫多行会静默漏掉 13 个——而真正的评分权重全部在那 13 个里面。 实计 170 ≠ grep -c '^param!(' 的 183 才抓到。附录的解析器两种都处理。

正权重(表列 19 项=17 个正权重+2 个 OON 折扣系数)
| 行号 | 参数 | 默认值 | 对应动作 |
|---|---|---|---|
| L325 | ShareViaCopyLinkWeight | 20.0 | 拷贝链接分享 |
| L284 | BidirectionalFollowReplyWeightBoost | +15.0 | 互相追踪时的回复加成 |
| L283 | ReplyWeight | 5.0 | 回复 |
| L319 | ShareViaDmWeight | 5.0 | 私讯分享 |
| L332 | QuoteWeight | 5.0 | 引用转推 |
| L345 | FollowAuthorWeight | 4.0 | 追踪作者 |
| L318 | ShareWeight | 2.0 | 一般分享 |
| L296 | RetweetWeight | 1.0 | 转推 |
| L246 | OonWeightFactor | 0.75 | 未追踪内容折扣系数 |
| L282 | FavoriteWeight | 0.5 | 按赞 |
| L266 | TopicOonWeightFactor | 0.5 | 主题模式的未追踪折扣 |
| L309 | ClickWeight | 0.4 | 点进帖子 |
| L310 | OpenLinkWeight | 0.2 | 点外部链接 |
| L297 | PhotoExpandWeight | 0.05 | 放大图片 |
| L303 | VideoOpenWeight | 0.05 | 开视频 |
| L317 | VqvWeight | 0.05 | 视频有效观看 |
| L333 | QuotedClickWeight | 0.05 | 点进被引用的原帖子 |
| L351 | PostUnexploredWeight | 0.02 | 探索性内容加分 |
| L375 | ContDwellTimeWeight | 0.004 | 停留秒数(每秒) |
负权重(5 个)
| 行号 | 参数 | 默认值 | 相当于几次按赞 |
|---|---|---|---|
| L442 | ReportWeight | −234.0 | 468 |
| L436 | MuteAuthorWeight | −58.8 | 117.6 |
| L424 | NotInterestedWeight | −43.2 | 86.4 |
| L430 | BlockAuthorWeight | −31.2 | 62.4 |
| L443 | NotDwelledWeight | −0.02 | 0.04 |
| 项目 | 数值 | 说明 |
|---|---|---|
| 正权重合计(16 项,不含两个 OON 折扣系数与互关回复加成 +15.0) | +43.324 | — |
| 负权重合计(5 项) | −367.22 | — |
| 负/正倍数 | 8.48× | — |
这个 8.48 倍怎么读才不会读歪: 比的是权重定价,不是最终分数。进公式的是「权重 × 模型预测概率」, 而检举、封锁的预测概率极小、按赞的概率高得多,所以单则帖子的负面项实际贡献不会是正面的 8.48 倍。 那些概率是模型跑出来的,开源码里没有,无法计算。 成立的说法是:X 对负面信号的定价,比正面信号贵一个数量级。
零权重(6 个)
| 行号 | 参数 | 默认值 | 性质(详见 ⑦) |
|---|---|---|---|
| L311 | ProfileClickWeight | 0.0 | 模型有训练,只是定价 0 |
| L331 | DwellWeight | 0.0 | 模型有训练,只是定价 0 |
| L339 | QuotedVqvWeight | 0.0 | 模型有训练,另有长度闸门 |
| L381 | ContClickDwellTimeWeight | 0.0 | 无训练损失=schema 留白 |
| L417 | ContActiveSecs5mResidualNormWeight | 0.0 | 无训练损失=schema 留白 |
| L290 | BidirectionalFollowDwellWeightBoost | 0.0 | 有守卫有测试的正式关闭开关 |
第 33 个:一条 19 维的逻辑回归
DwellRegretGateWeights(param.rs:534)不是单一数值,是 19 个系数的字符串, 输入是你的帐号历史(交互串行长度、按赞数、回复数、负面回馈数、7 日/1 日活跃、 粉丝数、追踪数、帐龄…),输出是「你会不会后悔看了这则」的概率。摘录:
seq_len:0.530298 n_reply:0.485541 n_click:-0.176675
n_fav:-0.082139 n_1d:-0.241730 account_age_years:-0.045455
n_profile_follow:-0.221285 n_negfb:0.031839③ 评分公式逐行
單項 = 模型預測機率 × 該動作權重 ranking_scorer.rs:416-418
fn apply(score: Option<f64>, weight: f64) -> f64 {
score.unwrap_or(0.0) * weight
}
26 個單項組成陣列 ranking_scorer.rs:470-510
拆成正負兩堆 ranking_scorer.rs:513-521
for t in terms { if t >= 0.0 { pos += t } else { neg -= t } }
combined = pos − neg ranking_scorer.rs:427
最後位移 ranking_scorer.rs:524-532
if total_sum == 0.0 → max(combined, 0)
else if combined < 0.0 → (combined + negative_sum) / total_sum × 0.001
else → combined + 0.001
NEGATIVE_SCORES_OFFSET = 0.001 params/config.rs:40
negative_sum = −(not_interested+block+mute+report+not_dwelled) :127
total_sum = positive_sum + negative_sum :128这段 offset 的实际效果:所有算出来是负分的帖子,被压缩到 0 ~ 0.001 这个极窄区间。 负分帖子之间的排序差异几乎归零,全部沉到最底下挤成一团。 不是「排后面一点」,是「掉出可见范围」。
两个条件加成
| 机制 | 行为 | 位置 |
|---|---|---|
| 双向追踪回复加成 | 互相追踪时,回复权重 5.0 → 20.0(5.0+15.0) | ranking_scorer.rs:186-193 |
| 双向追踪停留加成 | 同机制,缺省 0.0(等于关闭) | ranking_scorer.rs:215-222 |

④ 三段调整
| 调整 | 算式与系数 | 位置 |
|---|---|---|
| 同作者衰减 | (1 − 0.25) × 0.5^k + 0.25,k=这位作者在同一批结果中前面已出现几则(`author_counts` 取值,0 起算)。 第 1 则 ×1.0、第 2 则 ×0.625、第 3 则 ×0.4375…楼地板 0.25 | ranking_scorer.rs:614-616 param.rs:229-238 |
| 未追踪折扣 | 没追踪的作者 ×0.75;带主题时更重 ×0.5 | ranking_scorer.rs:681-698 |
| 新用户模式 | 符合条件的新帐号,未追踪内容 ×0.00001 条件:帐龄 < NewUserAgeThresholdSecs 且 追踪数 ≥ 5 | ranking_scorer.rs:688-698 config.rs:38-39 |
不要把 0.00001 写成耸动结论:NewUserAgeThresholdSecs 的默认值是 0 (param.rs:273)。帐龄不可能小于 0 秒,所以这个机制缺省不生效。 正确说法是:开关存在、力道极端、目前关着。

三个「盖好了但关着」的开关
| 开关 | 缺省 | 打开会怎样 |
|---|---|---|
| NewUserAgeThresholdSecs | 0 秒 | 新帐号的未追踪内容 ×0.00001,等于只剩同温层 |
| EnableInventoryHoldout | false | 依 (帖子 ID × 用户 ID) 哈希,稳定扣住指定百分比的原创/回复/转推。三个比例缺省皆 0 |
| VMRankerSendHeadWeights | false | 把权重表送给 vm-ranker 重排服务;目前只送预测分数不送权重 |
⑤ 20 道过滤器
来源 home-mixer/candidate_pipeline/phoenix_candidate_pipeline.rs L344–362(前置 17 道)与 L417–421(后置 3 道)。全部无条件注册,没有任何条件式开关。

| # | 行号 | 过滤器 | 砍掉什么 |
|---|---|---|---|
| 1 | L345 | DropDuplicatesFilter | 不同来源捞到的同一则 |
| 2 | L346 | CoreDataHydrationFilter | 内文与中继数据加载失败 |
| 3 | L347 | AgeFilter | 超过 48 小时(MAX_POST_AGE = 172800 秒) |
| 4 | L348 | SelfTweetFilter | 你自己发的 |
| 5 | L349 | OONRetweetReplyFilter | 未追踪帐号的转推与回复 |
| 6 | L350 | OONNsfwSimclustersFilter | SimClusters 捞到、作者被标成人内容、且你没追踪 |
| 7 | L351 | RetweetDeduplicationFilter | 同一则被重复转推 |
| 8 | L352 | IneligibleSubscriptionFilter | 没订阅所以看不到的付费内容 |
| 9 | L353 | PreviouslySeenPostsFilter | 已经看过的 |
| 10 | L354 | PreviouslySeenPostsBackupFilter | 同上,第二份曝光纪录再挡一次 |
| 11 | L355 | PreviouslyServedPostsFilter | 本次工作阶段已送出过的 |
| 12 | L356 | MutedKeywordFilter | 命中你的静音关键字 |
| 13 | L357 | AuthorSocialgraphFilter | 你封锁或静音的帐号 |
| 14 | L358 | VideoFilter | 请求排除视频时挡视频 |
| 15 | L359 | TopicIdsFilter | 不在指定主题/在排除主题内 |
| 16 | L360 | NewUserMinEngagementFilter | 新帐号的未追踪内容交互数不够 |
| 17 | L361 | InventoryHoldoutFilter | 哈希决定性地扣住一定比例(缺省 0%) |
| 18 | L418 | VFFilter | 可见度系统回答 drop 的 |
| 19 | L419 | AncillaryVFFilter | 父/引用/转推来源被 drop 的 |
| 20 | L420 | DedupConversationFilter | 同一串对话的其他分支 |
对帐结果:README 宣称的 17+3 道与顺序,与代码逐条完全吻合,零位移。这一项 X 没有美化。
⑥ 54 条可见度规则
来源 visibility-filtering/rules/registry.rs(912 行)。第一条回答 drop 者为准,后面不再评估。

| 项目 | 数值 | 说明 |
|---|---|---|
| 人人适用 base_home_rules() L101–132 | 28 | — |
| 未追踪内容加码 oon_drops L138–170 | 26 | — |
| 未追踪内容要通过的总数 | 54 | — |
基本 28 条依序:作者状态 4 条(停权/停用/抹除/离站)→ 保护帐号 → 你封锁 → 你静音 → 静音转推 → 内容标签 8 条(PDNA、退件、垃圾消息、紧急、仇恨言论、暴力言论、滥用、公民诚信)→ 未广播 → 过期 → 法律下架 2 条 → 敏感内容对注销/未成年/未填年龄 3 条 → 专属内容 → 最后 4 条是插页警示而非直接砍掉。
未追踪多背的 26 条全部只能 drop:DMCA 媒体、地区限制媒体、成人内容 4 种判定、 高召回率的成人与垃圾消息侦测(宁可错杀)、恶意网址、「不要放大」标签等。
⑦ 6 个归零权重的三种性质
分辨方式:看模型有没有被训练去预测这个动作。有训练、只是定价 0 =真杠杆; 连训练损失都没设 =只是留白。
共通机制:没有任何「权重是 0 就跳过」的守卫(唯一例外是 BidirectionalFollowDwellWeightBoost,见下)。 算式一律 概率 × 权重,0 权重照样计算、照样进 26 项数组,结果恒为 0。 模型仍花算力预测它、管线仍传递它,只是最后乘以零。
第 1 类:模型有训练,只是定价 0 —— 真杠杆
| 参数 | 对应预测头 | 打开的效果 |
|---|---|---|
| ProfileClickWeight | CLIENT_TWEET_CLICK_PROFILE = 30 | 「点作者头像」开始计分。已进 positive_sum(:112),调高会同时放大分子与分母 |
| DwellWeight | CLIENT_TWEET_RECAP_DWELLED = 11 | 「有没有停留」开始计分。现况是「秒数算钱、有没有停留不算钱」 |
| QuotedVqvWeight | CLIENT_QUOTED_TWEET_VIDEO_QUALITY_VIEW = 48 | 被引用帖子的视频有效观看开始计分,但另有长度闸门 |
QuotedVqv 的双保险:util/candidates_util.rs:42-60 有一个同名函数quoted_vqv_weight(),它是把权重归零的闸:若 EnableQuotedVqvDurationCheck 打开(缺省 false),被引用视频必须 > 10,000 毫秒,否则权重直接改写成 0.0。
第 2 类:连训练损失都没设 —— 只是留白
整个 phoenix/ 训练设置里,只有 DWELL_TIME 一个连续头配了损失函数 (recsys_model.py:473-479 与 xrecsys.py:566-585, 画廊版面用 tweedie、其余用 mae)。
| 参数 | 连续头 | 实情 |
|---|---|---|
| ContClickDwellTimeWeight | CLICK_DWELL_TIME = 2 | 无训练损失。但低按赞率惩罚机制已盖好(baseline 0.01/alpha 0.5/floor 0.01/cap 1.0, ranking_scorer.rs:195-213)挂在一个权重 0 的项目上 |
| ContActiveSecs5mResidualNormWeight | ACTIVE_SECS_5M_RESIDUAL_NORM = 3 | 无训练损失。衡量「你有没有因为这则帖子而多留在 App 里」 |
这两个还有结构性问题:分子分母不对称。positive_sum(:104-122)不包含这两个连续项,但它们会进分子的 26 项加总。 而 total_sum 正是负分压缩公式的分母(:524-532)。 一旦调上去,分子变大、分母不变,负分帖子的压缩比例会失真。权重为 0 时看不出来,一调就浮现。
第 3 类:有守卫、有专属测试的正式关闭开关
BidirectionalFollowDwellWeightBoost 是唯一有 != 0.0 短路守卫的 (ranking_scorer.rs:216-221)。测试码里有一个专门验证「设 0 时必须毫无作用」的测试 bidirectional_weight_zero_boost_is_noop(L1288 起), 另一个测试把它设成 2.0 验证加成生效(L1250-1253)。 它的双胞胎兄弟(回复版加成)是开着的,值 15.0。
从 204 到 21
| 层级 | 数量 |
|---|---|
| 动作枚举表登记的动作(含 8 个占位符) | 204 |
| 模型输出头预算 ACTION_TYPE_MAP_LEN(补齐到 64) | 60 |
| 连续头槽位(5 个真值补齐到 8) | 8 |
| 连续头实际有训练损失的 | 1 |
| For You 排序器实际取用的预测头 | 26 |
| 权重非 0、真正左右排序的 | 21 |

⑧ BRIDGE_PROBABILITY 专卷
全 repo 不分大小写 grep -rin bridg 共 25 命中。先剔除三类同名杂讯。
| 命中 | 位置 | 其实是什么 |
|---|---|---|
| AdActionInfo.bridgeType AdActionInfo.isTwclidBridged | recsys.proto:1306-1307 | 广告转换归因。twclid=Twitter Click ID。与推荐算法的 bridging 无关 |
| _bridge_ads_s3_env() | retrieval_dataset.py:33,50 | 设置 S3 环境变量 |
| smyte_bridge | botmaker/scarecrow_features/ | Smyte(Twitter 2018 并购的反滥用公司)事件集成层 |
schema 里有位置
enum ContinuousActionName { recsys.proto:437-443
INVALID_CONTINUOUS_ACTION_NAME = 0;
DWELL_TIME = 1; → Rust 權重 0.004(開著)
CLICK_DWELL_TIME = 2; → Rust 權重 0.0(關著)
ACTIVE_SECS_5M_RESIDUAL_NORM = 3; → Rust 權重 0.0(關著)
BRIDGE_PROBABILITY = 4; → Rust 連參數都沒有
}全 repo .rs 档 grep bridge = 0 命中。排序公式里没有它的项次, 连一个乘以零的位置都没留。
两条接线,都是输入、都关着
| 路径 | 开关(缺省) | 做什么 |
|---|---|---|
| A:主模型 | concat_history_bridge_prob = False recsys_model.py:534 | 取 ca[:, :, 0] → clip 0~1 → 接在作者嵌入矢量后(:976-978)→ 过投影矩阵 |
| B:特征前处理 | enable_bridge_prob = False recsys_feature_prep.py:166 | 取 cont_actions[:, :, 0] → clip 0~1 → _embed_scalar_times_vector(bridge_p, "hist_bridge_prob_vec")(:756-761) =概率 × 一个 2,560 维可学习矢量,加到历史 token |
全 repo 没有任何地方把这两个开关设成 True——不在 configs、不在测试、不在 yaml/json/toml。 对照组 enable_dwell_time 用一模一样的机制,缺省 True, 且在多个设置档明确带上。同样的水管,一条通水,一条封死。

索引矛盾:四条证据解开
两条 bridge 路径都读索引 0,但枚举说 0 是 INVALID、bridge 是 4。
| 证据 | 内容 |
|---|---|
| 一 | 枚举值 2、3、4 从未被当成数组索引使用。全 phoenix [:, :, 2]/[:, :, 3]/[:, :, 4] 各 0 命中; 只有 [:, :, 0] 与 [:, :, 1] 被读 |
| 二 | 存在只有 2 格的连续数组(parquet_recsys.py:845 缺省 num_continuous_actions: int = 2;grpc_recsys.py:372 写死 2)。 2 格里能用的只有 0 和 1——正好是 bridge 与 dwell。若布局全照枚举编号,2 格装不下 bridge |
| 三 | 两个 Rust 生产者 (crates/common/xai-recsys/src/util.rs:725-727、 crates/serving/xai-recsys-engine/src/util.rs:136-138) 写入连续数组时,唯一用到的枚举值是 ContinuousActionName::DwellTime。 全 repo Rust 档里 ContinuousActionName 只出现这 2 次。 即时服务路径从不写入 bridge,那格恒为 0.0 |
| 四 | 训练数据路径是逐格照抄: history_continuous_actions[base + j] = floats.value(j)(util.rs:1177-1187), 从 parquet 的 continuousActionValuesSeqSeq 字段搬进来,代码完全不解读语意。 谁定义第 0 格是 bridge?产生那份 parquet 的上游——而它不在这个 repo 里 |
结论:数组语意不完全由公开枚举决定。但在即时服务路径上没有歧义—— 只有 dwell 那格会被填,bridge 那格恒为 0.0。就算把开关打开,也是 0.0 × 学到的矢量,加了等于没加。
| 项目 | 数值 | 说明 |
|---|---|---|
| 为 bridge 写好的完整接线 | 2 | — |
| 被打开的开关 | 0 | — |
| 训练损失 | 0 | — |
| 排序权重参数 | 0 | — |
⑨ Phoenix 模型规格
来源 phoenix/xrex/configs/xrecsys.py。这是实际训练设置,不是示范用的玩具模型。

| 项目 | 数值 | 意义 |
|---|---|---|
| history_seq_len | 1,022 | 一次看你最近 1,022 个行为 |
| candidate_seq_len | 64 | 一批评分 64 则候选 |
| num_layers | 8 | 8 层 Transformer |
| emb_size | 2,560 | 模型宽度 |
| query_heads / kv_heads | 20 / 4 | 分组查找注意力(GQA) |
| total_samples | 1×10^11 | 1,000 亿笔训练样本 |
| user_vocab_size | 100,000,000 | 1 亿用户哈希桶 |
| item_vocab_size | 100,000,000 | 1 亿帖子哈希桶 |
| author_vocab_size | 30,000,000 | 3,000 万作者 |
| ip_vocab_size | 10,000,000 | 1,000 万 IP |
| emb_learning_rate | 0.2 | 嵌入层学习率 |
另有 nano 版(emb_size 512 / num_layers 4 / query_heads 4), 搭配仓库附的合成数据产生器,外人可以真的把模型从头训练跑一遍。这是这次开源最实在的一块。
技术选择:JAX/Haiku(hk.Module)而非 PyTorch,自写 CUDA kernel(6 个 .cu) 与 Pallas kernel 做注意力;损失支持 mse/mae/huber/tweedie (tweedie 专门处理「大量为零、偶尔很大」的分布,正合交互数据的形状)。
候选来源与周边组件
| 组件 | 规模 | 负责什么 |
|---|---|---|
| thunder/ | 24 档 Rust | 内存里存你追踪对象的近期帖子(已追踪来源) |
| phoenix/ | 303 档 | 检索+排序模型本体(未追踪来源+打分) |
| simclusters/ | 232 档 Scala | Twitter 时代的社群分群检索(未追踪来源) |
| vm-ranker/ | 10 档 Rust | 最后重排;内核 dpp.rs(决定性点过程,做多样化) |
| grox/ | 165 档 Python | 用 LLM(Grok)做内容安全标注的脱机流程 |
| botmaker/ | 492+73 档 | 规则引擎与 73 条安全规则(Java/Scala 遗产) |
⑩ 开源留白与三个破绽
X 自己承认没放的:Grox 的 LLM 提示词(.j2 档,即「AI 判定内容安全时到底问了什么」)、 部分 botmaker 规则、部署与基础设施代码。理由写得很明白:怕被拿去钻漏洞。

破绽一:一个过滤器文件没被声明,等于死码
home-mixer/filters/ 有 27 个 filter 档,mod.rs 只声明 26 个。 没被声明的是 popular_topics_author_dedup_filter.rs——在磁盘上,但编译时不会被纳入。
破绽二:mod.rs 第 8 行是空行,位置在字母序断点上
声明严格按字母排序,而 drop_duplicates_filter 与 following_retweet_deduplication_filter 之间空了一行。 这正是某个以 e 或 f 开头的模块被删掉会留下的痕迹。无法证明删了什么,但这是发布前有人动过手的痕迹。
破绽三:6 个过滤器存在但这条管线用不到
ad_adjacent_served、following_retweet_deduplication、 invalid_conversation_module、push_to_home_dedup、 result_size、self_reply_chain——有完整实现,但不在 Phoenix 主管线里。 它们属于其他 timeline 管线。这个 repo 给的是 For You 这一条线,不是 X 的全部。
⑪ 派工与交叉验证纪录
粗重但必须零误差的工作派给低级模型;每一条交付都以源代码亲自复验,未采信任何一方自报。
| 运行者 | 被派的工作 | 验收 | 实跑对帐结果 |
|---|---|---|---|
| CX gpt-5.6-luna (最低推理档) | ① 33 个权重交叉引用 1,679 行评分器 ② 6 个归零权重全流向 ③ bridge 全流向 | 全数通过 | 抽验 ranking_scorer.rs:63、:104-128、:216-221、 :470-510、:511-533、config.rs:38-40 —— 逐字相符。第三轮还主动找出我漏掉的 Rust 生产者 util.rs:725-727 |
| GM Gemini 3.7 Flash (High) | ① 过滤器顺序对帐 ② 54 条可见度规则顺序 ③ 测试码鉴识 | 全数通过 | 独立 sed -n '344,362p'、'101,133p' 重跑,名称/顺序/行号全部吻合。 第一轮我喂错档(给了只注册 2 个 filter 的 for_you 管线), 它如实回报「只有 2 个」而没有帮我圆场——是我的出题失误 |
| MX MiniMax-Text-01 | 权重数值保真复核(独立重读源代码) | 数值满分 计数失准 | 30 个重叠项目的数值 100% 逐字正确,一个小数点都没错。 但多抓 5 个名称不含 Weight 的参数、漏抓 1 个布尔参数、自报 37 列实际 35 列、 多行参数行号偏移 1–2 行。数字可信,计数不可信 |
| HK Haiku ×3 | Phoenix 模型盘点、8 个组件目录盘点、连续动作布局全扫 | 通过 | 抽验 xrecsys.py:241-251、:355-358 —— 逐字相符。 「只有 DWELL_TIME 有损失函数」这条关键线索就是从它的命中清单追下去的 |
| HK Haiku(第 4 次,盲测) | 不给答案,要求独立推导 10 个关键数字 | 整份弃用 | 运行 0 次工具调用,10 题全部凭空捏造。详见下方 |
一次造假事件(保留在案)
最后一轮盲测,代理回传了格式完整、看起来很专业的 10 题答案,附「指令+输出+答案」三段。 但它一次工具都没跑(tool_uses: 0),所有「原始输出」都是编的。实跑反驳:
| 它宣称的东西 | 实际 grep 命中 |
|---|---|
| param!(FavoriteWeight, 0.0, 1000.0, 8.5); | 0 |
| filters.push(...) | 0 |
| FutureOutstanding / NumDrafts 等 filter 名 | 0 |
| CONTINUOUS_ACTION_UNKNOWN | 0 |
| 「param! 区块共 37 个」 | 实际 183 |
| 「history_seq_len: 50」 | 实际 1,022 |
为什么要把这件事写进证据报告:这份捏造的交付格式完美、语气自信、还附了「可重跑指令清单」。 如果没有先创建机器真值,它会直接混进报告。 抓到它的不是怀疑,是对帐。——这正是「不信自报、必亲跑验收」这条纪律存在的理由。

我自己犯的三个错(一并在案)
- 解析器静默漏抓:第一版只扫多行 param!,漏掉 13 个单行写法—— 而真正的评分权重全部在那 13 个里。实计 170 ≠ grep -c 的 183 才抓到。
- 派工喂错档:把只注册 2 个 filter 的 for_you_candidate_pipeline.rs 当成主过滤链喂给 GM,白跑一轮。真正的主链在 phoenix_candidate_pipeline.rs。
- 验证脚本本身有 bug:第一版 verify-all.sh 用 grep -A4 抽多行参数的默认值,抓错行,产生 6 个假 FAIL。 换成完整解析器后 58/58 全过。闸门自己会坏,所以闸门要自验。
⑫ 证据界线:我不能证明什么
- 不能证明在线实际值。param.rs 开头注解写明它是 "mirrored from config feature-switch defaults; last sync 2026-08-12", 而 feature switch 在线可调。代码能证明「公开版的默认值是什么」, 证明不了「X 在线此刻用的是什么」。
- 不能计算实际分数组成。公式是 权重 × 预测概率,而概率由模型产生,不在 repo 里。 所有「某动作比某动作重要 N 倍」的说法,都只成立在定价层面。
- 不能还原 Grox 提示词。X 明说没放。内容安全判定的实际问法是黑的。
- 不能断定连续动作数组第 0 格的真正语意。训练数据是逐格照抄上游 parquet, 而产生 parquet 的组件不在 repo 内。
- 不能涵盖 For You 以外的线。6 个过滤器属于其他管线,那些管线没有公开。

⑬ 附录:完整复现脚本
以下三步可从零复现本文全部 58 条命题。第 2 步的解析器同时处理多行与单行 param!, 这是避开第 ⑪ 节「错误一」的关键。

# 1. 取得同一份程式碼(HEAD 必須是 a389166)
git clone https://github.com/xai-org/x-algorithm.git
cd x-algorithm && git log -1 --format=%H
# 2. 抽出全部 183 個參數(多行+單行兩種寫法都處理)
python3 - <<'PY'
src=open('home-mixer/params/param.rs').read().split('\n')
rows={}; i=0
while i < len(src):
l=src[i]
if l.startswith('param!('):
if l.rstrip().endswith(');'):
parts=[x.strip() for x in l[7:].rstrip()[:-2].split(',')]
rows[parts[0]]=(i+1,parts[-1]); i+=1; continue
j=i+1; body=[]
while j<len(src) and not src[j].startswith(');'):
body.append(src[j].strip()); j+=1
parts=[b.rstrip(',').strip() for b in body if b.strip()]
rows[parts[0]]=(i+1,parts[-1]); i=j+1; continue
i+=1
print('param! 區塊 =', len(rows))
print('名稱含 Weight =', sum(1 for k in rows if 'Weight' in k))
for k in ['FavoriteWeight','ReportWeight','MuteAuthorWeight','ShareViaCopyLinkWeight',
'ProfileClickWeight','DwellWeight','QuotedVqvWeight','NewUserAgeThresholdSecs']:
print(f'{k:36s} L{rows[k][0]:<5d} = {rows[k][1]}')
PY
# 3. 其餘命題
sed -n '30,45p' home-mixer/params/config.rs # 五個關鍵常數
sed -n '511,533p' home-mixer/scorers/ranking_scorer.rs # 正負拆分與位移
sed -n '104,128p' home-mixer/scorers/ranking_scorer.rs # positive_sum / total_sum
sed -n '681,700p' home-mixer/scorers/ranking_scorer.rs # 未追蹤折扣與新用戶
sed -n '610,620p' home-mixer/scorers/ranking_scorer.rs # 多樣性衰減公式
sed -n '216,221p' home-mixer/scorers/ranking_scorer.rs # 唯一的 !=0.0 守衛
sed -n '42,60p' home-mixer/util/candidates_util.rs # quoted_vqv 長度閘門
sed -n '344,362p' home-mixer/candidate_pipeline/phoenix_candidate_pipeline.rs # 17 道前置
sed -n '417,421p' home-mixer/candidate_pipeline/phoenix_candidate_pipeline.rs # 3 道後置
sed -n '101,133p' visibility-filtering/rules/registry.rs # 28 條基本規則
sed -n '138,172p' visibility-filtering/rules/registry.rs # 26 條 OON 加碼
# 死碼證明:27 個檔案 vs 26 個宣告
ls home-mixer/filters/*.rs | grep -vc mod.rs
grep -c '^pub mod' home-mixer/filters/mod.rs
# bridge 專卷
grep -rin bridg . --exclude-dir=.git | wc -l # 25(含 3 類雜訊)
grep -ri bridge --include='*.rs' . | wc -l # 0 ← Rust 側完全沒有
sed -n '437,443p' phoenix/python/common/xai-proto/proto/recsys.proto
grep -rn '\[:, :, 4\]' phoenix --include='*.py' | wc -l # 0 ← 列舉值 4 從未當索引用
grep -rn 'ContinuousActionName' phoenix/crates --include='*.rs' # 2 行,都是 DwellTime
sed -n '725,730p' phoenix/crates/common/xai-recsys/src/util.rs # 生產者只寫 dwell
sed -n '1177,1187p' phoenix/crates/common/xai-recsys/src/util.rs # 訓練路徑逐格照抄
# Phoenix 真實超參數
sed -n '238,252p' phoenix/xrex/configs/xrecsys.py
sed -n '353,360p' phoenix/xrex/configs/xrecsys.py
grep -n '^NUM_CONTINUOUS\|^DWELL_INDEX' phoenix/reference/dump_gen.py本页 58 条命题由 verify-all.sh 实跑输出直接转表,未经人工转录。 自验:注入一个错误期望值 → 脚本正确产生 1 FAIL,证明比对逻辑有效。 原始交付档(CX/GM/MX/HK 各方原文)与脚本留存备查。
来源与验证
本文依据 xai-org 于 GitHub 公开的 X 推荐算法源代码撰写,判读日期 2026 年 8 月 14 日。
| 项目 | 内容 |
|---|---|
| 源代码仓库 | xai-org/x-algorithm |
| 判读版本 HEAD | a389166f6cf5da70a286b568c87695d4dcdce3a1 |
| 快照日期 | 2026-08-13 |
| 机器命题验证 | 58 条,全数通过 |
| 本文引用的源代码文件 | x-algorithm README(官方說明)、權重參數定義 param.rs、評分器 ranking_scorer.rs、常數定義 config.rs、候選管線與過濾器註冊、可見度規則註冊表 |
本文所列每一条命题均由验证脚本实跑产生,未经人工转录;验证脚本本身另经 should-FAIL 反例检查。
效力界线:源代码中的参数注明为 feature switch 默认值的镜像,在线可随时调整。 本文能证明公开版本的默认值,不能证明平台在线当下实际使用的数值。 最终分数为「权重乘以模型预测概率」,而概率不在公开源代码内,因此所有倍数比较仅成立于定价层。
FAQ
- 负权重与正权重相比,在算法中定价相差多少?
- 根据代码内置默认值,正权重合计为 +43.324,负权重合计为 −367.22,负正倍数为 8.48 倍。这代表 X 对负面信号的定价比正面信号贵一个数量级,但单则帖子的实际得分仍需乘上模型预测概率。
- 帖子算出来若是负分,在推荐排序中会如何处理?
- 依据评分公式的位移机制,所有负分帖子会被压缩到 0 至 0.001 的极窄区间内。这导致负分帖子之间的排序差异几乎归零,全部沉到最底端而掉出可见范围。
- 推荐管线中一共设置了几道候选帖子过滤器?
- 候选管线中无条件注册了 20 道过滤器,包含 17 道前置过滤器与 3 道后置过滤器。过滤规则涵盖重复内容、超过 48 小时帖子、未追踪者的转推与回复,以及可见度系统判定剔除的内容。
- 推荐给非追踪者的未追踪内容(OON)需要通过几条可见度规则?
- 所有人适用的基本可见度规则有 28 条,未追踪内容则额外加码 26 条规则。因此推荐给陌生人的内容总共必须通过 54 条过滤规则,且只要第一条回答 drop 即直接剔除。
- 算法中的 BRIDGE_PROBABILITY 信号目前的激活状态为何?
- 在公开的代码中,BRIDGE_PROBABILITY 虽然已定义枚举项与接线结构,但所有开关设为 True 的次数为 0,且无训练损失与排序权重。这表示该功能处于未激活且无即时数据源输入的状态。
来源锚定
- xai-org/x-algorithm 原始碼儲存庫 · https://github.com/xai-org/x-algorithm · 在 IDAEO 的其他引用
- x-algorithm README(官方說明) · https://github.com/xai-org/x-algorithm/blob/a389166f6cf5da70a286b568c87695d4dcdce3a1/README.md · 在 IDAEO 的其他引用
- 權重參數定義 param.rs · https://github.com/xai-org/x-algorithm/blob/a389166f6cf5da70a286b568c87695d4dcdce3a1/home-mixer/params/param.rs · 在 IDAEO 的其他引用
- 評分器 ranking_scorer.rs · https://github.com/xai-org/x-algorithm/blob/a389166f6cf5da70a286b568c87695d4dcdce3a1/home-mixer/scorers/ranking_scorer.rs · 在 IDAEO 的其他引用
- 常數定義 config.rs · https://github.com/xai-org/x-algorithm/blob/a389166f6cf5da70a286b568c87695d4dcdce3a1/home-mixer/params/config.rs · 在 IDAEO 的其他引用
- 候選管線與過濾器註冊 · https://github.com/xai-org/x-algorithm/blob/a389166f6cf5da70a286b568c87695d4dcdce3a1/home-mixer/candidate_pipeline/phoenix_candidate_pipeline.rs · 在 IDAEO 的其他引用
- 可見度規則註冊表 · https://github.com/xai-org/x-algorithm/blob/a389166f6cf5da70a286b568c87695d4dcdce3a1/visibility-filtering/rules/registry.rs · 在 IDAEO 的其他引用
引用本文
TK Lin・《X 算法拆解证据总表》・IDAEO 知識庫・2026-08-14・https://km.idaeo.ai/post/ai/x-algorithm-evidence更新于 2026-08-15