IDAEO知識庫km.idaeo.ai

本文屬於主題館「AI 綜合討論」 →

X 演算法拆解證據總表

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 實跑產生,本頁數值直接由該腳本輸出轉成表格, 沒有經過人工抄寫。腳本本體見附錄。

一支銅水平尺架在兩塊高低不同的鐵塊上,氣泡明顯偏向一側
should-FAIL:故意餵已知錯值,證明檢查器真的會擋
項目數值說明
PASS58—
FAIL0—
should-FAIL 反例驗(注入錯值必須被抓到)1—
編號命題實測值結果
C01HEADa389166f6cf5da70a286b568c87695d4dcdce3a1PASS
C02param!區塊數183PASS
C03檔案總數2015PASS
C04FavoriteWeight0.5PASS
C05ReplyWeight5.0PASS
C06RetweetWeight1.0PASS
C07ShareViaCopyLinkWeight20.0PASS
C08ReportWeight-234.0PASS
C09MuteAuthorWeight-58.8PASS
C10BlockAuthorWeight-31.2PASS
C11NotInterestedWeight-43.2PASS
C12NEW_USER_OON_WEIGHT_FACTOR0.00001PASS
C13NEW_USER_MIN_FOLLOWING5PASS
C14NEGATIVE_SCORES_OFFSET0.001PASS
C15MAX_POST_AGE(秒)172800PASS
C16NewUserAgeThresholdSecs預設0PASS
C17AuthorDiversityDecay0.5PASS
C18AuthorDiversityFloor0.25PASS
C19OonWeightFactor0.75PASS
C20前置過濾器數17PASS
C21後置過濾器數3PASS
C22filters檔數(不含mod)27PASS
C23mod.rs宣告數26PASS
C24未宣告的filterpopular_topics_author_dedup_filterPASS
C25基本可見度規則數28PASS
C26OON加碼規則數26PASS
C27排序器取用預測頭數(scores.* 去掉方法呼叫 .clone)26PASS
C28MinVideoDurationMs10_000PASS
C29EnableQuotedVqvDurationCheckfalsePASS
C30EnableInventoryHoldoutfalsePASS
C31VMRankerSendHeadWeightsfalsePASS
C32Rust側bridge命中0PASS
C33phoenix [:,:,4] 命中0PASS
C34phoenix [:,:,2] 命中0PASS
C35phoenix [:,:,3] 命中0PASS
C36Rust用ContinuousActionName次數2PASS
C37Rust 引用 DwellTime 的處數2PASS
C38BRIDGE_PROBABILITY列舉值4PASS
C39bridge開關設True次數0PASS
C40有損失的連續頭種類數1PASS
C41NUM_CONTINUOUS(參考實作)8PASS
C42DWELL_INDEX(參考實作)1PASS
C43history_seq_len1022PASS
C44num_layers8PASS
C45emb_size2560PASS
C46ActionName列舉項數204PASS
C47PLACE_HOLDER佔位數8PASS
C48兩份proto是否相同samePASS
C49ProfileClickWeight0.0PASS
C50DwellWeight0.0PASS
C51QuotedVqvWeight0.0PASS
C52ContClickDwellTimeWeight0.0PASS
C53ContActiveSecs5mResidualNormWeight0.0PASS
C54BidirectionalFollowDwellWeightBoost0.0PASS
C55BidirectionalFollowReplyWeightBoost15.0PASS
C56ContDwellTimeWeight0.004PASS
C57NotDwelledWeight-0.02PASS
C58名稱含Weight的參數數33PASS

② 權重總表

來源 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 折扣係數)

行號參數預設值對應動作
L325ShareViaCopyLinkWeight20.0複製連結分享
L284BidirectionalFollowReplyWeightBoost+15.0互相追蹤時的回覆加成
L283ReplyWeight5.0回覆
L319ShareViaDmWeight5.0私訊分享
L332QuoteWeight5.0引用轉推
L345FollowAuthorWeight4.0追蹤作者
L318ShareWeight2.0一般分享
L296RetweetWeight1.0轉推
L246OonWeightFactor0.75未追蹤內容折扣係數
L282FavoriteWeight0.5按讚
L266TopicOonWeightFactor0.5主題模式的未追蹤折扣
L309ClickWeight0.4點進貼文
L310OpenLinkWeight0.2點外部連結
L297PhotoExpandWeight0.05放大圖片
L303VideoOpenWeight0.05開影片
L317VqvWeight0.05影片有效觀看
L333QuotedClickWeight0.05點進被引用的原貼文
L351PostUnexploredWeight0.02探索性內容加分
L375ContDwellTimeWeight0.004停留秒數(每秒)

負權重(5 個)

行號參數預設值相當於幾次按讚
L442ReportWeight−234.0468
L436MuteAuthorWeight−58.8117.6
L424NotInterestedWeight−43.286.4
L430BlockAuthorWeight−31.262.4
L443NotDwelledWeight−0.020.04
項目數值說明
正權重合計(16 項,不含兩個 OON 折扣係數與互追回覆加成 +15.0)+43.324—
負權重合計(5 項)−367.22—
負/正倍數8.48×—
這個 8.48 倍怎麼讀才不會讀歪: 比的是權重定價,不是最終分數。進公式的是「權重 × 模型預測機率」, 而檢舉、封鎖的預測機率極小、按讚的機率高得多,所以單則貼文的負面項實際貢獻不會是正面的 8.48 倍。 那些機率是模型跑出來的,開源碼裡沒有,無法計算。 成立的說法是:X 對負面訊號的定價,比正面訊號貴一個數量級。

零權重(6 個)

行號參數預設值性質(詳見 ⑦)
L311ProfileClickWeight0.0模型有訓練,只是定價 0
L331DwellWeight0.0模型有訓練,只是定價 0
L339QuotedVqvWeight0.0模型有訓練,另有長度閘門
L381ContClickDwellTimeWeight0.0無訓練損失=schema 留白
L417ContActiveSecs5mResidualNormWeight0.0無訓練損失=schema 留白
L290BidirectionalFollowDwellWeightBoost0.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.25ranking_scorer.rs:614-616 param.rs:229-238
未追蹤折扣沒追蹤的作者 ×0.75;帶主題時更重 ×0.5ranking_scorer.rs:681-698
新用戶模式符合條件的新帳號,未追蹤內容 ×0.00001 條件:帳齡 < NewUserAgeThresholdSecs 且 追蹤數 ≥ 5ranking_scorer.rs:688-698 config.rs:38-39
不要把 0.00001 寫成聳動結論:NewUserAgeThresholdSecs 的預設值是 0 (param.rs:273)。帳齡不可能小於 0 秒,所以這個機制預設不生效。 正確說法是:開關存在、力道極端、目前關著。
一支不成比例的長銅閥桿裝在一條細黑管上,桿子橫著沒開
力道極大的開關,被閂在關的位置

三個「蓋好了但關著」的開關

開關預設打開會怎樣
NewUserAgeThresholdSecs0 秒新帳號的未追蹤內容 ×0.00001,等於只剩同溫層
EnableInventoryHoldoutfalse依 (貼文 ID × 使用者 ID) 雜湊,穩定扣住指定百分比的原創/回覆/轉推。三個比例預設皆 0
VMRankerSendHeadWeightsfalse把權重表送給 vm-ranker 重排服務;目前只送預測分數不送權重

⑤ 20 道過濾器

來源 home-mixer/candidate_pipeline/phoenix_candidate_pipeline.rs L344–362(前置 17 道)與 L417–421(後置 3 道)。全部無條件註冊,沒有任何條件式開關。

木槽裡一列銅閘門依序排開,最前面那道關著,一枚深色圓片停在門前
過濾器依序執行,第一個說不的就結束
#行號過濾器砍掉什麼
1L345DropDuplicatesFilter不同來源撈到的同一則
2L346CoreDataHydrationFilter內文與中繼資料載入失敗
3L347AgeFilter超過 48 小時(MAX_POST_AGE = 172800 秒)
4L348SelfTweetFilter你自己發的
5L349OONRetweetReplyFilter未追蹤帳號的轉推與回覆
6L350OONNsfwSimclustersFilterSimClusters 撈到、作者被標成人內容、且你沒追蹤
7L351RetweetDeduplicationFilter同一則被重複轉推
8L352IneligibleSubscriptionFilter沒訂閱所以看不到的付費內容
9L353PreviouslySeenPostsFilter已經看過的
10L354PreviouslySeenPostsBackupFilter同上,第二份曝光紀錄再擋一次
11L355PreviouslyServedPostsFilter本次工作階段已送出過的
12L356MutedKeywordFilter命中你的靜音關鍵字
13L357AuthorSocialgraphFilter你封鎖或靜音的帳號
14L358VideoFilter請求排除影片時擋影片
15L359TopicIdsFilter不在指定主題/在排除主題內
16L360NewUserMinEngagementFilter新帳號的未追蹤內容互動數不夠
17L361InventoryHoldoutFilter雜湊決定性地扣住一定比例(預設 0%)
18L418VFFilter可見度系統回答 drop 的
19L419AncillaryVFFilter父/引用/轉推來源被 drop 的
20L420DedupConversationFilter同一串對話的其他分支
對帳結果:README 宣稱的 17+3 道與順序,與程式碼逐條完全吻合,零位移。這一項 X 沒有美化。

⑥ 54 條可見度規則

來源 visibility-filtering/rules/registry.rs(912 行)。第一條回答 drop 者為準,後面不再評估。

一枚銅棘輪咬著一支鐵掣爪,齒是單向的
只能往一個方向走的機構:能砍,不能放行
項目數值說明
人人適用 base_home_rules() L101–13228—
未追蹤內容加碼 oon_drops L138–17026—
未追蹤內容要通過的總數54—

基本 28 條依序:作者狀態 4 條(停權/停用/抹除/離站)→ 保護帳號 → 你封鎖 → 你靜音 → 靜音轉推 → 內容標籤 8 條(PDNA、退件、垃圾訊息、緊急、仇恨言論、暴力言論、濫用、公民誠信)→ 未廣播 → 過期 → 法律下架 2 條 → 敏感內容對登出/未成年/未填年齡 3 條 → 專屬內容 → 最後 4 條是插頁警示而非直接砍掉。

未追蹤多背的 26 條全部只能 drop:DMCA 媒體、地區限制媒體、成人內容 4 種判定、 高召回率的成人與垃圾訊息偵測(寧可錯殺)、惡意網址、「不要放大」標籤等。

⑦ 6 個歸零權重的三種性質

分辨方式:看模型有沒有被訓練去預測這個動作。有訓練、只是定價 0 =真槓桿; 連訓練損失都沒設 =只是留白。

共通機制:沒有任何「權重是 0 就跳過」的守衛(唯一例外是 BidirectionalFollowDwellWeightBoost,見下)。 算式一律 機率 × 權重,0 權重照樣計算、照樣進 26 項陣列,結果恆為 0。 模型仍花算力預測它、管線仍傳遞它,只是最後乘以零。

第 1 類:模型有訓練,只是定價 0 —— 真槓桿

參數對應預測頭打開的效果
ProfileClickWeightCLIENT_TWEET_CLICK_PROFILE = 30「點作者頭像」開始計分。已進 positive_sum(:112),調高會同時放大分子與分母
DwellWeightCLIENT_TWEET_RECAP_DWELLED = 11「有沒有停留」開始計分。現況是「秒數算錢、有沒有停留不算錢」
QuotedVqvWeightCLIENT_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)。

參數連續頭實情
ContClickDwellTimeWeightCLICK_DWELL_TIME = 2無訓練損失。但低按讚率懲罰機制已蓋好(baseline 0.01/alpha 0.5/floor 0.01/cap 1.0, ranking_scorer.rs:195-213)掛在一個權重 0 的項目上
ContActiveSecs5mResidualNormWeightACTIVE_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
一片銅盤,一端是密密麻麻的方格,收束到另一端只剩三根短柱
204 個動作收到 21 個真正左右排序

⑧ BRIDGE_PROBABILITY 專卷

全 repo 不分大小寫 grep -rin bridg 共 25 命中。先剔除三類同名雜訊。

命中位置其實是什麼
AdActionInfo.bridgeType AdActionInfo.isTwclidBridgedrecsys.proto:1306-1307廣告轉換歸因。twclid=Twitter Click ID。與推薦演算法的 bridging 無關
_bridge_ads_s3_env()retrieval_dataset.py:33,50設定 S3 環境變數
smyte_bridgebotmaker/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_PROBABILITY

索引矛盾:四條證據解開

兩條 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_len1,022一次看你最近 1,022 個行為
candidate_seq_len64一批評分 64 則候選
num_layers88 層 Transformer
emb_size2,560模型寬度
query_heads / kv_heads20 / 4分組查詢注意力(GQA)
total_samples1×10^111,000 億筆訓練樣本
user_vocab_size100,000,0001 億使用者雜湊桶
item_vocab_size100,000,0001 億貼文雜湊桶
author_vocab_size30,000,0003,000 萬作者
ip_vocab_size10,000,0001,000 萬 IP
emb_learning_rate0.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 檔 ScalaTwitter 時代的社群分群檢索(未追蹤來源)
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 ×3Phoenix 模型盤點、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_UNKNOWN0
「param! 區塊共 37 個」實際 183
「history_seq_len: 50」實際 1,022
為什麼要把這件事寫進證據報告:這份捏造的交付格式完美、語氣自信、還附了「可重跑指令清單」。 如果沒有先建立機器真值,它會直接混進報告。 抓到它的不是懷疑,是對帳。——這正是「不信自報、必親跑驗收」這條紀律存在的理由。
一個打開的木盒,內襯挖出工具的形狀,裡面是空的
看起來完整可信、實際上從未產生的交付

我自己犯的三個錯(一併在案)

  1. 解析器靜默漏抓:第一版只掃多行 param!,漏掉 13 個單行寫法—— 而真正的評分權重全部在那 13 個裡。實計 170 ≠ grep -c 的 183 才抓到。
  1. 派工餵錯檔:把只註冊 2 個 filter 的 for_you_candidate_pipeline.rs 當成主過濾鏈餵給 GM,白跑一輪。真正的主鏈在 phoenix_candidate_pipeline.rs。
  1. 驗證腳本本身有 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
判讀版本 HEADa389166f6cf5da70a286b568c87695d4dcdce3a1
快照日期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,且無訓練損失與排序權重。這表示該功能處於未啟用且無即時資料來源輸入的狀態。

引用本文

TK Lin・《X 演算法拆解證據總表》・IDAEO 知識庫・2026-08-14・https://km.idaeo.ai/post/ai/x-algorithm-evidence

更新於 2026-08-15

更新 2026-08-15T07:21:43.872Z · server-rendered · four-language · IDAEO 知識庫