Skip to content
AI Ferryman Alex
Go back

最新 X.com 推薦算法代碼解讀和測試:「第二篇只剩 62.5%」是被讀錯的

最新 X.com 推薦算法代碼解讀和測試:「第二篇只剩 62.5%」是被讀錯的

先交代一句篇幅:這篇正文比較長,全文約 25 萬字,是把代碼逐項覈對完的完整研究版。覺得太長,可以先看導讀版(我在 X 上發的 13 條實操版:https://x.com/alexlee20122022/status/2116710008553447863);或者直接用我已經做好的 skill:https://github.com/alexliyu7352/for-you-skills ——手冊裏的結論已經做成了能直接調用的技能,不用自己逐條對照。

先問一個大家每天都在踩的坑:一條帖子放四張圖,第一張是你精心設計的封面(比如寫着“這次測試的三個發現”),第四張圖纔是真正的測試結果表格。你覺得推薦系統的 AI 會先讀到哪張圖?

翻開 X 公開算法庫(xai-org/x-algorithm)裏 V8.2 的內容理解代碼(renderer_v82.py),負責挑圖的 _collect_post_media 函數給出了一個非常乾脆的答案:從第一張圖開始挨個檢查,只要遇到第一張有可用內容的圖片,立刻 return(直接返回收工,根本不往下讀了)。也就是說,當四張圖都能正常打開時,這個分支拿走的只有你的第一張封面圖。如果封面圖上只寫了一句空洞的標題“這次測試的三個發現”,那第四張圖裏真正核心的測試數據,在這一次圖片選取裏壓根不會跟着送進去。1

順着代碼繼續往下查發文頻率,又會撞見另一句流傳極廣的運營口訣:“一天發第二篇只剩 62.5% 權重,每天最多發兩三篇,隔四小時才能恢復權重。”在代碼裏確實能算出 0.625 這個數字,但程序根本沒有數“你今天一共發了幾篇”。它真正數的是:在給某位讀者單次刷新抓出來的同一批候選帖子裏,同一個作者的帖子排到了第幾篇。一旦把“單次候選池裏的排序位置”錯當成“每日發文額度”,後面推出來的“每天最多發兩三篇長文”、“兩篇之間必須隔四小時恢復權重”,就統統失去了代碼依據。2 3 4

看懂這兩件事,你手頭的發文動作馬上就不一樣了:第一件事提醒我們發多圖帖時必須盯緊首圖的信息量;第二件事幫我們卸下包袱,不用再被一個讀錯的數字綁架發帖排程。再順着源碼往下翻,你還會看到一連串直接影響日常運營的真相:讀者的“收藏(Bookmark)”是怎麼在暗中幫你在後續推薦裏撈人的?爲什麼在舊帖底下直接補一條重要更正,老讀者在首頁反而刷不到?自己直接點“轉發(Repost)”老帖子會撞上哪幾道攔截牆?以及當賬號曝光突然腰斬時,官方在代碼裏留了哪個後臺記錄可以讓我們自己查清原因?

本文完整覈對了 X 的 For You(爲你推薦)公開推薦代碼,原始基準固定在提交 5ed7963,並回溯覈對了十月份的 20 個歷史參數快照,一直追到最新公開提交 606b254(修訂於 2026 年 10 月 29 日)。源碼能夠證明系統的處理條件與邊界;而文中的寫作和運營實操建議,則是我根據這些代碼事實作出的推導判斷。文中的局部算術例子用來幫你直觀算清公式邏輯,不代表真實賬號的線上增長實驗;凡是公開代碼還沒披露、需要線上日誌或實驗數據才能確認的邊界條件,我都毫無保留地集中列在了文末的 49 個待確認問題清單裏。5

1 網上流傳的說法,哪些有依據

在逐條覈對傳言之前,我們先用大白話把 X 上的三種常見發文格式分清楚,免得後面張冠李戴:

  • 長 Post(Longer Post):本質上還是一條普通帖子,只是開通會員後字數上限放寬到了 25,000 個字符;
  • Article(專欄文章):是用專門的獨立文章編輯器發佈的專欄,支持多級標題、內嵌圖片視頻和引用帖子,發完會收進你個人主頁專屬的 Articles 欄目;
  • 串文(Thread):是一條接一條自己回覆自己、串聯起來的帖子組合(本文統一叫“串文”,後面說“三條串文”,指的就是同一條 Thread 裏首尾相連的三條帖子)。

這三種格式的底層數據結構、內容讀取方式和前端展示邏輯完全不同,千萬不能拿同一套“發幾篇”的規矩去硬套。6 如果你正糾結手頭寫好的一篇深度長文到底該發成“長 Post”還是“Article”,可以先跳去看後面的“同一篇長文,該髮長 Post 還是 Article”章節——我在那裏把正文截斷、閱讀計時、64 贊拉取圖片門檻(is_high_fav:Article 的正文圖片要達到這個熱度纔會被完整拉取,後文細說)、V5 與 V8.2 閱讀器差異以及可見性規則全部拆開覈對了一遍,並給出了可以直接照着做的發佈組合。

網上關於 X 算法的爆款攻略,大多源自 Hootsuite、X Algorithm Playbook、Gridlok、SocialPilot 和 Bangerkit 等第三方分析文章。我們先用兩張總表把這些流傳最廣的說法和源碼覈對結論擺在一起對個賬,隨後再把支撐它們的公式、代碼和邊界條件一層層剝開講透。7 8 9 3 4

公開文章中的說法對照代碼後的判斷
每天發 2–3 則。
Hootsuite
原文只是針對一般社交帖子的日常運營建議,根本沒有寫“最多”和“長文”這兩個限制詞。公開推薦路徑也證實不了“每天最多發兩三篇長文”的算法上限。
一天第二篇只剩 62.5%,最多三篇,間隔四小時。
X Algorithm Playbook
把“同一次刷新候選池裏的同作者排序位置”,錯當成了“全天發文篇數”。源碼公式只管同池競爭,推不出每天三篇或隔四小時恢復的排程。
長文之間搭配短帖。
常見運營建議
官方確實支持用短預告、文章摘錄來幫長文導流分發;但公開的同作者衰減計數器只認作者 ID,不會因爲中間插了短帖就清零重置。這兩種理由必須分清。
長文拆成三條 thread。
常見運營建議
有前端展示依據:官方說明與對話組裝代碼(convo_marshaller.rs)都涉及“三條”這個結構。但打分代碼裏沒有任何給三條串文額外加分、或給第四條扣分的公式。

關於互動權重、外鏈懲罰和小賬號冷啓動,網上同樣流傳着好幾條讓人真假難辨的口訣:7 9 10

公開文章中的說法對照代碼後的判斷
模型預測讀者會不會互動,再加權排序。
Bangerkit
完全成立。 預測概率是針對“此時此刻正在刷首頁的這位具體讀者”實時算出來的,根本不是一張全站通用的“互動計件積分表”。
讀者回復後,作者再回復,一次來回值 150 個贊。
Gridlok
算錯了世代,也搞錯了概念。 不僅錯拿了 2023 年 4 月早就淘汰的舊版權重(75 ÷ 0.5 = 150),還把“乘以預測概率”誤當成了“乘以實際互動次數”。
外鏈固定減少 30–50% 曝光,放首條回覆就能避開。
Gridlok
假的。 查遍公開計分路徑都沒有“帶外鏈釦 30–50%”的公式;而且最新 v2 外鏈審查機器人已經刪掉了“排除回覆”的豁免,塞首條評論照查不誤。
小作者的新帖子有探索機會,涉及兩小時、五萬粉和 200 次 Home 曝光。
Bangerkit
主要條件確有代碼依據(author_cold_start.rs),但必須同時滿足多項資格與抽樣挑選步驟;且 200 次是內部 Home 曝光上限門檻,不是系統保底白送 200 個觀衆。
Premium 在圈內/圈外推薦有 4 倍/2 倍算法加成。
Gridlok
目前核查的 For You 公開路徑證實不了這組固定倍數加成。官方幫助頁確實寫明訂閱會員享有“回覆排序優先”,但那不是主時間線 4 倍/2 倍乘數的證據。

1.1 十月更新裏,還有哪些話被說過了頭

2026 年 10 月的一系列代碼更新,確實重點改造了“停留閱讀時間預測(CREAD)”和“把好文章讀到底的召回訓練(ld 分支,ld=Long Dwell,深度閱讀停留)”。但網上的二傳手總結貼,習慣把模型訓練目標、入庫索引條件、排序權重係數和最終拿到的曝光量混爲一談。我們把這 12 條十月熱門傳言逐一拆回各自對應的代碼模塊,真相是這樣的:

流傳說法覈對結果與需要保留的條件
十月八日改善停留預測 十三日增加閱讀召回有官方 README 更新說明與 Git 提交歷史支撐;但 README 公告是後來補記的,且“預測改善了多少百分比”沒有公開可復現的線上評測數據。
點贊係數爲 0.66 停留係數增加 50%同一個參數文件(home-mixer/params/param.rs)的歷史快照完全支持;但這指的是乘在預測值上的公開權重係數(0.004 升至 0.006),不是讀者每看一次的記賬入賬分,更不等於曝光同比暴漲 50%。
讀完的文章現在能贏兩次閱讀停留信號確實同時參與了“第一步召回撈候選(ld 分支)”和“第二步打分排序(停留權重)”;但“完整讀到末尾(100% 完讀)”的前端事件定義並未公開,也沒有曝光翻倍的承諾。
兩小時 兩百次觀看 五萬粉以下的新帖有加推確有小賬號冷啓動機制(冷啓動=新帖剛發出、系統還不認識它,先給一小批曝光試試水溫的階段);但“發佈 ≤ 2 小時”與“Home 曝光 < 200 次”必須同時滿足,外加原創、非墊底 3%、Thompson 抽樣(一種邊試邊學的隨機抽樣挑選法,第 21 章會用“搖號”講透)等條件,且看的是內部 view_count_on_home 而非前臺總觀看數。
新帖不再先被截掉10 月 22 日啓用的 FairShareRankingFilter 確實改爲按候選來源比例分配 2,800 個打分名額;但它保護的是“冷啓動等來源渠道按比例進場”,不是給所有新帖發免死金牌,渠道內部排在後面的帖子仍會被截掉。
只有原創能觸及陌生人普通首頁的圈外過濾器(OONRetweetReplyFilter)確實會攔截未關注作者的普通轉發;但如果同行大 V 轉發了你的帖,對大 V 的粉絲來說這屬於“圈內候選”,依然能幫你觸達不認識你的陌生讀者。
第一個與第三十二個贊開啓新流量池1fav 和 32fav 索引及二次冪更新門檻確實存在;但寫入索引、更新、召回與最終曝光是四碼事,且普通帖 32fav_1day 在公開 For You 代碼樹裏還沒找到消費端在讀它。
收藏零分 視頻觀看零分主打分表裏某一項直接係數爲 0,絕不代表整套系統無視它:收藏(Bookmark)會作爲 SimClusters 相似召回種子和沉浸式(點開全屏看視頻、看圖的那種瀏覽方式)召回訓練正例;視頻也有打開權重、停留預測及專屬視頻索引流程。
互追回復值 20 第二篇只剩 62%兩個數字都有確切公式來源:前者(5 + 15 = 20)只作用於非回覆、非轉發原創帖在互關讀者面前的回覆預測;後者(0.625)按單次候選池內的同作者排序位置計算,絕不是每日發文配額。
視頻超過十秒才進名單三個核心沉浸式視頻索引(1fav_video、video、nsfw_video)確實要求時長嚴格大於 10,000 毫秒(> 10 秒);但 5 秒短視頻依然能進普通帖的 1fav 索引,不能說短視頻全站沒資格。
任一賬號標籤都會結束陌生人觸及指定的賬號級安全標籤(如 SPAM_HIGH_RECALL、NSFW_HIGH_PRECISION)確實會在 HomeRecommendations 攔截陌生人推薦;但必須看清標籤種類、受衆範圍、檢查入口和 7 天有效期,不能一概而論。
兩天後 For You 永遠不再顯示普通候選流程的 AgeFilter 確實只保留 ≤ 48 小時的候選;但它是按當前候選自己的 tweet_id 算年齡的,近期轉發擁有全新的 tweet_id,不能只拿原帖年齡斷定全站徹底失效。

2 “今天更新了算法”,究竟是哪一天、哪一項更新

平時刷 X 看到海外博主驚呼“X 今天(today)又改算法了!”,這句話可能對應三種完全不同的情況:可能是官方剛剛在 README 補寫了一段更新說明,可能是公開代碼庫剛剛合併了一次新的 Git 提交(commit),也可能是線上某個灰度實驗(灰度=先放給一小部分用戶試用的實驗)改了開關。要想不被帶節奏,第一步就是把“today”對應到具體的提交時間和代碼行上。本文覈對用到的兩份核心代碼快照,精確時間如下:11

公開提交UTC 時間洛杉磯時間(PDT,UTC−7)閱讀時的用途
5ed796374ea48ee26058aab66ab10c266bea2bef2026-10-28 02:49:032026-10-27 19:49:03本文主報告固定的主要代碼覈對基準
606b254b45be798bfaecfa8c23f5a9c51bc8000c2026-10-29 02:57:552026-10-28 19:57:55覈對最新一份公開快照新增或修改了哪些參數與開關

來源 11

你看,606b254 這筆提交在 UTC 世界標準時間已經是 10 月 29 日凌晨,但在美國加州洛杉磯當地時間還是 10 月 28 日晚上 7 點 57 分。所以判斷別人帖子裏的“today”準不準,得先看發帖人所在的時區和他指的具體改動。更重要的是:Git 提交時間只能證明這份代碼快照是什麼時候對外公開的,不能單獨證明某項線上實驗在那一秒鐘就已經覆蓋了全站所有用戶。11 12

把整個 10 月份官方公告與公開快照裏的關鍵變動按時間順序排開,哪些是實打實改了代碼參數的,哪些是過度引申的,一張表就能看清:

文件日期或公開快照變更所在層級能覈對到的內容不能直接推成的結論
官方更新說明:2026-10-08排序模型對停留時間的預測README 指出停留時間估計改善;從代碼裏有正式名字的配置(具名配置)與損失函數,可看到 CREAD 30 門檻對數切分方法每篇長文都獲得固定加分,或全站長文曝光增加某個固定百分比
官方更新說明及公開快照:2026-10-13召回訓練與部分 Home Mixer 係數雙塔召回新增 ld 分支(拿停留事件作正例);同一路徑連續停留係數由 0.004 升到 0.006所有“看完”事件都等於 100% 讀到全文末尾,或 0.006 是每次實際閱讀的記賬入賬分
公開快照:2026-10-14Home Mixer 默認係數點贊 Favorite 由 0.6 升到 0.66;不感興趣 Not interested 由 -47.52 變成 -52.272點贊已經成爲所有互動裏權重最大的係數(其實遠小於複製鏈接的 20 和回覆的 5)
公開快照:2026-10-21/22模型打分前的候選初篩FairShare 過濾器在 10/21 先寫進代碼但默認關閉;10/22 快照將啓用開關改爲 true所有新帖都絕對不會被刪,或每篇新帖都有保底流量池
公開快照:2026-10-28 UTC頁面記錄與可選排序路徑5ed7963 增加 page logging、page decode 與 page RL exploration 三個公開參數,默認啓用開關全是 false只要代碼文件裏出現了新函數,全站所有讀者當天就已經用上了它
公開快照:2026-10-29 UTC記錄、視頻 Carousel 與具名訓練配置606b254 將 page logging 改爲 true;新增 open × immersive dwell 乘項及 immersive_page_rl_cread 配置開啓日誌記錄等於排序結果已改變,或新增視頻項已經給所有視頻發了流量紅利

來源 11 13 14 15 16 17

對比 10 月 28 日的 5ed7963 和 10 月 29 日的 606b254 兩份快照可以確認:我們最關心的點贊(Favorite)、回覆(Reply)、複製鏈接(Copy link)、連續停留(ContDwellTime)和各項負向懲罰的 Home Mixer 默認權重係數,在這兩天之間完全沒有變化。同一時期變動的是模型配置、日誌開關和部分規則重構。因此,說“這組核心打分系數沒變”是準確的;但如果說“整套算法一字沒改”就不對了。15 17

2.1 新的視頻公式已經寫進代碼,默認開關卻還沒打開

舉個最典型的例子:在 10 月 29 日(606b254)的視頻輪播欄(Carousel)計分代碼 video_carousel.rs 裏,程序員確實新加了一項乘法公式——用“視頻被打開的預測概率(video_open_score)”乘以“沉浸式路徑預測的停留時間(immersive_dwell_time)”,再乘以一個新系數 VideoCarouselOpenTimesImmersiveDwellWeight。

聽起來像是視頻迎來了史詩級加強對吧?但只要你去翻一下配套的參數文件 param.rs,就會發現:在公開默認值裏,這個新系數的數值是 0.0,而且整個視頻輪播欄的總開關 EnableVideoCarousel 依然是 false(關閉)! 這說明代碼只是提前把公式框架搭好了,絕不能看到代碼更新就宣稱“10 月 29 日起所有視頻都按觀看時長拿到了新優待”。17

# 公式重述,並非逐字源碼
carousel_score =
    video_open_weight * video_open_score
  + immersive_vqv_weight * immersive_vqv_score
  + open_times_immersive_dwell_weight
      * video_open_score * immersive_dwell_time

# 606b254 公開默認:
# EnableVideoCarousel = false
# VideoCarouselOpenTimesImmersiveDwellWeight = 0.0

來源:17

同一次提交還新增了一份叫 immersive_page_rl_cread 的強化學習訓練配置。我們能從源碼裏查清楚它用了哪些訓練目標,但不能光憑配置文件寫進了倉庫,就斷定線上所有用戶都已經切換到了這個新模型權重(checkpoint)——那還需要線上部署記錄、流量分桶配置和實驗數據的支持。17

3 一條帖子要經過哪些步驟,纔會出現在首頁

很多創作者之所以被各種算法傳言繞暈,是因爲腦子裏把推薦算法想像成了“通關打怪”:以爲自己發一條帖子,系統就給帖子建個積分卡,有人點個贊加 1 分、轉推加 2 分,攢夠多少分就升入下一個流量池。真代碼完全不是這麼跑的!

真實的推薦發生在某位讀者下拉刷新 For You 首頁的那一次請求裏。爲了讓你徹底看懂後面的每一條代碼規則,我們先把這一次請求裏發生的事拆成四個核心步驟:5 18 19 20

  1. 第一步:抓候選(進臨時籃子 / 召回 Retrieval) 當讀者張三下拉刷新首頁時,系統會同時派出好幾個“採購員(候選來源 Sources)”去不同的倉庫裏幫張三抓可能感興趣的帖子——比如派 Thunder 採購員去抓“張三關注的人剛發的帖子(圈內 In-Network)”,派 Phoenix 採購員去抓“雖然張三沒關注、但根據張三近期閱讀歷史 AI 覺得他會感興趣的陌生人帖子(圈外 Out-Of-Network)”,派 SimClusters 去抓“同好社區熱議或與張三收藏相似的帖子”。這幾個採購員總共會抓出幾千篇帖子,統統倒進一個**專門爲張三這一次刷新準備的“臨時候選池(臨時籃子)”**裏。
  2. 第二步:初篩與資格過濾(Pre-scoring Filters) 幾千篇帖子裏有很多不能直接端上桌的:比如張三以前已經刷到過的帖子(previously_seen_posts_filter.rs)、超過 48 小時的舊候選(age_filter.rs)、張三已經拉黑或靜音的作者(author_socialgraph_filter.rs),都會在這裏被挑出去扔掉;如果剩下的帖子還是太多(超過 2,800 篇),檢票員 FairShareRankingFilter 還會按各個採購員送來的數量比例分配 2,800 張入場券。
  3. 第三步:算預測分排座次(打分排序 Scoring & Ranking) 進到打分房間的帖子,會由 AI 模型(Phoenix 與 Value Model;Value Model 是價值模型,負責給候選帖估分排序,後文簡稱 VM Ranker)挨個端詳,提前預測(押注):“如果現在把這篇帖子展示給張三看,張三有多大概率會點贊、回覆、複製鏈接、點開細讀、或者點不感興趣?” 把這些預測概率乘上對應的權重係數加總,再套上同作者 0.625 多樣性衰減、小賬號冷啓動提拔等調整,算出來的總分就叫排序分數(Ranking Score)。
  4. 第四步:後置去重、可見性檢查與卡片組裝(Post-selection & Marshalling) 按分數高低挑出前排勝出者後,系統還會做同一串對話去重(DedupConversationFilter)、檢查安全與可見性標籤(Visibility Filtering),最後由界面組裝器(如 convo_marshaller.rs)把被選中的帖子和它的被引用原文、最多 1 條中間對話祖先、以及穿插的廣告組裝成你在屏幕上看到的首頁信息流。5 18 19 20

你看:同作者 0.625 乘數發生在第三步“打分排序”,三條串文截斷發生在第四步“界面卡片組裝”,而舊帖底下補新回覆被過濾則發生在第二步“已讀檢查”。腦子裏有了這張“臨時籃子 → 過濾 → 算預測分 → 組裝卡片”的地圖,接下來看篇數、串文和補充更新時,你就再也不會搞混它們各自管哪一段了。

4 同作者第二篇乘 0.625,程序到底在數什麼

我們先看流傳最廣的“每天最多發 2–3 篇,第二篇打 6.25 折”。Hootsuite 在 2025 年發佈的社交媒體指南里,確實建議商業賬號每天發 2 到 3 條帖子。但去查它的英文原稿就會發現,人家說的是一般日常帖子的運營節奏建議,既沒有限定爲“長文”,更沒有說“超過三條會被算法懲罰降權”。把別人的日常運營建議傳成“平臺的算法硬上限”,純屬傳話傳歪了。3

另一份常被援引的《X Algorithm Playbook》,在文章前半部分其實解釋得很準確:同一個作者的多條內容,如果在**同一次推薦響應(同一個臨時籃子)**裏碰面,會按分數高低排序、依次打折衰減。可到了文章後半部分的總結表格裏,作者卻突然把適用範圍偷換成了“一天之內發第二篇只剩 62.5% 權重”,並由此推導出了“每天最多發三篇、兩篇之間至少隔四小時”。SocialPilot 指南里關於“每日作者發文額度”的說法,也犯了一模一樣的錯誤。4 8

打開 xai-value-model/scoring.rs 源碼,裏面負責計算“作者多樣性乘數(Author Diversity Multiplier)”的核心代碼其實只有這一行:2

(1.0 - floor) * decay_factor.powf(exponent) + floor

把 VM Ranker 的公開默認參數 decay_factor = 0.5(衰減率)、floor = 0.25(保底值)代進去,數學公式就是:21

$$ m(k)=0.75\times 0.5^{k}+0.25 $$

這裏的指數 $k$ 從 0 開始起算,代表的是:在當前這位讀者剛剛刷新出來的那一個臨時候選池(臨時籃子)裏,屬於同一個作者(相同 author_id)的帖子按分數從高到低排在第幾位!

  • 你在這個籃子裏分數最高的第 1 篇($k=0$):乘數是 $0.75\times 0.5^0 + 0.25 = \mathbf{1.0}$(完全不打折);
  • 你在這個籃子裏排在第 2 篇($k=1$):乘數是 $0.75\times 0.5^1 + 0.25 = \mathbf{0.625}$(打 6.25 折);
  • 你在這個籃子裏排在第 3 篇($k=2$):乘數是 $0.75\times 0.5^2 + 0.25 = \mathbf{0.4375}$(打 4.375 折);
  • 再往後排,乘數會一步步逼近最低保底線 0.25。而且因爲是按當前籃子裏的初步分數從高到低排座次,哪怕你下午剛發的那篇比上午發的那篇更晚,只要下午那篇預測分最高,它照樣排在同作者第一位拿 1.0 滿分!2

很多朋友會問:“爲什麼我的兩篇帖子 A1、A2 會同時掉進同一個讀者的臨時籃子裏?這 0.625 又是怎麼影響排名的?” 我們不妨拿粉絲張三刷首頁的例子算一筆賬:假設你上午 10 點發了帖子 A1,中午 12 點又發了帖子 A2。張三今天上午忙工作沒看手機,下午 1 點才第一次打開 X 下拉刷新。因爲 A1 和 A2 他都沒看過,採購員就把你的 A1(假設預測得分爲 1.0)和 A2(預測得分爲 0.9),連同另一位作者寫的 B1(預測得分爲 0.8)一起抓進了張三的臨時籃子裏。只看作者多樣性乘數這一步(固定其他處理不變),算分結果如下:

候選內容套乘數前的分數作者乘數調整後
你的 A11.011.0
你的 A20.90.6250.5625
別人的 B10.810.8

你看:原本你的 A2(0.9 分)比別人的 B1(0.8 分)分更高,但因爲在張三的這個臨時籃子裏,A2 是你的第二篇作品,喫了一記 0.625 的同作者衰減,調整後變成了 0.5625 分,結果被別人的 B1(0.8 分)反超了!這個算例直觀地說明了:在同一次推薦請求裏,如果你有多篇未讀帖子同時進池,它們確實會互相競爭位置(至於 A2 最終在全站少了多少曝光,還要看其他候選帖的分數和後續步驟,不能簡單拿 0.625 當作全站總曝光掉了 37.5%)。

但是,最關鍵的轉折來了——換一位讀者李四,情況就完全變了! 假設讀者李四上午 11 點刷手機時,就已經看過了你的 A1。等李四下午 1 點再次打開 X 刷新首頁時,A1 因爲已經在李四的“已讀名單(seen_ids)”裏,在前面第二步就被過濾掉了,壓根不會進李四下午 1 點的臨時籃子!此時,李四的臨時籃子裏只有你中午 12 點發的 A2 這一篇——那麼在李四這裏,A2 就是同作者第 1 篇($k=0$),照樣按 1.0 計算(同作者第 1 篇,不打折)!

這段函數每次處理讀者的刷新請求時,都會從零新建一張臨時的作者計數表(HashMap),輸入參數只有候選帖的 author_id 和當前排序分數,代碼里根本沒有“你今天已經發了幾篇”這個全局計數器。2

當然,短時間內密集連發好幾篇,確實更容易讓還沒上線的同一批讀者在刷新時把你的多篇帖子同時抓進一個籃子裏。另外,如果你去翻代碼庫,確實能在一個叫 PopularPosts(熱門帖召回源,popular_posts.rs)的文件裏看到一句限制:“默認從近 24 小時內,每位作者最多選 5 篇”。但請注意:那僅僅是 PopularPosts 這一個單一進貨渠道自己的局部挑選上限,而真正挑大樑的關注流(Thunder)和 AI 推薦流(Phoenix)根本沒有這個 5 篇限制,絕不能把它當成全站每天只能發 5 篇的規定。22

所以,兩篇帖子之間隔幾個小時再發,可以作爲照顧讀者閱讀消化節奏的運營安排;但誰要是跟你說“算法規定隔滿四小時就能重置冷卻計時、恢復權重”,你就讓他把計時器的代碼交出來——因爲 scoring.rs 這段函數既不看錶計時,也不會在半夜 12 點歸零。我自己的實操原則很簡單:如果手頭兩篇草稿翻來覆去講的還是同一個觀點,那就直接合併成一篇寫透;如果下一篇有了全新的測試數據、新問題或新進展,隨時寫完隨時發!光換個標題炒冷飯,也改不了你頭頂上的同一個 author_id。2

4.1 兩篇長文之間插短帖,能恢復權重嗎

運營圈裏還有一種常見說法:“連發兩篇長文權重會掉,但只要在兩篇長文中間穿插發一條短帖,就能把長文的權重洗回來。”

我們得把兩件事徹底分開:第一,用短帖給長文做預告或摘錄導流,好不好用?好用!第二,中間發一條短帖,能不能在算法裏重置同作者 0.625 計數器?完全不能,甚至可能幫倒忙!

先看第一件事:X 官方的 Articles 創作者指南確實推薦“長短搭配”的分發打法——比如長文發佈前,先發一條簡短的提問或預告預熱;長文發佈後,把裏面的核心結論或精彩片段拆成短帖或串文,掛上鏈接把讀者引回全文。但官方指南里從來沒有要求你必須“一長一短交替發”來伺候算法,也沒規定每天最多兩三篇長文或必須固定寫三條串文。6

再看第二件事:代碼裏的同作者衰減函數只認 author_id,根本不管你發的是兩萬字長文、還是十個字的短帖!我們還是拿剛纔那個臨時籃子算一筆明白賬——固定其他條件不變,假設你的長文 A1 得分爲 1.0,長文 A2 得分爲 0.9。現在你在它倆中間插發了一條短帖,而且這條短帖也同時掉進了這位讀者的臨時籃子裏。我們分別算一下“短帖得分高於 A2(比如拿了 0.95 分)”和“短帖得分低於 A2(比如拿了 0.5 分)”兩種情況:

固定其他條件後A2 的 kA2 乘數A2 調整後分數
不加短帖10.6250.5625
加入短帖,分數 0.9520.43750.39375
加入短帖,分數 0.510.6250.5625

結果一目瞭然:

  • 如果插進去的短帖表現神勇(0.95 分),排在了長文 A2(0.9 分)的前面,那長文 A2 在你名下的排序位置就從第 2 名($k=1$)被擠到了第 3 名($k=2$),乘數直接從 0.625 暴跌到 0.4375,調整後分數只剩 0.39375!
  • 如果短帖分低(0.5 分)排在 A2 後面,或者短帖壓根沒進這個籃子,那 A2 還是排第 2 名($k=1$),乘數依然是 0.625。 不管哪種情況,代碼裏都絕對沒有“遇到一條短帖就把作者計數器清零”的邏輯(當然,表裏的分數變化只代表這一步的乘數計算,不直接等同於最終曝光的增減比例)。

拿“怎麼跟客戶談報價”這個選題來說:你的長文章裏可以放完整的各檔方案對照表、標準回覆話術和不接單的紅線情況;而配套發的短帖,就專門挑出讀者最頭疼的一個具體場景,比如**“客戶開口就說預算不夠,報價單裏的哪些項目可以先砍掉延後?”**——在短帖裏直接把判斷標準和一個真實案例寫出來,最後再附上長文入口。

等過兩天,評論區又有人問出另一個新痛點:“客戶痛快接受了報價,但在交付過程中沒完沒了地追加小修改怎麼辦?” 這時候就非常值得單獨再寫一條新帖來回答,因爲這是一個全新的具體問題。相反,如果只是爲了迷信“長短交替洗權重”,硬湊一條毫無信息量的水貼(比如光喊一句“今天剛發的這篇乾貨大家一定要看!”),不僅算法裏洗不掉半點衰減,讀者看了也只會覺得你在刷屏。

4.2 同作者之外,相似內容還可能在另一輪選擇中競爭

很多懂一點技術的朋友還會追問一個更深的問題:“聽說除了同作者衰減,X 還有一套專門過濾相似內容的 DPP 算法。那我每次發帖前,能不能自己在電腦上用開源大模型把草稿轉成向量(Embedding)查個重,或者換幾個近義詞來躲過查重?”

在 vm-ranker/scoring/dpp_model.rs 和 dpp.rs 裏,確實有一套 DPP(Determinantal Point Process,行列式點過程)多樣性選擇機制。它的作用是在適用的請求裏(取決於 DPP 上下文、開關和產品條件),同時結合帖子的預測分數和多模態內容向量表示,從候選池裏挑出一組既高分、又題材不撞車的內容組合。85

我根據源碼邏輯做過一個簡化的數學算例:假設候選池裏有三條帖子,初步得分依次是第 1 條 1.0 分、第 2 條 0.99 分、第 3 條 0.8 分。其中第 1 條和第 2 條的內容向量完全重合(講的是同一件事),而第 3 條的內容向量跟它倆完全正交(講的是另一個新話題)。當 DPP 要從中挑出兩條時,最終勝出的是第 1 條(1.0 分)和第 3 條(0.8 分)!代碼會保留被選中帖子的分數,而把沒被選中的第 2 條(哪怕它原本有 0.99 的高分)的分數直接置爲 0 分。補一句邊界:這裏說的「置零」,是把它的分數壓到 0、排到隊尾,不是把帖子從系統裏刪掉;如果整個池子里正分候選不夠填滿名額,後面的 top_k_score_selector.rs 還可能把零分候選兜底撈回來。。85

那爲什麼你沒法自己在本地電腦上提前把文章轉成向量來查重,也沒法靠“換幾個近義詞”矇混過關? 因爲 X 用來生成帖子語義表示的,並不是你在網上隨便下載的某個通用開源文本模型,而是它內部不公開模型權重的 Grox 多模態模型(grox/flows/mm_emb),並且還會把多模態語義 ID 和經過哈希處理(哈希=把 ID 攪成一串固定長度的數字指紋,模型只認指紋不認原名)的作者 ID 組合在一起。更重要的是,多模態大模型提取的是整段文字和圖片的深層語義,防的就是“換湯不換藥”。連續寫同一個領域的話題時,與其費盡心機把同一句結論換十種說法、改幾個近義詞,不如每一篇都實打實補上不同的測試證據、失敗案例或新使用場景——內容真正有了新東西,向量自然就拉開了距離。

5 三條串文的依據,主要在展示方式

爲什麼國內外那麼多運營教程都在異口同聲地建議:“寫串文(Thread)最好寫成 3 條”?

先看官方自己的說法:X 官方幫助中心的《如何創建串文(Create a thread)》頁面明確寫到,當你刷到已經關注的作者發佈的串文時,如果是 2 到 3 條,通常會在時間線上連成一組直接展示出來;一旦達到 4 條及以上,時間線上就會把中間截斷摺疊,只提供一個“展開整串(Show this thread)”的點擊入口。注意,官方這裏描述的是“已關注作者在時間線上的常規展示方式”,並不是對所有推薦流結果的絕對承諾。23

再去翻公開算法庫,我們在界面組裝模塊 home-mixer/util/urt/convo_marshaller.rs 裏找到了與這個“3 條”嚴絲合縫對應的硬核代碼!代碼裏定義了一個常量 NUM_INTERMEDIATE_ANCESTORS = 1(最多隻保留 1 條中間祖先帖),然後按下面這幾行邏輯把帖子拼成首頁上的對話卡片:18

const NUM_INTERMEDIATE_ANCESTORS: usize = 1;

let item_ids: Vec<u64> = root
    .into_iter()
    .chain(intermediates.iter().copied())
    .chain(std::iter::once(focal_id))
    .collect();

很多不寫代碼的朋友第一次看到“根帖(root)+ 1 條中間祖先帖(intermediates)+ 當前被選中的候選帖(focal_id)”會一頭霧水:“這到底是幹什麼用的?跟寫 3 條串文有什麼關係?”

我們把它還原成讀者刷手機時的真實畫面,你一下就全明白了: 首先,這段代碼是在打分排序和篩選全部結束之後纔出來幹活的,所以打分公式裏沒有任何給 3 條串文加分、或給第 4 條扣分的規則。18 但是,更容易被所有創作者漏掉的殘酷真相是:當你的串文有好幾條時,系統最後選出來展示在讀者首頁上的那條“中獎帖(focal_id)”,不一定是前三條,更可能是最後一兩條! 上游的 Thunder 關注流和 Phoenix 回覆祖先補齊流程(phoenix_reply_ancestors_hydrator.rs),會給選中的回覆帖帶上它的“第一條根帖(root)”和“直接回復的上一條父帖(parent)”。假設你發了一條一氣呵成的直線串文(1 → 2 → 3 → …),並且最後一條分帖在打分中勝出、被選中要展示到讀者首頁上。我在本地照着 convo_marshaller.rs 的代碼重算了一遍,不同長度的串文在讀者屏幕上組裝出來的卡片序號是這樣的:18

串文與本次選中的候選這個模塊組出的帖子序號
共三條,選中第 3 則1、2、3
共四條,選中第 4 則1、3、4
共十條,選中第 10 則1、9、10

你看懂上面這張表有多嚇人了嗎?!

  • 如果你的串文一共只有 3 條,當第 3 條被選中時,系統拿出“根帖(第 1 條)+ 1 條直接上一條(第 2 條)+ 當前選中帖(第 3 條)”拼成卡片端給讀者——讀者在首頁上一眼看到的就是完整的 1、2、3,起承轉合一條都不漏!
  • 可如果你的串文寫了 10 條,當第 10 條被選中時,系統同樣只拿“根帖(第 1 條)+ 1 條直接上一條(第 9 條)+ 當前選中帖(第 10 條)”——結果讀者在首頁刷到的對話卡片,直接變成了詭異的 1、9、10!你辛辛苦苦在第 2 條到第 8 條裏寫的全部推導過程和鋪墊,在首頁卡片上被直接跳過隱身了!(當然,這是假設直線串文且末條入選的示例;實際選中哪一條、祖先數據是否齊全、中間有沒有刪帖都會影響結果,十條串文未必每次都顯示 1、9、10,但核心風險在於:中間的分帖隨時可能不在首頁首屏的組合卡片裏!)

設想一下:如果你在第 9 條的開頭只寫了一句“所以根據上面的分析,答案就很清楚了”,那一個在首頁只刷到 1、9、10 卡片的讀者,根本不知道你說的“上面的分析”是啥!反過來,如果你把第 9 條改成:“當網站設計報價超過客戶預算時,第一步是先縮小這次交付的頁面範圍,比如先做首頁、把 3 個內頁留到二期”——這樣哪怕讀者只看到 1、9、10,每一條分帖本身也把問題和結論交代得明明白白。所以發串文前,一定要把重要的分帖單獨拎出來讀一遍,看看去掉上下文別人還能不能看懂。

5.1 整條 thread 只佔一個作者名額嗎

《X Algorithm Playbook》裏還教過一招:“把多篇內容合成一條 Thread 發,整條 Thread 在算法裏只佔 1 個作者名額,能躲開同作者 0.625 衰減。”

去查源碼,系統裏確實有一個叫 DedupConversationFilter(dedup_conversation_filter.rs,對話去重過濾器)的東西,它的作用是在同一段對話(同一個 conversation_id)的多條候選中,只保留得分最高的那一條,把同串裏其餘分低的分帖刪掉,最後再把勝出者組裝成一個首頁對話卡片。4 19

但是!魔鬼全在“先後順序”裏! 打開 candidate_pipeline.rs 和 phoenix_candidate_pipeline.rs 查一下執行順序就會發現:整條推薦流水線是先送進打分器(Scorers,包含 VM Ranker)算完分、做完候選挑選(Selection),最後才跑後置過濾器(Post-selection filters,也就是 DedupConversationFilter)!而在送進 VM Ranker 打分的那一刻(vm_ranker_request.rs),程序傳過去的依然是一條條獨立的帖子 ID(tweet_id)和它們背後一模一樣的作者 ID(author_id),根本沒有先把整條串文打包合併成一個候選再去算作者數!19

翻成大白話就是:當你發了一條 5 段式的串文,只要裏面有兩三條分帖同時闖過了前面的初篩、掉進同一個讀者的臨時籃子裏,它們在打分環節就會先自己跟自己搶名額、實打實地觸發 0.625、0.4375 的同作者衰減!等它們互相砍完分數、挑出勝者之後,DedupConversationFilter 纔出來把同串裏落敗的分帖清理掉。 所以,串文雖然方便你把連貫的話題穿成一串,但千萬別指望靠它繞開同作者衰減,更不建議把一篇本來能寫進單篇長 Post 的內容硬拆成十幾條碎串文去互相搶權重。

5.2 用一個具體問題,試寫三條串文

真正動手寫串文時,除了上面說的“分帖自相殘殺”和“中間樓層被摺疊”,還有一個更現實的門檻:沒關注你的陌生讀者(圈外 Out-Of-Network),到底能刷到你串文裏的哪一條?

在我們覈查的 Phoenix 推薦候選流程中,有一個專門處理圈外轉發和回覆的過濾器叫 oon_retweet_reply_filter.rs。它裏面控制“是否放行未關注作者的回覆帖進入推薦流”的開關 EnablePhoenixOonReplies,在公開配置裏的默認值是 false(關閉)! 要知道,一條串文除了第 1 條(根帖 Root)是原創帖之外,從第 2 條開始往後的所有分帖,在數據結構上統統都是“回覆貼(in_reply_to_tweet_id 有值)”!也就是說,在 EnablePhoenixOonReplies = false 的默認設置下,後續的第 2、3、4 條分帖在這條普通推薦管線裏會被直接攔截,沒關注你的陌生人往往只有機會刷到你的第 1 條(根帖)。就算線上某些實驗把這個開關打開了,也還有召回來源、根節點等額外條件,不是開了就全放行。另外這隻管首頁這條推薦路徑:讀者點進對話詳情頁、或者已經關注你的粉絲,照樣能看到後續分帖。。24

正因爲陌生人極大概率只能先刷到你的第 1 條,如果你在第 1 條裏只寫一句吊胃口的廢話——比如“關於怎麼跟客戶談報價,我用下面十條給大家講清楚,最後一條最關鍵,往下看👇”——那你就等於把真正有價值的乾貨全都藏在了陌生人根本刷不到的後半截裏,只看到第 1 條的陌生人一頭霧水,直接就划走了!

如果一個具體問題剛好適合用 3 條串文 講清楚,怎麼寫才能既讓陌生人看第 1 條就拿走乾貨,又讓點開看全串的讀者獲得完整方案?我們拿“自由職業者怎麼應對客戶嫌報價貴”來寫一組可以直接套用的 3 條串文模板:

第一條(根帖:直接亮出核心判斷與原則,絕不空喊口號):

1/3 客戶說“太貴了”,先別急着打折。

把報價包含的成品、修改次數和交期列出來。預算確實不夠,再談刪掉哪些項目。

只降價卻照單全做,後面很難談追加費用。

第二條(中間帖:直接給出一眼看懂的方案對比,教讀者具體怎麼操作):

2/3 拿網站設計舉例:

原方案:首頁+3 個內頁,修改 2 輪。 縮減方案:這次先做首頁,內頁留到下一階段。

把兩個方案的費用分開列,讓客戶知道少付的錢對應少做哪些事。避免“便宜一點,其他照舊”。

第三條(末尾帖:補上邊界底線、給一句能直接複製發送的話術,最後再自然提問互動):

3/3 如果客戶要求“全部照做,只是降價”,問題就不是方案太大。

可以這樣回:“這個預算我能提供的是 A 方案。如果內容和交期都不調整,我無法按原規格承接。”

你遇到的“太貴”,通常是在談預算,還是在要求全做又降價?

你看這三條:哪怕陌生讀者只刷到第 1 條,他已經拿到了“降價必減交付範圍”的核心方法;如果粉絲在時間線上刷到 1、2、3 組合卡片,第 2 條展示了怎麼拆頁面,第 3 條連現成的回絕話術都喂到了嘴邊。像這種單一痛點的小閉環,用 3 條串文剛剛好。但如果你的內容是一份包含五張測試對比圖和三個反例的硬核測評報告,那就老老實實用一篇完整的長 Post 或 Article 把所有證據一次性鋪開,最多另外發一條 3 段式的摘要串文去導流,千萬別爲了硬湊“3 條串文”而把關鍵測試證據給刪了。

順便提一句,網上常有人爭論“發串文和發單篇長 Post 到底哪個流量更好”。Hootsuite 團隊曾在 2024 年 1 月做過一次真人對照實驗:讓同一個賬號先後發了 3 組串文和 3 條單篇長帖。結果是兩種格式裏各跑出了一篇爆款,打了個平手。但仔細看實驗條件就會發現:作者是在髮長帖階段纔剛開通的 Premium 會員,兩邊寫的選題不完全一樣,而且統計串文數據時只算了首條帖子的曝光。這 6 篇樣本可以作爲一個有趣的參考案例,但既不能證明 2026 年的今天哪種格式包贏,也不能證明“3 條就是全宇宙最優解”。25

這套“單條信息獨立完整”的原則,同樣適用於你去別人帖子底下留言回覆,以及怎麼放外部鏈接:

  • 去別人帖子下回復時:如果原帖作者問了一個你剛好懂的具體問題,那就直接把乾貨答案留在他的評論區裏。如果聊着聊着碰撞出了另一個值得展開的新話題,那就把前因後果補齊,單獨發成一條你自己的原創帖——千萬別直接把評論區裏那句沒頭沒尾的“正如我剛纔說的……”複製出來發帖,因爲刷到你主頁的陌生人根本不知道你剛纔跟誰聊了什麼。
  • 需要在帖子裏放外部鏈接時:核心是看讀者點開鏈接到底要幹嘛。比如你要送讀者一份能直接複製使用的報價單模板,那就在正文裏先把“這份模板包含哪幾個核心字段、怎麼用”講明白。如果你出於版面整潔考慮,選擇把鏈接放到第一條評論(首條回覆)裏,別忘了那本質上是另一條回覆帖,讀者得多點一步才能找到;至於“把外鏈挪到首條評論就能逃避處罰、多拿曝光”的說法,從公開代碼裏完全找不到依據(後面外鏈章節我們會專門拆解 v2 規則)。

6 “作者回一句,等於 150 個贊”的數字來自 2023 年(徹底搞懂“事前算命押注”與“事後記賬”的區別)

平時看網上的 X 運營攻略,最容易讓人熱血沸騰的就是各種“加分倍率表”:什麼“讀者評論後作者再回一句,一次來回等於 150 個贊”、“讀者從時間線點進你主頁並點關注,直接加 4 分”、“有人點一次複製鏈接就加 20 分”、“被舉報一次抵消 468 個贊”。

有趣的是,X 的 xai-value-model/scoring.rs 源碼註釋裏,還真原封不動出現過“一次舉報抵消 468 個贊”這句話——但程序員寫這句話,是爲了把它當成典型的錯誤理解靶子來批評!緊挨着這句話旁邊,源碼註釋清清楚楚地寫着一句警告:2

// watch time -- the weights do not multiply raw engagement counts.

翻譯成大白話就是:“注意!這些權重係數乘的根本不是實際發生的互動次數!” 誰要是拿“你的帖子實際收到了幾個贊、幾次轉發、幾次複製鏈接”直接去乘權重表裏的數字,那他算的根本就不是這套推薦系統的代碼!

那句流傳甚廣的“作者去評論區回一句頂 150 個贊”又是從哪來的呢?去翻 2023 年 4 月 5 日 Twitter 第一次開源時的舊版 Heavy Ranker 文檔,裏面確實有下面這三行參數(省略其餘行):26

scored_tweets_model_weight_fav: 0.5
scored_tweets_model_weight_reply: 13.5
scored_tweets_model_weight_reply_engaged_by_author: 75.0

你看:75.0 ÷ 0.5 = 150,除法算術本身沒算錯。但錯在了兩個致命地方: 第一,這是 2023 年 4 月早就淘汰的舊架構參數,現在的 xai-org/x-algorithm 早就不是這套係數了; 第二,哪怕在 2023 年,75.0 乘的也是“AI 預測當前這位讀者會留言回覆、並且作者會和這條回覆互動”的預測概率,從來沒有規定“作者去評論區每敲一行字回覆,系統就給原帖記賬兌現 150 個讚的曝光”。26

到了如今的 2026 年新版融合計分代碼(scoring.rs)裏,依然是嚴格的“權重 × 預測值”寫法,比如點贊項和回覆項的代碼是這樣的:2

apply(scores.favorite_score, weights.favorite),
apply(scores.reply_score, weights.reply_weight_for(candidate)),

把互動概率這一部分的計分邏輯寫成數學公式,就是:

$$ S_{\mathrm{engagement}}(u,p)=\sum_i w_i,P(a_i\mid u,p) $$

你看懂這個公式裏的字母代表什麼,就徹底頓悟了:$u$ 是此時此刻正在下拉刷新首頁的那位具體讀者(User),$p$ 是臨時籃子裏待打分的那篇候選帖子(Post),$a_i$ 是某種互動動作(比如點贊、回覆、關注、複製鏈接),而 $P(a_i\mid u,p)$ 就是 AI 模型在帖子展示給這位讀者之前,提前算命押注算出來的“這位讀者看到這篇帖子後做這個動作的概率”!

換一位讀者刷首頁,因爲他的閱讀習慣和歷史偏好不同,AI 對同一篇帖子算出來的預測概率 $P(a_i\mid u,p)$ 就會完全不同(完整的排序分數還會加上後面講的停留時間預測值以及同作者衰減等調整,上面這個式子專門用來看清互動權重到底在乘什麼)。2 5

這時候很多創作者會問:“既然排序分數是在讀者看到帖子之前‘事前算命’算出來的,那讀者看完帖子之後,真正去點了贊、點了關注、或者複製了鏈接,豈不是一點用都沒有了?”

當然有用!而且大有用處——只不過它不是給你做“事後記賬加分”,而是作用在“下一波刷首頁的讀者”身上! 在公開的 Home 模型配置(phoenix/xrex/configs/xrecsys.py)裏,明確開啓了真實互動計數(engagement counts)作爲上游 AI 大模型的輸入特徵(特徵=餵給模型看的一項項數據,比如這篇帖子已經攢了多少贊、讀者過去點過什麼);而且後面要講的小賬號冷啓動抽樣(Thompson sampling)也會直接讀取真實的點贊數 fav_count。 也就是說:當第一批刷到你帖子的讀者,真的紛紛點開細讀、複製了鏈接、或者順着帖子點進你主頁點了關注,這些真實發生的互動計數會立刻變成這篇帖子的實時特徵餵給上游 AI 模型。等下一秒成千上萬個同類型的陌生讀者下拉刷新首頁時,AI 給他們算出來的“預測點贊概率、預測複製鏈接概率、預測關注概率”就會水漲船高!所以最準確的區別是:最終融合打分公式不會按“實際點贊數 × 0.66”給你記死賬,但真實的互動數據會餵給上游模型和其他環節,撬動下一波讀者的預測概率!84

爲了讓你直觀感受到“預測概率 × 權重係數”是怎麼打破常規直覺的,我們拿真實代碼裏的兩個參數算一筆賬: 在當前公開默認值裏,一般回覆(Reply)的權重係數是 5,而複製鏈接(Share via copy link)的權重係數高達 20。光看係數,複製鏈接是回覆的整整 4 倍對吧? 但假設現在讀者張三刷首頁,AI 根據張三平時的習慣,預測他看到你這篇帖子有 2%(0.02) 的概率會留言回覆,但只有 0.1%(0.001) 的概率會去點“複製鏈接”(且假設不涉及互關等額外加成)。那麼在給張三算分時:

  • 回覆項貢獻的分數 = $5 \times 0.02 = \mathbf{0.10}$ 分;
  • 複製鏈接項貢獻的分數 = $20 \times 0.001 = \mathbf{0.02}$ 分。

你看!雖然複製鏈接的權重係數(20)比回覆(5)大得多,但由於發生概率差了 20 倍,在這次打分裏,反而是係數較小的“回覆項”幫你的帖子拿到了 5 倍於複製鏈接的分數!(注:這是幫助理解乘法邏輯的示意計算,不是對特定真實賬號的線上預測。)21

7 停留係數增加了 50%,這次能找到前後版本

網上傳言“10 月份 X 把閱讀停留權重提高了 50%,點贊權重漲到了歷史最高點 0.66”,這回是不是真的?

如果只看同一個 Git 提交快照,你會發現一個有趣的現象:在 Home Mixer 服務裏,連續停留時間係數(ContDwellTimeWeight)的默認值是 0.006;而在另一個 VM Ranker 服務裏,同名參數的默認值卻是 0.004。雖然 0.006 比 0.004 正好高出 50%,但我們絕不能拿同一時刻兩個不同微服務之間的默認差值,來證明“這個月漲了五成”。要證明它在時間上漲了 50%,必須順着同一個文件 home-mixer/params/param.rs 的 Git 修改歷史往前翻。12 15 27

爲此,我沿着 home-mixer/params/param.rs 的提交記錄,逐一覈對了整個 10 月份的 20 個參數快照:

  • 在 10 月 9 日的快照裏,ContDwellTimeWeight 的值確實還是 0.004;
  • 到了 10 月 13 日的快照裏,它被正式改成了 0.006(實打實增加了 50%)!
  • 同一時期,點贊權重 FavoriteWeight 先是在 10 月 13 日從 0.5 升到了 0.6,緊接着在 10 月 14 日又從 0.6 升到了 0.66;而“不感興趣(NotInterestedWeight)”的負向懲罰也同步加重了 10%。

前後的代碼歷史完全證實了“連續停留係數在 10 月份上調了 50%”這一事實(同樣要提醒的是:表裏的日期是公開代碼快照的提交日期,不代表線上每一個實驗分桶都在同一秒鐘切換)。15

首次在已查節點觀察到的日期(UTC)Home Mixer 參數前一個已查值該公開快照的值
2026-10-13ContDwellTimeWeight0.0040.006;係數增加 50%
2026-10-13FavoriteWeight0.50.6
2026-10-13VideoOpenWeight0.070.02
2026-10-14FavoriteWeight0.60.66
2026-10-14NotInterestedWeight−47.52−52.272;負向係數絕對值增加 10%

來源 15

至於網上傳的“點贊權重 0.66 創下歷史最高”,說話必須留好邊界:0.66 確實是我們覈查過的 10 月份 20 個公開快照裏最高的 FavoriteWeight,但由於沒有 X 誕生以來所有未公開歷史配置的數據,不能滿口保證它是“全歷史最高”。更關鍵的是,哪怕漲到了 0.66,點贊在所有正向行爲裏依然只是個“弟弟”——一般回覆、帶評論引用(Quote)和私信分享的係數都是 5,關注作者是 4,複製鏈接和符合互關條件的原創帖回覆預測更是高達 20!15 27

7.1 兩處公開默認值,有哪些差別

爲了讓你隨手就能查到當前代碼裏每一項行爲的真實權重,我把 Home Mixer 和 VM Ranker 兩個服務裏全部 24 項預測參數的公開默認值並列整理成了下面這張大表,並在最後一欄用大白話寫清了每一項到底該怎麼讀:14 21 27

預測項目Home Mixer 默認值VM Ranker 默認值如何理解
點贊 Favorite0.660.5乘個性化點贊預測概率;絕不是每收到一個贊就入賬 0.66 分
一般回覆 Reply55乘讀者留言回覆的預測概率
符合互關條件的回覆預測項5+15=205+15=20候選必須不是 reply、不是 retweet(即必須是原創帖),且讀者與作者互相關注
普通轉發 Retweet11指直接點轉發(Repost),與帶評論的引用(Quote)分開計算
引用 Quote55帶評論轉發的預測係數是 5;但不能由 5 比 1 直接推出曝光必然是普通轉發的五倍
私訊分享 Share via DM55係數乘私信分享預測概率,不是每私信發一次就加五分
複製鏈接 Share via copy link2020最大的普通正向係數之一;與合資格的互關回復項並列高達 20
點擊 Click0.30.3乘普通點擊預測;不等於讀者點開秒退時的最終總分
打開視頻 Video open0.020.07兩個服務默認值不同;也僅代表打開視頻這一項,不是視頻全部作用的總和
VQV(視頻品質觀看)00這個具名打分項默認係數爲 0,但不代表所有視頻觀看時長在系統裏都沒用
停留事件 Dwell0.050.05基礎停留事件的二元預測概率,與連續停留秒數、點擊停留分開算
連續停留 ContDwellTime0.0060.004乘模型預測的連續停留時間數值(秒)
點擊停留 ContClickDwellTime0.40.4點開後深度停留達標的預測概率(門檻值 10.0);注意:這個 10 的單位、以及模型輸出怎麼轉成打分字段,公開代碼沒交代(見第 11.3 節),別當成“看滿 10 秒就加 0.4 分”
關注作者 Follow author44預測讀者看完帖子後順手關注作者的概率;並非按你現有粉絲數每人固定加四分
不感興趣 Not interested−52.272−47.52乘當前讀者的“點不感興趣”負向預測概率;不是全站共同扣點
Post unexplored0.0150.02這是名字就叫 Post unexplored 的一項預測;是否包括關係網外候選另有條件,不是每篇帖子的保底探索曝光額度
一般分享 Share22獨立於私信分享和複製鏈接的系統分享動作,乘對應預測值
打開外鏈 Open link0.20.2乘讀者點擊打開外部鏈接的預測概率;不是帖子只要帶 URL 就白送 0.2 分
展開圖片 Photo expand0.050.05乘讀者點擊展開查看大圖的預測概率
點擊被引用帖子 Quoted click0.050.05乘點擊內部被引用原帖卡片的概率,與引用行爲本身及普通點擊分開
屏蔽作者 Block author−31.2−31.2乘當前讀者拉黑屏蔽作者的預測概率
靜音作者 Mute author−58.8−58.8乘當前讀者靜音(Mute)作者的預測概率
舉報 Report−234−234乘當前讀者舉報帖子的預測概率(全場最重懲罰),不能直接按實際舉報次數扣點
未停留 Not dwelled−0.02−0.02乘讀者一眼划走(未停留)的預測概率;與“看了但沒點贊評論”完全不是一回事

來源 14 21 27

看到這裏你可能會好奇:“爲什麼同一套代碼庫裏,Home Mixer 和 VM Ranker 會存着兩套略有不同的默認參數?到底哪一套纔是算數的主力?” 順着調用鏈(home-mixer/scorers/vm_ranker.rs)查下去,它們倆的配合流程是這樣的:

  1. Home Mixer 會先用自己的本地參數算出一份初步分數,並據此做好**小賬號冷啓動(Cold Start)**的提拔決策;
  2. 緊接着,Home Mixer 會發起一次遠程調用(RPC)去請 VM Ranker 服務做最終打分——發過去的請求裏帶着各項預測概率(prediction heads),並要求計算價值模型(compute_value_model);
  3. VM Ranker 收到請求後,會從它自己的 vm-ranker/params.rs 裏讀取權重係數來算分(如果某個候選帖身上已經帶了緩存好的加權分數 weighted_score,共用程序也可以直接沿用);
  4. 如果這次 RPC 調用成功返回,Home Mixer 就會採用 VM Ranker 算出來的分數;萬一 RPC 調用失敗超時,纔會退回(fallback)使用 Home Mixer 自己剛纔算的本地分數!因此,分析具體路徑時,到底讀哪個服務、有沒有命中緩存、以及線上實時配置開關(feature switches)怎麼設,都會決定最終用哪組數字。12

同時,我們也得客觀認識這些“公開默認值”的含金量:官方在倉庫 README.md 裏明確說明,他們使用定時任務(cron)把生產環境裏的主要正式默認配置自動同步到公開代碼庫中,並儘量讓佔用顯著流量比例的實驗在代碼裏可見;比如在 5ed7963 快照的 home-mixer/params/param.rs 文件第一行註釋裏,就清楚印着最後一次自動同步的時間戳:2026-10-27T16:00:37Z。這說明表裏的數字絕不是程序員隨手亂填的假範例,而是貨真價實的生產環境基準參考;只不過線上真實請求依然會動態讀取配置中心(configuration system),公開快照沒辦法把每一位讀者當下命中的灰度實驗開關全都列出來。12

7.2 係數漲了五成,總分會漲多少

看到“連續停留時間權重從 0.004 漲到 0.006,暴漲 50%”,有些做長文的博主歡呼雀躍,以爲自己的長文總分和曝光量馬上也要原地暴漲 50%。

我們不妨動筆算一道小學算術題,幫你瞬間冷靜下來: 固定一個假設場景:AI 模型預測某位讀者會在你的帖子上停留閱讀 5 秒鐘,而點贊、回覆、點擊等其他所有項目的原始加權和加在一起合計爲 0.20 分。

  • 當連續停留係數是舊版 0.004 時,停留這一項貢獻 $0.004 \times 5 = 0.020$ 分,加上其他項 0.20,原始總和是 0.220 分;
  • 當連續停留係數漲了 50% 變成 0.006 時,停留這一項貢獻 $0.006 \times 5 = 0.030$ 分,加上其他項 0.20,原始總和變成了 0.230 分。

在還沒套用後續的分數平移(offset)、同作者多樣性衰減與其他調整之前,整體原始總分只是從 0.220 變成了 0.230,實際總分只增加了約 4.5%(而不是 50%)!這還是保持其他預測值不變的純算術演示(真實線上模型升級後,預測出來的秒數本身也會變)。15 27

假設預測停留 = 5 秒,其他原始加權項合計 = 0.20
舊值:0.20 + 0.004 * 5 = 0.220
新值:0.20 + 0.006 * 5 = 0.230
停留項增加 50%;這個假例的原始總和增加約 4.5%
以上尚未套其他排序處理,也沒有換算曝光。

來源:15 27

用同樣的道理去看權重表裏的其他數字,你就不會再被忽悠了:

  • “複製鏈接 20”、“關注作者 4”、“不感興趣 -52.272”,統統都是乘在預測概率上的係數,不是每發生一次實際動作的計件獎罰;
  • 讀者“點開你的帖子看了一眼就退出去”,也不能簡單算成“白賺 0.3 分點擊分”——因爲融合公式是把所有正負預測項加在一起算的,如果他點開秒退,模型對他算出來的深度停留概率就會極低,甚至可能伴隨較高的負向預測;
  • 至於誘人的“互關好友回覆預測 5 + 15 = 20”,代碼硬性規定只作用於**原創候選帖(!is_reply && !is_retweet)**本身被回覆的概率預測——如果你跑到大 V 帖子底下發評論搶前排,你發的那條評論本身是 is_reply = true,直接被排除在外,一分錢互關加成都拿不到!27

所以,10 月份的參數對比真正告訴我們的是:系統確實越來越重視“讀者願不願意停下來把內容讀進去”,閱讀信號值得跟互動信號放在同等重要的位置上看待;但它絕沒有證明“在開頭寫十句廢話硬拖夠多少秒”、“瘋狂找人互關”、或者“在文末求每個人點一下複製鏈接”就能穩拿高曝光。要驗證哪種寫法真正漲流量,還得看賬號實測數據和受控對比,本文不做脫離證據的玄學承諾。

8 轉發和只看不互動,差距真有二十倍嗎

很多寫深度乾貨的創作者盯着上面的權重表,心裏會咯噔一下:普通轉發(RetweetWeight)的默認權重是 1.0,而基礎停留事件(DwellWeight)的默認權重只有 0.05——下面是直接從 home-mixer/params/param.rs 裏摘出來的兩行源碼:21

param!(RetweetWeight, f64, "rust_home_mixer_retweet_weight", 1.0);
param!(DwellWeight, f64, "rust_home_mixer_dwell_weight", 0.05);

看到 $1.0 \div 0.05 = 20$,不少人立馬得出一個悲觀的結論:“完了!轉發一次的權重比只看不互動高了整整 20 倍!我的長文大家都是默默看完不轉發,在算法眼裏豈不是虧到姥姥家了?”

代碼覈對並重算後的真相,恰恰跟你想的相反! 首先,這兩項乘的都是預測發生概率。沒錯,如果其他項不變,把轉發預測概率提高 1 個百分點(+0.01),原始加權和會增加 $1.0 \times 0.01 = 0.01$ 分;把基礎停留概率提高 1 個百分點,則增加 $0.05 \times 0.01 = 0.0005$ 分,“20 倍”僅僅是這兩個“每增加 1% 概率”的增量比例,絕不能換算成“現實中 1 次轉發抵得上 20 次閱讀觀看”!2

爲什麼?因爲在現實生活裏,一個讀者刷到好帖子“停下來閱讀”的概率,遠遠高於他順手點“轉發”的概率! 我用本地重寫的計分程序跑了一組最常見的算例:假設對某位讀者,AI 預測他轉發你這篇帖子的概率是 2%(0.02),而預測他停下來閱讀(觸發基礎停留事件)的概率是 60%(0.60)。那麼:

  • 普通轉發項貢獻的分數 = $1.0 \times 0.02 = \mathbf{0.02}$ 分;
  • 基礎停留事件貢獻的分數 = $0.05 \times 0.60 = \mathbf{0.03}$ 分!

你看,哪怕只比這單一一項,不管用 Home Mixer 還是 VM Ranker 的公開默認值算出來,係數只有 0.05 的基礎停留項(得 0.03 分),當場就反超了係數爲 1.0 的普通轉發項(得 0.02 分)!(注:這是固定假設概率後的局部算例,未使用真實賬號線上數據。)

更何況,當一個讀者“只看不點贊、不評論、不轉發”時,在推薦系統的代碼裏,他觸發的根本不止 0.05 那一個指標,而是整整一串“閱讀停留家族”同時疊加發力! 把普通轉發和與閱讀相關的預測項放在一起對比,你會看得更清楚:21

預測項目Home MixerVM Ranker讀法
普通轉發 Retweet1.01.0乘讀者點普通轉發的概率
停留事件 Dwell0.050.05乘基礎停留事件的概率
連續停留 ContDwellTime0.0060.004乘模型預測的連續停留秒數(比如看 30 秒就是 0.006 × 30 = 0.18)
點開後停留 ContClickDwellTime0.40.4乘點開帖子後深度停留(超過閾值 10)的概率(另外普通點擊 Click 還有 0.3)
未停留 Not dwelled−0.02−0.02乘讀者一眼划走(未停留)的概率

千萬別把“讀者看完了但沒點贊沒評論”當成表裏倒數第一行的“未停留(Not dwelled)”!

  • “未停留(Not dwelled,權重 -0.02)”:指的是讀者在時間線上看到你的帖子一眼略過、手指頭都不帶停頓地直接划走了;
  • “默默讀完但沒互動”:讀者不僅沒有觸發 -0.02 的划走懲罰,反而會同時觸發普通點擊(Click 0.3)+ 點開後深度停留(ContClickDwellTime 0.4)+ 基礎停留(Dwell 0.05)+ 連續停留秒數(ContDwellTime 0.006 × 秒數),甚至在第一步抓候選時還會激活新增的 ld 深度閱讀召回分支(權重 0.75)!把這幾層加在一起,一個“只看不說話”的深度讀者貢獻的排序分數,往往是普通轉發的好幾倍!(當然,前臺顯示的公開觀看數 Views 也不能直接拿來代入上面某一項去換算固定分數。)2 28

「點開後停留」(CLICK_DWELL_TIME,係數 0.4)在模型裏是一個「達標/不達標」的二選一判斷——原始數值嚴格大於門檻 10.0 就算達標,模型算出來的是「這位讀者達標的概率」(0 到 1 之間),再乘上 0.4 進總分。有兩個地方公開代碼沒交代:一是這個原始數值到底以什麼爲單位(常識上猜是秒,但生成它的上游代碼沒公開);二是模型算出的概率、轉成 Home Mixer 裏 click_dwell_time 字段的那段中間轉換代碼(adapter)也沒公開。所以別把 0.4 理解成「每多看一秒就加 0.4 分」,更不能拿它去算「一次轉發等於看幾秒」。它跟前面 0.05 的基礎停留是兩個獨立的判斷,不要混在一起。28

既然“默默閱讀”在打分時這麼能打,那“普通轉發(Retweet)”真正的獨家價值到底是什麼? 答案不在打分表裏,而在第一步的**“關係網召回通道(Thunder)”裏! 假設讀者甲根本不認識你(也沒關注你),但甲關注了你們行業的同行大 V 乙。當同行乙覺得你的乾貨有用、順手點了一下“普通轉發(Retweet)”之後,會發生什麼? 在 thunder/posts/post_store.rs 裏,系統會把乙的這筆轉發記錄寫進乙的個人動態索引庫。當乙的粉絲甲下拉刷新首頁時,Thunder 採購員按甲的關注名單去進貨,就會把乙轉發的這篇你的帖子,直接作爲“甲關注圈內的候選帖”抓進甲的臨時籃子裏**!也就是說,別人轉發你的帖子,相當於在 AI 算法推薦之外,直接借用轉發者的粉絲關係網給你額外打開了一扇“跨圈層大門”(當然,被抓進甲的籃子之後,依然要經過已讀過濾和打分排序,不保證乙的每一個粉絲都100%看到)。29

看明白這兩條腿走路的邏輯,你寫長文時的心態就徹底穩了:

  1. 對佔大多數的“沉默讀者”:踏踏實實給足案例、數據表和實操步驟,讓他們願意點開停下來讀完,靠 4 層閱讀停留信號幫你把帖子的排序基本盤撐起來;
  2. 對“同行與大 V”:在文章裏做一張一目瞭然的方案對比圖或避坑清單(比如講報價教程時,直接附一張完整的“原方案 vs 縮減方案對照表”,而不是乾巴巴喊一句“和客戶溝通很重要”),方便同行覺得“這張表對我粉絲也有用”而順手點轉發,借他們的關注流幫你破圈!

另外別忘了,代碼裏把**“普通轉發(Retweet,直接點轉發,權重 1.0)”和“帶評論引用(Quote,轉發時寫一段自己的評論,權重 5.0)”**分成了兩個完全獨立的預測項。Quote 的預測權重係數雖然是普通轉發的 5 倍,但同樣因爲乘的是各自的預測發生概率,不能機械地宣稱“轉發時隨便敲幾個字就能拿到 5 倍曝光”。21

8.1 轉發能不能出圈,要看是誰的圈子

前面我們看到一條網傳說法:“只有原創帖才能觸達陌生人,普通轉發(Retweet)會被圈外過濾器一刀切砍掉,所以轉發根本不能破圈。” 這句話之所以把無數人繞暈,是因爲說話的人把**“到底是誰的關注圈(In-Network)”**這個主語給吞掉了!

我們把一場轉發裏的三個人——甲(寫原帖的你)、乙(幫你點轉發的大 V)、丙(只關注了乙、沒關注你的陌生讀者)——擺在桌面上,對照 in_network_candidate_hydrator.rs 和 oon_retweet_reply_filter.rs 的源碼,看看候選帖裏的數據字段到底是怎麼填的:30

角色這個例子中的關係候選資料如何表示可得到的結論
甲:原作者(你)讀者丙沒有關注甲甲的原文 ID 保存在這筆轉發的 retweeted_tweet_id 字段裏甲的內容完全可以藉由乙的轉發,送到不認識甲的陌生讀者丙面前!
乙:轉發者(同行大 V)讀者丙關注了乙這筆轉發候選帖的直接作者 author_id 填的是乙!當系統檢查“候選作者乙在不在讀者丙的關注名單裏”時,判定結果是圈內(In-Network)!
丙:讀者只關注了乙,沒關注甲Thunder 按丙的關注名單,把乙的這筆轉發抓進丙的候選池成功繞過圈外攔截進入候選池(至於最後排第幾,仍由後續過濾與打分決定)

來源 30

你看清代碼裏的玄機了嗎? 在 oon_retweet_reply_filter.rs 裏,確實有一條鐵律:直接移除所有“候選帖的 author_id 不在當前讀者關注名單內(!in_network)”的普通轉發(is_retweet)(而且哪怕把回覆豁免開關打開,也不會豁免普通轉發)。

  • 如果這句話限定的是**“轉發者乙的這筆轉發,能不能在普通推薦管線裏直接推給既沒關注甲、也沒關注乙的純路人丁”,或者“你自己點普通轉發自己的老帖子,能不能推給沒關注你的陌生人”**——那代碼確實會把它一刀攔死!因爲在這兩種情況下,轉發人的 author_id 都不在讀者的關注名單裏,屬於圈外轉發(OON Retweet),必被過濾!(後面第 24 章我們會專門拆解“自己轉發自己老帖子”的 5 道關卡。)
  • 但如果是別人(乙)轉發了你的原帖,對於乙的粉絲丙來說,這筆轉發候選帖的 author_id 是乙(丙關注的人),在系統眼裏它屬於堂堂正正的圈內候選(In-Network),根本不會觸發圈外過濾器的攔截!對於原作者甲(你)來說,乙的粉絲丙就是完完全全的“圈外陌生讀者”。所以,把“圈外過濾器攔截未關注者的轉發”歪曲成“別人轉發你的帖子也沒法幫你觸達陌生人”,純屬把“轉發者”和“原作者”的主語給搞反了!30

這也再次提醒我們:當你寫一篇研究摘要或工具評測、希望同行大 V 順手轉發時,正文一定要把研究對象、核心結論和適用邊界寫清楚,讓大 V 的粉絲(這羣原本不認識你的陌生人)哪怕第一次刷到,也能一眼看懂你在幹什麼。至於大 V 轉發後他名下有多少粉絲最終能刷到,則由每位粉絲各自的已讀過濾和模型打分決定。30

8.2 回覆能否進入陌生人的候選,還要看開關和來源

說完了普通轉發,那“回覆貼(Replies,包括你在別人底下的評論,以及你自己串文的第 2 條往後)”能不能進入未關注陌生人的 For You 推薦候選池呢? 在代碼裏,回覆貼的待遇比普通轉發稍微留了一扇小窗戶,不能和普通轉發合併成一個絕對的“永遠不行”。

在當前公開默認參數(home-mixer/params/param.rs)裏,控制圈外回覆的開關 EnablePhoenixOonReplies 默認值是 false(關閉)——如果線上按這個默認值跑,普通推薦管線確實會把所有未關注作者的回覆帖統統過濾掉。 但程序員在代碼裏寫好了一段條件式放行分支:一旦線上配置把 EnablePhoenixOonReplies 開關設爲 true,只要這條回覆貼同時滿足以下條件,就能免於被 oon_retweet_reply_filter.rs 殺掉:30

  1. 它的召回進貨來源必須屬於指定的 Phoenix 推薦源(ForYouPhoenixRetrieval 或冷啓動源 ForYouPhoenixRetrievalCold);
  2. 如果另一個開關 PhoenixOonRepliesRootOnly 同時被打開(公開默認爲 false,但線上實驗可隨時調整),那這條回覆還必須是直接回復主帖根節點的“一級回覆”(不能是樓中樓回覆);
  3. 這條回覆必須已經成功補齊了可用的對話祖先數據(ancestors,如果缺祖先數據照樣會被移除)。30
OON 回覆要走這個例外,須同時符合:
EnablePhoenixOonReplies 開啓
來源屬指定 Phoenix home retrieval 類型
若 root-only 開啓,必須直接回復 root
回覆仍須有可用 ancestors

來源:30

你看,就算線上把例外開關打開,也不是隨隨便便一條回覆都能衝進陌生人的首頁。所以不管是寫串文還是寫評論,永遠要把最核心的問題和判斷放在第一條(根帖),同時保證後面的每一條回覆都有充足的上下文背景,千萬別把全文最精華的底牌全押在陌生人極大概率刷不到的串文末尾。30

8.3 首頁的一組對話,可能附帶其他帖子

關於轉發和回覆的出圈邏輯,代碼裏還有一層非常隱蔽的機制:單條通過篩選的候選帖,和最後端上讀者屏幕的“整組對話模塊”,並不是同一個數據單位!

怎麼理解這句話?比如 Thunder 關注流召回一條回覆候選帖時,會順帶保存它的直接父帖(parent)和對話根帖(root);等到最後一步界面組裝(convo_marshaller.rs)時,系統會把“根帖 + 有限的中間祖先帖 + 當前入選帖”拼成一個對話卡片一起展示出來。也就是說,如果讀者關注的人回覆了某條帖子,讀者在屏幕上看到的那組對話卡片裏附帶的根帖或父帖,並不是按它自己的作者關係單獨去走一遍相同的圈外候選過濾的(當然,所有附帶展示的內容依然要單獨過一遍 vf_candidate_hydrator.rs 的安全與可見性檢查,違規刪帖照樣出不來)。30

而且 Thunder 對回覆樓層的深度也有嚴格限制(thunder/posts/post_store.rs):“直接回復一篇原創根帖”和“在樓中樓裏回覆別人的回覆”,准入資格並不完全相同;更深一層的回覆會檢查父帖與根帖的關係、被回覆的人是不是當前讀者關注的對象等條件。所以我們也不能把對話組裝機制反過來吹成“隨便找人借一條回覆,就能讓任何八百年前的舊帖子無條件繞過全站限制”。30

另外,在 For You 首頁最頂層的流水線組裝(for_you_candidate_pipeline.rs)裏,除了常規的打分候選流(ScoredPosts),旁邊還並列着一個叫 PushToHomeSource(push_to_home_source.rs)的特殊來源。它是根據請求裏明確指定的 push_to_home_post_id 直接取帖子數據的,並不跟普通候選帖一起擠同一串 PostCandidate 過濾器。這說明我們在普通候選管線裏看到的過濾規則,並不是整個首頁所有入口的唯一總開關(更管不到對話詳情頁、搜索頁和個人主頁);但至於什麼樣的帖子才能被塞進 push_to_home_post_id,公開代碼並沒有披露上游觸發邏輯,我們也不能拿它當成創作者能自己手動調用的後門。30

9 陌生讀者爲什麼會遇到你這一篇(兼談中英雙語多語言發佈怎麼選)

搞懂了上面的過濾規則,我們再來看一個讓所有創作者着迷的問題:對於一個從來沒關注過我的陌生讀者,AI 到底是怎麼在茫茫帖海里,把我的這篇帖子精準抓進他的臨時籃子裏的?

舉個具體例子:假設你今天發了一篇乾貨,標題叫《網站設計報價被客戶嫌貴,如何通過縮小交付範圍保住訂單》。此時此刻,陌生讀者甲最近幾天經常在 X 上看自由職業接單與客戶溝通的內容;而陌生讀者乙最近幾天一直在看索尼和佳能的相機測評。 在 X 的推薦系統裏,根本不需要先把你的文章隨機撒胡椒麪推給全站所有人試水——在甲和乙下拉刷新的第一步(召回階段),系統就能根據他們倆近期的行爲序列,把你的文章精準抓給甲,而給乙抓去鏡頭測評!(注:這裏用甲和乙做個性化機制的直觀說明,並非兩個真實賬號的線上實測。)31

打開 retrieval_sequence_query_hydrator.rs 和 phoenix_source.rs 就能看到這套精準匹配的底層代碼:

  1. 當讀者下拉刷新時,程序會傳入當前這位讀者的 ID(query.user_id),去撈取這位讀者最近幹過的所有歷史互動行爲序列(點過什麼、讀過什麼、搜過什麼、收藏過什麼),然後把這個行爲序列打包發給 Phoenix 雙塔召回模型;
  2. 而在另一端,你的帖子在進入候選庫時,模型(recsys_two_tower_model.py)會把帖子的多模態語義表示(Semantic ID,由 Grox 多模態模型提取你的文字和圖片生成)與經過哈希處理的作者 ID 結合在一起,生成代表你這篇帖子的候選向量。 一邊是“這位讀者近期在看什麼”,另一邊是“你這篇帖子在聊什麼、你是誰”——兩邊向量一做相似度匹配,哪怕甲從來沒聽說過你,只要你寫的正是他最近在琢磨的痛點,Phoenix 採購員一伸手就把你的帖子撈進甲的臨時籃子裏了!31

看懂這段代碼,就能順手破除一個流傳很廣的“刷垂類養號玄學”: 很多教程教創作者:“你想做科技博主,平時自己刷 X 時就只能看科技帖、給科技帖點贊,這樣算法就會把你發的文章推給科技圈讀者!” 錯!你看代碼裏讀的是誰的歷史?讀的是 query.user_id(當前正在刷首頁的讀者)的歷史,不是作者的瀏覽歷史! 你自己連續一個星期只看科技帖、只給科技帖點贊,改變的是**“你自己作爲讀者刷首頁時會看到什麼”**,這段召回代碼裏沒有任何邏輯說“因爲作者昨天看了十篇科技帖,所以今天把作者發的文章定向推給科技讀者”(當然,作者 ID 本身仍是候選側的輸入特徵之一,所以也不能絕對斷言作者的歷史身份完全無關)。31

這對我們平時寫稿有什麼啓發?最大的啓發就是:別起空洞寬泛的玄學標題,要把標題和開頭第一段直接釘在目標讀者正在處理的“具體對象 + 具體任務”上!

  • 別寫《自由職業接單人的必修課》 → 改成**《網站設計報價被嫌貴時,如何縮小第一階段交付範圍》**;
  • 別寫《AI 大模型又迎來重大進步了》 → 改成**《用 AI 生成會議紀要漏掉了客戶否決條件,怎麼用 3 句話驗證》**。 當你把研究對象和解決的具體任務寫清楚了,多模態模型生成的語義向量(Semantic ID)靶心就極其精準,正文也自然知道該擺什麼證據。

同理,假如你的賬號上週寫的是“客戶嫌報價貴怎麼談”,這週寫的是“客戶接受報價後不斷追加修改怎麼防”,這兩篇看似換了細分題目,但服務的明明是同一羣自由職業讀者!你完全沒必要被所謂的“賬號垂直度 80% 紅線”嚇住,生怕換個具體問題就會觸發什麼“重置賬號標籤”——查遍公開召回和打分路徑,根本沒有“80% 同主題純度”、“固定帶幾個 Hashtag 才垂直”、或者“跨題發一篇就重置賬號權重”的數學公式。31

9.1 同一個內容用多國語言發佈(比如中英雙語發佈)會怎樣?

很多做技術、出海和開源項目的創作者經常問我一個非常糾結的實操問題:“我寫了一篇乾貨,想同時覆蓋中文讀者和英文讀者,到底應該把中文和英文上下混排塞在同一條帖子裏發,還是拆成一條純中文帖、一條純英文帖分開發?”

結合剛剛講完的“讀者歷史序列匹配(query.user_id)”、“同作者 0.625 衰減”、“V8.2 的 4,000 字符截斷”以及後面第 28 章要講的“PTOS 英語專屬安全規則”,我們把這兩種發法在代碼裏會遇到的真實待遇徹底算清楚:

9.1.1 發法 B:拆成“一條純中文帖”+“一條純英文帖”分開發布

**先說結論:同一個內容拆成一條純中文帖、一條純英文帖分開發,完全沒問題,幾千字的長內容就該這麼發。**在代碼裏的實際待遇是:

  1. 對只看單一語言的讀者(佔絕大多數):兩條各走各的讀者羣 別忘了前面剛講的核心機制:Phoenix 召回模型讀取的是當前讀者自己的歷史行爲序列(query.user_id)!
  • 對平時只刷中文圈的讀者張三來說,他的召回序列只會把你的純中文版抓進他的臨時籃子裏,英文版壓根不會進他的池子——所以按同作者乘數的算法,中文版在張三這裏不會被英文版佔掉名額;
  • 對平時只刷英文圈的老外讀者 John 來說,他的召回序列只會把你的純英文版抓進他的臨時籃子裏——所以按同樣的算法,英文版在 John 這裏也不會被中文版佔掉名額。兩邊互不佔名額——這是按召回和計數機制推的,線上是不是完全這樣跑,沒有日誌可證。31
  1. 對中英文都看的“雙語讀者 / 已關注你的老粉絲”:連發會同池競爭! 如果你在同一分鐘把純中文版和純英文版腳前腳後連着發出來,對於已經關注了你的粉絲(Thunder 關注流會按你的 author_id 把你剛發的兩條都抓進去)或者中英雙語都刷的讀者來說,這兩條帖子帶着同一個 author_id 掉進同一個臨時籃子,排第二的那條就會喫 0.625 同作者衰減,甚至在跨語言語義高度重合時還可能在 DPP 多樣性選擇(dpp_model.rs)裏互相競爭!2 85

9.1.2 發法 A:同一條帖子裏“上半截中文、下半截英文”混排發佈

  1. 有沒有“中英混寫扣分”?沒有! 公開代碼裏沒有任何“檢測到多語言混寫就固定扣分”的規則,語言標識只是餵給模型的普通特徵之一。31
  2. 但是!長文混寫會直接撞上兩個隱形大坑:
  • 第一坑:4,000 字符無情一刀切(MAX_POST_TEXT = 4000)! 後面第 17 章我們會看到,V8.2 內容理解處理器(renderer_v82.py)在讀取帖子正文 post.full_text 時,只截取前 4,000 個字符送往多模態 embedding 服務。如果你寫了一篇深度測試,上半截寫了 3,500 字中文,下半截接着放了 3,500 字符的英文翻譯——對不起,從第 4,000 個字符往後的英文主體會被直接切掉,根本進不去這條內容向量生成流程!47
  • 第二坑:英語專屬的自動審查規則(FOSNR_ABUSE_INSULTS)! 後面第 28 章安全規則裏有一條硬代碼:在 Grox PTOS 自動打標路徑中(Grox 是 X 內部負責「看懂內容」的 AI 系統,PTOS 是它裏面專門管安全審查、給違規內容打標籤的那套流程),HateOrAbuseInsultsWithTarget(帶目標的侮辱攻擊分類)明確要求當帖子語言被識別爲英語(English)時,纔會自動給非高 PageRank(PageRank=系統按影響力給賬號算的權重分,分越高越被當成大號,後文多處豁免都看它)/灰標賬號(灰標=政府/機構賬號的灰色認證徽章,不是花錢買的藍標)寫入 FOSNR_ABUSE_INSULTS 限制標籤(在 HomeRecommendations 攔截全部陌生人推薦)。如果你寫的是尖銳的產品測評或批評,按這條路徑的條件推測:如果雙語帖的語言被識別成英語、措辭又過激,就更容易撞上這條自動打標線——語言到底怎麼判,代碼裏沒有給雙語帖的明確說法。77

9.1.3 多國語言發佈到底怎麼做?

  • 如果是幾千字的技術長文、深度評測或教程:請務必拆成“純中文帖”和“純英文帖”兩條獨立發佈!並且建議把兩條的發佈時間錯開半天左右(具體隔多久,代碼裏沒有規定)(比如北京時間中午發中文版,等到北京時間深夜、歐美白天活躍高峯時再發英文版)——這樣既能讓中文版和英文版各自用滿 V8.2 的 4,000 字符語義額度、匹配各自語種的陌生讀者,也儘量錯開雙語老粉絲的刷新時段,避免兩條長文在同一個臨時籃子裏自己打自己!
  • 如果是兩三百字的簡短動態或配圖短帖(中英加起來遠遠不到 4,000 字符):可以直接放在同一條帖子裏上下對照發,省事且互動集中在一處;

10 閱讀信號在找候選時就已經有用

很多寫技術教程、做數據整理的創作者經常鬱悶:“我花三天做的實測對比表,讀者看完直接存圖拿去用了,評論區冷冷清清沒幾個人吵架留言,算法是不是覺得我的帖子沒人愛看?”

千萬別慌!評論區安靜,絕不代表讀者沒有在系統裏幫你投票。 在 2026 年 10 月 13 日的官方 README 更新說明裏,X 團隊專門宣佈了一件大事:Phoenix 召回模型(也就是第一步去倉庫裏撈候選帖的採購員)正式開始學習找出“人們會真正讀下去的帖子”!32

順着這條公告追進雙塔召回模型的配置文件 phoenix/xrex/configs/xrecsys_two_tower.py,你會看到:除了原有的 home(常規互動)和 immersive(沉浸式視頻)兩個分支外,代碼裏實打實新增了一個叫 ld(Long Dwell / 深度閱讀停留) 的獨立分支,它用來訓練模型的正例信號(Positive Actions)直接寫着下面這一行:32

"ld_positive_actions": [recsys_pb2.ActionName.CLIENT_TWEET_RECAP_DWELLED],

而且這絕不是寫在註釋裏的PPT概念——順着模型代碼 recsys_two_tower_model.py 和推理入口 model_runner.py 一路查到底,這個 ld 分支既有完整的訓練損失計算,又在實時召回推理時按權重參與打分! 這意味着,讀者的“停留閱讀信號”現在在算法裏會在兩個環節各起一次作用:

  1. 第一次在“第一步抓候選(召回)”:ld 分支專門幫採購員學會分辨哪些帖子是大家願意停下來讀進去的,直接把你的乾貨帖從海量庫裏撈進讀者的臨時籃子;
  2. 第二次在“第二步排座次(排序)”:進到籃子後,前面講的 0.4 點擊停留和 0.006 連續停留係數再幫你把總分往上推!

當然,我們也得守住嚴謹的證據邊界:CLIENT_TWEET_RECAP_DWELLED 這個客戶端事件在手機 App 前端到底是按什麼公式觸發的,公開倉庫裏並沒有放出前端源碼,所以我們不能信口開河把它吹成“讀者必須一字不落 100% 讀到文章最後一個標點符號”,也不能把後面點擊停留目標的“閾值 10”硬套到這個事件頭上。32

這對創作者來說是一顆巨大的定心丸:像工具教程、配置報表和方案對照這類乾貨,讀者的正常反應本來就是“靜靜看完、截圖保存、照着操作”,本來就沒啥好在評論區吵架的。千萬別因爲評論少,下一篇就焦慮地改寫沒營養的引戰罵街帖! 與其花心思在每段結尾塞一句“真正核心的重點還在後面,千萬別划走”來騙停留,不如檢查一下文中的表格有沒有直接回答痛點、操作步驟能不能照着跑通、例外情況有沒有交代清楚——把乾貨寫紮實,閱讀召回分支自然會認出你。

10.1 閱讀召回何時加入,只對小賬號有效嗎

圍繞這個新增的 ld 閱讀召回分支,網上還有兩個傳言:一是有人根據 10 月底的公告以爲這是 10 月 28 日纔剛上線的新功能;二是有人看到配置裏有個 HOME_COLD,就宣稱“閱讀召回只對小賬號有效,大號享受不到”。

我們直接拉出 Git 倉庫的提交時間線和源碼配置,把這兩個疑問一次性查個水落石出:33

時間與版本公開資料顯示的變化
2026 年 10 月 8 日,35650fb當時的雙塔召回具名配置裏只有 home 與 immersive 兩個分支,還沒有 ld。
2026 年 10 月 13 日 08:05:54 UTC,e1a0375公開提交正式加入 ld_positive_actions、ld 分支與分支權重 w_ld = 0.75,模型訓練與推理代碼也在同一次提交裏同步上線。
2026 年 10 月 28 日,5ed7963官方在 README.md 裏補寫了更新說明,將“找出人們會讀到底的帖子”明確標示爲 10 月 13 日的更新。

來源 33

你看,代碼早在 10 月 13 日就已經合入公開庫了,10 月 28 日只是在 README 文檔裏補了一筆記錄(當然,公開提交時間依然不等於線上所有流量分桶在同一秒切換,如果某天你的閱讀量波動,不能單憑日期就咬定是這次更新幹的)。33

再看第二個問題:ld 閱讀召回是不是隻給小賬號開的小竈?完全不是! 在 xrecsys_two_tower.py 的具名配置裏,ld 分支與 home、immersive 並列(在 home-only 的具名版本里也同時保留了 home 與 ld),裏面沒有任何檢查“作者粉絲數少於多少才啓用”的小賬號限制條件;而且它讀取的數據集同時涵蓋了 HOME、HOME_COLD、HOME_HOT,根本不是隻針對其中某一個!

更重要的一點闢謠:千萬別望文生義,把代碼裏的 HOME_COLD 翻譯成“小粉絲賬號專區”! 打開 phoenix/xrex/data/cold_pool_filter.py 源碼一看就明白了:HOME_COLD(冷帖子池)篩選時讀取的是單篇帖子的點贊數(fav_count)、觀看數(view_count)以及帖子剛發出來的新鮮度!也就是說:

  • 作者是個幾百萬粉的大 V還是幾百粉的小號(作者粉絲數)、
  • 正在刷首頁的讀者是不是剛註冊的新用戶(讀者行爲歷史)、
  • 這篇帖子本身是不是剛發出來還沒攢夠贊和觀看的新帖(HOME_COLD 真正查的東西), 這三者在代碼裏是完全獨立的三碼事!哪怕是一個十萬粉的成熟賬號,剛發出一篇新文章時,只要符合冷帖篩選條件,一樣會進 HOME_COLD;而無論大號小號,都能享受 ld 閱讀召回分支的訓練與推理機制。33 34
具名 combined 配置:head_names = ["home", "immersive", "ld"]
w_ld = 0.75
通用模型設置:w_ld = 0.0;是否有 ld,仍取決於實際配置。

來源:33

這裏順帶解釋一下 w_ld = 0.75:這個 0.75 是這份具名雙塔召回配置裏 ld 分支的向量打分組合權重,絕不是“讀者每讀完一次就給帖子加 0.75 分”;同時,基礎通用模型類裏的默認 w_ld 寫的是 0.0,說明線上具體某次請求用不用 ld、權重給多少,依然由該請求加載的具體配置文件決定。33

最後還要記住:雙塔模型在訓練時(recsys_two_tower_model.py),只是直接讀取數據表裏現成的 CLIENT_TWEET_RECAP_DWELLED 0/1 動作標記,模型自己並沒有在訓練代碼裏拿把尺子去量讀者到底滑到了第幾段。我們作爲作者最該做的,是在第一段把要解決的痛點亮出來,在正文里老老實實兌現承諾的乾貨——代碼裏可沒有任何“只要逼讀者滑到 100% 底部就自動觸發二輪全站爆推”的魔法開關。33

11 模型怎樣區分不同長度的停留

既然系統這麼看重“停留閱讀”,那 AI 模型到底是怎麼預測一個讀者會在你的帖子上停留 3 秒、15 秒、還是 90 秒的? 前面我們提過,點擊停留(CLICK_DWELL_TIME)在代碼裏只是一個簡單的“二元判斷(判斷原始數值有沒有跨過閾值 10.0)”。而在 2026 年 10 月 8 日官方宣佈的“停留時間預測改進”中,真正挑大樑的黑科技叫做 CREAD(多門檻分類與連續時間重建)——在 home_direct_packed 排序模型配置中,AI 會把停留時間切成 30 道精細的時間刻度門檻來同時學習,最後再把預測概率還原成具體的閱讀秒數!11 13 14 56

11.1 把停留時間拆成一組門檻

爲什麼要把停留時間切成 30 道門檻,而不是讓 AI 直接猜一個秒數?因爲不同讀者的閱讀停留時間跨度極大(有人掃一眼 2 秒划走,有人看長文或長視頻看兩三分鐘),直接讓神經網絡迴歸預測一個秒數很容易被極端值帶偏。

打開 phoenix/xrex/configs/xrecsys.py 和損失函數 loss_recsys.py,我們可以看到 CREAD 的切分方法非常巧妙:

  • 對於普通信息流(非 Gallery)的停留預測頭(head),系統從 2 秒到 120 秒(2 分鐘) 之間,按**對數間隔(Log-spaced)**切出了 30 個時間門檻;
  • 對於媒體畫廊頁(Gallery Page)的沉浸式停留預測頭(immersive head),系統則從 2 秒一直延伸到 240 秒(4 分鐘),同樣按對數間隔切出 30 個時間門檻。

什麼叫“對數間隔”?說白了就是**“前面刻度密、後面刻度疏”**——在 2 秒、3 秒、5 秒這些短停留區間,門檻切得非常密集(差一兩秒就是一道新坎);而到了幾十秒、上百秒的長閱讀區間,門檻之間的跨度就變大了。(注意:這裏的 120 秒和 240 秒僅僅是這兩個模型預測頭的刻度上限,絕不是說你的帖子字數或視頻長度不能超過 2 分鐘或 4 分鐘!)13

# 概念重述,並非逐字源碼;30 個門檻,k=0 到 29
threshold_k = 2.0 * (norm_scale / 2.0) ** (k / 29)

# 非 Gallery:norm_scale = 120.0
# Gallery Page:norm_scale = 240.0

# 以下一行爲標籤判斷源碼
targets = (gt_raw[..., None] > threshold_arr).astype(jnp.float32)

來源:13

你看最後一行源碼:當系統拿真實閱讀時長 gt_raw 去生成訓練標籤時,用的比較符號是嚴格大於(>)——只要觀察到的真實停留時間嚴格超過了第 $k$ 道門檻,這道門檻的標籤就記爲 1,否則記爲 0(剛好卡在門檻值上也是 0)。通過這種方式,AI 模型就能同時分別預測出:“這位讀者在你帖子上停留超過 2 秒的概率是多少、超過 5 秒的概率是多少、超過 30 秒的概率是多少……”,再也不會把“看 11 秒”和“看 100 秒”粗暴地混成同一種結果了!13

11.2 再把這些概率還原成時間

既然 AI 預測出了 30 個門檻各自的過關概率,那在打分時,怎麼把這 30 個概率變回一個具體的“預測停留秒數(比如 18.5 秒)”去乘那個 0.006 的連續停留權重呢?

打開模型推理代碼 recsys_model.py,解碼還原公式非常漂亮:先把 30 個門檻的輸出值(logits)通過 sigmoid 函數變成 0 到 1 之間的過關概率 phi,然後拿每個門檻的過關概率,去乘以它和前一個門檻之間的“時間跨度(deltas)”,最後把 30 段加起來(第 1 個門檻的前置基準設爲 0 秒)。正因爲每一格對應的秒數寬度完全不同,千萬不能把 30 個概率直接加在一起當成“最高加 30 分”或“30 次有效閱讀”!13

# 公式重述,並非逐字源碼
phi = sigmoid(cread_logits)
deltas = [t1 - 0, t2 - t1, ..., t30 - t29]
restored_time = sum(phi_k * deltas_k)

來源:13

我們用只有 3 個門檻的簡化例子算一遍,你一秒鐘就能看懂這個積分還原的思想: 假設 3 道門檻分別是 2 秒、5 秒、10 秒,那麼它們相鄰的時間跨度(deltas)依次是:$2-0=\mathbf{2}$ 秒、$5-2=\mathbf{3}$ 秒、$10-5=\mathbf{5}$ 秒。 現在 AI 預測某位讀者看你的帖子,停留超過 2 秒的概率是 0.8(80%),超過 5 秒的概率是 0.5(50%),超過 10 秒的概率是 0.2(20%)。那麼還原出來的預測停留時間就是: $$0.8 \times 2\text{秒} + 0.5 \times 3\text{秒} + 0.2 \times 5\text{秒} = 1.6 + 1.5 + 1.0 = \mathbf{4.1\text{秒}}$$ 然後再拿這個還原出來的 4.1 秒,送到後面去乘 0.006 的連續停留權重!(注:這裏用 3 個門檻做算術演示;正式的 home_direct_packed 配置用的是 30 個對數門檻。)13

而且在訓練這個模型時,程序員不僅考覈 AI 對那 30 道二元選擇題答得準不準(分類損失),cread_loss_compute 函數還會把還原出來的預測秒數和真實停留秒數放在一起對比,額外算一筆「總秒數算得準不準」的誤差(時間重建誤差,Restoration Loss)。算之前先把真實停留時間截斷在量程內(120 秒或 240 秒);算誤差用的是 Huber Loss(一種遇到極端值時不會被帶偏太多的誤差算法;相對權重 0.5、Huber 門檻 5.0 秒,另配合有效樣本遮罩與負例權重),逼着模型把總秒數也算準。

在 home_direct_packed 的公開基礎配置裏,普通停留和沉浸式停留的 CREAD 損失權重(dwell_cread_loss_weight 與 dwell_cread_immersive_loss_weight)都被設爲了 0.1,而老舊的 dwell_tweedie_loss_weight 與 dwell_mae_loss_weight 則被設爲了 0(正式退役)。我們要分清:CREAD 損失權重 0.1 管的是模型訓練階段怎麼學準停留秒數;而 Home Mixer 裏的 0.006 管的是模型預測出秒數之後,在最終排座次時給每秒鐘乘多少係數。13 15

11.3 四個容易混淆的“停留”指標

寫到這裏,我們已經遇到了四個長得很像、都跟“看帖子 / 停留”有關的指標。很多二傳手文章把它們張冠李戴,我專門做了一張對照表幫你徹底釐清它們各自管哪一攤事:13 14 35 36

名稱或字段所在環節這次查到的定義仍不能推理的事
DWELL_TIME/CREAD排序模型訓練與連續時間解碼30 個對數門檻分類 + 時間重建(120 秒/240 秒量程),輸出預測停留秒數供 ContDwellTime(0.006)相乘把文章字數硬拉長一倍,就能自動拿到雙倍預測停留時間或雙倍曝光
CLICK_DWELL_TIME具名排序模型的點擊停留二元目標二分類(binary),閾值 threshold = 10.0;輸出爲原始值嚴格大於 10.0 的概率,供 ContClickDwellTime(0.4)相乘讀者只要真實看滿 10 秒,系統就當場給這篇帖子記賬加 0.4 分
CLIENT_TWEET_RECAP_DWELLED/ldPhoenix 第一步召回的正例及分支雙塔召回的 ld 分支把該事件列爲訓練正例(分支權重 w_ld = 0.75)這個前端事件一定代表 100% 讀到全文末尾,或者直接共用上面那個 10.0 門檻
view_count_on_home小賬號冷啓動資格與探索抽樣候選帖身上攜帶的內部 Home 首頁曝光累計次數;< 200 是冷啓動的 5 大硬條件之一它直接等於創作者在前臺看到的總觀看數(Views),或是系統保底白送 200 個獨立讀者的測試配額

來源 13 14 35 36

表格第二行還有一處缺口要交代清楚。能追通的是兩頭:模型那邊(model_runner.py)確實返回這個「達標概率」;Home Mixer 這邊(scoring.rs)確實讀了名叫 click_dwell_time 的預測字段,乘上 0.4。中間把模型返回值轉成這個字段的那段轉換代碼(adapter),公開倉庫裏沒有放出來。55

gt_binary = (gt_raw.astype(jnp.float32) > threshold).astype(jnp.float32)

我在本地 CPU 上直接調用原函數傳入 [9, 10, 10.0001, 20] 跑過實測驗證,輸出的標籤依次是 0, 0, 1, 1——證實了剛好等於 10 時依然是 0(必須嚴格大於 10 纔爲 1)。但要說清這次測試證明了什麼、沒證明什麼:它只證明了數學上的邊界——必須嚴格大於 10,剛好等於 10 不算。至於這個 10 的單位是什麼、點開 Article 算不算進去、最後能換來多少曝光,上游代碼沒公開,這次測試答不了,我們只按代碼寫的說「超過閾值 10」。98

把這些代碼邏輯落實到我們平時寫稿上,道理其實樸素得不能再樸素了:你想讓讀者在你的帖子上多停留一會兒,你首先得在帖子裏擺出真正值得他看上二三十秒的硬貨!

  • 拿寫“怎麼跟客戶談報價”來說:你在第一句話裏答應給讀者看“原方案與縮減方案的報價對照”,那正文緊接着就得把兩份報價單亮出來;答應講“降價不減量怎麼翻車的失敗案例”,就老老實實把當時客戶是怎麼一步步扯皮的過程寫出來。讀者眼裏有實打實的材料可看,停留時間自然就上去了。
  • 反過來,如果你本來只有三句話的乾貨,爲了迎合算法硬把它注水拉長成十段,中間每隔兩段就寫一句車軲轆話:“大家先別急,真正決定成敗的第三個重點在最後面……”——這根本不是在增加閱讀價值,而是在消耗讀者的耐心,極大概率讓人直接划走(觸發 -0.02 的 Not dwelled 懲罰)甚至反手點一個“不感興趣(-52.272)”!
  • 配圖也是同一個道理:如果你放了一張方案對比表,字號一定要調到在手機屏幕上能輕鬆看清“左邊刪了哪幾項、右邊省了多少錢”。如果圖片字縮得像螞蟻一樣小,讀者點開大圖(哪怕觸發了 Photo expand 0.05)放大還是糊成一團看不清,他來你帖子裏想解決的問題沒解決,下次刷到你的名字就不會再點開了。

11.4 讀者多花的時間,要有東西可讀

所以,日常創作時千萬別把“怎麼在開頭設套路把讀者騙滿 10 秒鐘”當成寫作目標:

  • 如果一張清晰的對照表讓讀者花 6 秒鐘就找到了他急需的參數、心滿意足地收藏離開,那這 6 秒就是高質量的有效停留;
  • 如果一篇深度測評報告確實需要讀者花 90 秒才能看完,那就把測試樣本、對比數據和翻車反例鋪陳紮實,讓讀者每往下滑一段都能讀到新信息。

官方在更新日誌裏說 CREAD 讓停留時間預測變得“更準更好”,公開代碼也讓我們親眼看到了這套 30 門檻對數重建的精妙設計;但由於官方沒有一併公開評測數據集、誤差下降百分比和線上 A/B 實驗結果,我們可以把 CREAD 的運作原理講得明明白白,但絕不憑空捏造“準確率提升了百分之多少”、“長文流量從此暴漲多少倍”、或者宣稱“短帖從此徹底失寵”。11 13

12 第 1 個贊和第 32 個贊,究竟觸發了什麼

網上有一句流傳很廣的“破圈密碼”:“帖子發出後,拿到第 1 個贊(1fav)就能進入初級推薦池;攢夠第 32 個贊(32fav)就能解鎖高級陌生人流量池!”

去翻公開代碼庫,1fav 和 32fav 這兩個名字確實白紙黑字地寫在索引模塊裏,所以這句傳言並不是憑空編造的。但問題在於:二傳手們把**“觸發索引更新”、“寫進某個數據庫名單”、“被召回採購員讀取”和“最終展示在陌生人首頁上”**這四個完全不同的步驟畫上了等號!單靠一條入庫條件,系統可從來沒給任何人承諾過保底曝光。37 38 34

我們先順着“有人給你的帖子點了一個贊”那一刻往後看: 在 phoenix-rankall-strato/columns/favoriteEventProcessor.strato 裏,有一個專門監聽點贊事件的處理器叫 favoriteEventProcessor。當它收到一筆 Favorite(點贊)事件時,首先得能從事件數據包里正常讀出當前的累計點贊數(favorite count),如果讀不到計數就直接放棄這次更新請求(注意:非點贊事件比如取消贊在這個處理器裏會被直接忽略,但不能由此誇大成整套 X 系統完全不處理取消贊)。 接着,程序會去查緩存記錄:這篇帖子之前有沒有送出過索引更新? 根據“還沒有緩存記錄(第一次觸發)”和“已經有緩存記錄(後續觸發)”,它會分別走兩套截然不同的檢查條件:37

事件情況這裏實際檢查什麼邊界不能推成什麼
尚無更新緩存(首次觸發)帖子還沒超齡,且當前點贊數低於系統計數上限帖子年齡必須嚴格小於 49 小時;點贊數小於 $2^{30}$並不是只有 count == 1 才能第一次送出索引請求(如果第一次處理時已經 3 個讚了也照樣過)
已有更新緩存(後續更新)點贊數達到了下一個二次冪門檻;距離上次更新已經過了至少 1 分鐘;距離首次更新和帖子本身都沒超齡更新間隔 ≥ 1 分鐘;距首次更新 ≤ 48 小時;帖子年齡 < 49 小時絕不是每多收 1 個贊就立刻刷新一次索引或擴大一次分發
計數缺失無法從事件數據包裏讀出 favorite count直接跳過,不發送這次索引請求前臺界面顯示有人點讚了,不代表後臺每個內部索引步驟都已經同步跑完
建立時間缺失計算帖子年齡時,如果缺失創建時間則默認填 0在當前年份(2026 年)減 0 會直接判定爲幾十年老帖(超齡淘汰)不能把缺失時間戳誤以爲是“不受年齡限制、永久有效”

來源 37

已有緩存時,必須同時符合:
距首次索引更新 <= 48 小時
帖子年齡 < 49 小時
目前贊數 >= nextTriggerThreshold
目前贊數 < 2^30
距最近索引更新 >= 1 分鐘

來源:37

你看上面這幾行硬代碼裏的不等號,每一處都有講究:

  • “距離第一次索引更新”用的是 <= 48 小時(超過 48 小時才排除);
  • “帖子本身的發佈年齡”用的是 < 49 小時(一滿 49 小時就排除);
  • 兩次索引更新之間還卡了一道 >= 1 分鐘 的節流閥(1 分鐘之內的密集點贊絕不重複觸發更新)。 這些數字只管 favoriteEventProcessor 這一個點贊事件處理器“要不要往後發送索引更新請求”,跟後面首頁候選池的 48 小時年齡過濾(AgeFilter)各管各的攤子,千萬別把它們揉成一個統一的“發帖倒計時鬧鐘”。37 39

12.1 到了 32 個贊,索引也未必立刻更新

爲什麼大家總是提到 1 和 32 這兩個數字?因爲在 favoriteEventProcessor.strato 裏,每當成功發送一次索引更新後,程序就會把“下一次觸發更新的點贊門檻(nextTriggerThreshold)”設定爲高於當前點贊數的下一個 2 的次方(二次冪)!

  • 當你拿到 1 個贊更新後,下一道門檻就設爲 $2^1 = \mathbf{2}$ 個贊;
  • 後面依次是 4、8、16、32、64、128……
  • 假如某次事件處理時,你的帖子一口氣漲到了 33 個贊,程序算出來的下一道門檻同樣是 64 個贊,而不會倒回去補跑中間跳過的數字。37
count > 0 時:
nextTriggerThreshold = 2^(floor(log2(count)) + 1)

count == 0 的公開特例:
nextTriggerThreshold = 2

來源:37

看懂了這個“2 的次方門檻 + 1 分鐘節流閥”,我給你舉個完全符合代碼邏輯的真實場景,你就明白爲什麼盯着前臺“第 32 個贊”毫無意義了: 假設你的帖子剛發出來挺受歡迎,在拿到 16 個贊的那一刻剛剛觸發了一次索引更新(此時系統把下一道門檻設爲了 32)。結果才過了 30 秒(半分鐘),你的帖子就迅速衝到了 32 個贊! 請問:這第 32 個贊會觸發索引更新嗎? 不會! 因爲雖然你的點贊數已經達到了 nextTriggerThreshold(32 贊),但距離上一次(16 贊時)的更新還不到 1 分鐘(才過了 30 秒),直接被 距最近索引更新 >= 1 分鐘 這道節流閥給攔下了!至於 1 分鐘之後還能不能補上更新,得看後面還有沒有新的點贊事件進來、以及何時處理成功。(注:這是嚴格按照源碼條件推導的算例,未使用真實賬號線上日誌。)37

所以,當你看到自己帖子的點贊數停在 31、32 或者 33 個贊時,千萬別神神叨叨地診斷說“哎呀,我的帖子正在等第 32 個贊解鎖新流量池”,更別到處拉羣求朋友幫你點滿 32 個贊——認真在評論區回答讀者的具體問題、補充有用的資料才實在;代碼里根本沒有“湊滿 32 個贊就自動發一批陌生人流量”的機制。37 34

12.2 1fav 和 32fav 各自怎樣收錄內容

當點贊更新請求順利通過了前面那道門,被送到下一站候選處理器 phoenixRankAllCandidateProcessor.strato 後,程序並不會閉着眼睛直接入庫,而是會重新去數據庫讀取一遍這篇帖子的最新詳情與互動計數,然後按照事件來源、是不是社羣(Community)帖子、是不是回覆或轉發、以及安全可見性條件進行分流: 在普通合格原創帖的點贊分支(Fav 分支)裏,程序會先建立 1fav、備份與主題相關索引,然後再單獨判斷夠不夠資格寫進 32fav 和專屬視頻索引。也就是說,光有一筆點贊事件,絕不等於所有索引名單都會把這篇帖子收進去:38

索引可見的主要入庫條件重要細節對運營說法的限制
1fav進入一般合格帖子的 Fav 分支build1FavIndex 函數內部並沒有再卡一道 贊數 >= 1;甚至重新讀到 0 贊時,只會記一筆競態日誌,照樣把帖子送進 1fav 索引!雖然名字叫 1fav,但後臺不同服務間的點贊計數在收到第 1 個贊時未必毫秒級同步
32fav進入一般合格帖子的 Fav 分支,且重新讀取到的 favoriteCount >= 32判斷條件是 >= 32(大於等於 32),不是隻認準第 32 個贊那一次事件寫進 32fav 索引只代表存進了這個數據桶,絕不能直接換算成陌生人曝光量
search_unfilteredFav 事件、非社羣帖子、非普通轉發,且計數 >= 1排在後面的回覆分流與一般可見性過濾之前建立進了搜索索引庫,不能拿來當成已經放行進入 For You 推薦流的證據
1fav_reply/32fav_replyFav 事件下的合格回覆帖;明確排除作者自回自評(self-reply)與在此處被過濾的回覆32fav_reply 另外要求重新讀到的點贊數 >= 32;回覆帖走的是自己獨立的索引名就算建了回覆專屬索引,也不證明線上每個首頁召回源都在讀取它
post_creation一般合格帖子的 PostCreation(發帖創建)分支在你剛剛按下發帖鍵(0 贊)時就會另外建立這個索引鐵證如山:絕不能把“拿到第 1 個贊”當成整套推薦系統所有索引的共同唯一起點!

來源 38

build1FavIndex 的計數競態處理:
若重新讀到的 favoriteCount == 0:記錄 1fav_uec_count_race
然後仍送出 indexName = "1fav" 的索引事件。

來源:38

你看上面這段源碼細節有多真實:在 build1FavIndex 函數里,程序員甚至專門寫了一段處理“重新讀到的點贊數爲 0”的代碼——當發現事件觸發了、但另一邊數據庫查出來的 favoriteCount 還是 0 時,系統會記錄一條叫 1fav_uec_count_race(點贊計數讀寫競態不同步)的監控指標,然後照樣把這篇帖子寫進 indexName = "1fav" 的索引裏!這再一次告訴我們:後臺分佈式系統的計數同步本來就有微小延遲,千萬別把手機屏幕上顯示的點贊數字當成精密無誤的“算法進度條”(當然,這只是處理讀寫延遲的兜底邏輯,不代表系統故意把所有零贊帖子都無腦塞進 1fav)。38

同時還要注意:普通帖子的這條主索引流程,會直接跳過社羣(Community)帖子與普通轉發(Retweet),回覆帖(Reply)則被分流到獨立的 1fav_reply 分支;如果帖子帶有可見性限制或成人內容(NSFW)標記,也會被分流到特定分支處理。這些前置資格缺一不可,絕不能掐頭去尾簡寫成“只要是原創帖,拿到 1 個贊就會全網推流”。38

12.3 索引建好了,還要查誰在讀取它

把帖子寫進索引庫,就好比把商品擺進了倉庫貨架;貨架上有貨,還得看前面的“召回採購員”去不去這個貨架拿貨!

我們順着代碼去查數據消費端(phoenix-rankall/src/config/mod.rs 和 phoenix/xrex/data/retrieval_dataset.py): 在 rankall 的公開時間窗口配置裏,確實同時定義了 1fav 的 24 小時與 48 小時窗口,以及 32fav 的 24 小時窗口,寫入的索引事件也會被路由到對應的數據桶裏。但當我們去查**“普通 For You 首頁到底在讀哪個數據文件”**時,發現了最關鍵的證據差異:34

數據層公開程序中已追到的內容
1fav 的生產與存儲合格點贊事件會產生 1fav 索引事件,存儲層設有對應的 24 小時/48 小時窗口。
普通 Home 推薦流的消費RetrievalDataset 裏的三大主力數據集——HOME、HOME_COLD、HOME_HOT——全部白紙黑字地明確引用 1fav_1day.parquet(即 1fav 的 24 小時庫)!
冷/熱 Home 池的切分HOME_COLD 與 HOME_HOT 都是從同一個 HOME(1fav_1day.parquet)數據源讀進來的,只是再按“冷帖子條件(點贊數、觀看數、新鮮度)”切分成兩半——根本不是 HOME_COLD 代表 1 贊、HOME_HOT 代表 32 贊!
32fav 的生產與存儲確實有 favoriteCount >= 32 的入庫條件、索引事件與 24 小時存儲窗口(32fav_1day)。
普通 32fav 的消費端(證據缺口)在這份公開的 For You 代碼樹裏,自始至終沒有找到任何一個具體的普通首頁召回服務在讀取 32fav_1day!(此處嚴格保留爲證據缺口。)

來源 38 34

你看:在 RetrievalDataset 枚舉列表裏,唯一一個名字裏帶 32Fav 的讀取項叫做 IMMERSIVE32FavVideo14To30Day,它讀取的文件是 32fav_video_14to30day.parquet——那是專門給沉浸式視頻流準備的“14 到 30 天老視頻庫”,根本不能拿來給普通圖文帖的“第 32 個贊解鎖 For You 大流量池”圓場!當然,本着嚴謹原則,普通 32fav_1day 也許被公開倉庫之外的某個內部服務讀取,或者由未公開的線上配置調用;但在公開代碼能證明的範圍裏,我們只能確認“系統生產並存儲了 32fav”,絕不能替未知的部分打包票說“滿 32 個贊必得一波新推薦”。34

哪怕是實打實被 HOME 讀取的 1fav_1day.parquet,帖子被採購員抓進臨時籃子後,也照樣要過已讀過濾、關注關係、48 小時年齡限制、模型預測打分和同作者衰減等一連串關卡。你在賬號後臺分析(Analytics)裏看到的曝光數,只是這一切跑完之後的最終結果;至於某篇帖子到底進了哪個庫、爲什麼在某次刷新裏輸給了別人的帖子,沒有內部服務器請求日誌誰也看不見,千萬別拿面板上的幾個贊去生搬硬套。34

13 收藏沒有獨立加權項,系統仍然會用它

很多做乾貨教程、工具清單的博主都會注意到一個現象:自己的帖子經常是“點贊只有十幾個,但收藏(Bookmark)卻有上百個”。可是一翻前面的 24 項融合打分權重表(xai-value-model/weights.rs 和 scoring.rs),心又涼了半截:主計分表裏居然壓根沒有 bookmark(收藏)這一項!網上甚至因此傳言“收藏在 X 算法裏是 0 分,一丁點用都沒有”。

別被“主計分表裏沒單列”騙了! 當一位讀者把你的乾貨模板點進收藏夾,往往意味着他準備過兩天干活時翻出來照着用。我們順着收藏數據流(BookmarkMetadata)在代碼庫裏一路往下追,揪出了收藏在推薦系統裏的兩大隱藏核心用途!2 40

第一個隱藏用途,在個性化相似內容召回(SimClusters)裏: 打開 explicit_engagement_signals_query_hydrator.rs 和 simclusters_source.rs,你會看到:當讀者刷首頁時,系統不僅會讀取他最近點過贊、轉發過的帖子,還會專門讀取他最近的收藏記錄(BookmarkMetadata)!然後,SimClusters 採購員會把這位讀者最近收藏過的帖子 ID 和其他互動帖子合併在一起,當成**“尋找相似好帖的種子(Seeds)”**,去全站撈取跟這些收藏帖主題高度相似的新帖子!(這條路的公開開關默認全部開啓;能不能生效,還要看這個召回源當次啓沒啓用、種子數量、種子年齡和候選篩選這幾項條件。)40

這裏要注意作用對象:假設讀者甲收藏了你寫的《中文發票整理與自動對賬教程》,那麼你這篇帖子的 ID 就會變成甲的“興趣種子”。等甲明天、後天再刷首頁時,SimClusters 就會拿着你這篇帖子的種子去幫甲找相似的效率工具新帖——找回來的可能是同行寫的同類乾貨,也很可能是你接下來剛發的下一篇財務自動化新帖!(當然,還要看後續過濾和打分,代碼沒有寫成“只要甲收藏了你的舊帖,就100%保送你的下一篇”。)40

13.1 收藏也會參與召回模型訓練

除了在 SimClusters 裏當相似召回種子,收藏還有第二個更硬核的用途:直接作爲雙塔召回大模型的訓練正例!

打開 phoenix/xrex/configs/xrecsys_two_tower.py,在雙塔召回模型的沉浸式分支正例清單(immersive_positive_actions)裏,CLIENT_TWEET_BOOKMARK(客戶端收藏帖子動作)赫然在列,與點贊、回覆、轉發、視頻品質觀看、關注作者和分享等核心正向動作平起平坐!模型在訓練時會直接拿包括收藏在內的正負例計算損失函數——也就是說,雖然收藏不在最後一步的融合公式裏按“每個收藏加幾分”算死賬,但它直接教會了上游召回大模型“什麼樣的帖子是用戶喜歡存下來的好內容”!41

immersive_positive_actions 包含:
recsys_pb2.ActionName.CLIENT_TWEET_BOOKMARK

來源:41

把“收藏(Bookmark)”在整套算法庫裏的三個位置擺在一起對比,你就再也不會被“收藏零分無用論”誤導了:41

位置收藏在這裏怎麼用作用對象不能保證的結果
共用融合打分公式(scoring.rs)沒有單獨列出 bookmark 權重字段最終排序打分環節的加權和計算絕不能因爲這一處公式沒列字段,就擴大成“整套 X 算法完全不看收藏”
SimClusters 相似內容召回讀者收藏帖子的 ID 會併入相似內容查詢種子(每類最多保留最近 15 筆)點下收藏按鈕的那位讀者本人,及其後續刷首頁時的候選召回不保證再把已讀原文推一遍,也不算作給作者存下了固定的“流量兌換券”
雙塔模型 immersive 分支訓練CLIENT_TWEET_BOOKMARK 被明確列入該分支的訓練正例(Positive Actions)訓練召回模型學會識別哪些候選內容值得被撈回這是模型訓練目標,不等於普通首頁每多一個收藏就立刻給單篇帖子加固定分數

來源 41

我們再把 SimClusters 這條收藏種子路徑的邊界數字摳清楚(home-mixer/params/param.rs 與 simclusters_source.rs):

  • 數量上限:公開參數裏,每類顯式互動信號最多保留讀者最近的 15 筆(且要求 SimClusters 召回源啓用、當前請求不是僅限圈內關係網請求、不是已帶緩存帖子的請求,並存在可用信號);
  • 兩個年齡限制(90 天 vs 48 小時):作爲種子的那篇被收藏帖子,它本身的發佈年齡必須在 90 天以內;而用這顆種子去撈出來的相似新候選帖,按公開默認則限制在發佈 48 小時以內(並受相似度分數門檻與返回數量上限約束)。

這裏有一個非常容易搞混的時間細節:90 天種子有效期,查的是“被收藏那篇原帖自己的發佈時間(tweet_id 創建時間)”,而不是“讀者點收藏按鈕的那一天”! 打個比方:假如讀者今天翻到了你兩年前寫的一篇老教程,覺得太棒了,今天順手點了收藏——雖然收藏動作發生在今天,但因爲那篇老帖本身的年齡已經超過了 90 天,在 SimClusters 這道種子年齡檢查裏它依然會被排除掉。先說清這句的範圍:這隻說明它在 SimClusters 這一條路里當不了種子,不代表收藏舊文章在其他模型特徵裏也完全沒用。另外這裏講的是公開默認開關,代替不了線上每次請求的實際配置。。41

所以,當我們寫工具模板、配置指南和避坑清單時,最好在文末清晰標出**“這張表在什麼場景下用、每個字段代表什麼意思、最後更新於哪一天”**——這樣收藏你的讀者過半個月回來翻收藏夾時能立刻用上,而你在 48 小時內繼續發佈同系列的深度內容時,也更容易接住 SimClusters 順着收藏種子撈過來的精準讀者!41

13.2 給讀者一個下次還會用到它的理由

怎麼把一篇普通的觀點帖,改造成讓讀者忍不住想點“收藏”和“複製鏈接”的實用工具帖? 我們拿寫**“如何挑選 AI 會議紀要/錄音轉寫工具”來舉個實操例子:如果整篇帖子只是主觀地給 A、B、C 三款工具排個名(“第一名某某、第二名某某”),讀者掃一眼記住名字就划走了,根本沒必要收藏。 但如果你在帖子裏給出一套讀者下次自己測試任何會議工具時都能直接拿去套用的“3 句話試金石對照表”——教讀者看 AI 摘要會不會漏掉否決條件**、能不能分清討論提案與最終決議、會不會把待確認事項瞎編成已拍板定案,甚至連測試用的 3 句標準輸入臺詞都幫讀者準備好了:

檢查項目可用的範例輸入(可直接餵給工具測試)覈對 AI 摘要時重點看什麼記錄測試結果
否決條件“若需要把客戶原始資料上傳到外部公有云,這個方案就不採用。”摘要裏是否完整保留了前提條件與“不採用”的底線通過/漏記/寫反
提案與決議“剛纔說的只是建議下個月先小範圍試用,今天還沒同意正式採購。”摘要是否把“建議試用”錯誤寫成“已決定採購”通過/漏記/寫反
待確認事項“具體的年度預算額度,等下週三財務覈對後再最終確認。”摘要是否擅自腦補寫成“預算已覈准通過”通過/漏記/寫反

每當你評測一款新工具,就把這三句話喂進去,在最後一欄填上實測結果,並註明工具版本號、測試日期和適用語種。在帖子結尾,你根本不需要乾巴巴地求讀者“大家記得點贊收藏啊”,只需要自然地寫上這樣一段話:

可以這樣結尾: “下次你們團隊選型任何 AI 會議紀要工具,都可以先拿上面這三句帶陷阱的原話測一遍,再對照錄音原文覈查。別光看 AI 生成的排版順不順眼,重點看它有沒有把‘還沒定的提議’瞎寫成‘已經拍板的決議’。”

你看,這樣一段結尾直接告訴了讀者**“這張表什麼時候拿出來用、具體怎麼測”**,任何有選型需求的讀者看到,第一反應就是點一下“收藏(Bookmark)”存進自己的工具箱,或者點一下“複製鏈接(Share via copy link,預測權重高達 20)”發進公司的飛書/微信工作羣!當然,如果是發一條突發新聞快訊或臨時通知,就沒必要硬拗成工具表了,形式永遠爲內容服務。

這裏也順便把“私下傳播”的機制拎清楚:在主計分表裏,**私信分享(Share via DM,權重 5)和複製鏈接(Share via copy link,權重 20)**擁有極高的獨立預測權重,這和上面講的“收藏進入 SimClusters 種子”是兩條並行的路徑。很多深度的行業分析帖,表面上看公開轉推(Retweet)不多,但大家都在瘋狂點“複製鏈接”往私密羣裏轉,這種帖子在模型眼裏照樣是含金量極高的優質內容(只不過僅憑公開代碼,我們在前臺看不到別人的帖子一共被點了多少次複製鏈接或私信分享)。2 21 40

14 互相關注的加成,對哪位讀者生效

在前面的 24 項權重表裏,有一項高達 20 的鉅額權重特別吸睛:“符合互關條件的回覆預測項(5 + 15 = 20)”。 不少人看到這個 20,馬上衍生出兩套江湖打法:

  • 第一套打法:“那我見人就互關(Follow back),攢幾千個互關好友,發什麼帖子豈不是所有互動權重都翻 4 倍?”
  • 第二套打法:“我和幾個大 V 互相關注了,那我天天蹲在大 V 的評論區搶沙發留言,我的這條回覆就能拿到 20 倍權重衝上熱評第一!”

我們直接把 xai-value-model/inputs.rs 和 weights.rs 裏的判斷源碼拿出來對質,這兩套幻想當場就破滅了:42

!self.is_reply && !self.is_retweet && self.is_mutual_follow_author

請逐字看清上面這行 Rust 代碼裏的三個 &&(必須全部同時滿足):

  1. !self.is_reply:當前被打分的這篇候選帖子,絕對不能是一條回覆貼(Reply)!
  2. !self.is_retweet:當前被打分的這篇候選帖子,絕對不能是一條普通轉發(Retweet)!
  3. self.is_mutual_follow_author:當前正在刷首頁的這位讀者,與這篇原創帖的作者之間,必須是**雙向互相關注(Mutual Follow)**關係!

只有當這三條鐵律同時成立時,程序纔會把“預測這位互關讀者給你留言回覆”的權重係數,從基礎的 5 加上互關加成 15,變成 20! 注意看它的邊界:

  • 它只給**“回覆預測”**這一項加 15 分,並不是把點贊、轉發、停留等所有互動項一起乘以 4;而且代碼裏專門有一個“互關停留額外加成”參數,在當前公開默認值裏設的是 0(一分不加)!
  • 這項加成是**“因讀者而異”**的!假設你發了一篇原創帖,當你的互關好友李四刷到它時,如果 AI 預測李四有 2%(0.02)的概率會留言回覆,那麼在李四的籃子裏,回覆項貢獻的分數會從 5 × 0.02 = 0.10 暴漲到 20 × 0.02 = 0.40;但同一秒鐘,當一個還沒關注你的陌生讀者王五刷到同一篇帖子時,王五和你不互關(is_mutual_follow_author = false),在王五的籃子裏回覆係數依然是普通的 5!42
同一個回覆概率假設採用係數符合互關條件這個項目的貢獻
預測讀者回復爲 2%(非互關讀者)5不適用0.10
預測讀者回復爲 2%(互關好友)5+15適用0.40

固定同一個 2% 的回覆預測概率,在互關好友面前,單單回覆這一項的得分確實從 0.10 變成了 0.40(漲了 4 倍);但由於總分裏還有其他二十多項正負預測和後續調整,這絕不等於全站總曝光翻了 4 倍。42

14.1 普通關注關係還有另一項乘數

除了“互關好友看原創帖時回覆權重變 20”,關注關係在 VM Ranker 裏還有另一道非常關鍵的乘數:圈外候選乘數(Out-Of-Network Multiplier,簡稱 OON 乘數)。

在 vm-ranker/params.rs 的公開默認值裏,針對“讀者尚未關注該作者”的普通關係網外候選帖,系統設置了一個默認值爲 0.75 的 OON 乘數! 我們來算一下這個 0.75 意味着什麼:如果固定其他所有條件不變,只對比這一項乘數,一篇來自陌生人的“圈外帖子(乘 0.75)”,在套用乘數之前的原始分數必須達到“已關注作者圈內帖子(乘 1.0)”的 $1 \div 0.75 \approx \mathbf{1.3333}$ 倍(即高出約 33.3%),打完折之後的最終分數才能和圈內帖子打個平手!86

當然,這是在同一個候選池裏比拼分數的數學條件,不能粗暴翻譯成“陌生人曝光一定比粉絲少 25%”。(有兩個例外記在這裏:主題請求 Topic Request 用的是它自己的一套配置;另外代碼也允許把這套乘數設置,用到一部分圈內回覆和轉發上。)把“粉絲圈內 1.0 vs 圈外 0.75”和前面的“互關好友原創帖回覆係數 5 + 15 = 20”結合起來看,你會明白關注關係在不同環節各司其職,但絕不是一張“賬號每多一萬粉絲就固定加多少分”的等級表。86

特別是前面提到的“去大 V 評論區搶前排留言”:當你在大 V 帖子底下發了一條回覆,你發出去的那條東西本身就是一條 Reply(is_reply = true),在前面第一關 !self.is_reply 就被直接踢出局了!哪怕你和那個大 V、或者和刷評論區的讀者互相關注,你的這條評論也絕對拿不到 5 + 15 = 20 的互關加成(它依然可以在對話詳情頁裏被點開評論區的人看到,但別拿互關 20 倍權重來給“到處搶熱評一樓”當理論依據)。24 42

14.2 讓熟悉這個問題的人有話可接

看懂了“互關好友對原創帖的回覆預測高達 20”,那我們真正該怎麼用好這個機制? 答案不是去搞殭屍粉互關羣(殭屍粉根本不會看你的專業內容,AI 預測他們回覆你的概率接近於 0,乘以 20 還是 0!),而是要和真正同領域的同行、老讀者建立互關,並在寫原創帖時“留出讓內行同行有話可接的專業話頭”!

舉兩個最接地氣的例子:

  • 假如你是做小型餐飲創業內容的:別發那種“今天又是努力搬磚的一天,餐飲人加油”的萬能正確的廢話——改成直接列出兩款真實外賣打包盒在送湯麪時的成本與漏湯率對比,然後拋出一句同行每天都在面對的真問題:“你們店裏送帶湯米粉時,用的是卡扣碗還是封口膜?哪一種更容易被顧客投訴灑漏?” 關注你的餐飲同行一看到這個問題,手癢癢立刻就會在底下回一段自己的實測經驗!
  • 假如你是做程序員技術開發內容的:遇到一個詭異的報錯,別光發一句“終於修好了”,而是把報錯日誌截圖、運行環境版本號、以及你已經排除掉的三個假原因列出來,讓同樣踩過這個坑的同行能順着你的排查思路補上他遇到過的邊界案例。

當互關的同行在評論區補上了極有價值的反例或新場景,你覈對屬實後,又可以把它整理進下一篇原創帖裏。這樣你的互關圈子就變成了一個真正高活躍度的“專業智庫”——每當你發出一篇新原創帖,系統在算這批互關同行會不會回覆時,用的是 5 + 15 = 20 這個係數——乘的仍然是每位讀者各自的預測概率,係數大不等於一定推得起來,總分還要看其他二十多項。

15 讀者點進主頁後,爲什麼要關注你

很多創作者發現後臺數據裏有很多“個人主頁點擊(Profile Clicks)”,以爲只要把人騙進主頁,這篇帖子的算法分數就能大漲。 我們直接看 home-mixer/params/param.rs 和 scoring.rs 裏的公開默認權重表,這兩項的待遇天差地別:43

預測項目這組公開默認的直接係數
點進作者個人頁面(profile_click)0
關注作者(follow_author)4

你看:單純“點進作者個人主頁(profile_click)”在主融合打分公式裏的直接權重係數是 0 分!而“關注作者(follow_author)”的預測權重係數則是整整 4 分(比點讚的 0.66 高出 6 倍多)! (當然,同樣要說明邊界:這不等於每漲一個粉絲給帖子記賬加 4 分,而且 VM Ranker 另有個人頁停留等相關參數,個人頁點擊也是促成關注的前置動作,可能在模型的其他特徵裏被使用。)43

不僅如此,在同一個算法庫的 V8.2 內容理解代碼(grox/flows/mm_emb/renderer_v82.py)裏,當 AI 模型去理解你發的帖子時,除了讀帖子的正文和首圖,還會把**作者的顯示名稱(Display Name)、賬號名(Username / Handle)以及個人簡介(Bio,按字符上限截斷後)**一併拼進文本輸入裏餵給多模態大模型!這證明了:你的個人簡介(Bio)不僅給點進主頁的真人讀者看,在這條流程裏也是 AI 大模型直接看得到的輸入資料!(不過代碼裏只是把 Bio 讀進去做語義理解,沒有任何“在簡介裏塞滿熱門關鍵詞就能額外加分”的作弊公式。)44

15.1 把帖子、簡介和置頂連起來看

既然“點進主頁本身是 0 分,點進主頁後願意點關注纔有 4 分的高權重”,那我們必須想明白一件事:一個陌生讀者刷到你的一篇好帖子,好奇地點進你的個人主頁,他在那 3 秒鐘裏看到了什麼,纔會決定按下“關注(Follow)”按鈕?

設想一個最常見的翻車現場: 假設你持續在做“AI 辦公工具實測”,今天剛發了一篇硬核好帖《實測某會議紀要 AI:居然漏掉了客戶的否決條件》,吸引了一大批做項目管理的讀者點進你的主頁。結果人家一進你主頁,看到你的個人簡介(Bio)寫着八個大字:“熱愛科技,探索未來,感悟人生”;再往下看你的置頂帖,是一條半年前轉發的錦鯉抽獎或者不知所云的心情吐槽。 這位讀者腦子裏立馬打出一個問號:“這人到底是個剛巧寫了一篇測評的路人,還是以後會持續輸出這類工具實測?” 他拿不準關注你以後會刷到什麼,乾脆關掉主頁走了——你白白拿了一個 0 分的主頁點擊,丟掉了一個權重高達 4 分的“關注作者”轉化!

怎麼改?把你的**單篇爆款帖、個人簡介(Bio)和主頁置頂帖(Pinned Post)**串成一條嚴絲合縫的證據鏈:

個人簡介(Bio)可以改成這樣具體、可驗證的承諾: “專注實測 AI 工具在真實中文辦公流裏的表現。每篇評測均保留原始測試樣本、翻車反例與可復現的操作步驟。”

緊接着,在你的主頁置頂位置,直接掛上你寫得最紮實、證據最完整的一篇代表作(比如你的評測方法論總綱或最硬核的一期多工具橫評,題目明確、數據可查、適用邊界清楚)。 哪怕你是做美食食譜的賬號,道理也一模一樣:簡介別寫“唯愛與美食不可辜負”,改成**“專做一人食、一口平底鍋搞定的快手晚餐,每道菜都標好超市隨手能買的替代食材”**,然後置頂一篇最受好評的平底鍋食譜合集去兌現這句話!

每次發完新帖子,不妨切到訪客視角,把你剛發的這篇帖子、你的 Bio 簡介和置頂帖連起來讀一遍:被今天這篇帖子吸引點進主頁的陌生人,能不能在 3 秒內看懂你接下來還會持續爲他提供什麼價值?(把簡介改具體是爲了提高真人讀者的關注轉化率、讓 AI 更清晰地識別賬號語義定位,但別輕信網上說的“只要改幾個簡介詞就能一鍵重置賬號受衆池”。)

16 評論多了,也要看看是什麼人在說什麼

運營圈裏還有一種很危險的套路:“既然一般回覆(Reply)的權重高達 5 分(是點贊 0.66 的近 8 倍),那我故意在帖子裏說一句極端偏激的話、或者留個低級常識錯誤,引誘全網來評論區罵我、糾正我,評論刷爆了流量豈不是起飛?”

千萬別玩這種火! 打開 scoring.rs、home-mixer/params/param.rs 和 vm-ranker/params.rs 看看融合公式的下半部分你就知道爲什麼了:系統在算正向互動預測的同時,把四個一票否決級的負向懲罰項死死釘在了公式裏:2 45

  • 預測讀者屏蔽拉黑你(Block author):權重 -31.2;
  • 預測讀者點**“對這篇帖子不感興趣(Not interested)”**:權重 -52.272(VM Ranker 爲 -47.52);
  • 預測讀者靜音你(Mute author):權重 -58.8;
  • 預測讀者舉報你(Report):權重 -234.0!

你看清這幾個負數的量級了嗎? 一條普通回覆的權重是 +5,而一個“不感興趣”的係數是 -52.272,一個“舉報”更是 -234.0。注意,這幾個數字乘的都是預測概率,不能換算成“頂多少條回覆”;能說的只是:負向係數的量級比正向大得多。當你靠引戰、攻擊別人或低級釣魚把評論區吵翻天時,回覆預測概率確實漲了一點,但厭煩你的讀者順手點“不感興趣、靜音、拉黑、舉報”的負向預測概率也會同步暴漲——正負一相抵,你的帖子總分當場就會被砸成負數!

更直接的懲罰還在後面:一旦某個讀者真的因爲看煩了你的引戰帖,對你點下了靜音(Mute)或屏蔽(Block),在後續所有推薦請求的評分前過濾階段,關係過濾器 author_socialgraph_filter.rs 會直接查出這條已存在的拉黑/靜音關係,只要這段關係還在,你的帖子就進不了這位讀者的候選池。這可不是“模型預測他可能靜音你”,而是實打實把路堵上了。45

比如你寫一篇產品對比測評,你完全可以客觀犀利地指出“某款軟件官方宣傳的 99% 識別率與我們的實測結果嚴重不符”,並把你的測試樣本和翻車截圖擺出來——這種就事論事的硬核批評,同樣能引發熱烈的專業討論。你完全沒有必要爲了騙評論,在文章裏開地圖炮辱罵用這款軟件的用戶“智商低”,或者故意艾特(@)跟測試毫無關係的大 V 挑起罵戰。靠罵戰引來的評論,吸引來的根本不是你想留下的目標受衆。

平時復盤兩篇帖子的評論區時,別光數評論條數:要看大家是在評論區裏補充測試邊界、追問具體場景、分享自己的踩坑案例(這些全是你寫下一篇爆款的絕佳素材),還是在單純地互相攻擊謾罵——後者的數字再熱鬧,算上背後的負向懲罰權重和靜音流失,也是賠本買賣。45

17 同一篇長文,該髮長 Post 還是 Article(含 64 贊拉圖門檻與 V5/V8.2 實測拆解)

這幾乎是每一個寫深度內容的 X 創作者最糾結的問題:“我手頭寫好了一篇幾千字的深度乾貨,到底是直接發成一條**長 Post(Longer Post)流量更好,還是放進專欄文章編輯器(Article)**裏發佈更容易被算法推薦?”

在把所有跟長 Post 和 Article 相關的代碼文件翻了個底朝天之後,我的核心結論是:

  1. 在最終打分公式(scoring.rs)裏,沒有任何看到 is_article 就給你額外乘幾倍分數的“格式特權加分”;
  2. 但是!這兩種格式在底層的對象結構、AI 閱讀器(V5 與 V8.2)抓取圖文的方式、上游拉取圖片的“64 贊門檻(is_high_fav)”,以及草稿修改時的可見性過濾規則上,確實存在巨大的工程差異! 我們既不能籠統地說“兩種格式在算法眼裏一模一樣”,也不能聽信網上吹的“只要改成發 Article 曝光就自動暴漲 5.7 倍”。

如果先給一個最實用的省流結論,我平時自己發稿的判斷標準非常明確:

  • 圍繞單一痛點、一條邏輯線就能一氣呵成講透的內容(比如三四千字以內) → 直接發 長 Post,並在普通圖片欄掛 1 張最核心的結果對比圖;
  • 需要分多個章節、穿插多張圖表和代碼塊、方便讀者像查手冊一樣反覆檢索的重磅研究(比如像你現在讀的這篇兩萬字長文) → 用 Article(或按問題分篇的 Articles)承載全文,同時務必在發佈後單獨發一條“帶核心結果圖的導讀長 Post”去引用推廣它!

爲什麼“Article + 一條帶圖導讀 Post”是最穩妥的穩妥組合?看完下面代碼裏的 6 層硬核拆解,你就徹底明白了。

17.1 長 Post 和 Article 在系統裏是什麼

我們先確認長 Post 和 Article 在 X 產品和代碼裏的真實身份:

  • 長 Post(Longer Post):在產品上依然是一條普通帖子(只是開通 Premium 後單帖字數上限放寬到了 25,000 個字符,並且可以用在普通發帖、回覆和帶評論引用裏);
  • Article(專欄文章):擁有獨立的富文本編輯器,支持多級標題(H2/H3)、正文中內嵌多張圖片/視頻/其他帖子,發佈後會專門收進你個人主頁獨立的 Articles 欄目裏。(注意:我們這裏對比的是這兩種 X 站內原生格式,往帖子裏塞一個跳去站外個人博客的鏈接,或者拆成十幾條串文 Thread,都屬於另外的玩法。)6 95

在後臺代碼裏,系統是完全分得清這兩者的:比如反濫用系統 BotMaker 的特徵抽取器(FeaturesOfTweet.java)會分別提取 noteTweetId(長帖 ID)和 articleId(專欄文章 ID);而在 Grox 多模態與安全系統的 Post 數據模型(data_types.py)裏,同一個帖子對象既保存了帖子文本 full_text,又有一個可選的 article_metadata(Article 元數據,裏面裝着 Article 標題、Article 封面圖和 Article 正文內嵌媒體)。這證明系統底層絕不是靠“數數字數有多長”來認出 Article 的;只不過這些字段主要服務於內容理解與安全檢查,並不是打分器裏的“格式加分卡”。87

我把長 Post 和 Article 在代碼裏的 6 個核心層次列成了一張對比總表,先看全景,再逐層細拆:

比較層次長 Post/普通帖子文本路徑Article 相關路徑目前能作出的判斷
對象與內容結構Post.full_text 保存傳入的帖子文本;另有 noteTweetId 身份字段同一個 Post 對象可以額外掛載 article_metadata(含標題、封面圖、內嵌媒體)系統底層完全能區分兩種格式,並非只數正文字數
V8.2 內容理解(新版閱讀器)對傳入的 full_text 截取前 4,000 個字符;只從普通附件 post.media 取第 1 張可用圖額外讀取 Article 標題(截取前 200 個字符);不遍歷 Article 封面圖和內嵌圖!這是 V8.2 處理器的輸入規則,不是全站人類閱讀字數上限
V5 內容理解(舊版閱讀器)讀取帖子文本及普通帖子媒體按順序讀取:Article 標題 → Article 封面圖 → 帖子文本 → 普通媒體 → Article 內嵌媒體兩代閱讀器挑圖規矩截然不同,不能共用同一句“只看首圖”
閱讀與點擊行爲記錄普通點擊、展開全文(Show more)、詳情頁曝光及停留分別設獨立編號協議裏有 PAGE_ARTICLE 頁面枚舉,但從打開 Article 到訓練標籤的映射鏈未完全公開不能打包票說“點開長 Post 展開”與“點進 Article 專欄”算成同一種停留事件
已覈查的候選召回與計分走通用候選來源、24 項預測融合和同作者 0.625 衰減未找到任何僅憑 is_article 身份就生效的保底配額或固定加分乘數代碼裏沒有顯式格式加分,但不排除上游模型從內容特徵中學到隱性差異
可見性與安全過濾走通用帖子安全規則和訂閱受衆資格檢查另有 ArticleTweetContent(攔截非 Published 已發佈狀態)、封面及內嵌媒體安全檢查這些是展示資格與風控規則,不是曝光獎勵表

17.2 4000 字符處理的是哪個文本,Article 正文又在哪裏

我們先看錶格第二行:V8.2 內容理解閱讀器(grox/flows/mm_emb/renderer_v82.py)是怎麼讀文字的? 把源碼裏跟文字截斷和組裝直接相關的幾行核心代碼抽出來(省略其餘無關字段),真相就在眼前:47 83

MAX_POST_TEXT = 4000
MAX_ARTICLE_TITLE = 200

def _truncate(text: str, limit: int) -> str:
    text = (text or "").strip()
    if limit < 0:
        return text
    return text[:limit].rstrip()

if post.full_text:
    blocks.append(
        f"Post text: {_truncate(_strip_dangling_media_urls(post.full_text), MAX_POST_TEXT)}"
    )

article = cls._article_block(post)
if article:
    blocks.append(article)

請仔細看上面這段 Python 代碼裏的兩個關鍵細節:

  1. 兩個 if 判斷是上下並列執行的,根本不是“二選一(if ... else ...)”! 函數 _article_block(post) 負責讀取 article_metadata.title(Article 的標題,截取前 200 個字符)。如果一篇掛了 Article 元數據的帖子,它的 post.full_text(承載這篇 Article 的外層帖子文本)也不爲空,那麼前 4,000 字符的 post.full_text 和前 200 字符的 Article 標題會同時被拼進輸入塊 blocks 裏!網上有人把這段代碼傳成“髮長 Post 會讀正文,發 Article 就把正文丟掉只讀標題”,那是連代碼裏的兩個 if 都沒看懂。83
  2. 4000 是實打實的 Python 字符串切片字符數(text[:4000])! 無論是中文漢字、英文字母還是標點符號,在 Python3 字符串切片裏,1 個字符就佔 1 個位置(不是大模型按詞根拆分的 token 數,也不是前端編輯器的 25,000 字發佈上限)。截好之後的文本和挑出來的圖片,會被一起打包送給 embedder_v82.py 服務,用來生成代表這篇帖子主題的多模態語義向量(Embedding)——注意,這裏是用來做語義理解和匹配受衆的,並不是在這裏按字數直接給你算曝光量。47

爲了驗證這段邏輯毫不含糊,我在本地構造了填好字段的內存 Post 對象,直接調用公開的 renderer_v82.py 處理函數跑了實測(注:本地測試只檢驗該處理器喫進什麼、吐出什麼,不調用線上未公開權重的 embedding 模型服務):88

固定其他字段後的輸入V8.2 的輸出這個檢查說明什麼
full_text 填入 4,000 個“字”,第 4,001 個字符填“尾”輸出的 Post text: 恰好是 4,000 個“字”,“尾”字被無情切掉4,000 字符截斷邊界嚴格按 Python 字符位置一刀切
保持前 4,000 個字符一字不動,只修改第 4,000 字符後面的內容V8.2 輸出的文本塊一字未變在 V8.2 這條語義生成路徑上,第 4,000 字符往後的文字完全不可見(其他系統模塊不在此試驗範圍)
同時填入 full_text 和長達 201 個字符的 Article 標題最終輸出裏同時包含 Post text: 和 Article title:(標題保留前 200 字符)承載帖文本與 Article 標題在 V8.2 輸出中完全共存,互不排斥

這裏有一處要老實交代:公開代碼沒把「Article 正文到底怎麼進模型」這件事講全。已知的部分是:在公開的數據映射器(grox/core/data_loaders/post_mapper.py)裏,上游傳來的 post_metadata.text 被放進 Post.full_text;而 article_metadata 裏只映射了標題(title)和媒體(cover_media/media),沒有一個單獨裝 Article 正文全文的字段。不知道的部分是:線上真正的上游服務(Strato 是 X 內部後臺服務的統稱)怎麼填這個 text 字段、Article 的萬字正文有沒有走別的內部通道餵給模型——這部分實現沒公開。所以兩個極端都不能說:不能因爲字段名叫 full_text,就斷定所有格式的正文全文都進去了;也不能因爲 article_metadata 裏沒列正文字段,就斷言全站所有模型都看不見 Article 正文。87

此外,在 home-mixer/models/content_features.rs 裏,系統還會提取帖子的加權文本長度(weighted_text_len)和換行數(newline_count)等基礎特徵傳給下游。這說明“帖子有多長、分了多少行”是模型能看到的特徵,但代碼裏同樣沒有任何“字數越長加分越多”或“空一行加幾分”的固定公式。46

不過,知道了 V8.2 的“前 4,000 字符正文 + 前 200 字符 Article 標題”讀取規則,我們寫稿時的鐵律就已經非常清楚了:寫長 Post 時,務必在前 4,000 個字符以內把研究對象、核心痛點和主要結論全部亮出來;寫 Article 時,務必把前 200 個字符的標題和外層承載帖導語寫得信息量拉滿,絕不要把所有核心關鍵詞都憋在文章最後兩千字才揭曉!

17.3 Article 的封面和正文圖片,不能照搬普通圖帖的規則(徹底講透什麼是“64 贊 is_high_fav”與 V5/V8.2 差異)

很多朋友在看這一節時最容易卡殼:“到底什麼是 Article 的 64 贊門檻(is_high_fav)?V5 和 V8.2 兩個閱讀器讀 Article 的圖片爲什麼不一樣?我發 Article 時圖片到底該怎麼放?”

我們不甩乾巴巴的術語,直接按**“當你按下發布 Article 按鈕之後,X 後臺按先後順序發生了哪兩步”**,用大白話一層層順下來:

17.3.1 第一步:AI 想看懂你的圖,得先有個“搬運工(MediaLoader)”把圖從數據庫拉過來

當你發出一篇內容,X 後臺的 Grox 多模態大模型要去讀你的文字和圖片,生成代表這篇內容主題的“語義向量”,用來判斷該推給哪些興趣圈子的讀者。 但是,去服務器下載和解析高清大圖是非常消耗算力的!於是在負責拉取媒體數據的“搬運工”代碼(grox/core/data_loaders/media_loader.py)裏,程序員設了一個判斷開關叫 is_high_fav(直譯過來就是:“這是一篇高贊帖子嗎?”),並在配置文件(grox/config/config.py)裏把它的公開默認門檻設成了 64 個贊(deluxe_fav_count_threshold = 64)!89

這行代碼具體幹了什麼事? 在 MediaLoader 這條媒體搬運路徑上,只有當帖子滿足了 is_high_fav 成立(也就是點贊數達到至少 64 個贊),並且同時符合待處理帖子選擇、當前任務類型和已有媒體狀態等條件時,搬運工纔會走入專門的分支(media_loader.py#L293-L303),去拉取 Article 的專屬封面圖(cover_media)和 Article 正文裏的內嵌圖片(article_metadata.media)!

  • 說人話就是:在你的 Article 剛剛發出來、還沒攢夠 64 個贊之前,走這條 MediaLoader 搬運路徑時,搬運工爲了省服務器算力,可能壓根不會去拉取你放在 Article 編輯器裏的封面圖和正文插圖!
  • 同時必須守住嚴謹邊界:這個 64 贊僅僅管的是 MediaLoader 這條特定媒體拉取路徑的公開默認參數,絕不代表“Article 必須先拿夠 64 個贊纔有資格進推薦流”!89

17.3.2 第二步:就算圖片已經拉過來了,V5 和 V8.2 兩代“閱讀器”挑圖的規矩也完全不同!

在公開代碼庫裏,同時共存着兩代多模態內容閱讀器(Renderer):舊版 V5(renderer.py) 和新版 V8.2(renderer_v82.py)。它們倆對待 Article 圖片的態度簡直是天壤之別:88

  1. 舊版 V5 閱讀器怎麼讀 Article: V5 非常勤快,它的讀取順序依次是:Article 標題 → Article 封面圖 → 帖子文本 → 普通帖子媒體附件 → Article 正文內嵌媒體。當然,V5 受“圖片數量預算(Budget)”的限制——如果某次調用把圖片預算設爲“只讀 1 張圖”,那排在第一順位的 Article 封面圖 就會獨佔這唯一一個名額,正文裏內嵌的插圖就輪不上了。
  2. 新版 V8.2 閱讀器怎麼讀 Article(最大的坑在這裏!): V8.2 在處理 Article 時,文字部分會正常讀入 post.full_text(前 4,000 字符)和 Article 標題(前 200 字符);但是!到了負責挑圖片的函數 _collect_post_media 時,它只去翻“普通帖子的媒體附件欄(post.media)”,在源碼里根本沒有寫任何循環去翻 Article 專屬的封面欄(article_metadata.cover_media)和正文內嵌圖欄(article_metadata.media)!

爲了驗證這個驚人的差異,我在本地寫測試腳本,給同一個內存 Post 對象同時塞進了三張已經就緒的圖片數據:① Article 封面圖、② 普通帖子媒體附件(post.media)、③ Article 正文內嵌圖,然後分別調用 V5 和 V8.2 的原版函數:

  • 調用 V5 時:它乖乖按“封面圖 → 普通附件 → 正文內嵌圖”的順序全部返回(當把圖片預算設爲 1 張時,就只返回 Article 封面圖);
  • 調用 V8.2 時:它只返回了“普通帖子媒體附件(post.media)”!緊接着我做了一個更絕的測試——把普通帖子附件清空,只把圖片放在 Article 封面和 Article 正文裏(這正是大家平時直接在 Article 編輯器裏發文章時的真實狀態),結果調用 V8.2 時,返回的圖片列表直接是空的(0 張圖)!88 (注:這項本地實測證明的是 V5 與 V8.2 在「讀哪些字段」上的代碼差異;5ed7963 與 606b254 兩個版本里這段邏輯一致。但線上又是另一回事:上游會不會先把 Article 封面複製一份塞進 post.media、哪些模型用 V5 的向量、哪些用 V8.2 的,取決於線上內部配置。所以不能下「線上所有 Article 都沒有圖片向量」這種絕對結論。)

17.3.3 發 Article 時到底該怎麼做?(3 條實操動作)

既然普通多圖帖是“別把核心數據藏在第 4 張圖”,那到了發 Article(專欄文章) 時,爲了同時兼容“未滿 64 贊前的 MediaLoader”、“挑剔的 V8.2 閱讀器”和“看封面的 V5 閱讀器”,最穩妥的實操打法就是下面這三招:

  1. 動作一:Article 的“標題(前 200 個字符)”必須塞滿核心乾貨詞,千萬別起文藝空洞的標題! 因爲在你的 Article 還沒攢夠 64 個贊之前(MediaLoader 還沒拉取 Article 圖片),或者在走 V8.2 閱讀器時(不讀 Article 專屬圖片),AI 百分百能穩定讀到的就是你的 Article 標題(前 200 個字符) 和外層承載帖文本!如果你起個標題叫《週日深夜的一點思考》,圖片又沒被讀進去,AI 就徹底抓瞎了,完全不知道你這篇 Article 在聊什麼;改成**《實測兩款中文發票 OCR 工具:模糊掃描件下稅額與日期字段的識別錯誤率對比》**,哪怕一張圖都沒讀進去,AI 光靠標題這幾十個字也能精準幫你匹配財稅與技術圈的目標讀者!
  2. 動作二:Article 的“封面圖”別放純風景或抽象表情包,要放信息明確的主圖。 因爲一旦走 V5 閱讀器(當圖片預算爲 1 張時),或者當你的 Article 點贊滿 64 個觸發了 MediaLoader 拉取之後,排在第一順位被 AI 讀走的就是 Article 封面圖,正文裏嵌的第 2、3、4 張圖都排在它後面。
  3. 動作三(最穩妥的穩妥組合):發完 Article 後,一定要單獨發一條“導讀長 Post”,並把最核心的 1 張結果對比圖直接掛在這條導讀 Post 的普通圖片附件欄裏! 爲什麼這一招最穩妥?因爲導讀 Post 本質上是一條普通長帖子,你掛在它上面的圖片屬於“普通帖子媒體附件(post.media)”——它既不受 Article 那 64 個贊(is_high_fav)的拉取門檻限制,又能從第 0 個贊開始,立刻被 V8.2 閱讀器把“前 4,000 字導讀正文 + 第 1 張核心數據圖”喫得乾乾淨淨! 這就是爲什麼懂行的大 V 每次發完萬字 Article,一定會緊跟着發一條帶核心結果圖的導讀 Post 去引用它!

17.4 展開長 Post、打開 Article、讀到末尾,是不同的待覈問題

很多創作者還會問:“讀者在時間線上點‘展開全文(Show more)’看長 Post,和點進卡片打開一篇 Article 專欄,在算法後臺算不算同一種點擊和停留?”

我們去翻通信協議定義文件 phoenix/python/common/xai-proto/proto/recsys.proto,發現代碼把這幾種看似相近的動作編成了完全不同的獨立編號(Action Enum):90

動作枚舉編號名稱能說明什麼
CLIENT_TWEET_CLICK29獨立的普通帖子點擊事件
CLIENT_TWEET_SHOW_MORE_EXPAND45點擊長帖的“展開全文(Show more)”,並沒有和普通點擊共用編號 29
CLIENT_TWEET_DETAILS_IMPRESSION72點進帖子詳情頁的曝光被單獨記錄
CLIENT_TWEET_DETAIL_DWELL103在帖子詳情頁裏的停留也被單獨記錄
CLIENT_TWEET_RECAP_DWELLED11前面講的雙塔召回 ld 分支專門使用的閱讀停留正例事件名

你看,編號 45 的 CLIENT_TWEET_SHOW_MORE_EXPAND(展開更多)不僅有獨立編號,還出現在歷史互動特徵集合(history_id_lists.py)和 IsShowMoreExpanded 映射(constants.py)裏,說明系統在收集用戶歷史特徵時確實認得“展開長帖”這個動作。 但是,當我們去查最終價值打分模型(xai-value-model/phoenix_scores.rs)時,裏面既沒有一個單獨叫 show_more_score(展開加分)的字段,也沒有一個叫 article_completion_score(Article 完讀加分)的字段。所以我們既不能說“讀者點展開全文一點用都沒有”,也不能拍腦袋編造說“讀者每點一次展開全文就固定加幾分”。90 94

同樣,在協議文件裏也能查到專門代表 Article 的頁面類型枚舉:PAGE_ARTICLE(Article 正文頁)和 PAGE_ARTICLE_PREVIEW(Article 預覽頁)。但“頁面類型(Page)”和“動作類型(Action)”在協議裏是兩個不同的字段——能查到 PAGE_ARTICLE 這個名字,不代表公開代碼已經把“讀者點開 Article 頁面 → 觸發了哪個編號的動作 → 怎麼折算成訓練數據裏的閱讀時長標籤 → 最終餵給哪個預測頭”的完整映射鏈條交出來了。90

爲什麼這一段映射查不到?因爲這正好卡在了公開代碼庫的邊界之外: 公開出來的訓練代碼(recsys_batch.py)直接讀取的是已經由上游處理好的行爲向量和連續數值列,而 Home Mixer(scoring_sequence_query_hydrator.rs)也是直接向外部行爲聚合服務伸手拿結果。至於手機客戶端從哪一秒開始給 Article 計時、讀者從 Article 退回首頁後停留時長怎麼歸因、切到手機後臺算不算停留、點長 Post 的“展開全文”會不會順帶同時觸發一次編號 29 的普通點擊,官方在 phoenix/README.md 裏明確說明:生產環境的數據源與內部遙測聚合管線並未開源。91

最後把兩個「停留」數據槽位分清。連續停留 DWELL_TIME 的單位有據可查:公開的 Rust 工具代碼(xai-recsys-engine/src/util.rs)裏明明白白把它從毫秒除以 1000 換成秒,用作 predicted_dwell_sec。但點擊後停留 CLICK_DWELL_TIME(門檻 10.0)這邊還差一截:它的原始數值到底是什麼單位、讀者點開 Article 的時長算不算進這個槽位,公開代碼裏沒給出答案。這正是「Article 字數更長 → 讀者停留一定更久 → 發 Article 一定比長 Post 多拿推薦」這條直線推不出來的原因:文章有多少字、讀者實際看了幾秒、AI 事前預測他會看幾秒、有沒有讀到最後一段,本來就是四個不同的變量。91 98

17.5 沒有找到 Article 固定加成,也沒有證據證明兩種格式待遇完全相同

爲了徹底排查“發 Article 有沒有隱藏的流量特權”,我把 Home Mixer 裏的候選來源(sources)、過濾器(filters)、打分器(scorers)、參數表(params)和主候選流水線(phoenix_candidate_pipeline.rs)全部檢索了一遍:

  • 在 Thunder、Phoenix、TweetMixer、SimClusters 等所有公開召回入口裏,沒有任何一個入口按“是不是 Article”分配專屬保底名額(前面講的 FairShare 也是按召回來源渠道分組,而不是按長 Post 或 Article 格式分組);94
  • 在最終價值計分模型的輸入結構體 CandidateScoringInputs(xai-value-model/inputs.rs)裏,根本沒有 is_article 或 is_long_post 這兩個布爾字段!
  • 在開啓同作者多樣性衰減(0.625)時,函數也只是按 author_id 累計同作者候選次數——也就是說,如果你上午發了一篇長 Post,中午又發了一篇 Article,它倆要是同時掉進同一個讀者的臨時籃子裏,排第二的那篇照樣喫 0.625 衰減,絕不會因爲你換成了 Article 格式就把同作者計數器清零!2 94

當然,本着科學嚴謹的態度,“已公開的打分函數里沒有寫死 is_article 固定乘數”,只能幫我們證僞“算法代碼直接給 Article 寫了固定幾倍加成”的謠言;它並不能排除上游深度學習模型通過學習內容特徵對不同格式產生隱性偏好,也不能排除線上存在未公開的實驗分流。

另外,很多創作者把另一件事搞混了:X 官方以前在創作者收益公告裏確實提過,在計算創作者廣告收益分成(Creator Revenue Sharing)或舉辦百萬美元徵文比賽時,可能會給 Articles 更高的收益分配權重;但那是分錢算稿費的權重,根本不是 For You 推薦流的排序係數!而且舊版的廣告分成計劃已經在 2026 年 9 月正式結束並切換到了新的 Original Content Rewards 規則,千萬別拿老黃曆裏的“分錢權重”當成今天的“推薦算法加成”。97

17.6 Article 確有獨立可見性處理,但先看觸發條件和入口

雖然打分時沒有 Article 專屬加分,但在安全與可見性過濾系統(visibility-filtering)裏,Article 確實有一條專屬的攔截規則,而且藏着一個很多創作者不知道的**“改稿隱身坑”**!

打開 visibility-filtering/rules/tweet_rules.rs,裏面有一條名叫 ArticleTweetContent 的規則:只要一條帖子關聯了 Article,並且這篇 Article 當前的狀態不是 Published(已發佈狀態),系統就會直接執行過濾攔截(Drop)! 公開測試樣例(golden_corpus/article.rs)裏明確測試了草稿(Draft)、軟刪除(SoftDeleted)、狀態缺失以及已發佈(Published)四種狀態,只有 Published 能通過這道檢查(注意兩個邊界:一,這條規則掛在 TimelineHomeHydration 這個檢查級別上;Home Mixer 另一些地方用的是 TimelineHome、TimelineHomeRecommendations 另外兩個級別,三個級別線上怎麼串起來,取決於每次請求的實際配置。二,所以不能簡單說:每篇 Article 在進 Phoenix 打分之前,都必定多過這一關。)。92

那爲什麼說這裏有個**“改稿隱身坑”? 去查 X 官方的 Articles 幫助文檔就會發現:當你對一篇已經發布的 Article 點擊編輯修改時,系統的機制是先把這篇 Article 從已發佈狀態撤下來(變成未發佈草稿狀態),等你改完點擊重新發布後,才恢復成 Published 狀態**! 這就意味着:如果你發完一篇 Article 後,發現裏面有幾個錯別字,於是撤下來慢慢改了半個小時卻忘了點重新發布,或者一天之內反覆撤下改稿好幾次——在你撤下改稿的這段時間裏,這篇 Article 的狀態不是 Published,在觸發 ArticleTweetContent 規則的入口就會被直接當成未發佈內容攔截過濾掉! 所以發完 Article 如非必要別頻繁撤下大改,改完更要第一時間確認它已經回到 Published 已發佈狀態!6 92

此外,Article 的封面圖和正文內嵌媒體也會被合併計入可見性系統的“是否包含媒體(compound.rs)”判斷裏(這只是用來走對應的媒體安全規則,普通文章帶張健康封面圖絕不會因此自動降權)。而如果你把 Article 設爲“僅限訂閱者可見(Subscribers-only)”,通用過濾器 IneligibleSubscriptionFilter(ineligible_subscription_filter.rs)就會檢查當前刷首頁的讀者有沒有付費訂閱你(subscription_author_id),沒訂閱的讀者自然刷不到;同時 Article 媒體接口(article_client.rs)在沒有權限時也會隱藏媒體字段——這是正常的付費牆權限控制,不能誤判爲“Article 圖片丟了”或“被算法限流”。92 93

17.7 實際數據裏 Article 表現更好,爲什麼還不能判定同稿必勝

這時候肯定有朋友會拿出一份數據反駁:“不對呀!第三方機構 NotPeople 在 2026 年 9 月剛發了一份實測報告,統計了 8 月份的數據,人家算出 Article 的瀏覽量中位數是普通帖子的 5.7 倍 呢!”

這份報告(NotPeople 原文)我也專門調出來逐表覈對過。它的統計主表裏一共包含了 42 篇 Articles、843 條帶有 Article 鏈接的普通導流帖,以及 64 條不帶 Article 鏈接的普通帖子。如果拿每位作者自己的平均帖子瀏覽量做基準歸一化,那 42 篇 Articles 的歸一化瀏覽量中位數確實達到了 5.7 倍。96

但是!你看清那兩個數字的比例了嗎:42 篇 Articles 背後,跟着整整 843 條普通導流帖! 報告原作者在文內自己都坦誠說明了:在這批創作者樣本里,作爲對照的絕大多數普通帖子其實是簡短的“導流推廣帖”,並不是拿同樣一篇幾千字的完整乾貨分別發成“長 Post”和“Article”做同稿對比;而且這批創作者每發 1 篇 Article,平均要在後面連發 6 到 28 條相關的普通帖子(摘錄、短評、引用)去給這篇 Article 瘋狂導流推廣! 一邊是花了重金和心血寫出來、又連發十幾條帖子衆星捧月般導流了幾個星期的旗艦 Article,另一邊是隨手發的日常短導流帖——這兩者的題材分量、寫作投入、導流推廣力度和累積瀏覽量的時間窗口完全不在一個起跑線上!所以,這份樣本能證明“採用【1 篇重磅 Article + 十幾條導流帖】矩陣打法的創作者,其主 Article 攢下了很高的瀏覽量”,但絕對證明不了“把同一篇稿子從長 Post 粘貼進 Article 編輯器,什麼額外導流都不做,曝光就會自動翻 5.7 倍”!96(至於前面提過的 Hootsuite 2024 年小實驗,只比了 Thread 和長 Post,壓根沒測 Article。25)

17.8 要發佈的這篇內容,具體怎麼選

剝離了所有的水分和玄學之後,當你手頭有一篇新稿子準備發佈時,到底該選 長 Post、Article,還是 Article + 導讀 Post?直接對照下面這張決策表對號入座:

你準備發佈的材料我會優先選什麼格式選擇的具體理由
圍繞一個明確判斷,幾段話+1 張對比圖就能徹底說清;或者需要直接接在某條熱門討論底下回復/引用長 Post一氣呵成完成論證,且普通圖片附件(post.media)從 0 贊起就能被 V8.2 直接讀入,無需爲形式硬拆章節
一份多章節深度調查、完整操作手冊或工具指南,需要用到多級小標題、穿插多張圖表供讀者日後反覆查閱Article多級標題層級和內嵌材料排版極佳,且永久沉澱在個人主頁的 Articles 專欄裏方便檢索
完整研究報告非常長(比如上萬字),同時又希望從未關注過你的陌生讀者在刷首頁時一眼看懂它解決了什麼痛點Article(或分篇 Articles)+ 1 條帶核心圖的導讀長 Post穩妥組合:用 Article 承載嚴謹全文,同時發一條掛着核心結果圖的導讀長 Post,既繞開 Article 64 贊拉圖門檻與 V8.2 漏圖問題,又讓讀者先拿到乾貨結論
同一篇三千字稿件在兩種格式裏都排得通,你唯一的目的只是想知道在自己賬號上哪種自然曝光更高用自己賬號的可比樣本做交替測試目前公開代碼與外部研究都沒有“同稿必勝”的鐵證,自己賬號的實測受衆反饋最準
需要面向付費訂閱讀者定期交付深度研究或專屬資料開啓相應訂閱受衆控制的 Article按交付對象選擇;但記住付費牆是權限過濾(IneligibleSubscriptionFilter),不會給公開推薦加分

我們還是拿前面聊過的**“中文發票 OCR 識別工具測評”**來舉個一錘定音的例子:

  • 如果你這次測試的發現非常集中——僅僅是發現**“當發票掃描件有摺痕模糊時,稅額這一欄極容易把 8 識別成 3”**——那你只需要放 1 張模糊發票原圖、1 張兩款工具的識別結果對比表,外加三段文字講清適用條件,直接發一條長 Post 就夠了!
  • 反過來,如果你這次做的是全方位橫評——要交代 50 張不同畫質的發票樣本分組、兩款工具的 API 參數設置、日期/稅額/買方稅號等多個字段的準確率大表、典型翻車案例以及二次複測記錄——那就把這份完整報告放進 Article 裏發佈,緊接着單獨發一條帶核心結果圖的導讀長 Post!

這條配套的導讀長 Post 千萬別寫成“我剛發了一篇發票 OCR 深度好文,大家快點進鏈接看全文!”(這種空洞導流沒人愛點),而是應該寫成一條哪怕讀者不點進 Article 也能立刻學到一招的獨立乾貨帖:

導讀長 Post 示範文案(同時在普通圖片欄掛上最核心的 1 張稅額識別對比圖): 評估中文發票 OCR 工具能不能直接對接財務入賬系統,千萬別隻看廠商宣傳的“全文總字符準確率 99%”。

一定要把開票日期、稅額、買方稅號三個字段拆出來單獨測:哪怕一整張發票上百個字裏只認錯 1 個數字,只要那個數字剛好落在“稅額”欄裏,這張憑證入賬就會直接報錯!

我用同一批帶摺痕的真實中文發票,對兩款主流 OCR 工具做了逐字段盲測,把測試原圖、各字段錯誤率對比表以及必須轉人工複覈的邊界條件整理成了下面這篇完整專欄。正在做財務自動化選型的朋友,建議直接先看裏面的稅額對照表👇

你看上面這段導讀(這是寫法示範,裏面的測試要換成你自己真做過的事,沒做過別照抄):它本身已經把“別看全文準確率,要拆稅額字段單獨測”的核心乾貨交付給了讀者,掛在普通圖片欄的首圖又能從第 0 個贊起直接餵給 V8.2 閱讀器;真正有財務選型需求的讀者看完導讀,自然會點進下方的 Article 把整套表格抱走。官方幫助頁推薦的“用摘錄帖子引向完整 Article”指的就是這種組織方式(當然,這是科學的圖文分發配合,不是每發一條導讀系統就白送一份流量配額)。6

順便提醒一句排版實操細節:如果你準備把像本文這樣包含大量代碼塊、數學公式和複雜 Markdown 表格的長稿放進 Article 編輯器,發佈前一定要在預覽界面逐段檢查!Article 編輯器雖然支持富文本,但直接粘貼複雜的 Markdown 語法或 LaTeX 公式進去,有時會出現表格錯位或公式渲染失敗。如果整篇報告加附錄太長,完全可以按“能夠獨立回答的完整問題”拆成上下兩篇 Articles,或者在文末附上完整版 Markdown / PDF 文檔的下載入口,千萬不要爲了硬塞進一條普通帖子裏而把改變結論的關鍵邊界條件給刪掉。

17.9 怎樣比較自己的結果,纔不會把瀏覽量當作讀完人數

如果你打算在自己的賬號上親手測一測“長 Post”和“Article”到底哪個效果更好,怎麼測纔不會被假數據騙了?

  1. 第一步:先定準你要考覈的真實業務指標,別拿前臺公開瀏覽量(Views)當成“讀完全文的人數”! 官方幫助文檔(View counts)寫得明明白白:前臺顯示的帖子瀏覽量(Views),只要有人在時間線上劃過看到就算 1 次,而且同一個讀者反覆刷到、甚至你自己點開看,都會重複計入瀏覽量,還混雜了搜索、主頁等不同入口!面板上有 10,000 次瀏覽,既不能證明有 10,000 個獨立活人點開了你的全文,更不能證明他們讀到了最後一段。如果你想測“破圈拉新”,就重點記錄主頁訪問量、新增關注數;如果你想測“乾貨轉化”,就重點記錄收藏數、有效諮詢私信或資料下載點擊量。59
  2. 第二步:做“同檔題材交替對比”,並且把導流投入算清楚。 挑出 6 到 10 篇選題難度、目標受衆和寫作投入差不多的原創乾貨,單數篇髮長 Post,雙數篇發 Article,並且都固定在同一個活躍時間段發佈:
  • 第一輪測試:兩邊都只發主帖、都不發額外導流帖,純粹觀察兩種格式本身的自然曝光與收藏轉化差異;
  • 第二輪測試:拿“1 篇 Article + 2 條帶圖導讀 Post”去和“單發 1 篇長 Post”對比——這時候你要記住,前者一共發了 3 條內容、多花了兩倍的宣傳精力,記賬時要把整組投入和單篇表現分開記,更不能把導讀帖的瀏覽量和 Article 的瀏覽量直接相加當成“去重總讀者數”!
  1. 第三步:看 24 小時與 7 天中位數,千萬別把“同一篇稿子連發兩遍”當成嚴格 A/B 測試! 每篇統一記錄發佈後 24 小時和 7 天的核心數據(同時備註期間有沒有遇到大 V 轉發、熱點事件或付費推廣),對比多篇樣本的中位數,別讓某一篇偶然爆款帶偏了平均值。尤其注意:千萬不要把同一篇稿子上午發一遍長 Post、下午原封不動再發一遍 Article,然後管這叫“嚴格控制變量 A/B 測試”! 因爲上午已經看過你長 Post 的核心老粉,下午刷到一模一樣的 Article 根本不會再點開第二次;而且要是這兩篇同時掉進某些讀者的候選池,還會直接觸發同作者 0.625 衰減和 DPP 相似內容置零!

18 第一張圖,最好就能說明這篇的發現(兼談長文帶一張漫畫圖片會怎樣)

很多做圖文測評或教程的朋友,習慣照搬公衆號或小紅書的排版審美:一條帖子掛 4 張圖,第 1 張圖放一張花裏胡哨的純標題海報或搞笑封面,第 2 張圖纔開始交代背景,第 3、4 張圖才把真正核心的測試結果表格放出來。

真人讀者有沒有耐心往右滑到第 4 張圖,還得看你的封面吸不吸引人;但在推薦算法的 V8.2 內容理解流程(grox/flows/mm_emb/renderer_v82.py)裏,AI 到底讀了哪張圖,源碼早就寫死了! 打開 _collect_post_media 函數,它從你的第 1 張媒體附件開始往後循環檢查:只要先遇到一段可用視頻,就抽取一組視頻幀然後立刻返回;只要先遇到第一張有可用圖像數據的靜態圖片,立刻執行下面這行代碼直接返回(return):1

return "Post image:", [medium.convo_image.content]

看清楚了嗎?對於一條掛了 4 張靜態圖片的純圖帖,這個函數根本不會把 4 張圖全部收走,而是拿到第 1 張能正常讀取的圖片就立刻收工下班了!(隨後本帖選出的媒體會與被引用帖的媒體合併、受總圖片預算上限約束,再由 embedder_v82.py 送往多模態向量服務。當然,嚴謹地說,這是 V8.2 內容理解這一條主路徑的做法,不能誇大成 X 全站所有模型永遠只看第 1 張圖——比如前面講過的同庫舊版 V5 renderer.py 就會按預算逐張處理圖片。)1

18.1 長文帶一張漫畫圖片會怎樣?權重是按圖片算,還是按長文算?

講到這裏,很多喜歡給長文配插圖的創作者會問出一個非常具體的問題:“如果我寫了一篇幾千字的深度長文,爲了版面好看,順手配了 1 張搞笑漫畫或手繪插圖,推薦系統會不會把我的帖子判定成‘圖片帖’,結果把我長文本身的閱讀停留權重給吞掉了?”

我們對照 scoring.rs 的計分公式和 renderer_v82.py 的多模態代碼,給你喫一顆定心丸,同時指出一個必須避開的大坑:

  1. 在打分排序環節(scoring.rs):絕對不是“圖文二選一”,而是“長文閱讀分 + 圖片展開分”全部疊加! 系統的融合計分公式對所有候選帖一視同仁:你寫了深度長文,前面講的 4 大閱讀停留加分項(普通點擊 Click 0.3、點開後深度停留 ContClickDwellTime 0.4、基礎停留 Dwell 0.05、連續停留每秒 ContDwellTime 0.006)該算的都會算;同時,公式裏本來就有一項展開圖片的預測(Photo expand,係數 0.05,乘的是這位讀者會點開看圖的預測概率)。所以,給長文配一張漫畫插圖,不會吞掉長文本身的停留項,但也別把 0.05 理解成配圖就送的分。2 21
  2. 真正受影響的是“AI 多模態模型怎麼理解你這篇帖子的主題”(grox/flows/mm_emb): 在 V8.2 處理器裏,程序會把兩樣東西打包在一起送去生成帖子的語義向量(Semantic ID):截取前 4,000 個字符的正文文本(Post text:) + 挑出來的第 1 張可用圖片(Post image:)。這裏分兩種情況:
  • 情況 A(整篇長文只配了這 1 張漫畫圖):只要你長文的前 4,000 個字符把核心研究對象和結論寫得清清楚楚,配一張貼合文章主題的漫畫插圖完全沒問題(公式裏本來就有一項圖片展開預測,係數 0.05,乘的是讀者點開看圖的概率,不是誰配圖就送的分)!唯一要忌諱的是:正文開頭兩百字還在雲山霧罩地抒情,配的那張漫畫又是跟正文毫無關係的搞笑貓貓表情包——圖文語義對不上,就會干擾多模態向量的精準度。
  • 情況 B(既有 1 張裝飾漫畫,又有 2 張實測數據表——90% 創作者踩過的大坑!):千萬記住上面那行 return "Post image:" 源碼!如果你一條長文掛了 3 張圖,把搞笑裝飾漫畫放在第 1 張,把真正核心的實測數據對比表放在第 2、3 張——完蛋了!V8.2 的 _collect_post_media 看到第 1 張漫畫能正常打開,直接拎着這張漫畫就 return 交差了,你後面第 2、3 張圖裏的硬核測試數據,在這條多模態理解流程裏被徹底無視了!1

18.2 四張測評圖可以怎麼重排

明白了“V8.2 只抓第 1 張可用圖”的底層邏輯,我們平時發 4 張圖的測評帖或長文配圖時,該怎麼安排圖片順序? 還是拿“測試兩款 OCR 工具識別中文發票”舉例:

  • 錯誤排法(傳統海報流):第 1 張放一句懸念大字報《震驚!測完這兩款 OCR 我沉默了》(或者放一張搞笑漫畫),第 2 張放測試環境說明,第 3 張放準確率表格,第 4 張放模糊發票報錯案例——這樣排,不管是匆匆劃過的時間線讀者,還是隻取第 1 張圖的 V8.2 流程,都抓不到你這期測試的核心乾貨。
  • 正確排法(結論首圖流):
    • 第 1 張圖(首圖):直接做成一張清晰易讀的**“核心結果對比卡”**——圖上直接寫明被測的兩款工具名稱與任務,放上最能說明差距的“模糊發票稅額識別一正一錯對比圖”,並用醒目字體標出核心結論:“當掃描件有摺痕時,工具 A 稅額欄需人工複覈”;
    • 第 2 張圖:交代 50 張發票的樣本分組與測試參數設置;
    • 第 3 張圖:放其餘字段(日期、買方稅號)的完整彙總數據表;
    • 第 4 張圖(或裝飾漫畫):補充適用邊界、極端失敗案例或調節氣氛的插圖。

當然,把首圖做成“核心結果卡”,絕不是讓你把整篇論文密密麻麻幾千個小字硬塞進一張圖裏(字太小誰都看不清)。首圖只需要聚焦最核心的 1 個發現,把工具名、對比條件和結論對象標清楚就夠了;如果某個結論必須附帶二十條免責註腳才能成立,說明這個問題在首圖裏切得還不夠細。 同時,正文前幾段也要用文字把首圖裏的核心發現同步寫出來——這樣萬一讀者網絡卡頓圖片沒加載出來,光看文字也知道你測出了什麼;圖片加載出來後,圖文又能互相印證,再也不會把全篇最值錢的寶貝藏在算法根本沒去讀的第 4 張圖裏了。

19 視頻的幾個“十秒”,分別管什麼

做視頻內容的創作者一定聽過一句鐵律:“發在 X 上的視頻必須超過 10 秒鐘,否則算法不推流!” 去翻公開代碼庫,“10 秒(10000 毫秒)”這個數字居然在好幾個不同的地方同時出現了——但它們管的根本不是同一件事!有的管視頻品質觀看(VQV)的計分資格,有的管三個核心沉浸式視頻索引庫的入庫生死線,還有的管長視頻安全審查的裁切片段。我們把這幾個“10 秒”拆開看,你就知道視頻到底該剪多長了。

先看第一個“10 秒”:視頻品質觀看(VQV,Video Quality View)的資格判斷。 在 home-mixer/util/candidates_util.rs 和參數文件 param.rs 裏,系統在判斷一條視頻候選帖夠不夠資格算 VQV 分數時,會先檢查視頻本身的長度是否超過設定門檻,公開默認值確實是 10000 毫秒(10 秒)(注意:這裏是以毫秒明確標註的視頻總片長條件,跟前面講的點擊停留閾值 10.0 不是一回事)。48

但是,光滿足了這個 VQV 資格,能讓你在打分表裏多拿分嗎? 不能!原因非常具體:在當前公開版本里,無論是 Home Mixer 還是 VM Ranker,VqvWeight(視頻品質觀看權重)的默認值統統都是 0!(部分延續觀看項的公開默認係數也是 0;只有“打開視頻 VideoOpenWeight”保留了非零權重 0.02/0.07。)當然,某處直接權重爲 0 絕不代表視頻觀看行爲沒用,因爲在雙塔召回模型的沉浸式分支(immersive_positive_actions)裏,依然把視頻品質觀看列爲了核心訓練正例。48

同時,在 V8.2 多模態理解流程(renderer_v82.py)裏,AI 會讀取已抽取的視頻畫面幀(Frames)和語音轉錄文字(Transcript)來理解你的視頻在講什麼;但代碼裏沒有任何“加了字幕就固定加分”或“1080P 全高清畫質就給固定獎勵”的公式,更不能把 V8.2 抽取的視頻幀數上限歪曲成“整個推薦系統只看視頻裏的四個瞬間”。1 44 48

19.1 三類視頻索引,確實要求片長超過十秒

雖然打分表裏的 VqvWeight 默認是 0,但第二個“10 秒”卻是實打實卡住視頻入庫脖子的生死線! 在負責建立推薦索引庫的 phoenix-rankall-strato/lib/eventProcessing.strato 裏,程序員直接寫死了下面這兩行片長檢查代碼:49

minLongVideoDurationMillis = 10 * 1000
videoInfo.durationMillis > minLongVideoDurationMillis

來源:49

請把放大鏡對準第二行代碼中間的那個大於號 >(嚴格大於)! 程序檢查的是視頻文件自帶的總時長 videoInfo.durationMillis 是否嚴格大於 10000 毫秒(10 秒)! 這意味着什麼?意味着如果你在剪輯軟件裏卡着表,把視頻剪成了整整 10.000 秒(10000 毫秒)——對不起,10000 > 10000 爲假(false),直接不通過! 至少要 10001 毫秒(10.001 秒,爲了防止轉碼掉幀,實操中建議一律剪到 11 秒以上) 才能跨過這道門檻!(注意:這裏查的是視頻本身的文件總時長,不是量讀者看了幾秒。)49

更要命的還在後面——實際調用這個 10 秒檢查的函數叫做 hasValidImmersiveVideo,它的代碼邏輯裏藏着一個讓無數人翻車的**“圖文混排大坑”: 這個函數首先要求帖子裏至少存在一個可接受的視頻媒體,緊接着,它對這條帖子裏掛載的每一個媒體附件(each media entity)使用了 forall(全部滿足)檢查**——要求每一個媒體都必須是 TweetVideo 或 AmplifyVideo 類型、帶有 VideoInfo,且時長全部嚴格大於 10 秒! 這意味着兩個極其重要的實操鐵律:49

  1. 多視頻同發時:如果你一條帖子裏掛了 2 支視頻,1 支 30 秒、另 1 支只有 8 秒,因爲 8 秒那支不達標,forall 檢查直接全軍覆沒!
  2. 千萬別在同一條帖子裏搞“1 支視頻 + 1 張靜態圖片”混排! 如果你一條帖子裏放了 1 支 20 秒的乾貨視頻,又順手塞了 1 張靜態截圖混排在一起,因爲靜態圖片不是視頻類型、通不過 forall 檢查,整條帖子會因爲那張靜態圖片,直接失去進入下面三個核心視頻索引庫的資格!

到底是哪三個核心視頻索引庫在調用 hasValidImmersiveVideo?我把它們的調用鏈路列在了表裏:49

索引名稱直接調用的構建函數(Builder)這條路徑的觸發情況十秒條件的地位
1fav_videobuild1FavVideoIndex一般合格帖子的點贊(Fav)分支直接調用 hasValidImmersiveVideo;時長 > 10秒 是入庫硬資格之一
videobuildVideoIndex一般合格帖子的點贊(Fav)或發帖創建(PostCreation)分支同樣調用 hasValidImmersiveVideo(注意:發帖創建時就能觸發,不是非要等拿到贊才建庫)
nsfw_videobuildNsfwVideoIndex特定成人視頻的點贊(Fav)分支(構建函數還會另查成人標記)同樣要求 hasValidImmersiveVideo;其餘來源與內容條件也須同時滿足

來源 49

你看,1fav_video、video、nsfw_video 這三大視頻索引的構建函數,全都死死卡在 hasValidImmersiveVideo 上。只要你的視頻不超過 10 秒、或者跟靜態圖片混排了,在這三個視頻索引庫門前就會被直接拒之門外(當然,進庫之後依然要經過後續的召回和打分排序)。49

19.2 兩個都叫 Evergreen 的名稱,讀的未必是同一份數據

進到視頻索引庫之後,系統還會按發佈天數切分成不同的時間窗口(phoenix-rankall/src/config/mod.rs):比如 1fav_video 有 2 天、2 至 4 天、4 至 14 天、4 至 30 天等窗口,video 和 nsfw_video 也有各自的天數窗口(這些天數指的是數據庫保留或選取的時間跨度,跟視頻片長 10 秒是兩碼事)。50

而在雙塔召回的數據集配置(retrieval_dataset.py)裏,有幾個名字特別容易讓人看走眼,尤其是名字裏帶 EVERGREEN(長青視頻) 的項:50

召回數據集名稱實際讀取的文件所屬 Index可見的十秒鏈路
IMMERSIVE2Dayvideo_2day.parquetvideo可沿 video 構建函數直接追到嚴格大於 10 秒
IMMERSIVE4Dayvideo_4day.parquetvideo同上,嚴格大於 10 秒
EVERGREENvideo_4to14day.parquetvideo雖然枚舉名字叫 EVERGREEN,但實際讀的仍是 video 索引的 4–14 天窗口,同樣受 > 10 秒限制
IMMERSIVENSFWnsfw_video_2day.parquetnsfw_video可沿 nsfw_video 構建函數追到嚴格大於 10 秒
IMMERSIVE32FavVideo14To30Day32fav_video_14to30day.parquet另一個獨立數據集名稱完整上游生產鏈路未在公開樹追齊,不能僅憑名字腦補條件

來源 50

你看錶格第三行:召回數據集裏的枚舉名雖然叫 EVERGREEN,但它底層讀取的文件其實是 video_4to14day.parquet(也就是 video 索引的 4 到 14 天老視頻窗口),所以它照樣受前面 > 10000 毫秒 的嚴格限制! 但在同一個索引處理器裏,另外還有兩個真正名叫 evergreen_video 和 evergreen_nsfw_video 的索引——它們走的是獨立的 EvergreenVideo 事件分支,只調用了 hasImmersiveVideo(只檢查是不是視頻類型,沒有檢查 durationMillis > 10000!)。這說明代碼並沒有把 10 秒門檻一刀切加到所有分支上(不過上游 evergreen 事件名單是怎麼生成的並未開源,所以也不能反過來保證短視頻一定能進 evergreen)。 同樣,用 Grok 生成的 AI 視頻索引 buildImagineIndex 檢查的是 isImaginePost(看媒體裏的 Grok 元數據),也沒有調用 hasValidImmersiveVideo。把這些分支擺出來,是爲了幫大家精確分清“哪三個視頻庫卡 10 秒”、“哪些分支另有規矩”。50

19.3 五秒視頻仍可能進入一般帖子索引

那麼問題來了:如果我手頭有一支只有 5 秒鐘的軟件操作動圖視頻,發出來是不是在 For You 首頁就徹底成了“死帖”、一個陌生人都刷不到了?

並不會徹底死掉! 我們順着普通合格帖子的點贊(Fav)分支(phoenixRankAllCandidateProcessor.strato#L506-L524)往下看:當一條 5 秒視頻帖收到點贊時,程序會先執行普通帖子的 build1FavIndex(建立普通 1fav 索引)、主題索引和 32fav 索引,然後再去嘗試建立視頻專屬索引! 而在普通帖子的 build1FavIndex 函數里,壓根沒有任何視頻時長檢查! 這意味着:你這支 5 秒鐘的短視頻,雖然因爲時長不夠 10 秒進不了 video 和 1fav_video 那三個專屬視頻庫,但它完全可以正常進入普通帖子的 1fav 索引庫(1fav_1day.parquet)!而前面我們已經證明過,普通 For You 首頁的三大主力數據集(HOME、HOME_COLD、HOME_HOT)讀取的恰恰就是 1fav_1day.parquet!(注:這是根據源碼分支推導的程序條件說明,不是 5 秒視頻的線上曝光實驗。)38 34 50

所以,關於視頻時長的實操結論非常清晰:

  • 如果你演示的是一個 5 到 8 秒就能一眼看懂的極簡小技巧,保留短小精悍的 5 秒版,它依然能走普通帖子的 1fav 通道上首頁,沒必要爲了湊時長在片尾硬塞 5 秒鐘黑屏或無意義空鏡(硬塞空鏡反而拉低完播體驗);
  • 但如果你希望這支視頻同時進入 video 和 1fav_video 等沉浸式視頻專屬流量通道(包括 IMMERSIVE2Day、IMMERSIVE4Day 和 4–14 天的 EVERGREEN 窗口),那就一定要把前後對比、操作步驟或適用邊界展開講講,把視頻實打實剪到 11 秒以上(嚴格大於 10,000 毫秒),並且絕不要在同一條帖子裏混塞靜態圖片!49 50

19.4 另一個十秒判斷,目前還沒找到完整調用路徑

爲了保證代碼覈對的完整性,這裏順帶記錄一處公開樹裏的“孤兒代碼”:在 eventProcessing.strato 裏還有一個叫 isMediaEligible 的函數,裏面也寫了 > 10000 毫秒的判斷並要求媒體非 NSFW,隨後被 getTweetypieResponse 組裝成 hasEligibleMedia(外加作者非 NSFW 條件)。但在整棵公開代碼樹裏,只能找到 getTweetypieResponse 的定義和導出,找不到任何下游模塊調用它。因此我們把它誠實列爲“可見但下游未追齊的條件”,證明視頻 10 秒鐵律時,一律以我們上面完整追通的 hasValidImmersiveVideo 調用鏈爲準。49

20 64 個贊和 512 個贊,對應不同的視頻安全任務

網上傳言:“視頻帖拿到 64 個贊會觸發第一輪流量助推,拿到 512 個贊會觸發第二輪超級大推流!” 去源碼裏一搜 64 和 512,這兩個贊數門檻還真的一字不差地寫在 grox/flows/ptos 目錄下——但讓人哭笑不得的是:它們根本不是什麼“流量獎勵池門檻”,而是視頻安全與違規審查機器人(PTOS)的啓動門檻!51 52 53

你看下面這張表,64 個贊和 512 個贊在三條專門抓違規視頻的審查流水線裏,各自扮演着非常具體的審查角色:

安全審查任務名稱64 個讚的角色512 個讚的角色還要覈對什麼前置條件
SpecialVideo(特殊動態畫面視頻審查)觸發該審查的默認最低點贊門檻此任務無 512 贊切換必須有視頻,且必須命中 motion_reveal 動態閃現篩查
MediaInjected(夾帶成人/紅外垃圾視頻檢測)觸發該審查的默認最低點贊門檻滿 512 贊時開啓深度推理(use_reasoning)先前未判 NSFW、成功提取視頻幀、且能載入違規參考視頻庫
AdultContentLeadingFrames(長視頻前 10 秒涉黃審查)此過濾器未使用 64 贊門檻滿 512 贊後不再要求先前出現過 AdultContent 分類視頻時長 >= 30秒(或直播)、已有前置 PTOS 結果且尚未標 NSFW

來源 51 52 53

20.1 64 個贊是部分任務的最低資格

爲什麼安全審查要卡 64 個贊?道理跟前面講 Article 圖片搬運工一模一樣:用大模型逐幀掃描視頻太燒顯卡算力了,所以系統重點盯防已經開始起量的視頻! 在第一條任務 SpecialVideo(task_safety_ptos_special_video_filter.py)裏,過濾器先檢查:能獲取到作者信息、帖子裏(含本帖或被引用帖)有視頻,並且當前帖子的點贊數 post.get_fav_count() 不低於 deluxe_fav_count_threshold(公開默認值爲 64)。 跨過 64 贊門檻後,程序會爲視頻開啓 motion_reveal(動態畫面突變檢測,專門抓那種“前幾秒正常、中間突然閃現一幀違規畫面”的套路),拉取視頻數據後還要先過一道 task_special_video_screen.py 初篩:只有真的檢測到了 motion_reveal_frames 信號,纔會繼續往後送去做內容分類、違規政策判定與交叉驗證。所以“滿 64 贊”只是觸發了這道動態安檢的入場條件,絕不等於每條滿 64 讚的視頻都會把全套模型跑到底,更不代表會被判違規。51

20.2 512 個贊在這條流程裏用於開啓 reasoning

再看第二條任務 MediaInjectedAdultInfraredVideoSpamDetection(專門抓在正常視頻裏惡意注入成人畫面、紅外透視或垃圾水印的作弊視頻): 它的過濾器同樣要求有作者、本帖或引用帖含視頻、點贊數至少達到 64 個贊,並且先前的審查還沒把它標爲 NSFW。等到真正執行大模型推理時(task_safety_ptos_media_injected_adult_infrared_video_spam_detection.py),必須確認已經提取到視頻幀,並加載“已確認違規的黑名單參考視頻庫”來做比對(如果沒取到幀或參考庫加載失敗則無法完成比對)。 那麼 512 個贊在這裏幹了什麼? 當視頻點贊數達到 512 時,程序會把 use_reasoning(開啓大模型思維鏈深度推理) 開關設爲 true,切換提示詞與輸出模式,讓 AI 先寫出推理過程再做違規比對!一旦被判違規,它會生成 SpamManipulatedMedia(操縱媒體垃圾)分類送往公共寫入池(走普通 Spam 分支的作者資格判斷,不會直接觸發後面講的“5 條裏有 3 條封號”規則)。52 54

20.3 檢查開頭畫面,還要滿足片長和先前結果的條件

第三條任務 AdultContentLeadingFrames(長視頻片頭涉黃檢查)更是把 30 秒、10 秒、512 贊 三個數字串在了一起:

  1. 它首先要求有作者信息,且本帖或引用帖裏有時長至少 30 秒(>= 30秒)的長視頻(或有可用標識的直播 broadcast),同時要求這條帖子已經有過前置 PTOS 初審結果(如果沒有前置 PTOS 結果,哪怕已經 1 萬個贊也會在這個過濾器被跳過),且尚未被正式打上 NSFW 標籤;
  2. 滿足上述前提後,只要符合以下兩個條件中的任意一個,就會正式啓動片頭深度檢查:
    • 要麼先前的任意一條標註裏曾經出現過 AdultContent(成人內容)嫌疑分類;
    • 要麼當前帖子的點贊數已經達到至少 512 個贊!
  3. 一旦進入檢查,程序會把這支長視頻(或直播)設置爲專門裁切前 10 秒鐘的開頭畫面,送去做內容分類、政策判定,並和另一個獨立的 sex-and-nudity 視覺模型做雙模型交叉驗證(Cross-validation)(如果兩個模型結論不一致,會走仲裁流程再定;有些不支持直接硬攔截的特殊視頻任務,交叉驗證沒通過時會改走較輕的「軟處理」,最後按保留下來的政策分類寫入標籤)。53

20.4 跨過贊數門檻,不等於那一刻必然完成檢查

同時要注意,這三條視頻安檢流水線是由不同的 Kafka 消息隊列(Kafka=系統內部傳遞任務消息的隊列通道,可以理解成後臺的傳送帶)觸發的,並且都配了 60 秒去重限流緩存(task_rate_limit.py)。公開代碼展示的是消費端收到任務後怎麼過濾和審查,並沒有保證每條視頻在前臺跳到第 64 個贊或第 512 個讚的那一毫秒,上游都會實時發一條消息過來。51 52 53

但把這三段代碼看完,你至少徹底看清了一件事:視頻的 64 贊和 512 贊,完完全全是安全審查系統的“安檢升級線”,跟“解鎖下一級流量獎勵池”半毛錢關係都沒有! 平時發視頻時,不僅要注意自己拍的視頻封面和前 10 秒畫面,連你隨手轉發引用(Quote)的別人視頻素材也要看清楚乾不乾淨——因爲上面這三條安檢線,全都把**本帖視頻和被引用帖視頻(Quoted Video)**一併納入了掃描範圍!51 52 53

21 小賬號的 200 次 Home 曝光,究竟是什麼門檻

這一節是所有中腰部創作者和剛起步的新號最關心的話題:“聽說 X 算法給粉絲少於 5 萬的小賬號開了一條綠色通道——新帖發出來前 2 小時有 200 次曝光的冷啓動扶持!這到底是怎麼運作的?我作爲小號該怎麼接住這波流量?”

在之前的版本里,如果只列一堆參數名,大家看完還是雲裏霧裏。我們直接用大白話把這套冷啓動機制還原成一個形像的場景:“打分房間裏的小賬號直升電梯(author_cold_start.rs)”!

先看那個著名的 200 在源碼(home-mixer/scorers/author_cold_start.rs)裏是怎麼寫的:57

&& c.view_count_on_home
    .is_some_and(|imp| imp < params.impression_threshold)

公開默認參數裏,impression_threshold 確實等於 200,判斷符號是 <(嚴格小於 200)。我在本地重寫這段函數做邊界驗證時,固定其他條件不變,傳入 199 時返回通過(true),傳入 200 時當場返回不通過(false)! 但請注意兩個極其關鍵的真相:

  1. 這不是“每發一篇新帖,系統先保底白送給 200 個讀者看,測完好壞再決定升不升級”的分發流水線;恰恰相反,它是說**“當你的新帖已經在某位讀者的臨時籃子裏,只要它目前在全站 For You 首頁累計被刷到的次數還不到 200 次,它就有資格參加這次直升電梯的抽籤”**!
  2. 代碼裏查的字段叫 view_count_on_home(純 For You 首頁推薦曝光數),根本不是你在帖子底下看到的公開總觀看數(Views)! 你在前臺看到的 Views,包含了別人點進你個人主頁看的次數、搜索看到的次數、外部鏈接點進來的次數,甚至包含了你自己反覆點開看自己的次數!所以當你看到前臺顯示已經有 210 次 Views 時,後臺純粹的 view_count_on_home 是多少,外人看不到——它跟前臺的這個數不是一回事,不能拿前臺數字判斷冷啓動還在不在。千萬別盯着前臺數字一過 200 就自己嚇自己說“完了,200 次冷啓動測試沒過,這篇廢了”!57 58 59

21.1 兩小時以內、Home 曝光少於 200,要同時滿足

想要坐上這臺“小賬號直升電梯”,你的這篇候選帖子必須同時滿足以下全部硬條件(代碼裏全是用 && 串聯的,缺一個都不行;而且早在 10 月 9 日的公開快照裏就已經是這套規則了):35 60

# 條件重述,並非逐字源碼;代入所讀公開默認
cold_start_base_eligible(candidate, follower_cap)
    && cold_start_corpus_eligible(viewer_arm, author_corpus)
    && age.is_some_and(|age| age <= max_post_age)
    && position_among_nonzero < floor(0.97 * nonzero_count)
    && view_count_on_home.is_some_and(|imp| imp < 200)

來源:35 60

我們把上面這 5 行代碼翻譯成你能逐條對照的 5 張入場門票:

  1. 門票一(作者體量與原創性):作者的粉絲數必須已知且不超過 50,000 人(<= 50000,剛好 5 萬粉也算合格);並且這篇帖子絕對不能是回覆貼(!is_reply),也絕對不能是普通轉發(!is_retweet)!(注意:代碼這裏只檢查沒有回覆 ID 和普通轉發 ID,並沒有排除帶評論引用 quoted_tweet_id——也就是說,你發原創帖或者發 Quote 引用帖,都能拿這張門票!)
  2. 門票二(實驗分組匹配):系統做實驗時會把讀者和作者各自分組,這次刷首頁的讀者所在的分組(viewer_arm),要和作者所在的那一組內容池(author_corpus)對得上;同時冷啓動總開關是開着的,而且這次請求不是主題請求(Topic Request)。
  3. 門票三(2 小時窗口):帖子發佈至今的年齡必須不超過 7,200 秒(<= 2 小時)!
  4. 門票四(不能是徹底墊底的爛帖):在當前這個臨時籃子所有非零分候選帖裏,這篇帖子的初步得分排名必須在前 floor(0.97 × 非零候選總數) 名以內(也就是剔除掉得分最墊底的大約 3%)。
  5. 門票五(首頁曝光未滿 200 次):這篇帖子目前累積的內部首頁曝光數 view_count_on_home 必須嚴格小於 200 次(< 200)!(另外,這套直升電梯只能提拔已經先被召回採購員抓進當前臨時籃子、並通過了已讀和拉黑過濾的候選帖。)35 61

爲了讓你一眼看清這幾張門票是怎麼卡人的,我們列一張 6 種常見情況的實測判定表:35

假設其他資格都符合需要覈對的值這一道資格的結果原因
帖子剛發了 1 小時內部 Home 曝光 199 次通過資格!199 < 200 且年齡 ≤ 7200 秒(至於最後抽不抽中它,看下一步抽樣)
帖子才發了 10 分鐘內部 Home 曝光剛到 200 次直接出局!代碼寫的是 < 200(嚴格小於),一到 200 立刻畢業下車
帖子已經發了 3 小時內部 Home 曝光只有可憐的 10 次直接出局!曝光再少也沒法抵消年齡超過 2 小時(&& 必須同時滿足)
作者粉絲數剛好卡在 5 萬整followers = 50000通過粉絲條件!代碼上限使用的是 <= 50000,包含 50,000 本身
前臺公開觀看數(Views)顯示 180不知道內部 view_count_on_home無法用前臺數字直接判定代碼讀的是內部專屬的 Home 首頁曝光字段,不能直接拿前臺 Views 代替
這是一條去別人底下評論的回覆貼in_reply_to_tweet_id 有值直接出局!第一關 !is_reply 直接攔死,發得再早、曝光再低也沒資格進冷啓動

來源 35

還要順便提一個技術細節:在 engagement_counts_hydrator.rs 裏,系統去拉取一般 view_count 和專屬 view_count_on_home 時,是分成兩個獨立字段拉取的,而且配了一個 60 秒有效期(TTL = 60s)的計數緩存。這說明後臺計數本身就有最多 60 秒的緩存刷新間隔,再一次印證了沒必要死盯前臺數字跳到 200 的那一秒鐘。35

21.2 合格之後,還要從候選裏選一篇

好了!假設現在讀者張三下拉刷新首頁,他的臨時籃子裏有好幾篇來自不同小作者的新帖,全都同時集齊了上面那 5 張門票。但直升電梯每次最多隻能保送 1 篇帖子上去!系統該挑哪一篇呢?

打開 author_cold_start.rs#L236-L333,這裏用了一套非常經典的強化學習探索算法——Thompson Sampling(湯普森採樣,基於 Beta 分佈的概率抽樣),而且分兩步挑出最終的幸運兒:36

# 公式重述,並非逐字源碼;代入所讀先驗默認
n = impression_scale * view_count_on_home
x = min(max(fav_count, 0), n)
alpha = 0.75 + x
beta = 49.25 + max(n - x, 0)
sampled_reward = sample(Beta(alpha, beta))

# 默認:先留下抽樣值最高的 2 篇
# 再從這 2 篇中挑目前觀衆的 ranking score 最高者

來源:36

別被 Beta(alpha, beta) 嚇到了,我用大白話給你翻譯一下這幾行代碼在幹嘛:

  1. 第一步:看“歷史首頁點贊率”搖號抽出前 2 名(top_k = 2) 程序會直接讀取每篇合格新帖目前真實收到的點贊數(fav_count)和內部首頁曝光數(view_count_on_home)(注意:這裏實打實用到了真實點贊數!)。 在還沒有任何曝光(n = 0, x = 0)時,系統給每篇新帖設了一個默認先驗參數(先驗=還沒看到任何真實數據之前,先假設的一個起點值):alpha0 = 0.75、beta0 = 49.25。算一下先驗平均值:$0.75 \div (0.75 + 49.25) = 0.75 \div 50 = \mathbf{1.5%}$! 換句話說:系統默認對一篇小作者新帖的基準預期,大約是“每在首頁曝光 100 次,能拿到 1.5 個贊(1.5% 首頁點贊率)”!(注:這是 Beta 分佈的先驗均值,不是保底給 1.5% 流量。) 隨着你的新帖在首頁被幾十個人刷到,如果你的實際首頁點贊率高於 1.5%,你的 alpha 變大,搖出高數字的概率就會大幅增加;但因爲是隨機抽樣(保留探索不確定性),剛發出來 0 曝光的新帖也有機會搖出高點數。搖完號後,系統會先留下抽樣點數最高的 前 2 篇(默認 top_k = 2)!36
  2. 第二步:在這前 2 名裏,挑出“當前這位讀者最感興趣(預測分 score 最高)”的那 1 篇! 這第二步設計得太精妙了:搖號進決賽圈的有 2 篇新帖,最後誰能真正坐上電梯?系統不再看誰的點贊率高,而是直接比拼**“對此時此刻正在刷首頁的這位讀者張三來說,哪一篇的模型預測排序分(ranking score)更高”**,挑出分高的那 1 篇保送上樓!(如果當次籃子裏本來就只有不超過 2 篇合格新帖,top_k = 2 會把它們全留下來,直接按當前讀者的模型預測分挑最高的那篇。)36

看懂這個“先按首頁點贊率搖號選 2 篇,再按當前讀者預測分二選一”的機制,你就明白爲什麼**“拉微信羣找朋友點進主頁互贊”對冷啓動幾乎沒用**了:

  • 第一,羣友順着鏈接或點進你個人主頁給你點的贊,雖然讓 fav_count 加了 1,但羣友不是在 For You 首頁刷到你的(分母 view_count_on_home 規則不同),而且你在羣裏找來的朋友跟你目標陌生讀者的畫像完全不搭;
  • 第二,哪怕你靠刷贊混進了前 2 名的決賽圈,最後二選一PK的依然是陌生讀者張三的 AI 模型預測分!如果你的內容本身跟張三的閱讀歷史不匹配,在決賽圈照樣會被刷下來!35 36

21.3 程序裏的第十六名,怎樣變成一個目標分數

那被選中的這唯一 1 篇幸運新帖,“坐直升電梯”到底會被保送到第幾名呢? 打開參數文件 home-mixer/params/param.rs 和 author_cold_start.rs:公開默認設置裏,ColdStartSlotMin = 15、ColdStartSlotMax = 16。程序在抽取目標位置時,調用的是左閉右開區間的隨機函數 random_range(15..16)(上界 16 不包含在內)——也就是說,在公開默認配置下,它唯一鎖定的目標位置就是從 0 開始計數的 index 15,也就是當前候選排行榜的第 16 名!(如果整個非零分池子裏的帖子總數還不到 16 篇,則不執行提拔。)35 60

緊接着,程序會拿出當前排行榜第 16 名那篇帖子的分數作爲“目標分數(Target Score)”,然後把你這篇被選中的小號新帖的分數改寫成 max(你原來的分數, 第 16 名的目標分數)! 也就是說:如果你本來就能排進前 15 名,系統不會動你的高分;如果你本來排在第 500 名,系統就會直接把你的分數強行拔高到第 16 名的水平!(另外前面提過門票四:position_among_nonzero < floor(0.97 * nonzero_count),比如池子裏有 100 篇非零分帖子時排除最後 3 篇,有 20 篇時取整排除最後 1 篇,“排除墊底約 3%”是它的直觀說法。)35 36 60

不過要注意,在冷啓動把你的分數抬到第 16 名水平之後,在 VM Ranker 的共用流程裏,後面還會接着套用同作者 0.625 多樣性衰減與 0.75 圈外 OON 乘數,最後還要過可見性過濾並與廣告、對話卡片一起混排(blender_selector.rs)。所以這相當於給了你一張衝進前排視野的“強力助推器”,而不是把你焊死在每個人手機屏幕的第 16 個格子裏。12 60

所以,對於粉絲不到 5 萬的創作者來說,發帖後的前 2 個小時(7,200 秒)就是冷啓動窗口:儘量挑你目標受衆最活躍的時段發佈原創乾貨帖(或高質量 Quote 引用帖),前兩小時有人在評論區指出漏了什麼條件就及時補充,但完全沒必要像機器人一樣在評論區無限刷屏回覆,更不要因爲前十分鐘前臺觀看數沒動就慌忙刪帖重發!35 36

21.4 NewUser 在這裏指新讀者

在結束冷啓動這一節前,必須順手闢一個害苦了無數新手的謠言:“新註冊的 X 賬號千萬別直接發帖,必須先裝成普通讀者每天刷帖、點贊、評論‘養號’滿 7 天,否則過不了 NewUserMinEngagementFilter(新用戶最低互動過濾器)!”

去把 home-mixer/filters/new_user_min_engagement_filter.rs 的源碼打開看一眼,你就會發現造謠的人連主語都沒看懂:

  1. 這個過濾器檢查的變量叫 query.user_id——在整套 Home Mixer 代碼裏,query.user_id 代表的永遠是**“此時此刻正在下拉刷新首頁的這位讀者(Viewer)”**,根本不是發帖的作者(candidate.author_id)!
  2. 更何況,在公開參數配置(param.rs#L832-L860)裏,這個過濾器的啓用開關默認值是 false(關閉狀態)!

拿着一個“默認關閉、且本來是用來查刷首頁的新讀者”的過濾器,去忽悠新作者“前七天不準發帖先去給別人點贊養號”,純屬指鹿爲馬!如果你剛註冊了一個新賬號,第一天就把頭像、具體清晰的 Bio 簡介弄好,直接發出你精心準備的第一篇乾貨原創帖並置頂,粉絲不到 5 萬的新帖,前 2 小時有冷啓動的資格窗口,第一篇就該拿準備好的乾貨去用。57 58 62

22 “新帖不再先被砍”,實際改的是來源名額分配

在 10 月下旬的算法更新裏,除了上面的“打分房間裏的直升電梯(author_cold_start.rs)”,官方還在**“進打分房間之前的檢票口”**新增了一道對新帖和小號非常友好的保護機制——這就是網上傳的“10 月底更新後,新帖在進模型打分前不會再被先砍掉了(FairShareRankingFilter)”。

我們先查它的準確出生時間:在 home-mixer/filters/fair_share_ranking_filter.rs 的提交歷史裏,這個過濾器是在 2026 年 10 月 21 日(提交 7f2ca2b) 第一次寫進代碼的,當天默認開關是 false(關閉);緊接着在第二天——2026 年 10 月 22 日(提交 989fb91),公開默認開關 EnableFairShareRanking 就被正式改成了 true(開啓),模型打分預算 PhoenixScoresResultSize 默認設爲 2800!16 61

公開提交UTC 時間洛杉磯時間(PDT)公開默認
7f2ca2b914cadac591ea7fceec0c477e473d3dee2026-10-21 00:52:082026-10-20 17:52:08新增 FairShare 過濾器;開關 false;打分預算 2800
989fb91254d461bf4b9df53fb12d5c9a61c2b3542026-10-22 06:49:382026-10-21 23:49:38FairShare 開關正式改爲 true;打分預算仍爲 2800

來源 16

22.1 按來源分組,再分配名額

很多朋友之前看不明白 FairShareRankingFilter 到底是幹嘛的,我用一句話給你講透: 每次讀者刷首頁,各個採購員(關注流 Thunder、常規推薦流 Phoenix、冷啓動流 ForYouPhoenixRetrievalCold、零贊流 ZeroFav 等)抓進臨時籃子裏的候選帖加起來可能有 3,000 多篇;但是,負責精細算命打分的 AI 大模型(Phoenix Scorer)算力有限,每次最多隻肯看 2800 篇(PHOENIX_CLIENT_MAX_CANDIDATES = 2800)!

  • 在 10 月 22 日之前怎麼砍人? 檢票員不管三七二十一,直接把所有渠道送來的帖子按列表平鋪排成一隊,只留前 2,800 個,排在第 2,801 往後的直接一刀砍掉! 結果那些排在隊伍尾巴上的“冷啓動渠道(ForYouPhoenixRetrievalCold)”或“零贊新帖渠道(ZeroFav)”送來的小作者新帖,連見 AI 裁判一面的機會都沒有,在門外就被團滅了!
  • 10 月 22 日啓用 FairShare 之後怎麼檢票? 檢票員先把所有候選帖按它們的出身渠道(served_type)分成不同的小組,然後嚴格按照每個渠道送來的帖子數量佔總數的比例(外加最大余數法),把這 2,800 張打分入場券公平分給每一個渠道!61
# 流程重述,並非逐字源碼
total = sum(source_counts)
if total <= budget:
    keep every candidate
else:
    allocation_i = floor(source_count_i * budget / total)
    distribute remaining slots by largest remainders
    keep the first allocation_i candidates within each source group

來源:61

我們拿一個具體的數字例子算一遍,你就徹底看懂它的威力與邊界了: 假設某次刷新,臨時籃子裏一共進了 3,000 篇 候選帖(超出了 2,800 的打分預算,必須砍掉 200 篇)。其中主力大渠道 A 送來了 1,200 篇,大渠道 B 送來了 1,200 篇,而排在列表最末尾的**冷啓動渠道 C(Cold)**送來了 600 篇:

假設來源進入初篩的候選數以前按列表硬砍的結果現在 2800 名額按比例分配(FairShare)仍被此步移除的數量
主力來源 A1200留下 1200112080
主力來源 B1200留下 1200112080
冷啓動來源 C(排在隊尾)600只剩 400(被砍掉 200 篇!)560(保住了 560 篇!)40
合計300028002800200

來源 61

你看上面這張表:

  • 以前按列表順序一刀切,排在最後的冷啓動渠道 C 要獨自吞下全部 200 個裁員名額,600 篇新帖裏直接被砍掉 200 篇,只剩 400 篇能進場;
  • 現在有了 FairShare 按比例分配,主力渠道 A 和 B 各自讓出 80 個名額,冷啓動渠道 C 成功保住了 560 個進場打分的名額(比原來多了 40% 的進場機會)! 同時,你也看到了嚴謹的邊界:冷啓動渠道 C 裏排在最後面的那 40 篇 候選帖,在這一步依然會被裁掉(因爲組內依然是保留原有順序的前 allocation_i 篇,並沒有在組內按帖子新舊或點贊率重排)。所以最準確的說法是:FairShare 保護了冷啓動與零贊等弱勢渠道按比例進場見裁判的公平機會,但並不是給全站每一篇新帖發了“絕對不被裁員”的免死金牌(如果某次籃子裏的總候選本來就不超過 2,800 篇,則一篇都不砍,全部進場)。61

22.2 2800 個候選名額,和 200 次 Home 曝光無關

這裏順手幫大家把代碼裏幾個容易撞車的數字徹底拎清:

  • 2800(PhoenixScoresResultSize / PHOENIX_CLIENT_MAX_CANDIDATES):是某一位讀者單次刷新首頁時,送進 Phoenix 打分模型的候選帖子數量上限;
  • 第一個 200(PhoenixColdStartMaxResults = 200):是向 Phoenix 召回服務要貨時,單次最多要回多少篇冷候選帖的請求參數;
  • 第二個 200(ColdStartImpressionThreshold = 200):是我們上一節講的,你自己的那篇新帖在全站 For You 首頁已經累積被刷到了多少次的冷啓動資格上限。 這三個數字管的是完全不同的環節,千萬別聽信某些營銷號瞎編的“新帖先進 200 人冷啓動池,合格後再升入 2,800 人中級流量池”——把“單次打分候選池能塞 2,800 篇帖子”當成“把你的帖子推給 2,800 個觀衆”,那是連“帖子數”和“觀衆數”都沒分清!16 35 61

23 重要更正只補在舊帖下面,原來的讀者可能刷不到

平時我們發完一篇技術測評或教程,第二天突然發現裏面有個數據算錯了、或者漏了一個重要前提,絕大多數人的第一反應都是:“我趕緊去昨天那條原帖底下,自己回覆自己補一條勘誤說明吧!”

千萬注意!如果你只把重要更正補在舊帖的評論區裏,昨天已經看過你那條舊帖的成千上萬名老讀者,在他們的 For You 首頁上極大概率根本刷不到你這條新更正! 爲什麼?我們直接打開負責過濾“已讀帖子”的源碼文件 home-mixer/util/candidates_util.rs 和 previously_seen_posts_filter.rs,答案就在下面這三行代碼裏:20

std::iter::once(candidate.tweet_id)
    .chain(candidate.retweeted_tweet_id)
    .chain(candidate.in_reply_to_tweet_id)

你看清這三行代碼是怎麼查“已讀記錄”的了嗎? 當系統檢查一條候選帖該不該被“已看過濾器(PreviouslySeenPostsFilter)”攔下來時,它不僅檢查這條候選帖自己的 ID(candidate.tweet_id),還會順着鐵鏈(.chain)一併檢查它的轉發原文 ID(retweeted_tweet_id)以及它直接回復的父帖 ID(in_reply_to_tweet_id)!只要這三個 ID 裏有任意一個命中了這位讀者本次請求帶入的已看記錄(包括明列的 seen_ids 列表或近似的布隆過濾器 Bloom filter(一種快速判斷“好像看過”的近似名單,偶爾會認錯);另外 previously_served_posts_filter.rs 也會用同樣邏輯檢查本次會話已下發過的 ID),整條候選帖就會當場被當成“已讀舊聞”直接過濾踢走!20

我們拿一個具體場景走一遍這三行代碼: 假設你昨天發了一篇《數據庫性能壓測報告 A》,反響很好,有 1 萬名讀者在首頁刷到並看過了這篇帖子 A(此時,帖子 A 的 ID 就寫進了這 1 萬名讀者的 seen_ids 已讀記錄裏)。 今天早上,你突然發現昨天的壓測漏掉了“重啓後冷緩存(Cold Cache)”這個關鍵條件,結論完全反過來了!於是你在昨天的帖子 A 底下,直接點“回覆”發了一條重要更正說明 B。 請問:今天這 1 萬名看過 A 的老讀者刷新首頁時,能刷到你的新更正 B 嗎? 刷不到! 因爲新更正 B 是直接回復 A 的,所以 B 身上的 in_reply_to_tweet_id 字段填的正是昨天那篇舊帖 A 的 ID!當 B 進入那 1 萬名老讀者的候選池過安檢時,previously_seen_posts_filter.rs 一查發現:“咦?B 的父帖 A 已經在讀者的已看名單裏了!” 咔嚓一刀,直接把你今天剛發的新更正 B 給過濾掉了!20

23.1 一般補充留在對話裏,改變結論的結果單獨發

看懂了這三行代碼,以後遇到內容補充和勘誤,你就知道該怎麼分情況處理了:

  1. 如果是讀者在評論區問的局部小問題(比如有人問“你測試腳本的啓動命令是什麼?”、“第三行配置是不是少打了個分號?”):直接在原帖評論區裏回覆他就夠了,方便後來點進評論區的讀者順着樓層往下看。
  2. 如果是足以改變原文核心結論的重大更正、補測反轉或新版發佈:絕對不能只補在舊帖評論區裏!必須同時做兩件事:① 在舊帖底下留一條簡短的更正指路鏈接;② 單獨發一條全新的獨立原創帖(或者用帶評論引用 Quote 原帖的方式發出來)! (爲什麼單獨發新帖或者用 Quote 引用原帖不會被攔?因爲上面那三行代碼只查 tweet_id、retweeted_tweet_id 和 in_reply_to_tweet_id,並沒有查 quoted_tweet_id!)

當你單獨發一條獨立更新帖時,開頭千萬別寫得沒頭沒尾,要讓“沒看過昨天舊帖的新讀者”和“看過昨天舊帖的老讀者”都能一眼看懂:

獨立更正新帖的開頭示範: “更正說明:昨天的數據庫性能壓測漏掉了一個關鍵條件——重啓後的冷緩存(Cold Cache)。

今天補完冷緩存測試後,原本關於‘首次查詢響應耗時’的結論需要修正。這篇把最新的測試條件、修正後的對比表格,以及原報告中依然成立的部分完整列在下面,供大家覈對。”

這樣一來,昨天看過舊帖 A 的老讀者能在首頁正常刷到這條獨立新帖,避免被錯誤結論誤導;而今天剛刷到你的新讀者,也能直接拿到最完整、最準確的最新測試數據!20

24 舊內容可以重新介紹,已看記錄卻不會隨轉發消失(徹底講透自己轉發 Repost 老帖子的 5 道關卡與 Quote 破圈法)

很多創作者看到“普通候選帖超過 48 小時就會被年齡過濾器(AgeFilter)淘汰”,同時又聽說“轉發(Repost / Retweet)會生成一個新的 tweet_id”,腦子裏立馬就會冒出一個絕妙的點子: “那我每隔兩天,把我自己以前寫過的乾貨老帖子直接點一下‘普通轉發(Repost / Retweet)’頂上來,豈不是能讓我的老帖子無限復活、源源不斷推給全站陌生人?”

在之前的討論裏,很多朋友專門讓我把**“直接點普通轉發(Repost)自己的老帖子,在代碼裏到底會發生什麼”徹底掰開講透。 今天我們就順着源碼,帶你親眼看看當你按下“Repost(普通轉發)”自己 5 天前的老帖子時,這筆轉發在推薦管線裏會接連撞上哪 5 道關卡,以及爲什麼“跨時區補漏用 Repost,破圈找陌生人必須用 Quote(帶評論引用)”**!63

24.1 直接普通轉發(Repost)自己的老帖子,在代碼裏會經歷哪 5 道關卡?

  1. 第一關(48 小時年齡關 AgeFilter):確實能順利通過! 在 home-mixer/filters/age_filter.rs 裏,AgeFilter 只保留髮布時間不超過 48 小時(MAX_POST_AGE = 48 * 60 * 60 秒)的候選帖。但它檢查的是當前候選帖自己的 tweet_id(由 thunder_source.rs 把你今天點轉發生成的全新 ID 填在 tweet_id 裏,而把 5 天前的老帖原文 ID 存在 retweeted_tweet_id 裏)。因爲你今天剛點的轉發擁有一個今天剛出生的 tweet_id,所以它確實能順利繞過 48 小時年齡限制,不會被 AgeFilter 當場砍死。39 63
  2. 第二關(陌生人破圈關 OONRetweetReplyFilter):直接被一刀斃掉,根本去不了陌生人面前! 這是粉碎“靠自己 Repost 老帖破圈”幻想的最關鍵一步! 還記得我們在第 8 章講過的圈外過濾器 oon_retweet_reply_filter.rs 嗎?它有一條毫無商量餘地的鐵律:直接移除所有“候選作者(author_id)不在當前讀者關注名單內”的普通轉發(is_retweet)! 別人(同行大 V 乙)轉發你的老帖之所以能幫你破圈,是因爲對乙的粉絲丙來說,轉發人乙是丙關注的人(屬於圈內 In-Network),不會被這個過濾器攔住;但當你自己點普通轉發自己的老帖時,轉發人還是你自己!對於全站所有還沒關注你的陌生人來說,你依然是“圈外人(Out-Of-Network)”,所以你自己點的普通轉發,在普通推薦候選管線裏會被 100% 攔截,根本不可能被推給未關注你的陌生人!30
  3. 第三關(自家老粉絲已讀關 previously_seen_posts_filter.rs):看過的老粉絲絕對不會再看見第二次! 既然去不了陌生人那裏,那推給已經關注我的自家粉絲總行吧?這裏又嚴格分成了兩撥粉絲:
  • 5 天前已經刷到過你那篇老帖的粉絲:剛剛上一節纔看過源碼,已讀過濾器會把新轉發的 tweet_id 和老帖原文的 retweeted_tweet_id 綁在一起查!只要這位粉絲 5 天前已經刷到過你的原帖,他的已讀記錄(seen_ids)裏就已經記下了你老帖的原文 ID,今天你點的這筆新轉發會被當場攔下,他在首頁絕對不會刷到第二次!
  • 5 天前剛好沒上線漏看的老粉絲,或者這兩天剛關注你的新粉絲:他們關注了你(走圈內 Thunder 通道,不被第二關攔),而且他們的已讀記錄裏還沒有那篇老帖的 ID(不被第三關攔)——只有這羣“漏看的老粉 + 新漲的粉絲”,纔會在首頁刷到你對自己老帖的普通轉發!20 39
  1. 第四關(同池去重與 0.625 搶權重關):會跟你今天發的新帖子自己打自己! 如果你今天既發了一篇全新的原創帖,又隨手點了一下普通轉發自己的老帖子,這兩條動態頭頂上的作者 ID(author_id)全是你自己!對於那些還沒看過你老帖的粉絲來說,這兩條動態會同時掉進他的臨時籃子裏,在 VM Ranker 打分時直接觸發 0.625 同作者衰減(老帖轉發搶了你今天新帖的滿分名額,或者新帖把老帖轉發壓到 0.625)! 另外,如果原帖發出來還沒滿 48 小時你就去點普通轉發,RetweetDeduplicationFilter(retweet_deduplication_filter.rs)還會按原文 ID 把原帖和轉發合併去重,絕不會讓你在同一個籃子裏佔兩個坑;而且前面講的小賬號冷啓動 200 次曝光扶持(author_cold_start.rs)和互關好友 20 倍回覆加成(inputs.rs)都明確寫了 !self.is_retweet,普通轉發統統拿不到!2 35 42 63
  2. 第五關(安全標籤連坐關):如果老帖帶敏感標籤,轉發會把雷直接引爆到今天! 後面第 28 章會詳細講“最近 5 條帖子裏有 3 條帶 NSFW_HIGH_PRECISION 標籤就給賬號打上賬號級標籤”的規則(safetyLabelToUserLevelAggregationV2Processor.strato)。在這段代碼裏,當掃描你的時間線遇到普通轉發時,程序會調用 originalTweetForRetweet 去查那篇老帖原文身上的安全標籤,但卻用今天這筆新轉發的 ID 來算 60 天有效期窗口!也就是說,如果你把一兩個月前曾被貼過敏感標籤的老帖手欠點了一下轉發,它會直接佔掉你當前最近 5 條帖子的計數名額,甚至直接湊夠 3 條觸發賬號級標籤!79 80

24.2 這次重新介紹,給它一個現在的用途(Repost 與 Quote 的正確分工)

把上面這 5 道關卡看完,“怎麼讓以前寫過的優質老幹貨重新發光發熱”,最科學的實操標準答案就已經呼之欲出了:

  1. 什麼時候直接點“普通轉發(Repost / Retweet)”?——只在“跨時區補漏”時點一次! 比如你在北京時間中午 12 點發了一篇重磅長文,國內白天的粉絲看完了;到了北京時間晚上 11 點(北美和歐洲時區的中文讀者剛剛起牀刷手機),你可以順手點一下“普通轉發(Repost)”,專門把這篇乾貨補餵給白天沒上線漏看的海外時區老粉絲,以及今天剛點關注的新粉絲(發完記得別跟自己的下一篇新原創帖撞在同一分鐘發)。
  2. 想讓三個月前的老幹貨重新破圈、觸達全站“未關注你的陌生人”?——千萬別點普通轉發,一定要用“帶評論引用(Quote Post)”! 爲什麼 Quote(帶評論引用) 能完美避開普通轉發的所有死穴? 因爲在代碼底層,Quote 帖擁有自己獨立的正文和全新的 tweet_id,它的 is_retweet 字段是 false(老帖 ID 存在 quoted_tweet_id 字段裏)!這意味着:
  • ① 完美通過陌生人破圈關:它不是 is_retweet(也不是 is_reply),所以完全不會被 OONRetweetReplyFilter 攔截,能像全新原創帖一樣正常推給全站未關注你的陌生人!
  • ② 完美通過已讀過濾關:前面看過的 previously_seen_posts_filter.rs 那三行代碼只查 tweet_id、retweeted_tweet_id 和 in_reply_to_tweet_id,根本沒有查 quoted_tweet_id!所以哪怕是以前看過原帖的老讀者,也能在首頁刷到你帶新評論的 Quote 帖!
  • ③ 滿血享受冷啓動與高權重:它不被 author_cold_start.rs 的 !is_retweet 排除,小賬號發 Quote 帖照樣能拿前 2 小時 200 次 Home 曝光的直升電梯扶持;而且 Quote 本身的互動預測權重高達 5.0(是普通轉發 1.0 的 5 倍)!20 21 30 35

當然,用 Quote 重新介紹三個月前的老帖子時,千萬別隻在上面敲四個字“重溫舊文”或者每天機械地復讀“這篇很重要”——一定要結合讀者當下的新場景,給老幹貨賦予一個“今天就要用”的新理由! 比如你三個月前寫過一份《租房退租交接檢查表》,到了畢業搬家季,你用 Quote 引用那篇老帖,配文寫上:“最近到了退租高峯期,退租扯皮最常出在這三處角落。退房交鑰匙前務必按這份表格逐項拍照留底,已根據今年常見扯皮點補充了水電錶讀數覈對項👇”(如果原表格有內容過時了,記得先更新並標明修訂日期)。這樣發出來,不管是算法還是真人讀者,看到的都是一篇解決當下燃眉之急的滿血新幹貨!

順便說一句“直接點擊編輯(Edit)修改已發帖子”的規則:在可見性系統 visibility-filtering/models/tweet.rs 和 tweet_rules.rs 裏,有一條專門過濾“已經被新編輯版本取代的舊版本帖子(stale edited version)”的規則——它的作用僅僅是保證讀者刷到的是你改完之後的最新版,而不是那個還沒改錯別字的舊殘影!網上有人把它傳成“帖子發出來只要點編輯改一個錯別字,整篇帖子就會被算法降權作廢”,純屬自己嚇自己(當然,點編輯也不會幫你把 48 小時的帖子年齡重置回 0 秒;發現了影響結論的硬傷,第一時間改好讓讀者看到正確內容纔是最重要的)。64

24.3 一天、兩天和 49 小時,各自限制什麼

一路讀到這裏,你已經先後見到了 24 小時(1 天)、48 小時(2 天)和 49 小時 這好幾個跟帖子壽命有關的時間數字。爲了防止你把它們混成同一個“全站統一的帖子死亡倒計時”,我把它們在源碼裏各自管的地盤彙總成了下面這張表:37 34 39

所在代碼位置檢查的具體對象公開代碼裏的條件這個條件沒有回答(不能瞎推)的事
普通候選管線的 AgeFilter當前候選帖自己的 tweet_id 所對應的創建時間保留 age <= 48 小時;嚴格超過 48 小時才排除沒有直接拿 retweeted_tweet_id(被轉發老帖原文)的年齡做這項比較
普通 HOME 召回數據集指定的 Parquet 索引數據文件HOME/HOME_COLD/HOME_HOT 引用 1fav_1day.parquet(24 小時窗口)不能由這一個枚舉反推線上所有請求與其他召回源(如 Thunder)都只抓 24 小時內的內容
rankall 索引存儲窗口各個 Index 的數據保留範圍1fav 有 24/48 小時窗口;32fav 有 24 小時等窗口某個數據桶的存儲窗口,不等於一篇內容在全站所有入口的總曝光壽命
Favorite 點贊事件更新器帖子本身年齡,以及距離首次索引更新的時間帖子年齡 < 49 小時;已有緩存時距首次更新 <= 48 小時,更新間隔 >= 1 分鐘這隻管“收贊後還更不更新索引”,不能代替候選帖最後過不過 AgeFilter

來源 37 34 39

AgeFilter 實際使用:
is_within_age(candidate.tweet_id)
保留條件:age <= MAX_POST_AGE
MAX_POST_AGE = 48 * 60 * 60 秒

來源:39

你看 AgeFilter 的源碼:它用的是 age <= 48 * 60 * 60 秒(小於等於 48 小時保留,超過 48 小時才移除)。把這個細節擺出來,是爲了幫我們準確描述代碼邊界,而不是讓你去卡着 47 小時 59 分 59 秒搞什麼玄學操作。20 39

24.4 其他入口也有自己的資格

最後還要記住:普通候選管線的 48 小時 AgeFilter,只管 ScoredPosts 這條常規候選流。前面我們提過,在 For You 頂層流水線裏並列的 PushToHomeSource(按指定帖子 ID 推送),以及沉浸式視頻數據集里長達 4 天、14 天甚至 14 到 30 天 的視頻窗口(video_4day、video_4to14day、32fav_video_14to30day),都有各自獨立的時間窗口和准入規則。所以千萬別拿視頻的 14 天窗口去證明普通圖文帖能免除 48 小時限制,也別因爲普通候選有 48 小時限制就以爲兩天前的長文在全站徹底消失了——學會用 Quote(帶評論引用)+ 當下新痛點 把沉澱下來的老幹貨二次激活,纔是長效運營的正道。30 50 39

25 回覆質量還有另一套評估

前面我們聊了“回覆貼能不能進陌生人的首頁候選池”,以及“主計分表怎麼給別人回覆你的概率算分”。但在算法庫的 grox/flows/reply_spam 目錄下,其實還藏着另一套專門針對**“評論區回覆內容本身的質量與垃圾評估系統”**——這兩套系統千萬不能混爲一談。65

在 classifier_reply_ranking.py 和 task_write.py 裏,程序會把整段對話上下文、互動信號和作者粉絲信息打包送給 Grox 大模型,讓模型給這條回覆打一個回覆質量分(ReplyRankingScore),部分低質結果還會觸發有條件的風險打標(不過具體用來評判好壞的大模型提示詞 prompts.py 並未開源,因此我們能確認評論區另有大模型質量評估,但不能瞎編“超過幾個字或用哪個固定句式就必死”)。65

即便不看未公開的提示詞,我們把評論區裏最常見的兩種回覆擺在一起對比,高下立判:

  • 假設一位同行發帖貼出了一張“文件格式轉換報錯”的截圖,你在底下回一句萬能正確的廢話:“寫得太棒了!很有啓發,感謝博主的無私分享!”(甚至是用 AI 批量生成的二十句同義詞誇獎)——這種回覆對原帖討論沒有任何信息增量;
  • 反過來,如果你在回覆裏直接指出:“這個報錯碼是因爲輸入文件名帶了中文括號,對應轉換腳本的第 3 步;我在 macOS 15 + v2.4 版本下重現過,把路徑先做一次引號轉義就能跑通”——你的這條回覆直接給整個討論串補上了可驗證的排查材料。如果用 AI 輔助寫評論,也是先讓 AI 幫你提取原帖的痛點、已有結論和缺失條件,再由你填入自己親歷的實測細節,而不是拿 AI 當復讀機到處刷屏。

25.1 在別人帖子下連續回覆自己,什麼分數可能被寫成零

很多人在做評論區引流時喜歡用一個套路:跑到粉絲很多的大 V 熱門帖底下搶個前排留言,然後爲了放自己的推廣鏈接或長篇大論,在這條留言底下連續“自己回覆自己”蓋起三四層樓。 網上傳言:“在大 V 底下連續回覆自己會被判定爲垃圾號,直接把你的賬號權重或者大 V 原帖的分數清零!”

我們去翻 grox/flows/reply_spam/task_multi_step_reply_spam.py 和 classifier_multi_step_reply_spam.py 的源碼,先把“到底是誰的什麼分數被清零”說清楚:一旦被這條規則判定爲“多層自回自評垃圾推廣(Multi-Step Reply Spam)”,程序寫成 0.0 分的是你那幾條被判爲垃圾的回覆貼自己的 ReplyRankingScore(評論區排序分),既不會扣掉人家大 V 原帖的分數,也不會把你整個賬號的主頁推薦分數清零!66 67

25.2 對話結構檢查與模型判斷的先後

這套專門抓“在別人底下蓋樓自回自評”的過濾器叫 TaskMultiStepReplySpamFilter(task_multi_step_reply_spam.py)。並不是你在評論區回自己一句就立刻觸發大模型審查,它必須先過一道非常具體的**“對話結構門檻”**:66

  1. 祖先鏈完整且排除官方 AI:當前回覆必須有完整的對話祖先鏈(不能含缺失項),當前帖、直接上一條父帖與最頂層根帖都能取到作者資料,且排除 @grok 和 @gork 賬號;
  2. 關鍵豁免——排除“根帖作者自己寫串文(Thread)”:如果當前回覆的作者就是最頂層根帖(Root Post)的作者本人,直接跳過不查!這證明了:你在自己的主帖底下連續回覆自己寫串文(Thread),絕對不會觸發這條自回垃圾規則!
  3. 三層樓結構 + 直接父帖同作者:整段對話必須至少有 2 條祖先帖(也就是至少形成了“別人發的根帖 → 你的第一層回覆 → 你接着回覆自己的第二層回覆”這三層結構),並且直接上一條父帖的作者必須和當前回覆的作者是同一個人(你自己回你自己)!
  4. 根帖作者粉絲門檻是 1,000 粉:最頂層那篇根帖的作者,粉絲數必須至少達到 1,000 人(>= 1000)(代碼裏寫的就是明確的數字 1000,不是什麼模糊的“超級大 V”);同時,如果當前回覆者本人擁有高 PageRank V2 或灰標認證(政府/機構灰標),也會被這個過濾器直接豁免跳過。66

把這組結構條件畫成一張表,你就看明白什麼叫“在大 V 底下蓋樓自回”了:66

同一條示例對話的樓層發帖作者在 TaskMultiStepReplySpamFilter 裏的角色光靠結構是否就已經判爲垃圾?
第 1 層:最頂層根帖(Root)另一位粉絲數 >= 1000 的博主提供討論起點的他人主帖否(受系統嚴格保護)
第 2 層:一級評論回覆你自己當前回覆的直接父帖(Direct Parent)否
第 3 層:在自己評論下接着回覆自己依然是你自己滿足“至少兩層祖先+父子同作者”的待檢回覆否!結構達標只是送進大模型做內容判斷

來源 66

你看錶格最後一列:滿足了“在千粉博主底下自己回覆自己”的結構,僅僅意味着觸發了送交大模型審查的資格,絕不等於自動被判爲垃圾! 比如別人發了一道技術難題,你第 1 條回覆貼了排查步驟,緊接着第 2 條回覆自己補充了不同系統版本的兼容性差異——雖然結構上一模一樣,但只要大模型看完內容認爲你是正常補充討論,就不會判你違規(當然,由於分類器的具體 Prompt 未公開,我們不去瞎編“連回幾條必死”或“控制在多少字以內絕對安全”的假口訣)。66

25.3 模型圈出的帖子,還會經過一次篩選

就算大模型看完了整串對話,圈出了一批它覺得像垃圾推廣的樓層(Flagged set),程序在真正下手寫 0.0 分之前,還在 classifier_multi_step_reply_spam.py 裏設了三道嚴密的防誤傷篩子:67

  1. 必須包含最新這一條回覆:如果大模型只圈出了你前面的舊樓層,卻沒有把當前正在評估的最新這一條回覆圈進去,程序會認爲不構成持續多層垃圾,直接把整組結果全部丟棄,一條都不罰!
  2. 剔除無辜路人且至少保留 2 條:程序會先把對話裏其他作者發的帖子全部剔除掉(只留你自己的回覆);剔完之後如果發現只剩下孤零零的 1 條,不滿足“多步(Multi-step)”定義,同樣整組丟棄不罰!
  3. 根帖鐵桶保護:在把對話餵給大模型時,程序不僅在文本里把第 0 層明確標爲 root post 提醒模型不準標記,在解析模型返回結果時還寫了硬代碼只接受 index > 0 的樓層,從物理上徹底排除了把千粉博主的原帖(Root Post)誤傷標黑的可能!67 (順便提一個模型視野限制:如果整串對話的祖先樓層超過 10 層,這個分類器只會截取最前面 5 層 + 最後面 5 層 + 當前最新回覆,且每條最多讀 2 個媒體附件;這說明它看的是頭尾抽樣,不是把百層高樓一字不漏全讀完。)67

25.4 寫成零的是被判爲垃圾的回覆記錄

只有穿過上面所有篩子最終保留下來的那幾條你自己的垃圾回覆 ID,寫入器(task_multi_step_reply_spam.py#L151-L198)纔會挨個先嚐試給它們打上 RiskyHighVizReply(高曝光風險回覆)標籤,然後發佈下面這行將評論排序分歸零的指令(僅在正式生產環境 production 模式下執行):67

ReplyRankingScore(
    score=0.0,
    reasoning=reasoning[-500:]
)

來源:67

注意這裏“打 RiskyHighVizReply 標籤”和“把 ReplyRankingScore 寫成 0.0”在代碼裏是前後兩步動作:負責打標的輔助函數(task_write.py)內部還會再查一遍高 PageRank/信用分、灰標與測試賬號豁免;就算因爲豁免沒打上那個標籤,外層函數依然會繼續往下走、把 score=0.0 的分數發佈到緩存、Kafka 和 Strato 數據庫裏。(公開代碼裏能追到這個 0.0 分的生成與發佈,但下游各個評論區排序入口具體怎麼消費它未完全公開,所以我們嚴格按源碼稱之爲“將該垃圾回覆的 ReplyRankingScore 歸零”,而不誇大成賬號被封殺。)66 67

對我們創作者來說,道理再簡單不過:去別人評論區留言時,如果有新的數據、步驟或反例要補充,大大方方把背景寫清楚;如果是爲了在別人的熱門帖底下掛羊頭賣狗肉,一層接一層地自己回自己貼賣課廣告或引流二維碼,那正是 TaskMultiStepReplySpamFilter 瞄準的活靶子!

26 引用別人的原文,也會遇到可見性條件

很多做行業點評、熱點分析或闢謠的博主,最常用的一招就是**“帶評論引用(Quote Post)”**別人的帖子。大家往往覺得:“只要我自己寫的這段評論沒違規,這可是堂堂正正的原創 Quote 帖(權重 5.0),流量穩得很!”

但你很可能忽略了一條隱藏在 home-mixer/candidate_hydrators/vf_candidate_hydrator.rs 和 ancillary_vf_filter.rs 裏的**“附帶內容連坐規則”: 當你的候選帖準備上讀者首頁時,可見性系統不僅檢查你這條帖子本身,還會順帶檢查它身上掛載的所有附帶內容(Ancillary Tweets)——包括你引用的原帖(Quoted Tweet)、轉發的原帖以及對話祖先帖! 如果被你引用的那條別人發的原帖,後來被原作者自己刪掉了,或者因爲違規被平臺判了移除處置(代碼裏明確檢查 Drop、Tombstone 墓碑屏蔽或 NotEvaluated(尚未評估);注:一般的摺疊警告軟處置不在此列),ancillary_vf_filter.rs 就會直接把你這條引用帖(整個候選)也一起從推薦候選池裏一刀移除!**68

想想看這個場景有多冤: 假設你看到網上有人發了一條漏洞百出的謠言帖,你義憤填膺地點了“引用(Quote)”,在上面只敲了一句話:“這人純屬胡說八道!真實數據根本不是這樣的,大家千萬別信!” 結果兩小時後,那個造謠的人心虛把原帖刪了,或者原帖被平臺封禁變成了墓碑(Tombstone):

  1. 在算法推薦層面:因爲被引用原帖觸發了 Drop / Tombstone,你的這條闢謠引用帖在 ancillary_vf_filter.rs 這一關直接跟着陪葬,從陌生人的推薦候選池裏消失了;
  2. 在真人讀者層面:哪怕有粉絲點進你的個人主頁看到了這條帖子,由於底下的被引用原帖卡片已經變成了一塊灰色的“該帖子不可用”,而你的正文只寫了一句“這人純屬胡說八道”,讀者根本不知道你在反駁誰、對方說了什麼、真實數據又是什麼!

所以,每次當你準備用 Quote 去點評或反駁別人的帖子時,務必在自己的正文裏把“對方原來的核心主張是什麼、爲什麼錯、你的真實證據和原始出處是什麼”完整交代清楚(甚至可以把核心爭議點客觀總結在你的首圖裏);如果是一個非常重要且對方隨時可能刪帖跑路的闢謠選題,乾脆直接發一條完全不掛引用卡片的純獨立原創帖,這樣你的心血之作就永遠不會被別人的刪帖或違規牽連下水!68

27 發外鏈前,先確認它最後把讀者帶到哪裏

關於在 X 上發外部鏈接(External URLs,比如你的獨立博客、GitHub 倉庫、Substack 電子報或 Notion 模板下載頁),網上流傳着兩條最讓人頭疼的傳言:

  • 傳言一:“只要帖子裏帶了外部鏈接,算法就會固定扣除 30%–50% 的曝光!”
  • 傳言二:“只要把外鏈從主帖正文挪到第一條評論(首條回覆)裏,就能完美騙過算法、逃避外鏈懲罰!”

我們把公開代碼庫裏所有跟外鏈相關的模塊翻出來對質:這兩條傳言在公開代碼裏統統不成立!真正決定你發外鏈會不會出事的,根本不是“放正文還是放評論區”,而是你這條鏈接跳轉鏈條上的“網址信譽評級(URL Reputation)”以及你有沒有把壞鏈接掛在主頁置頂上!69 70

先看計分表:在 home-mixer/models/content_features.rs 裏,系統確實提取了一個叫 has_url(是否包含鏈接)的布爾特徵傳給下游;但在最終打分公式(scoring.rs)裏,沒有任何“只要 has_url == true 就乘以 0.5 或扣 30% 分數”的懲罰代碼!恰恰相反,在 24 項權重表裏,“預測讀者點擊打開外部鏈接(Open link)”還擁有 +0.2 的正向加分權重!21 69

27.1 檢查電子報、作品集和下載入口

既然帶正常外鏈不扣分,那爲什麼現實中確實有人發了外鏈之後流量暴跌? 因爲他們的鏈接撞上了反垃圾系統(BotMaker)專門抓低質量/惡意跳轉鏈接的審查機器人! 在日常發外鏈(比如發你的電子報、作品集或資料下載入口)之前,請務必養成一個保命習慣:親自從草稿或測試帖裏點開一次你準備發的鏈接,盯着瀏覽器地址欄看它中間跳轉了幾次、最後落到了哪個域名上,並覈對落地頁內容是不是和你在正文裏承諾的一模一樣! 比如你正文答應給讀者一份 Excel 報價模板,結果短鏈接點進去先跳了兩個莫名其妙的廣告統計域名,或者你三年前買的老作品集域名早就過期被博彩網站搶注篡改了——這種跳轉鏈失效或域名易主,纔是觸發外鏈風控的頭號元兇(當然,肉眼檢查能幫我們排除死鏈和被篡改的域名,但 X 內部網址信譽庫對某個域名的具體評級數值,在網頁外觀上是看不出來的)。

同時,在正文裏要把“點開這個鏈接會看到什麼”交代得明明白白(比如寫清“點擊下方 GitHub 鏈接可直接下載包含 3 個字段的 CSV 測試樣本,對應 v2.1 版本”)。如果你爲了正文排版清爽,選擇把鏈接放在一樓評論區,也要在主帖結尾指路讓讀者找得到——但千萬別指望“挪到一樓評論區就能躲開低質鏈接審查”,爲什麼?看下面 v1 和 v2 機器人的源碼對比你就懂了!

27.2 置頂裏的問題鏈接,可能給整個賬號打上標籤

更兇險的一顆雷藏在你的個人主頁置頂帖(Pinned Post)裏: 在 botmaker-rules/scarecrow/bot/PinnedLowQualityOrBadUrl.bot 裏,有一條專門盯着“更換置頂帖”的賬號級規則!一旦你把一條帶有 BAD 或 LOW_QUALITY 評級鏈接的帖子設爲了主頁置頂(且滿足作者條件),系統不會只罰那一條置頂帖,而是會直接給你的整個賬號打上長達 7 天的 SPAM_HIGH_RECALL 賬號級限流標籤! 一旦背上這個賬號級標籤,在接下來的整整 7 天裏,你發的所有新帖子(哪怕一字外鏈都不帶)在陌生人推薦入口(HomeRecommendations)都會被直接攔截!所以如果你突然發現自己連續好幾篇新帖的陌生人曝光斷崖式歸零,第一件事就是回頭檢查:最近是不是換過主頁置頂帖?置頂帖裏掛的舊鏈接是不是出問題了?(配合後文教你的官方 Under the Hood 工具,可以直接查出報告期內有沒有背上這個標籤。)71 72

27.3 文件名裏的“陌生人”條件,v2 已經不再要求

爲什麼網上會流傳“把外鏈放到第一條回覆(評論區)就能免罰”? 因爲這幫寫攻略的人看的還是老掉牙的 v1 舊版規則,壓根不知道代碼庫裏早就升級到了 v2 新版規則! 我們把 botmaker-rules/scarecrow/bot/ 目錄下的舊版 LQ_Tweets_With_LQ_URL_Verdict_At_Mention_To_NonFollower.bot(v1)和最新版 ..._v2.bot(v2)並排放在一起對比,真相大白:73

檢查條件舊版 v1 規則最新版 v2 規則對創作者的真實意義
帖子裏 @(Mention)了未關注你的陌生人要求至少 @ 了一名非粉絲已徹底刪掉此條件!雖然 v2 文件名還留着歷史名字,但代碼里根本不再查有沒有 @ 陌生人
回覆貼(isReply)/轉發貼(isRetweet)豁免明確排除回覆和轉發(放回復裏確實不查)已徹底刪掉排除條件(回覆和轉發照查不誤)!“把低質外鏈塞進首條評論就能逃避處罰”在 v2 裏已經徹底失效!
網址跳轉鏈質量判定(redirectionChain)跳轉鏈整體評級符合 LOW_QUALITY跳轉鏈中任意一跳含 LOW_QUALITY,且最後一跳不是 GOOD 或 WHITELIST(白名單)哪怕最終落地頁正常,只要中間用的短鏈跳轉服務被判 LOW_QUALITY 照樣中招!
命中後寫入的懲罰標籤帖子級 SPAM_HIGH_RECALL帖子級 SPAM_HIGH_RECALL在 HomeRecommendations 推薦入口對該帖執行直接移除(Drop)

來源 73

你看上面這張表第二行和第三行:

  1. 在舊版 v1 時代,代碼裏確實寫了排除 isReply 和 isRetweet,所以當年把外鏈塞進評論區確實能鑽空子;但在最新版 v2(判斷時只看三樣輸入——發帖人的 ID、帖子 ID、非空的跳轉鏈記錄——再排除掉測試號、高 PageRank、臨時豁免名單與灰標號)裏,程序員已經把“排除回覆和轉發”以及“必須 @ 陌生人”的條件刪得一乾二淨了!只要你用了被標爲 LOW_QUALITY 的短鏈或跳轉域名(且最終落地頁不在白名單或 GOOD 名單裏),不管你是放主帖正文,還是偷偷塞進一樓評論區,v2 機器人照抓不誤,當場給那條帖子打上 SPAM_HIGH_RECALL 標籤!
  2. 反過來,如果你發的是乾乾淨淨、信譽良好的正規網址(比如直接放 GitHub、主流媒體或正常備案的高信譽站點),哪怕直接放在主帖正文裏,也根本不會命中這條規則(當然,正常的短網址、UTM 統計參數或正規聯盟鏈接只要域名信譽沒變黑也不會無故挨罰)。73

27.4 七天從寫入標籤時起算

我們再把前面那個兇險的**“置頂帖壞鏈接炸彈(PinnedLowQualityOrBadUrl.bot)”的觸發細節摳清楚: 這個機器人監聽的是用戶資料修改事件(user_modification)。只有當你的置頂帖 ID 列表(pinnedTweetIds)發生了變化(修改後的 after 值存在、不爲空、且跟修改前的 before 值不一樣),它纔會去抓取你新換上去的那條置頂帖裏的所有展開鏈接(expanded URLs),解析它們的真實落地去向與網址信譽(Reputation)。只要其中任意一個鏈接包含 BAD 或 LOW_QUALITY(且作者不屬於測試賬號、高 PageRank、AutoExpiringTempSkipList 臨時豁免名單或政府機構灰標 Grey Badge**——注意:普通花錢買的藍標 Premium 絕不等於這裏的灰標,沒有免死金牌!),就會立刻給整個賬號寫入 SPAM_HIGH_RECALL 標籤!74

這裏有兩個關乎切身利益的時間細節:

  1. 7 天封禁期從哪一秒算起? 代碼裏寫的是 CurrentTimeMs() + 7天(一週),也就是從你換上這條問題置頂帖、觸發機器人寫入標籤的那一秒鐘開始往後數整整 7 天(跟那條老帖子本身是什麼時候發的無關,也跟你哪天打開後臺看到報告無關)。
  2. 如果我發現不對勁,馬上把置頂帖取消(Unpin)掉,7 天限流標籤會立刻消失嗎? 不會立刻自動消失! 在 PinnedLowQualityOrBadUrl.bot 這份規則文件裏,只寫了“換上問題置頂帖時新增 7 天標籤”的邏輯,根本沒有寫“一旦取消置頂就立刻刪除該賬號標籤”的對應分支!(當然,我們也不能排除後臺其他申訴或人工修正服務會提前介入處理;而且等 7 天標籤到期自動消失後,新帖依然要正常過召回、已讀和打分流程,代碼沒有承諾第 8 天早上流量自動補償翻倍。)所以,在點下“置頂到個人主頁(Pin to profile)”按鈕之前,花 5 秒鐘親手點一下里面的鏈接確認能正常打開,能幫你省去整整 7 天的無妄之災!74 75

28 同一個安全標籤,在不同入口會怎樣處理

很多創作者一聽到“我的帖子或賬號被打了安全標籤(Safety Label)”,第一反應就是:“完了,我是不是全網徹底黑號了?連關注我的老粉絲都看不到我了?” 還有人會找一個已經關注自己的鐵粉朋友問:“兄弟,你點進我主頁或者刷關注流,能看到我剛發的帖子嗎?” 朋友看了一眼說:“能看到呀!” 於是他就放心地以爲自己根本沒被限流。

這兩種想法全都錯了! 在 X 的架構裏,“安全系統給帖子或賬號貼標籤(Safety Labeling)”和“可見性過濾系統決定怎麼攔截(Visibility Filtering)”是上下游分開的兩套系統。同一個安全標籤,在“老粉絲刷的主頁(TimelineHome)”、“給陌生人推流的入口(HomeRecommendations)”以及“點進詳情或主頁(HomeHydration)”裏,受到的待遇完全不同!76 77 75

先交代一個版本問題,免得有人拿代碼改動亂傳限流:我把 10 月 28 日(5ed7963)和 10 月 29 日(606b254)兩個版本的安全與可見性代碼對過一遍,本文後面要講的自動打標、5 帖聚合、視頻和回覆審查,規則和結構都沒變。可見性過濾那個目錄倒是重構過一次——重複的規則被抽成可複用的列表,散落的開關改寫成統一的 ClientSwitch 集合——但我把重構前後的 14 組規則列表逐項展開覈對,所有入口的過濾規則和執行順序都一致。(這是按結構覈對的結論,不是逐字節比對。)所以別把程序員正常的一次代碼整理,傳成「10 月 29 日又搞了一輪全網大限流」。76

28.1 侮辱標籤限制哪些讀者、哪些入口

我們先拿一個最典型的帖子級標籤——FOSNR_ABUSE_INSULTS(辱罵與人身攻擊標籤;FOSNR 的全稱,公開代碼裏沒有給出)——來看看它在三個不同檢查入口的真實待遇:

爲什麼這個標籤在代碼規則裏寫的適用對象是 NonAuthors(除了作者本人以外的所有人),但在實際效果上卻變成了“老粉絲還能看見,唯獨陌生人完全刷不到”? 祕密就在 Home Mixer 的分流邏輯(vf_candidate_hydrator.rs)裏! 當 Home Mixer 把候選帖送去做安全檢查時,它會先看這位讀者有沒有關注你:

  • 如果讀者已經關注了你(in_network = true),你的帖子會被送去 TimelineHome 安全級別做檢查——而在 TimelineHome 的規則表裏,壓根沒有配置“遇到 FOSNR_ABUSE_INSULTS 就直接移除”的規則!所以你的老粉絲在首頁依然能刷到!
  • 如果讀者還沒有關注你(in_network = false,圈外陌生人),你的帖子會被送去 TimelineHomeRecommendations 安全級別做檢查——而在這個陌生人推薦入口裏,白紙黑字配了“對作者本人以外的所有人(NonAuthors)直接移除候選(Drop)”!77 75

把 FOSNR_ABUSE_INSULTS 標籤在各個檢查入口的待遇列成表,你就看懂這個標籤在不同入口的待遇差別了:77

安全檢查入口當前讀者身份或客戶端條件對 FOSNR_ABUSE_INSULTS 標籤的處置這一步說明什麼
TimelineHome(圈內關注流入口)只考慮這一個標籤時沒有配置該標籤的移除(Drop)規則老粉絲走這個入口不會被這條規則攔下(但若同時帶其他違規標籤或拉黑仍會被別的規則攔)
HomeRecommendations(圈外陌生人推薦入口)作者本人以外的所有人(NonAuthors)直接移除候選(Drop)!這正是“陌生人推薦流量徹底歸零”的罪魁禍首!
HomeHydration(數據補齊層)未關注你的陌生人(且客戶端支持 FOSNR 規則)直接移除(Drop)受客戶端開關(FosnrRules 默認開啓)控制
HomeHydration(數據補齊層)已關注你的粉絲(且客戶端支持 FOSNR 規則)軟干預提示(Soft intervention)粉絲能看到,但可能會附帶提示層
HomeHydration(數據補齊層)作者本人(且客戶端支持 FOSNR 規則)展示可申訴的處置提示信息你自己看自己的帖子完全正常,甚至帶申訴入口(舊版客戶端若觸發 FosnrFallbackDrops 則對所有人移除,但該 fallback 默認關閉)

來源 76 77

同時,自動打上這個 FOSNR_ABUSE_INSULTS 標籤在 Grox PTOS 寫入路徑(task_write_safety_post_annotations_result_sink.py)裏也有三個明確的前提條件: ① 模型必須判定帖子屬於 HateOrAbuseInsultsWithTarget(針對特定目標的仇恨或侮辱攻擊); ② 帖子的語言必須被識別爲英語(English); ③ 作者不是高 PageRank 或灰標賬號(測試賬號更早被排除)。 (當然,這隻說明這一條自動寫入分支要求英語,絕不代表你用中文罵人就不受其他自動規則或人工舉報的約束。)所以平時寫銳評或技術反駁時,對事不對人、擺數據講邏輯,別圖嘴快加人身攻擊詞彙,否則一旦掛上這個標,老粉絲雖然還能在評論區跟你互動,但整篇帖子的陌生人破圈通道就徹底關門了。77

28.2 LOW_QUALITY 和 MISINFO:警告給誰看,限制哪些操作

網上還有一句傳言:“只要帖子被貼上 LOW_QUALITY(低質量)或者 MISINFO(不實信息)標籤,系統就會對所有非粉絲彈出警告遮罩,並且直接鎖死點贊和轉發分享按鈕!”

去核對 visibility-filtering/rules/tweet_rules.rs、rule_spec.rs 和 verdict.rs 的源碼,警告遮罩(Interstitial)和互動按鈕鎖死(Limited Engagements)確實存在,但傳言把適用對象和觸發條件搞錯了三個地方:78

  1. 適用受衆是所有人(Everyone),不只是非粉絲! 這條名叫 PUBLIC_INTEREST_LABEL_INTERSTITIAL 的規則,針對的是 2019 年 4 月 1 日之後發佈的、帶有帖子級 LOW_QUALITY 標籤,或者帶有四種不實信息標籤(MISINFO_CIVIC 公民選舉、MISINFO_GENERIC 通用不實、MISINFO_MEDICAL 醫療健康、MISINFO_CRISIS 危機事件)的帖子——它的展示受衆寫的是 Everyone(所有人,連粉絲也一樣會看到警告)!
  2. 到底鎖死哪幾個互動按鈕,取決於標籤的來源(source)與策略配置!
  • 如果是 LOW_QUALITY 標籤,程序會直接選用 NonCompliant(不合規) 作爲互動限制等級——在公開測試預期(limited_actions_policy.rs)裏,NonCompliant 確實是最狠的“全家桶鎖死”:回覆、普通轉發、點贊、表情回應(React)、私信發送、加入收藏夾、加入 Moments、置頂、查看帖子數據、系統分享和複製鏈接,統統被禁止!
  • 但如果是四種 MISINFO 標籤,程序會先去讀這個標籤身上的 source(來源字段):比如當 source 爲 limited_replies 時,它只會選用 ConversationControl(對話控制),在測試預期裏僅僅限制“回覆(Reply)”這一項,點贊和轉發分享根本沒鎖死!
  • 不過這裏有一個極容易漏看的保底陷阱(Fallback):如果一條 MISINFO 標籤身上壓根沒有填 source 字段,雖然在第一步生成警告時留空了限制項,但到了第二步 LabelInterstitial 組裝最終互動限制原因(verdict.rs#L77-L83)時,代碼會自動退回(Fallback)使用最嚴厲的 NonCompliant 全家桶鎖死!所以千萬別以爲“沒填 source 就不會被鎖互動按鈕”。(另外,代碼裏把普通轉發、引用、私信、系統分享、複製鏈接算成幾個不同的獨立動作;線上到底鎖哪幾個按鈕,由一份實時配置(limited_actions_policy_limited_actions)決定,公開代碼裏的是測試預期。)。78
  1. 分清兩個名字都叫 LOW_QUALITY 的東西: 這裏觸發全套按鈕鎖死的 LOW_QUALITY,是貼在帖子身上的帖子安全標籤;而上一節我們講外鏈時提到的 LOW_QUALITY,是網址信譽庫給域名打的網址評級(網址評級命中後給帖子寫的是 SPAM_HIGH_RECALL 標籤)。千萬別因爲名字一樣,就以爲自己隨手發一條字數少、寫得普通的日常動態也會被貼上 LOW_QUALITY 鎖死點贊鍵!78 73

28.3 賬號標籤會影響多篇帖子,但要看具體名稱

比單篇帖子標籤殺傷力大得多的,是直接貼在你賬號頭上的賬號級安全標籤(Account Labels)——因爲在陌生人推薦入口,賬號一旦背上清單裏的標籤,你名下發的候選帖會在這個入口被整批攔下,根本不需要再逐篇審查你的新帖內容(粉絲那邊的待遇不同,見下文)! 打開 visibility-filtering/rules/levels.rs 和 author_rules.rs,在陌生人推薦入口 HomeRecommendations 裏,系統列出了長長一串會直接把該作者所有候選帖一刀移除(Drop)的賬號級標籤清單:75

  • 成人與敏感類:作者自行標記爲敏感賬號(NSFW self-flagged)、管理員標記 NSFW 狀態,以及 NSFW_HIGH_RECALL(高召回涉黃)、NSFW_HIGH_PRECISION(高精度涉黃)、頭像涉黃(Avatar)、背景橫幅涉黃(Banner)、近乎確定涉黃(Near-certain)等賬號標籤;
  • 垃圾與違規類:SpamHighRecall(高召回垃圾號)、Compromised(賬號被盜/存在安全風險)、ReadOnly(只讀封禁狀態)、ImpersonationHighPrecision(高精度冒充他人)、AbusiveHighRecall(高召回辱罵濫用)以及 DoNotAmplify(禁止算法放大推薦)。

但是,即便背上了上面這些嚇人的賬號標籤,網上那句“任何一個賬號標籤都會徹底斷絕所有非粉絲觸達”依然說得太絕對了: 因爲代碼裏每一條規則都明確指定了受衆(有的是 NonAuthors,有的是 NonFollowers),而且老粉絲刷的 TimelineHome 並沒有整套照搬上面這張攔截清單;正如官方 Under the Hood 報告裏對其中多個標籤的準確定義——它們的作用是**“不向未關注該賬號的非粉絲推薦其帖子(Do not recommend posts from this account to non-followers)”**,並不是把你在搜索框、個人主頁直接訪問、對話詳情頁或直接點鏈接等全站所有入口全都物理抹除掉。75

28.4 “最近五條裏有三條”,到底在數什麼

在所有賬號級標籤裏,最讓創作者心驚肉跳的莫過於這條“五三封號鐵律”:網上傳言“只要你最近發的 5 張圖片裏有 3 張涉黃(或者最近 5 條帶圖/視頻的帖子裏有 3 條涉黃),整個賬號就會被直接封禁推薦 7 天!”

我們直接把 safety-label-user-agg/postToUserLabelRules.strato 裏的公開默認 JSON 規則源碼端上來,看看程序到底是怎麼數的:79

"windowSize": 5,
"minimumMatchingPosts": 3,
"maxPostAgeDays": 60,
"mediaOnly": false,
"postLabels": {"anyOf": ["NSFW_HIGH_PRECISION"], "allOf": []}

來源:79

請把眼睛釘死在第四行:"mediaOnly": false(只數媒體帖 = 否)! 這行代碼直接戳破了網上的兩個重大誤區:

  1. 它數的單位是“幾條帖子(Posts)”,根本不是“幾張圖片”,也不是隻數帶圖片/視頻的帖子! 處理器(safetyLabelToUserLevelAggregationV2Processor.strato)會從你的個人時間線接口(userTimeline)按時間倒序取出你最近發的帖子,先截取最前面的 5 條帖子(windowSize: 5),然後數這 5 條帖子裏有幾條在 60 天內並且身上帶着 NSFW_HIGH_PRECISION 安全標籤! 我們用一張 5 條帖子的時間線算例表,幫你一眼看懂它到底怎麼記賬:79 80
你時間線倒序的位置帖子形式身上的 NSFW_HIGH_PRECISION 標籤這條規則算幾筆?
最新第 1 條一條視頻帖子有計 1 筆
倒數第 2 條一條純文字日常吐槽(無任何圖片視頻)沒有計 0 筆(但它佔掉了前 5 條窗口裏的 1 個位置!)
倒數第 3 條同一條帖子裏一口氣放了 4 張敏感圖有只計 1 筆!(4 張圖裝在 1 條帖子裏,只算 1 條帖子)
倒數第 4 條一條普通圖文更新沒有計 0 筆
倒數第 5 條另一條單張圖片帖子有計 1 筆(累計滿 3 筆,觸發賬號級標籤)

來源 79

你看懂上面這張表裏的門道了嗎?

  • 第三條帖子裏哪怕塞滿了 4 張 敏感圖片,因爲它只是一條帖子,在這條規則裏只算 1 筆(不會因爲一條帖子放了 4 張圖就當場湊夠 3 筆封號);
  • 第二條哪怕是一句純文字帖子,因爲 mediaOnly 默認是 false,它照樣佔掉了“最近 5 條窗口”裏的 1 個名額!如果連發兩條純文字正常帖,原本排在第 4、第 5 位的老敏感帖就會被擠出前 5 條的檢查窗口——這是計數方法的結果說明,不是躲避方法:觸發看的是標籤事件,別拿窗口當配方用。(注:表格僅演示代碼計數邏輯,未使用真實賬號線上數據。)
  1. 第二個細節:不需要等發滿 5 條纔開始查! 代碼裏用的是 take(5)(最多取前 5 條),然後直接判斷匹配數量是否 >= 3(minimumMatchingPosts: 3)。哪怕一個新號總共只發了 3 條帖子,只要這 3 條全帶 NSFW_HIGH_PRECISION,當場就夠 3 條觸發,絕不是“必須發滿第 5 篇才啓動檢查”,也不是按 60% 百分比算的!79

28.5 六十天、七天、十分鐘,別混成一個倒計時

圍繞這條“5 條裏有 3 條”的規則,代碼裏還有 60 天、7 天、10 分鐘 三個時間參數,以及前面提過的**“轉發老帖引爆地雷”**機制:

  1. 什麼時候觸發檢查(60 天窗口)? 並不是你每發一條普通帖子都會跑一遍這個檢查,它是由 Applied(某條帖子被新打上安全標籤)事件觸發的。公開默認要求觸發事件對應的那條帖子在最近 60 天內,且新打上的標籤正是 NSFW_HIGH_PRECISION。觸發後,程序先截取你 userTimeline 最前面的 5 條帖子,再數里面有多少條同時滿足“年齡 ≤ 60 天”且“帶有 NSFW_HIGH_PRECISION 標籤”。79 80
  2. 轉發(Retweet)會怎麼查? 正如我們在第 24 章警告過的:當掃描你前 5 條時間線遇到一筆普通轉發(Retweet)時,處理器會調用 originalTweetForRetweet 去讀取被轉發原帖身上的安全標籤,但用來計算“是否在 60 天內”的帖子 ID 用的卻是你時間線上這筆新轉發的 postId!所以千萬別手欠去轉發別人(或自己以前)帶 NSFW_HIGH_PRECISION 標籤的敏感帖,否則等於把別人的雷直接背到自己最近 5 條的計數窗口裏!80
  3. 沒有高 PageRank 或灰標豁免! 在這條 3/5 聚合規則的默認配置裏,雖然排除了 nsfwAdmin = true 的賬號和已經揹着 NSFW_HIGH_PRECISION 賬號標籤的賬號,但 nsfwUser(已自行標記敏感內容的用戶)排除開關設爲了 false,highPageRankOrGreyBadge(高權重或灰標大號)排除開關也設爲了 false! 也就是說,在這條規則面前,哪怕你是灰標大 V,或者已經在設置裏勾選了“我的媒體包含敏感內容”,只要前 5 條湊夠 3 條 NSFW_HIGH_PRECISION,照樣會給你整個賬號打上賬號級標籤。這條寫入路徑在公開代碼裏帶的公開 TTL 是 7 天,從寫入那一刻起算——這是這條路自己的設置,跟置頂路的 7 天不是一回事(見第 31 條的區分)。(另外,事件轉發器 safetyLabelToUserLevelAggregationV2Forwarder.strato 設置了 10 分鐘延遲 delay 和 20 分鐘最大延遲目標 maxLag,所以是從第 3 條帖子被打標大約 10 分鐘後才異步聚合到賬號頭上,不是第 3 條剛發出來的第 1 秒鐘就立刻變天。)79 80

28.6 三條命中的默認規則,也能被配置覆蓋

當然,我們也得保留配置層面的嚴謹性:上面的“前 5 條中 3 條、mediaOnly: false”來自代碼裏的 defaultRulesJson(公開默認配置),而程序運行時會通過 feature switch 讀取 configuredRulesJson,隨時可以動態覆蓋這個默認值(比如把某組實驗改成 mediaOnly: true)。 同一個文件裏甚至還寫了一條名叫 possibly_nsfw_account 的規則:它的開關 enabled 雖然是 true,但裏面的參數居然寫着**“在 10 條窗口(windowSize: 10)裏要求至少匹配 11 條(minimumMatchingPosts: 11)”**——從 10 條裏找 11 條在數學上是永遠不可能達成的(不可達默認),這多半是程序員用修改閾值的方式在默認配置裏把這條規則軟停用了(線上可通過配置覆蓋激活)。79

此外,在 botmaker-rules/scarecrow/ 下還有另一條更早的 NSFW 媒體事件聚合路徑(NsfwTweetMediaProcessor.bot 與 ApplyNsfwUserLabel.df),它是按帖子 ID 把媒體事件放進 HLL 計數器(HLL=一種只數“大概有多少個不重複項目”的計數器),檢查 1 天之內是否超過 2 筆,再送去打標或人工審覈。這說明系統裏抓成人內容的防線不止一條,千萬別把“穿插發兩條文字帖把敏感帖擠出前 5 條”當成永遠不會被封的免死金牌。75 79 80

29 重複內容、互動誘導和 hashtag,能查到什麼

29.1 能查到 COPYPASTA_SPAM 的寫入,查不到完整的相似度門檻

很多做矩陣號、或者習慣把同一段文案反覆發的朋友最關心:“X 算法是怎麼抓複製粘貼(Copypasta)重複內容的?我們寫中文沒有英文那種空格分詞,是不是就抓不到中文重複了?”

千萬別抱僥倖心理!專門抓中文(中日韓 CJK 字符)重複的機器人就明晃晃地寫在代碼庫裏! 打開 botmaker-rules/scarecrow/bot/BBQDuplicateTextProd.bot 和專門管評論區的 BBQDuplicateTextRepliesProd.bot,你會看到這兩個機器人接收上游定時任務跑出來的重複帖子聚類(tweetIdCluster),而上游任務(Job)的名字清清楚楚地列着兩個:81

  • duplicate_text_unigrams(針對英文等按詞切分的重複文本檢測);
  • duplicate_text_characters_cjk(專門針對中日韓漢字按字符切分的重複文本檢測)! 而且連評論區回覆都有獨立的對應任務!一旦命中並通過資格檢查(排除已處理或已帶該標籤的帖子、檢查特定推廣卡片、排除測試號/高 PageRank/臨時豁免與灰標號,並受寫入速率限制),機器人就會直接給帖子打上 COPYPASTA_SPAM(複製粘貼垃圾) 標籤!81

這裏我們必須誠實守住兩個代碼邊界:

  1. 查不到“到底重複多少個字、相似度百分之多少纔算違規”:因爲公開的這兩個 .bot 文件是從“收到上游已經聚好類的 tweetIdCluster”纔開始往下走的,上游離線任務到底用什麼閾值、跨多少小時、重複幾次才把帖子打包成一個 Cluster,代碼並未放入公開倉庫。因此,正常文章裏引用同一句名言或同一個專業術語絕不等於必被打標,我們也絕不瞎編“重複滿 15 個字必死”或“把句號改成歎號就能防查重”的假口訣。81
  2. COPYPASTA_SPAM 的下游消費端缺口:在這次公開的 Home Mixer、VM Ranker 和 visibility-filtering 代碼樹裏,我們能確認機器人實打實地寫入了 COPYPASTA_SPAM 這個標籤,但還沒有找到直接讀取這個標籤名並執行扣分或 Drop 的下游代碼(可能由未公開的規則或服務消費)。我們如實把“確有 CJK 重複打標機器人”和“下游具體扣分比例未公開”這兩件事原原本本擺出來,但不管怎麼說,把同一段引流話術複製粘貼到十幾個不相關的帖子底下刷屏,既容易招來這個標籤,更會招來真人的舉報(Report 的係數是 -234.0,乘的是預測概率)。76 81

29.2 三類互動誘導,沒有這項高 PageRank/灰標豁免

平時刷 X 經常看到有人發這種騙互動的帖子:“同意的打 1,不同意的扣 2”、“轉發這條錦鯉,評論區留下你的願望,我抽十個人送……”。 在 Grox PTOS 的安全寫入代碼(task_write_safety_post_annotations_result_sink.py#L233-L248)裏,程序員專門把三類互動誘導行爲拎出來開了“嚴打通道”:54

  • SpamEngagementBaiting(互動誘餌/釣魚騙互動);
  • SpamEngagementFarming(互動農場/刷贊刷評養號);
  • SpamCardManipulation(惡意操縱外鏈預覽卡片騙點擊)。

這三類違規在代碼裏的待遇有多狠? 對於其他普通的 Spam 垃圾類別,程序在打標前還會先看一眼作者是不是“高 PageRank 大號”或者“灰標認證號”,如果是就網開一面跳過不打標;唯獨當大模型判定你的帖子屬於上面這三類(Baiting、Farming、CardManipulation)之一時,程序直接把 should_label_for_spam 設爲 true,當場跳過高 PageRank 和灰標豁免檢查,哪怕你是高權重賬號也照樣給你貼上 SpamHighRecall 垃圾標籤(直接從陌生人推薦流裏移除)!54

當然,觸發這條嚴打的前提是 PTOS 大模型在正式生產模式下先把你的帖子歸入了這三類(具體判定的 Prompt 未公開,所以並不是你在乾貨長文末尾正常寫一句“你們在實際項目裏遇到過嗎?歡迎在評論區聊聊”就會被判違規)。怎麼提問才叫高質量互動?比如你測完兩款軟件後問讀者:“上面這三項測試條件裏,哪一項跟你們公司真實的部署環境不一樣?歡迎貼出你的版本號和報錯案例,我挑典型場景做下一期複測。” 這種問題有具體錨點、服務於內容本身,跟空洞的“扣 1 領資料”完全是兩碼事。54

29.3 有 hashtag 特徵和濫用分類,沒有通用的最佳數量

最後我們把創作者常問的另一個問題徹底講透:“發帖子時帶 # 話題標籤(Hashtag),到底是有助於算法推薦,還是會被當成垃圾降權?一條帖子帶幾個 # 標籤最合適?”

對照源碼裏的三處確鑿證據,關於 # 標籤的真相是這樣的:54

  1. 帶 # 標籤有用嗎?有用,但不是直接加分項! 在主計分表裏,沒有任何“每加 1 個 # 標籤就加幾分”的公式;但在 Phoenix 模型的用戶歷史行爲特徵清單(history_id_lists.py 與 id_list_features.py)裏,明確包含了一項叫 CLICK_HASHTAG(用戶點擊過的 # 標籤歷史) 的特徵!這證明系統在給讀者做個性化召回和排序時,確實會參考用戶平時愛點哪些 # 標籤的行爲信號,絕不能說 # 標籤完全零價值。
  2. 代碼裏的硬上限是 4 個(MaxHashtagsPerTweet = 4)! 在 SimClusters 的帖子實體抽取器(simclusters_v2/summingbird/common/TweetEntityExtractor.scala)裏,程序員明確定義了一個常量:MaxHashtagsPerTweet = 4——當它從你的帖子文本里提取話題標籤實體來構建興趣社區關聯時,最多隻保留前 4 個 # 標籤,從第 5 個 # 標籤開始往後,在這條路徑裏會被直接丟棄無視!(注:這個 4 是該抽取器的讀取上限,不是說帶滿 4 個就一定比帶 1 個流量高,也不是說第 5 個就開始扣分。)
  3. 亂塞無關熱門標籤會觸發 SpamHashTagAbuse 懲罰! 在 PTOS 的違規分類枚舉(grox/flows/ptos/state.py)裏,專門設有一項罪名叫 SpamHashTagAbuse(話題標籤濫用)。如果你寫了一篇賣茶葉或聊開發的帖子,卻在文末一口氣堆上十幾個當天最火的娛樂明星、體育賽事或幣圈熱門 # 標籤想蹭流量,一旦被大模型判定爲 SpamHashTagAbuse(且無高 PageRank/灰標豁免),就會直接給帖子寫上 SpamHighRecall 垃圾標籤,在陌生人推薦流裏把你徹底斃掉!54

所以,平時發帖用 # 標籤的準則很簡單:普通日常帖完全不需要硬湊標籤;只有當你的文章確實圍繞某個明確的專有名詞、開源項目名、具體產品或行業活動展開時,自然地放上 1 到 2 個(這條抽取路徑最多讀前 4 個,第 5 個起就不讀了)高度相關的 # 標籤即可,千萬別在文末堆砌一串跟正文八竿子打不着的熱搜詞!

30 曝光異常時,怎樣用已有資料排查

聊完了所有的加分項和防風控雷區,萬一哪天你精心寫了一篇乾貨,發出去一看只有幾十次觀看,心裏直犯嘀咕:“我到底是沒進召回池、打分輸給了同行、撞上了已讀過濾,還是不小心踩雷被貼了安全限流標籤?” 光盯着那幾十次觀看數猜來猜去毫無意義,因爲不同原因需要看完全不同的證據。5 59 20 72

好消息是:在這次公開的算法倉庫 README.md 和 under-the-hood 目錄下,X 官方直接公開了一個專門給創作者查自己“到底有沒有被貼安全與限流標籤”的官方透明度後臺——Under the Hood(點擊直接訪問:x.com/i/jf/under_the_hood)! 這是官方目前正在試行(Pilot)的賬號透視鏡工具,登錄你的 X 賬號後打開這個鏈接,就能直接查出在報告統計期內,你的**賬號(Account)和帖子(Posts)**到底有沒有被系統貼上影響可見性的限制標籤!72

30.1 報告期間與可用性

在使用這個官方自查後臺時,先注意代碼(underTheHoodReport.User.strato)裏寫的兩個規則:72 82

  1. 先看右上角的統計月份(Period):頁面默認展示的是上個月的月度彙總統計(如果上個月的數據還沒生成完畢,服務會自動退回展示更前一期的數據)。所以打開頁面後,第一件事是看清 Period 寫的是哪個月份以及生成時間——千萬別拿一份 9 月份的舊彙總報告,去解釋你今天早上剛發的帖子爲什麼沒流量!
  2. 如果打不開或提示暫無報告,別慌,不代表你被封號了! 源碼裏寫得很清楚:這個工具目前處於試行階段(受服務開關控制),並且設置了明確的報告生成資格門檻——通常要求你的賬號註冊賬齡滿 1 年左右,並且在統計的那個月裏至少發佈了 10 條符合統計條件的合格帖子,系統纔會爲你生成月度報告。如果你是剛註冊兩個月的新號,或者上個月總共只發了 3 條帖子,看不到報告僅僅是因爲沒達到生成報表的統計門檻,跟你的賬號有沒有推薦資格毫無關係。82

30.2 分清帖子標籤和賬號標籤

打開 Under the Hood 報告後,你會看到上下兩塊核心統計數據——Post labels(單帖級標籤)和Account labels(賬號級標籤),它們的計量單位在源碼(report.tsx)裏是完全不同的:72

報告項目裏面的數字和百分比到底代表什麼
Post labels(帖子標籤)在該統計月份內,你發的所有合格帖子裏有多少篇帖子被貼上了該標籤,以及佔當月總髮帖數的百分比
Account labels(賬號標籤)在該統計月份內,你的整個賬號一共有多少天揹着該標籤,以及佔當月總天數的百分比

我們拿兩個具體數字教你怎麼讀這張表:

  • 假如你在 Post labels 裏看到某標籤顯示“3 篇(7.5%)”:這代表你上個月發的 40 篇帖子裏,有 3 篇帖子曾被貼上這個標(佔發帖數的 7.5%),絕不是說你整個賬號被扣掉了 7.5% 的流量!
  • 假如你在 Account labels 裏看到某標籤顯示“5 天(16.1%)”:這代表在 31 天裏,你的賬號有 5 天時間揹着這個賬號級標籤,但也不代表那 5 天裏你在全站所有頁面都人間蒸發了。72

具體怎麼看它對流量的真實影響?請直接看報告裏緊挨着標籤名稱旁邊的兩欄官方解釋:What it means(這個標籤代表什麼原因) 和 Effect on visibility(對可見性的具體影響)! 在 underTheHoodLabels.strato 源碼裏,官方把每個標籤的具體處置寫得一清二楚:有的標籤寫的是**“不向未關注你的非粉絲推薦該帖/該賬號”,有的寫的是“附加內容警告遮罩”,有的寫的是“特定國家或地區受限”**。 這就再次解釋了我們前面說的:千萬別找一個已經關注你的粉絲朋友問“你能不能看到我的帖子”來測試自己有沒有被限流! 因爲絕大多數限流標籤只攔截“向非粉絲陌生人推薦(HomeRecommendations)”,你的老粉絲在關注流或點進你主頁當然看得見你!只有對照報告裏的 Effect on visibility,才能準確知道到底攔了哪扇門。72

30.3 報告沒有列出標籤,也不能解釋每次排名

如果查完報告發現了標籤,就把報告月份、標籤英文原名和官方說明截圖保存下來,回想一下那幾天是不是換過失效的置頂外鏈、是不是連發過帶敏感圖的帖子、或者在評論區刷過重複內容;如果確屬誤判且界面提供了申訴入口,就按流程申訴。 反過來,如果你的報告裏乾乾淨淨、顯示沒有任何受限標籤(0%),那就說明你的賬號和帖子在安全合規層面是完全健康的(注:代碼標註該報告爲 best effort 盡力而爲統計,且月報存在時間滯後)。既然安全層面沒被貼標攔截,那某篇帖子觀看量低,問題就出在候選召回匹配度、首圖與前 4,000 字的信息提取、或者打分排序時的停留與互動預測上——這時候我們就可以放心大膽地回到內容本身做單變量優化了!82

30.4 比較下一篇時,只先改一個主要因素

排除了安全標籤嫌疑後,怎麼一步步把賬號的自然推薦流量拉起來? 先對照我們前面講過的代碼鐵律,給手頭的草稿做一次“五步體檢”:

  1. 標題和前兩百字有沒有直接寫出具體的研究對象和解決的任務(別寫空洞的文藝口號)?
  2. **第 1 張圖(首圖)**放的是不是核心結果對比表(別把搞笑漫畫或純文字海報放第 1 張,把乾貨藏在第 4 張)?
  3. 開頭第一段答應給讀者的材料,在正文裏有沒有立刻兌現(別搞注水鋪墊騙 10 秒停留)?
  4. 如果是發萬字 Article,前 200 字標題有沒有塞滿關鍵詞?發完有沒有單獨配一條掛着普通結果圖的導讀長 Post?
  5. 如果是補充重大更正或翻新老帖,有沒有單獨發新原創帖或用 Quote 引用(別隻回覆在已經 1 萬人看過的舊帖底下,也別對老帖只點普通 Repost)?

在做優化實驗時,最忌諱的就是“一上來同時改掉題材、格式、配圖風格、發帖時間和受衆方向”——五個變量一起改,就算下一篇閱讀量漲了 3 倍,你也根本不知道到底是哪一招起了作用! 每次只改 1 個核心變量:比如這週同樣發兩篇難度和受衆相近的 AI 工具測評,只把第 1 張圖從“標題大字報”改成“核心結果對比表”,保持發佈時段和推廣動作完全一致,直接用賬號自帶的後臺分析數據(Analytics)做對比記錄(千萬別自己瞎編一套“點贊×0.5+轉發×1”的民間積分公式去算總分):59

建議記錄的字段具體怎麼用來復盤
帖子鏈接、具體選題、發佈格式(長 Post/Article/Thread)、發佈時間、是否 Quote、外鏈位置用來把任務相近的帖子歸到同一組對比,避免拿“突發喫瓜帖”去和“硬核代碼教程”硬比總瀏覽量
發佈後滿 24 小時、滿 48 小時的後臺可見數據鎖死統一的觀察時間窗口(同一篇帖子的 24h 和 48h 是前後追蹤記錄,不能當成兩篇獨立樣本)
後臺實際提供的分享、回覆、主頁點擊、新增關注、收藏等細分指標嚴格按後臺字段定義記錄(拿不到的內部停留秒數直接留空,千萬別填成 0)
帶來的有效私信諮詢、資料下載點擊或實際業務轉化有些專業乾貨雖然總曝光平平,但吸引來的全是精準客戶和鐵粉關注(權重 4),比泛流量更有價值
同期是否蹭上行業熱點、是否修改過稿件、以及 Under the Hood 已知標籤記錄記錄外部干擾因素,避免把行業大熱點帶來的自然暴漲錯誤歸功於某次排版微調

對比多篇帖子時,多看中位數和整體分佈,別被某一篇偶然被大 V 轉發的爆款拉偏了均值。如果你剛開始建立自己的發佈節奏,可以試試這套穩紮穩打的**“四周實戰迭代法”**:

  • 第一週(打地基):用前文的方法改好具體清晰的個人簡介(Bio),檢查並換上一篇最硬核、無死鏈的代表作當置頂帖,統計過去十篇帖子的各項中位數作爲你的基線(Baseline);
  • 第二週(穩產能):在保證乾貨質量不注水的前提下,按你自己能長期堅持的節奏(比如每天 1 篇,如果精力不夠寧可改成每週 3 到 5 篇高質量原創,也別硬湊水貼)穩定輸出;
  • 第三週(單變量對照):固定題材難度,只挑 1 個核心動作做前後對比(比如專門對比“首圖放結果對比表 vs 首圖放標題封面”,或者對比“長 Post vs Article+帶圖導讀”);
  • 第四周(汰弱留強):回頭盤點這一個月裏,哪類選題、哪種首圖排版真正給你帶來了最高的收藏數、複製鏈接分享和主頁關注轉化,把它沉澱成你賬號的專屬標準模板!

31 把這些發現用在下一篇工具測試裏

爲了讓你看清上面所有代碼規則合在一起是怎麼指導一篇具體文章從 0 到 1 誕生的,我們最後來做一次完整的實戰沙盤推演——假設你明天準備發一篇**《用同一批真實中文發票,橫評 A、B 兩款 OCR 識別工具》**(A、B 爲代稱,下面演示的是怎麼根據算法代碼編排文章結構,不預設哪款工具贏):

31.1 讀者準備拿這篇做什麼

動筆寫第一行字之前,先想清楚刷到你帖子的目標讀者(比如財務主管或企業開發工程師)到底要拿你這篇帖子幹嘛? 他們要麼正在爲公司選型採購 OCR 接口,要麼已經在用其中一款、正頭疼哪些字段老出錯需要安排人工複覈。 所以,你的開頭第一段(直接決定前 4,000 字符語義向量與讀者前 3 秒會不會划走觸發 -0.02 懲罰),絕對不能寫成“近年來 AI 視覺大模型發展迅猛,今天我們來聊聊 OCR 識別到底有多強”這種廢話,而是直接開門見山切入具體字段與痛點:

開頭第一段實戰草稿: “這次測試只盯死中文增值稅發票最容易出事的三個字段:開票日期、稅額、買方稅號。

我拿同一批帶摺痕和印章遮擋的真實發票原圖,對工具 A 和工具 B 做了盲測對比,原始報錯案例和參數設置都在下面。如果你正準備把 OCR 識別結果直接接入財務自動入賬系統,建議先看哪幾個字段目前還必須保留人工複覈。”

緊接着第二段,立刻把測試樣本張數、兩款工具的具體版本號、測試日期、發票圖片分辨率和判定對錯的標準列出來(沒測過的發票類型明確說沒測,絕不瞎吹普適結論)。 然後看配圖與格式選擇:

  • 第 1 張圖(首圖,會被 V8.2 的 _collect_post_media 第一個抓走並返回):直接放一張最直觀的**“帶印章遮擋發票原圖 + A/B 兩款工具稅額識別結果一正一錯同框對比卡”**!如果這個錯誤只在“紅章蓋住金額數字”時發生,就直接把“紅章遮擋場景”六個大字標在首圖上,讓只看第一張圖的讀者和 AI 一眼就能抓準核心發現;後面第 2、3 張圖再依次放完整統計表和邊界反例。
  • 格式選擇:如果這次測試只講“紅章遮擋稅額報錯”這一個具體發現,直接發成一條 長 Post 即可;如果是一份涵蓋 5 種發票類型、30 頁數據的深度報告,就發佈爲 Article(前 200 字標題寫滿核心詞),並單獨發一條掛着上面那張首圖的導讀長 Post(或者 3 條以內的精煉摘要串文 Thread:第 1 條給核心結論、第 2 條給對比表、第 3 條給適用邊界與全文入口,確保每一條去掉上下文都能獨立看懂,不怕 convo_marshaller.rs 的 1、9、10 截斷)。18

寫到文章中段時,回頭掃一眼:有沒有哪一段是在車軲轆話重複標題、或者寫“重點在後面大家別走開”?發現這種注水句子立刻刪掉,換成具體的反例數據(比如“當圖片壓縮到 72 DPI 以下時,工具 B 的稅號識別錯誤率從 2% 飆升到了 18%”)。讓讀者在 CREAD 的每一個時間刻度上都有實打實的乾貨可讀。

31.2 讓完整資料找得到、查得回去

如果你在文末提供了一份可供讀者下載復現的測試腳本或 Excel 完整對照表:

  1. 在表格和正文裏清晰標明文件名、測試日期和字段說明,給讀者一個點下**“收藏(Bookmark,進入 SimClusters 種子與沉浸式訓練正例)”和“複製鏈接(Share via copy link,係數 20,乘的是預測概率)發給同事”**的充分理由;
  2. 附上外部下載鏈接前,親手點開檢查一遍跳轉鏈,確認直接落到 GitHub 或正規網盤頁面、沒有任何失效或低質中轉域名(如果需要註冊或付費才能下載,提前在正文裏坦誠說明);如果這篇測試後來成了你的代表作、準備設爲個人主頁置頂(Pin),更要定期檢查裏面的鏈接有沒有過期變質,嚴防觸發 PinnedLowQualityOrBadUrl.bot 的賬號標籤(這條路寫進去的標籤帶 7 天有效期);
  3. 挑你的目標讀者(財務與技術人員)真正刷手機的活躍時段點擊發布——冷啓動的探索機會只在發出後前 2 小時、內部首頁曝光(view_count_on_home)還不到 200 次時存在,時段選對才用得上。

31.3 發佈後,按問題補充和更正

帖子發出去之後:

  • 如果有同行在評論區問:“你們測試那張模糊發票時,有沒有開啓工具 A 的自動傾斜矯正參數?” —— 趕緊去核對測試日誌,如果只是局部細節補充,直接在他的評論底下認真回覆,把討論區做成內行人的高質量交流場;
  • 如果核對後倒吸一口涼氣:“哎呀!測試時真的把工具 A 的傾斜矯正開關忘打開了,打開重測後工具 A 的錯誤率下降了一大半,原帖的核心結論反過來了!” —— 千萬記住 previously_seen_posts_filter.rs 的父帖已讀過濾規則!不要只把這麼重大的更正偷偷摸摸回在舊帖評論區裏,而是立刻在舊帖留下更正指路,同時單獨發一條全新的原創帖(或用 Quote 引用舊帖)把補測後的修正結論端出來!
  • 哪怕你今天上午已經發過兩篇帖子了,只要下午這第三篇是實打實的補測新發現,也根本不用管什麼“一天最多發兩三篇、隔四小時恢復權重”的假口訣,隨時改完隨時發!

這條我對自己執行得比建議別人時嚴。我的規矩是 X 上已發佈的帖子不原地編輯,改過的帖子曝光數據會歸零;真發現錯了,寧可另發一篇,講清改了哪裏。2026 年 10 月底我真幹過一次:一篇帖子首發時把來源鏈接放進了正文,違反我自己定的規矩,我刪掉重發了一遍,沒有點編輯。博客不一樣,博客是母本,錯了就直接改,改完在 X 上發一篇更正帖,指向改好的版本。

最後,把下一篇的首圖和開頭單獨拿出來看看,我給自己定的標準就一條:一個不認識你、也不會點開整串的讀者,只看這兩樣,就能知道你發現了什麼、這件事爲什麼與他有關。達不到,就改完再發。

這篇手冊我會跟着 X 的公開代碼更新繼續修訂。我會一直跟蹤算法庫的更新,一旦有更新,我會同步更新這份文檔和 skill 庫(https://github.com/alexliyu7352/for-you-skills),你收藏的永遠是最新版。這個博客不追熱點,只放我親手拆過、覈對過的東西,AI、安全、開源三條線都有。覺得這篇對你有用,歡迎訂閱或收藏,下一篇更新你能第一時間看到。

仍待確認的問題(49 項“代碼已證實真相 vs. 線上待查盲區”大白話全解)

很多朋友看技術報告最頭疼的就是:報告最後列了一堆“待確認問題”,裏面全是像天書一樣的縮寫詞(什麼 TTL、CREAD、ld、adapter、OON、HLL),既沒解釋這個詞是什麼意思、有什麼作用、對流量有什麼影響,也沒說清楚到底哪一半是真的、哪一半是瞎吹的。

爲了讓你哪怕單獨跳着看這 49 個問題中的任意一條,都能在 30 秒內徹底看懂前因後果,我把這 49 個核心問題全部重新改寫了一遍。每一條都嚴格按以下四步用大白話講透:

  1. 先說人話(這到底在問什麼、有什麼作用與影響):先把題目裏的工程術語翻譯成大白話,告訴你這個機制是幹嘛的、對你的帖子曝光有什麼實際影響;
  2. 代碼已證實的真相(已知):公開源碼裏已經白紙黑字寫死、100% 跑不掉的規則是什麼;
  3. 代碼還看不見的盲區(待查):哪一部分數據是因爲官方沒公開線上服務器日誌或前端代碼,導致誰也沒法替你打包票的;
  4. 給創作者的實操結論(判斷):搞懂了已知和盲區後,我們平時發帖到底該怎麼做、千萬別信哪句謠言。

01 海外博主常喊的“X 今天(today)又改算法了”,究竟指哪一次更新?

  • 先說人話(這在問什麼、有什麼影響): 平時我們在 X 上經常看到海外大 V 發帖驚呼:“X 今天(today)剛剛更新了算法,大家趕緊改發帖方式!”很多創作者一看就慌了,以爲今天全站規則大洗牌。其實,“算法更新”可能指三種完全不同的事:① 程序員往 GitHub 公開代碼庫裏傳了一份新代碼(Commit);② 官方在說明文檔(README)裏補寫了一條更新公告;③ X 後臺服務器真正把新規則切換給全站用戶使用。搞不清對方說的“今天”指哪件事,就容易被帶節奏瞎改發帖習慣。
  • 代碼已證實的真相(已知): 我們覈對的兩份核心代碼快照,公開上傳(Commit)的精確時間分別是:第一份基準快照 5ed7963 上傳於世界標準時間(UTC)2026-10-28 02:49:03(換算成美國加州洛杉磯時間是 10 月 27 日晚上 19:49:03);第二份最新快照 606b254 上傳於 UTC 時間 2026-10-29 02:57:55(換算成洛杉磯時間是 10 月 28 日晚上 19:57:55)。與此同時,官方在 README.md 更新日誌裏另外標註了 10 月 8 日和 10 月 13 日兩個功能更新日期。11
  • 代碼還看不見的盲區(待查): 發帖喊“today”的那位海外博主當時處在哪個時區、精確在幾點幾分發的帖,以及他口中的“今天更新”到底是指看到了 GitHub 上的代碼提交、看到了補寫的公告,還是指某項內部灰度實驗,外人無法從靜態代碼裏得知。
  • 給創作者的實操結論(判斷): 由於存在時差(UTC 的 10 月 29 日凌晨其實就是美國加州的 10 月 28 日晚上),我們把兩個時間都列出來方便覈對;更重要的一條鐵律是:代碼上傳到 GitHub 的時間,只代表“公開給你看的時間”,絕不等於“全球幾億用戶今天同一秒鐘全都換上了這套新規則”,千萬別看到一句“今天算法變了”就自亂陣腳。

02 代碼庫裏寫的“公開默認權重”,是不是此時此刻每個讀者刷首頁時真正用的配置?

  • 先說人話(這在問什麼、有什麼影響): 我們在正文裏列出了點贊 0.66、回覆 5、複製鏈接 20、連續停留 0.006 等一長串“公開默認參數(Default Params)”。這些參數的作用是在給候選帖子算總分時,決定每一種預測行爲佔多大分量。大家自然會問:代碼文件裏寫的這些默認數字,是不是線上每個讀者刷手機時 100% 正在運行的數字?
  • 代碼已證實的真相(已知): 首先,官方在 README.md 裏明確承諾:他們用自動定時任務(cron)把線上生產環境裏的主要正式默認配置同步到公開代碼庫中(比如 Home Mixer 參數文件第一行就印着同步時間戳 2026-10-27T16:00:37Z),所以這些數字是貨真價實的正式環境基準。其次,在同一個代碼版本里,Home Mixer(負責統籌組裝與冷啓動)和 VM Ranker(負責調用價值模型算分)兩個微服務裏的同名默認參數確實存在細微差異(比如點贊一個是 0.66、一個是 0.5),且代碼裏有遠程調用(RPC)、直接使用緩存分數以及調用失敗時退回本地算分(fallback)的不同分支。12 27
  • 代碼還看不見的盲區(待查): X 線上有一套實時配置中心(Feature Switches / Configuration System),隨時可以把某一部分讀者分進不同的灰度測試桶(A/B Test)裏試用微調過的參數,還會動態切換不同的 AI 模型權重文件(Checkpoint)——這些針對具體用戶的實時實驗開關,在公開代碼庫裏是看不到的。
  • 給創作者的實操結論(判斷): 代碼裏的“公開默認參數”完全可以作爲我們判斷行爲輕重緩急的權威基準參考(比如複製鏈接 20、回覆 5、點贊 0.66,量級差得很明顯;但係數還要乘各自的預測概率,不能只比係數大小就斷定哪種行爲一定更值錢),絕不是程序員隨手亂填的假數字;但同時也要明白線上存在灰度實驗,不要拿計算器去死摳小數點後四位,以爲全球每個讀者的算分公式分毫不差。

03 10 月份“停留時間權重係數上漲 50%”,會讓長文的總分和曝光量也跟着暴漲 50% 嗎?

  • 先說人話(這在問什麼、有什麼影響): 在打分公式裏,有一個叫 ContDwellTimeWeight(連續停留時間權重係數)的參數,它的作用是:AI 預測讀者會在你的帖子上停留閱讀多少秒,就拿那個秒數乘以這個係數,加進帖子的總分裏。10 月中旬,這個係數從 0.004 調高到了 0.006,漲幅正好是 50%。很多博主據此歡呼:“長文的算法總分和曝光量要直接暴漲 50% 了!”這是真的嗎?
  • 代碼已證實的真相(已知): 翻查同一個參數文件 home-mixer/params/param.rs 的修改歷史可以 100% 證實:10 月 9 日 快照裏該係數確實是 0.004,到了 10 月 13 日 快照正式升到了 0.006,這一個單項係數的漲幅千真萬確是 50%!但是在 scoring.rs 的總分公式裏,一篇帖子的總分是由 24 個預測項加在一起算出來的(還要經過分數平移、同作者 0.625 衰減和同池對手比拼)。如果假設 AI 預測讀者看你的帖子 5 秒鐘、其他互動項加權和爲 0.20 分,係數從 0.004 漲到 0.006 只會讓停留項從 0.020 分變成 0.030 分,整篇帖子的原始總分只是從 0.220 變成了 0.230,僅上漲了約 4.5%!15 27 60
  • 代碼還看不見的盲區(待查): 線上真實環境裏,把這個係數調高 50% 之後,全站長帖和短帖的真實曝光量到底各自漲跌了多少百分比,需要看官方內部的線上 A/B 實驗統計報表,而這份運營報表並未公開。
  • 給創作者的實操結論(判斷): 係數上調 50% 是一個明確的利好信號,證明系統更加看重“讀者願不願意停下來把內容讀進去”;但因爲總分是多項求和,單一系數漲 50% 絕不等於總分漲 50%,更不等於曝光量或廣告收益直接漲 50%。寫紮實乾貨吸引真實閱讀是對的,靠開頭寫十行廢話硬拖時間則毫無意義。

04 點贊權重漲到 0.66,是不是創下了 X 有史以來的“全場最高權重”?

  • 先說人話(這在問什麼、有什麼影響): FavoriteWeight(點贊權重係數)管的是“AI 預測讀者會給你點讚的概率”在總分里乘多少倍。10 月份它從 0.5 一路調高到了 0.66。網上立刻有人說:“點贊權重到了歷史最高點,以後又是點贊爲王的時代了!”
  • 代碼已證實的真相(已知): 我們把 10 月份全部 20 個 Home Mixer 參數歷史快照挨個查了一遍,在 10 月這一個月裏,0.66 確實是 FavoriteWeight 出現過的最高值(10/9 爲 0.5 → 10/13 爲 0.6 → 10/14 爲 0.66)。但是,橫向對比同一張表裏的其他正向行爲,點讚的 0.66 依然排在很後面:複製鏈接是 20、互關好友對原創帖回覆是 20、一般回覆是 5、帶評論引用(Quote)是 5、私信分享是 5、關注作者是 4、系統分享是 2、普通轉發是 1!15 27
  • 代碼還看不見的盲區(待查): Twitter / X 過去十幾年所有未公開的歷史代碼版本、內部測試分支裏有沒有給點贊設過更高的數字,沒有全歷史檔案無法查證。
  • 給創作者的實操結論(判斷): 準確的表述是“10 月公開快照中點贊係數的最高值”;千萬別被“歷史最高”四個字忽悠去刷贊,因爲在算法眼裏,一個能讓讀者關注你(4)、寫評論討論(5)或複製鏈接分享給同事(20)的帖子,權重係數依然遠遠甩開單純的點贊(0.66)。

05 “點擊後停留(CLICK_DWELL_TIME)”的 10 秒門檻與 0.4 分權重,在代碼裏是怎麼銜接的?

  • 先說人話(這在問什麼、有什麼影響): 當讀者在首頁點開你的帖子(比如點開長文或點進詳情)並停下來閱讀時,系統裏有一個專門的加分項叫 ContClickDwellTime(點擊後深度停留),它的權重係數是 0.4(普通點擊是 0.3;係數乘的是預測概率,不能換算成頂多少個贊)。大家最關心的是:讀者點開後到底要看滿多少秒纔算達標?達標後是不是立刻給帖子加 0.4 分?
  • 代碼已證實的真相(已知): 在公開代碼庫裏,我們能追通兩頭的鐵證:① 在上游 AI 排序模型的訓練配置(xrecsys.py)和損失函數(loss_recsys.py)裏,有一個叫 CLICK_DWELL_TIME 的二分類預測目標,它的判斷標準是“原始標籤數值是否嚴格大於閾值 10.0”(剛好等於 10 還不算,必須 > 10.0),模型推理時會輸出一個 0 到 1 之間的達標預測概率,並由推理服務(model_runner.py)返回;② 在下游 Home Mixer 的總分融合公式(scoring.rs)裏,程序會讀取候選帖身上的 click_dwell_time 預測字段,乘以 0.4 的權重加進總分。14
  • 代碼還看不見的盲區(待查): 中間有兩小段代碼官方沒有放進公開倉庫:① 上游數據管線在生成 CLICK_DWELL_TIME 的原始標籤時,物理單位到底是不是純秒數、點開 Article 專欄算不算在裏面;② 把模型服務返回的預測值賦值給 Home Mixer 裏 click_dwell_time 字段的那段中間轉換代碼(Adapter)沒有公開。98
  • 給創作者的實操結論(判斷): 首先,乘以 0.4 的依然是 AI 事前預測這位讀者“點開後停留跨過 10.0 門檻的概率”,而不是事後每看滿 10 秒記賬加 0.4 分;其次,雖然中間轉換層未開源,但 0.4 的高權重明明白白告訴我們——“騙讀者點開卻讓他 2 秒鐘失望退出”是拿不到這筆大分的,點開後有真材實料讓他看進去纔是關鍵。

06 10 月 8 日上線的 CREAD 停留預測黑科技,到底是怎麼算閱讀時間的?能讓長文流量翻倍嗎?

  • 先說人話(這在問什麼、有什麼影響): 以前算法預測讀者看多久可能比較粗糙;10 月 8 日官方宣佈上線了 CREAD 模型來改進停留時間預測。它的作用是:精準估算這位讀者會在你的帖子上停留多少秒(比如 4.1 秒還是 45 秒),然後把這個預測秒數拿去乘 0.006 的連續停留權重。很多人問:這套新模型是怎麼算秒數的?它上線後是不是意味着寫得越長的文章就穩贏短帖?
  • 代碼已證實的真相(已知): 從 xrecsys.py、loss_recsys.py 和 recsys_model.py 源碼中,我們完整還原了 CREAD 的計算過程:它把停留時間按“前面密、後面疏”的對數間隔切成了 30 道時間刻度門檻(普通信息流從 2 秒到 120 秒,畫廊沉浸流從 2 秒到 240 秒)。AI 先分別預測讀者停留時間跨過這 30 道門檻各自的百分比概率(sigmoid),然後再拿每一格的過關概率乘以相鄰門檻的秒數寬度(deltas)加總,還原出一個具體的預測停留秒數(訓練時還加了 Huber 時間重建損失來校準總秒數)。11 13
  • 代碼還看不見的盲區(待查): 官方沒有公開 CREAD 上線前後的內部評測數據集、預測誤差具體下降了百分之幾,也沒有公開全站長帖與短帖因此發生了多少流量轉移的 A/B 測試報告。
  • 給創作者的實操結論(判斷): CREAD 的 30 道刻度設計,說明系統現在能極其細膩地區分“掃一眼 2 秒划走”、“看 10 秒短乾貨”和“讀 90 秒深度長文”的區別。但要注意:AI 預測的是“這位讀者實際願意看幾秒”,而不是“你這篇文章一共寫了多少字”!如果一篇三千字的水文讀者看 3 秒就划走了,CREAD 預測出來的照樣是兩三秒的低分;只有每一段都有高密度乾貨,CREAD 預測出來的停留秒數纔會高。

07 10 月 13 日新增的 ld 深度閱讀召回分支,是不是要求讀者必須 100% 滑到文章最後一行纔算數?

  • 先說人話(這在問什麼、有什麼影響): 前面說過,推薦分兩步:第一步是採購員去倉庫撈候選帖(召回),第二步是裁判算分排座次(排序)。10 月 13 日,X 在第一步“雙塔召回模型”裏專門新加了一個叫 ld(Long Dwell,深度閱讀停留) 的分支,權重設爲 0.75。它的作用是:哪怕一篇深度乾貨帖點贊評論不多,只要它是那種“讀者刷到後會靜下心來讀進去”的好文章,採購員在第一步就會優先把它撈進更多人的候選池裏! 網上有人據此傳言:“必須讓讀者 100% 滑到文章最末尾,纔會觸發這個 ld 獎勵!”
  • 代碼已證實的真相(已知): 在 xrecsys_two_tower.py 和 recsys_two_tower_model.py 裏,ld 分支用來訓練模型的正例信號(ld_positive_actions)明確指定爲一個叫 CLIENT_TWEET_RECAP_DWELLED 的客戶端事件;這個分支在訓練和實時推理召回時都有完整的代碼路徑。官方 README 在介紹這次更新時,用的通俗描述是“找出人們會讀到底的帖子”。11 14
  • 代碼還看不見的盲區(待查): CLIENT_TWEET_RECAP_DWELLED 這個事件是由你手機上的 X App(客戶端前端)上報給服務器的,而手機 App 的前端源碼並未開源。因此,手機端到底是看“停留滿多少秒”、還是看“屏幕滾動到了第幾段”才發送這個事件標記,在後端算法庫裏是看不到的。
  • 給創作者的實操結論(判斷): 不需要去搞什麼“在文章最底部藏一個暗號逼讀者滑到底”的歪門邪道。只要你的文章開頭直接切中痛點、正文表格和案例讓人願意停下來細讀,就會自然觸發這個閱讀停留正例,在第一步召回和第二步排序裏各起一次作用。

08 我看到自己帖子的瀏覽量(Views)剛跳到 200,是不是代表小賬號冷啓動扶持已經結束了?

  • 先說人話(這在問什麼、有什麼影響): 對於粉絲不超過 5 萬的小賬號,系統有一個“前 2 小時、200 次曝光以內”的冷啓動扶持機制(author_cold_start.rs),能把你的新帖直接保送到讀者候選池的第 16 名!很多小號創作者發完帖就死死盯着帖子底下的公開瀏覽量(Views),一看數字跳到了 200,就嘆氣說:“完了,200 次冷啓動額度用光了!”
  • 代碼已證實的真相(已知): 在 author_cold_start.rs 和數據拉取器 engagement_counts_hydrator.rs 裏,代碼檢查的那個 < 200 的字段名叫 view_count_on_home(純 For You 首頁推薦曝光次數),而你在帖子下方看到的公開總瀏覽量對應的是另一個字段 view_count!而且拉取這兩個計數的服務設有一個 60 秒有效期(TTL = 60s)的緩存。35
  • 代碼還看不見的盲區(待查): 對於你的某一篇具體帖子,前臺顯示的 view_count(總瀏覽量)裏面到底混進了多少次個人主頁點擊、搜索查看、外部鏈接點擊和作者自己刷新,只有後臺內部數據庫有逐筆明細。
  • 給創作者的實操結論(判斷): 前臺總瀏覽量(Views)到了 200,不等於後臺真正的首頁推薦曝光(view_count_on_home)也到了 200——後者是多少,外人看不到,兩者不是一個數。 再加上還有 60 秒的計數緩存延遲,所以發帖後前 2 個小時內千萬別盯着前臺的 200 數字焦慮,更別以爲一到 200 就立刻失寵而刪帖重發。

09 當好幾篇小賬號新帖都符合冷啓動條件時,系統到底挑哪一篇保送到第 16 名?點贊率最高的一定贏嗎?

  • 先說人話(這在問什麼、有什麼影響): 當一位讀者下拉刷新首頁時,他的臨時籃子裏可能同時有 10 篇來自不同小作者的新帖,全都符合“粉絲 ≤ 5 萬、發佈 ≤ 2 小時、首頁曝光 < 200 次”的冷啓動條件。但這臺“直升電梯”每次刷新最多隻能保送 1 篇帖子上第 16 名!很多人以爲:“誰的點贊率最高,系統就一定挑誰上去,所以我趕緊找羣友刷幾個贊就能穩贏!”
  • 代碼已證實的真相(已知): 打開 author_cold_start.rs 的源碼,挑選過程其實是分兩輪走的:① 第一輪(搖號初選 2 篇):系統讀取每篇新帖目前的點贊數(fav_count)和首頁曝光數(view_count_on_home),以 1.5% 的默認首頁點贊率(alpha0=0.75, beta0=49.25)爲基準跑一次 Thompson Sampling(Beta 分佈隨機概率抽樣),抽出點數最高的 前 2 篇(默認 top_k = 2);② 第二輪(按讀者興趣二選一):在這留下的 2 篇新帖裏,系統不再看誰的點贊率高,而是直接對比**“當前正在刷首頁的這位讀者對哪一篇的模型預測分(ranking score)更高”**,挑預測分最高的那 1 篇保送上第 16 名!35 36 60
  • 代碼還看不見的盲區(待查): 線上某位讀者刷新時籃子裏到底有幾篇合格新帖、當次隨機數搖出了多少點、以及模型給這位讀者算出的實時分數,屬於單次請求的動態運行數據。
  • 給創作者的實操結論(判斷): 這裏有一個直接能戳破“刷贊必勝論”的代碼反例:如果某次籃子裏本來就只有 2 篇合格新帖,第一輪 top_k = 2 會把兩篇全留下來,到了第二輪100% 選的是對當前讀者預測分更高的那篇,而不是表面點贊率更高的那篇!所以別去搞微信羣互贊(羣友從鏈接點進來既不算首頁曝光,畫像也跟陌生讀者不匹配),把內容寫得精準切中目標受衆痛點,才能在第二輪二選一里真正勝出。

10 10 月 22 日啓用的 FairShare 比例分配,是不是保證新帖從此再也不會在打分前被裁掉了?

  • 先說人話(這在問什麼、有什麼影響): 每次讀者刷首頁,各個進貨渠道抓進臨時籃子的帖子可能有 3,000 多篇,但負責精細打分的 AI 大模型每次最多隻看 2,800 篇。以前按列表順序一刀切,排在隊尾的“冷啓動新帖渠道”經常還沒見着裁判就被砍光了。10 月 22 日,系統默認開啓了 FairShareRankingFilter(公平份額初篩過濾器),改成了按各個渠道送貨數量的比例來分配這 2,800 個名額。網上有人把這解讀爲:“新帖從此有免死金牌,100% 不會被提前截斷了!”
  • 代碼已證實的真相(已知): 從 fair_share_ranking_filter.rs 和 param.rs 的提交歷史可知:該功能在 10/21(7f2ca2b)加入、默認關閉,在 10/22(989fb91)將公開默認改爲開啓(true),預算爲 2800。它按候選帖的來源渠道(served_type,其中冷啓動渠道 ForYouPhoenixRetrievalCold 和零贊渠道 ZeroFav 都是獨立分組)按比例加最大余數法分配 2,800 個名額。但是,在每個渠道小組內部,程序依然只是簡單保留原有列表順序的前 N 篇,排在該小組末尾的帖子照樣會被裁掉!16 61
  • 代碼還看不見的盲區(待查): 線上真實請求中各個渠道每次送來多少篇帖子、組內原本按什麼順序排列,以及開啓 FairShare 前後全站小號新帖的整體曝光上漲了多少百分比,需要內部 A/B 測試日誌才能得知。
  • 給創作者的實操結論(判斷): 就像我們在正文算過的例子(3,000 篇進 2,800 篇,冷啓動渠道從原來剩 400 篇提高到保住 560 篇,但仍有 40 篇被裁),FairShare 實打實地大幅提高了小作者新帖“進打分房間見裁判”的公平機會,但不能神化成“每一篇新帖都100%不被淘汰或必得保底流量”。

11 “互關好友回覆預測權重高達 20”,是不是說明我瘋狂找人互關(Follow back)就能讓流量起飛?

  • 先說人話(這在問什麼、有什麼影響): 在打分表裏,普通讀者給你留言回覆的預測權重是 5;但如果刷到你帖子的這位讀者和你互相關注(Mutual Follow),且你發的是原創帖,系統就會在 5 的基礎上額外加上 15 分互關加成,變成 20!很多人一看:“翻了 4 倍!那我趕緊去互關大廳見人就互關,湊幾千個互關好友,流量豈不是翻 4 倍?”
  • 代碼已證實的真相(已知): 在 xai-value-model/inputs.rs 和 weights.rs 裏,拿到這 +15 分加成的條件寫得極其嚴格:必須同時滿足 !self.is_reply && !self.is_retweet && self.is_mutual_follow_author(即:① 候選帖本身不能是回覆貼;② 不能是普通轉發;③ 當前刷首頁的讀者與作者雙向互關)。而且它只給“預測這位互關讀者會留言回覆的概率”加權重,點贊、轉發、停留(互關停留加成爲 0)等其他項一分錢都不多加!27
  • 代碼還看不見的盲區(待查): 如果一個賬號到處亂加毫無共同興趣的互關粉,到底會把上游模型的作者受衆畫像帶偏到什麼程度,沒有公開的受控實驗數據。
  • 給創作者的實操結論(判斷): 千萬別去搞無腦互關羣!因爲 20 乘的是**“AI 預測這位互關好友看到你這篇帖子後會寫評論的概率”**——如果你互關了三千個根本看不懂你專業內容的殭屍號或無關賬號,AI 預測他們回覆你乾貨帖的概率接近於 0,20 × 0 還是 0!更何況如果你跑去大 V 底下搶沙發留言,你發的那條評論本身是 is_reply = true,當場失去資格。真正有用的做法,是隻和同領域的真實創作者、核心讀者互關,並在原創帖裏拋出內行人才接得上話的專業問題。

12 10 月 29 日最新代碼里加的“視頻輪播停留公式”,是不是已經開始給所有視頻發流量紅利了?

  • 先說人話(這在問什麼、有什麼影響): 在 10 月 29 日(606b254)的最新代碼提交裏,有人發現視頻輪播欄(Video Carousel)的算分文件 video_carousel.rs 裏新加了一行公式:把“視頻被打開的概率”乘上“沉浸式觀看停留時長”,再乘一個新權重係數。於是網上馬上有人發快訊說:“10 月 29 日起,視頻只要觀看時長久就能拿到全新的輪播加分!”
  • 代碼已證實的真相(已知): 公式確實寫進了 video_carousel.rs 裏;但只要同時打開配套的參數文件 home-mixer/params/param.rs(#L1191-L1269)就會看到:這個新增乘項的公開默認權重係數 VideoCarouselOpenTimesImmersiveDwellWeight 寫的是 0.0(乘 0 等於啥也沒加),而且整個視頻輪播欄的總開關 EnableVideoCarousel 默認也是 false(關閉)! 同次提交新增的 immersive_page_rl_cread 訓練配置也只是把配置文件放進了倉庫。17
  • 代碼還看不見的盲區(待查): 線上有沒有拿出 1% 或 5% 的小流量測試桶把這個開關設爲 true 並填入非零係數做實驗,以及實驗效果如何,在靜態代碼裏是看不到的。
  • 給創作者的實操結論(判斷): 這是典型的“兵馬未動,代碼先行”——工程師先把公式代碼推上線、默認開關設爲關閉或 0,等待後續灰度實驗。看代碼一定要同時看公式和參數開關,絕不能一看到新公式名字就宣稱“全站視頻今天已經拿到新優待了”。

13 雙塔召回裏的 CLIENT_TWEET_RECAP_DWELLED 事件,在模型訓練時是怎麼被使用的?

  • 先說人話(這在問什麼、有什麼影響): 前面第 07 題提到了 10 月 13 日新增的 ld(深度閱讀)召回分支。有些喜歡鑽研技術的讀者會問:在雙塔召回大模型的訓練代碼裏,模型到底是自己去計算讀者讀了多少字、滑到了百分之幾,還是直接讀取現成的標記?
  • 代碼已證實的真相(已知): 打開 phoenix/xrex/models/recsys_two_tower_model.py(#L621-L647 與 #L2711-L2739)可以看到:模型在訓練時,根本沒有在模型代碼裏去算字數或滑動百分比,而是直接去讀訓練數據表裏現成的動作標記——只要某次曝光記錄裏帶有 CLIENT_TWEET_RECAP_DWELLED 這個動作標記,就把它當成 ld 分支的正樣本(Positive Action)來計算訓練損失。33
  • 代碼還看不見的盲區(待查): 上游客戶端和日誌管線在什麼精確條件下才會給一條曝光記錄打上 CLIENT_TWEET_RECAP_DWELLED 標記(怎麼結合可見面積、字數、展開動作和秒數),這塊上游規則不在公開倉庫內。
  • 給創作者的實操結論(判斷): 明確知道“模型認的是停留閱讀正例標記”,我們寫文章時就專注於讓讀者停下來把乾貨讀進去,而不必輕信任何“必須湊夠多少字”或“必須逼讀者滑到最後一行”的民間偏方。

14 新增的 ld 閱讀召回分支是不是“小賬號專屬福利”?代碼裏的 HOME_COLD 又是什麼意思?

  • 先說人話(這在問什麼、有什麼影響): 網上有人看到雙塔召回配置裏有一個叫 HOME_COLD(冷池)的數據集,又看到官方說新加了 ld 閱讀召回分支,就把這兩件事拼在一起造了個謠:“10 月份的閱讀召回升級只對小粉絲賬號(冷賬號)有效,大號享受不到!”
  • 代碼已證實的真相(已知): 第一,在 10/13(e1a0375)公開的具名配置(combined 與 home-only)裏,ld 分支同時覆蓋了 HOME、HOME_COLD、HOME_HOT 三大數據集,且代碼裏沒有任何檢查“作者粉絲數少於多少才啓用 ld”的條件;第二,打開 phoenix/xrex/data/cold_pool_filter.py 源碼一看就明白:HOME_COLD(冷帖子池)篩選時檢查的是“單篇帖子自己的點贊數(fav_count)、觀看數(view_count)和發佈新鮮度”,根本不是查“作者有多少粉絲”!33 34
  • 代碼還看不見的盲區(待查): 線上各個集羣加載哪份具名配置(因爲基礎通用模型類裏也保留了 w_ld = 0.0 的默認選項)、何時全量切換,未公開線上部署表。
  • 給創作者的實操結論(判斷): 不管是幾百粉的小號,還是幾十萬粉的大號,剛發出來還沒攢夠贊和觀看的新帖子都會進 HOME_COLD;具名配置裏 ld 不挑賬號大小,但線上每組讀者實際加載哪份配置、用不用 ld,公開代碼定不了,不能說全員都已經享受到了。千萬別把“冷帖子(剛發的新帖)”錯當成“小粉絲賬號”。

15 爲什麼說“攢夠第 32 個贊(32fav)就能解鎖 For You 大流量池”在公開代碼裏缺少關鍵一環?

  • 先說人話(這在問什麼、有什麼影響): 幾乎所有 X 運營教程都會告訴你:“發帖後第 1 個贊進 1fav 初級池,第 32 個贊進 32fav 高級池,一旦滿 32 個贊,For You 首頁就會給你灌一大波陌生人流量!”這個說法到底有幾分真、幾分假?
  • 代碼已證實的真相(已知): 一分爲二看:① 前半截“存進數據桶”是真的:在 phoenixRankAllCandidateProcessor.strato 裏,當一條合格普通帖收到的點贊數 >= 32 時,程序確實會生成一條 indexName = "32fav" 的索引事件,並且在存儲層設有 24 小時窗口(32fav_1day);② 但後半截“誰來讀這個桶”卻出了意外:當我們去查雙塔召回的數據集定義 retrieval_dataset.py 時,發現負責普通 For You 首頁推薦的三大主力數據集——HOME、HOME_COLD、HOME_HOT——全都在讀 1fav_1day.parquet(1 贊庫)!38 34
  • 代碼還看不見的盲區(待查): 在整棵公開的 For You 代碼樹裏,除了一條專門針對 14–30 天老視頻的 IMMERSIVE32FavVideo14To30Day(讀 32fav_video_14to30day.parquet)之外,找不到任何一個普通圖文首頁的召回服務在讀取 32fav_1day 這個數據桶!(不知道是線上某個未開源的內部服務在讀,還是目前公開配置壓根沒啓用它。)
  • 給創作者的實操結論(判斷): 拿到第 1 個贊進入 1fav_1day 確實是進入普通首頁主力召回庫的關鍵一步;但對於普通圖文帖來說,千萬別迷信“湊滿 32 個贊就能自動打開新世界大門”,更沒必要爲了湊夠 32 個贊到處找人互贊——因爲公開代碼裏連誰去讀普通帖的 32fav 都沒見到影兒。

16 爲什麼前臺剛跳出第 1 個贊或第 32 個贊時,後臺索引庫未必立刻同步更新?

  • 先說人話(這在問什麼、有什麼影響): 有些創作者發完帖後死死盯着點贊數,覺得只要有人點下第 1 個贊或第 32 個讚的那一秒鐘,後臺的 1fav 或 32fav 索引庫就會在同一秒鐘立刻刷新,馬上開始推流。
  • 代碼已證實的真相(已知): 在點贊事件處理器 favoriteEventProcessor.strato 和 eventProcessing.strato 裏,寫着好幾道節流閥和邊界條件:① 1 分鐘節流閥:如果這篇帖子已有更新緩存,距離上一次索引更新必須**滿 1 分鐘(>= 1 分鐘)**才允許送出下一次更新!比如你在第 16 個贊時剛更新過索引,才過了 30 秒就衝到了 32 個贊,這第 32 個贊因爲沒滿 1 分鐘會被直接攔下不更新!② 48/49 小時壽命線:距首次更新須 <= 48 小時 且帖子年齡 < 49 小時;③ 讀寫不同步競態:在 build1FavIndex 裏甚至專門記了一筆 1fav_uec_count_race 日誌——當點贊事件傳過來了,但去數據庫重讀計數卻還是 0 時,記下競態日誌後仍送出 1fav 事件。37 38
  • 代碼還看不見的盲區(待查): 你發的某一篇具體帖子在線上遭遇了多少毫秒的跨服務同步延遲、哪一次點贊事件剛好撞上了 1 分鐘節流閥,沒有後臺服務器日誌是看不到的。
  • 給創作者的實操結論(判斷): 後臺是一個龐大的分佈式系統,有 1 分鐘節流閥、二次冪跳躍門檻(1、2、4、8、16、32、64……)和計數同步延遲。別把手機前臺顯示的點贊數當成毫秒級同步的“推流開關”,專心做好內容和評論區互動即可。

17 帖子成功寫進了 1fav 推薦索引庫之後,是不是就能保證一定被陌生讀者刷到?

  • 先說人話(這在問什麼、有什麼影響): 什麼是“寫進索引庫(Indexing)”?你可以把 X 的推薦系統想像成一個超級大超市:“寫進 1fav 索引庫”,意思就是你的帖子拿到第 1 個贊之後,倉庫管理員把你的帖子擺上了超市的後備貨架。很多教程把這一步吹成了:“只要拿到 1 個贊進了 1fav 庫,系統就保證把你推給成千上萬個陌生人!”那擺上貨架,真的等於已經被顧客買回家(在讀者手機屏幕上曝光)了嗎?
  • 代碼已證實的真相(已知): 在公開源碼裏,從“擺上貨架”到“出現在讀者屏幕上”中間隔着整整五道生死關:① 索引入庫(phoenixRankAllCandidateProcessor.strato 把帖子寫進 1fav);② 數據集加載(retrieval_dataset.py 讀取 1fav_1day.parquet);③ 第一步雙塔個性化召回(phoenix_source.rs 根據當前讀者的閱讀歷史,從幾十萬篇帖子裏挑出跟這位讀者興趣匹配的幾百篇放進他的臨時籃子——如果不匹配,你在貨架上根本不會被拿下來);④ 初篩過濾(砍掉已讀、超 48 小時、拉黑以及超出 FairShare 2,800 名額的候選);⑤ 模型打分與排座次(算 24 項預測概率加權總分,分高的前幾十名才能真正出現在讀者屏幕上)。37 38 34
  • 代碼還看不見的盲區(待查): 你的某一篇具體帖子在貨架上躺着的時候,今天到底被多少個讀者的“召回採購員”挑中過、又在多少個讀者的籃子裏因爲打分不夠高而沉底淘汰,這些內部漏斗數據在創作者後臺是看不到的。
  • 給創作者的實操結論(判斷): “進索引庫”只是拿到了參加比賽的“入場資格證”,絕不是“保底曝光承諾書”! 拿到第 1 個贊讓你上了貨架,但要想被採購員抓走並排在前面,靠的還是清晰的主題語義(前 4,000 字+首圖)和能讓讀者停下來細讀的乾貨質量。

18 讀者點了“收藏(Bookmark)”之後,系統是不是就保證把我的下一篇新帖推給他?

  • 先說人話(這在問什麼、有什麼影響): 我們在正文裏講過,雖然主計分表裏沒有單獨列“收藏加幾分”,但收藏(Bookmark)在後臺有兩個隱藏大用處:一是作爲 SimClusters 相似內容推薦的“興趣種子”,二是作爲沉浸式召回模型的“訓練正例”。有些創作者聽完後就問:“既然收藏會當成種子,那隻要讀者張三今天收藏了我的一篇帖子,是不是代表明天我發新帖子時,系統就 100% 保證把我的新帖推給張三?”
  • 代碼已證實的真相(已知): 打開 explicit_engagement_signals_query_hydrator.rs 和 simclusters_source.rs 可以看到:當張三刷首頁時,系統確實會把張三最近收藏過的最多 15 篇帖子(要求原帖發佈年齡在 90 天以內)拿出來,和張三最近點贊、轉發過的帖子混在一起組成“興趣種子包”,然後去全站尋找發佈在 48 小時以內、且內容相似度達標的候選新帖。同時在 xrecsys_two_tower.py 裏,收藏(CLIENT_TWEET_BOOKMARK)也被列爲 immersive 召回分支的訓練正例。41
  • 代碼還看不見的盲區(待查): 當 SimClusters 拿着張三收藏的你那篇帖子的 ID 去找“相似新帖”時,找回來的名單裏到底有幾篇是你剛發的新帖、有幾篇是同行寫的同類主題好帖,以及它們進籃子後誰的打分更高,取決於當次請求的實時計算結果。
  • 給創作者的實操結論(判斷): 讀者點收藏,本質上是告訴算法**“我對這類具體問題(比如中文發票 OCR 或 AI 會議紀要測評)極感興趣”**。如果你接下來繼續圍繞同一受衆的痛點發高質量新帖,確實極容易被 SimClusters 順着收藏種子撈進他的籃子裏;但這不是一張“只要收藏一次就強制綁定推流作者下一篇”的賣身契,持續輸出同領域的連貫乾貨纔是接住收藏流量的關鍵。

19 爲什麼說“回覆貼(Replies)能不能被未關注你的陌生人刷到”,得看線上開關怎麼設?

  • 先說人話(這在問什麼、有什麼影響): 什麼是“圈外回覆(OON Reply,Out-Of-Network Reply)”?只要你發的是一條回覆貼(包括你去別人帖子底下寫的評論,以及你自己寫串文 Thread 時從第 2 條開始往後的所有分帖),對於還沒有關注你的陌生讀者來說,這條回覆就叫“圈外回覆”。它能不能出現在陌生人的 For You 首頁推薦裏,直接決定了“在大 V 底下神評能不能被路人刷到”以及“串文後半截能不能直接破圈”。
  • 代碼已證實的真相(已知): 在 oon_retweet_reply_filter.rs 和參數文件 param.rs 裏,程序員寫了兩手邏輯:① 在公開默認配置下,控制是否放行圈外回覆的總開關 EnablePhoenixOonReplies 設爲了 false(關閉)——按這個默認值跑,所有未關注作者的回覆貼在這一關都會被直接過濾踢走;② 但程序員在代碼裏同時保留了一扇“條件放行後門”:一旦線上把 EnablePhoenixOonReplies 開關設爲 true,只要這條回覆來自指定的 Phoenix 推薦渠道(ForYouPhoenixRetrieval 或 Cold)、補齊了對話祖先數據,並且在開啓 PhoenixOonRepliesRootOnly 時屬於直接回復主帖的“一級回覆”,就能被放行過關!30
  • 代碼還看不見的盲區(待查): 線上此時此刻針對不同地區、不同實驗分桶的讀者,到底給多少比例的人打開了 EnablePhoenixOonReplies 開關,屬於線上動態配置中心的實時數據。
  • 給創作者的實操結論(判斷): 既然公開默認開關是 false(關閉),我們在做內容規劃時就必須按最穩妥的底線來設計:千萬別把全篇最重要的乾貨結論藏在串文(Thread)的第 5 條或第 10 條裏,一定要放在第 1 條(根帖 Root Post)! 因爲第 1 條根帖是純正的原創帖,不受這個回覆過濾器的限制——它攔的是回覆帖;根帖能不能被陌生人刷到,還要看召回和打分。

20 代碼裏有兩個名字都帶“Evergreen(長青視頻)”的東西,爲什麼一個卡 10 秒時長、另一個沒寫 10 秒檢查?

  • 先說人話(這在問什麼、有什麼影響): 什麼叫“Evergreen(常青/長青視頻庫)”?普通帖子發出來超過 48 小時就很難進常規推薦池了,但對於優質視頻,系統專門建了一個“長青視頻庫”,把發佈 4 到 14 天 的好視頻留着繼續推給讀者!很多做視頻的朋友問:“進這個長青視頻庫,是不是也必須遵守視頻長度嚴格大於 10 秒(10,000 毫秒)的鐵律?”
  • 代碼已證實的真相(已知): 去翻代碼,你會發現有兩個地方都出現了 Evergreen 這個詞,但它們根本不是同一個東西:① 在第一步召回模型讀取的數據集清單(retrieval_dataset.py)裏,有一個大寫枚舉叫 EVERGREEN——看它底層讀取的文件路徑,讀的其實是 video_4to14day.parquet(即 video 核心視頻索引庫的 4 到 14 天窗口)!而要寫進 video 索引庫,在 phoenixRankAllCandidateProcessor.strato 裏必須先通過 hasValidImmersiveVideo 函數,100% 嚴格要求視頻時長 > 10000 毫秒(超過 10 秒)!② 但在同一個文件裏,另外還有兩個小寫名字的索引叫 evergreen_video 和 evergreen_nsfw_video,它們走的是獨立的 EvergreenVideo 事件分支,在那個分支裏只調用了 hasImmersiveVideo(只檢查是不是視頻格式,沒有再寫一遍 > 10000 毫秒 的判斷)。49 50
  • 代碼還看不見的盲區(待查): 上游系統在什麼條件下才會產生第二種 EvergreenVideo 事件(是不是在上游就已經篩過一輪時長了),那段上游生成代碼並未公開。
  • 給創作者的實操結論(判斷): 既然主力召回數據集 EVERGREEN 明明白白讀的是 video_4to14day.parquet(嚴格受 > 10 秒 限制),如果你想讓自己的乾貨視頻享受長達 4 到 14 天的長尾推薦壽命,請務必把視頻剪到 11 秒以上(嚴格大於 10,000 毫秒),並且絕不要在同一條帖子裏混放靜態圖片!

21 視頻召回庫裏的 32fav_video_14to30day(滿 32 讚的 14–30 天老視頻庫),是怎麼生產出來的?

  • 先說人話(這在問什麼、有什麼影響): 我們在查數據文件時發現,沉浸式視頻流居然還有一個保質期更誇張的倉庫——名字叫 IMMERSIVE32FavVideo14To30Day,讀取的文件是 32fav_video_14to30day.parquet。名字看起來是給 14 到 30 天之間的視頻留的庫,還帶着 32fav 的字樣;但它到底按什麼條件生產,公開代碼沒追齊,不能光憑名字就定它的入庫門檻。大家自然好奇:我的視頻要滿足什麼條件才能進這個能活整整一個月的養老金庫?
  • 代碼已證實的真相(已知): 在雙塔召回的數據集配置文件 phoenix/xrex/data/retrieval_dataset.py(#L247-L282)裏,確實白紙黑字定義了 IMMERSIVE32FavVideo14To30Day 並指向 32fav_video_14to30day.parquet 這個文件。34 50
  • 代碼還看不見的盲區(待查): 在當前公開的 phoenix-rankall-strato 代碼樹裏,我們能看到 1fav_video 的各個天數窗口,但還沒有找到直接負責生成 32fav_video_14to30day.parquet 這個特定文件的完整上游構建函數(Producer)。
  • 給創作者的實操結論(判斷): 第一,這證明了優質視頻在 X 上的推薦壽命遠遠不止 48 小時,甚至存在長達 14 到 30 天的長尾召回池;第二,要注意這是專屬視頻數據集,千萬別拿它去給“普通圖文帖滿 32 個贊解鎖新流量池”當證據。

22 代碼裏另一個叫 isMediaEligible 的“視頻大於 10 秒”檢查函數,到底是幹嘛用的?

  • 先說人話(這在問什麼、有什麼影響): 在翻查代碼時,我們除了找到卡住三大視頻索引庫的 hasValidImmersiveVideo(要求視頻 > 10 秒)之外,還在同一個文件裏發現了另一個長得很像的函數叫 isMediaEligible,裏面也寫了“視頻時長必須大於 10,000 毫秒且非成人內容”。這倆函數是什麼關係?
  • 代碼已證實的真相(已知): 在 phoenix-rankall-strato/lib/eventProcessing.strato(#L125-L204)裏,isMediaEligible 明確檢查 VideoInfo.durationMillis > 10000 且媒體不帶 NSFW 標記;隨後另一個函數 getTweetypieResponse 調用了它(組裝成 hasEligibleMedia 並要求作者非 NSFW)。49
  • 代碼還看不見的盲區(待查): 在目前公開的這份代碼樹裏,只能看到 getTweetypieResponse 被定義和導出(Export),但搜遍全庫沒看到有下游文件調用它(可能是給未開源的外部 Strato 列調用的)。
  • 給創作者的實操結論(判斷): 我們已經追通調用鏈的 hasValidImmersiveVideo,門檻寫的是 > 10000 毫秒(嚴格大於 10 秒);這個備用的 isMediaEligible 裏也出現了同樣的 10 秒寫法,但它下游誰在用還沒追到,只能說明代碼裏又出現了一次同樣的門檻,不能拿它給全系統的標準加碼。

23 既然 5 秒鐘的短視頻也能進普通帖子的 1fav 庫,那它的曝光機會和 11 秒以上的視頻一樣多嗎?

  • 先說人話(這在問什麼、有什麼影響): 我們在第 19 章幫大家闢了一個謠:如果你發了一支只有 5 秒鐘的短視頻,它並不是完全進不了推薦庫——它進不了專屬視頻庫(video/1fav_video),但依然能正常進入普通帖子的 1fav 索引庫(被普通首頁 HOME 讀取)。於是有人問:“既然 5 秒視頻也能進普通首頁庫,那我以後發 5 秒視頻和發 11 秒視頻,拿到的曝光機會是不是完全一樣?”
  • 代碼已證實的真相(已知): 從 phoenixRankAllCandidateProcessor.strato 的代碼分支可以確認:5 秒短視頻在普通 Fav 分支裏能順利通過 build1FavIndex(因爲該函數不查視頻時長),進入 1fav_1day.parquet;但緊接着往下走到 build1FavVideoIndex 和 buildVideoIndex 時,就會因爲不滿足 > 10000 毫秒 被直接攔在專屬視頻庫門外。38 34 49 50
  • 代碼還看不見的盲區(待查): 少進了 video 和 1fav_video 這兩個專屬視頻庫(以及對應的 IMMERSIVE2Day、IMMERSIVE4Day、EVERGREEN 4–14 天長尾視頻通道),在線上最終會讓一支視頻少拿百分之多少的曝光,需要線上對照實驗數據。
  • 給創作者的實操結論(判斷): 5 秒視頻是“只有一條腿走路(只能走普通帖的 24/48 小時通道)”,而 11 秒以上的視頻是“兩條腿走路(既能走普通帖通道,又能進專屬沉浸式視頻流和 4–14 天長青視頻庫)”! 所以只要內容撐得住,把乾貨視頻剪到 11 秒以上(且不混排靜態圖片),拿到的推薦入口明顯更寬、壽命也更長。

24 我把超過 48 小時的老帖子直接點“普通轉發(Repost)”,到底能不能讓老帖子重新獲得推薦?

  • 先說人話(這在問什麼、有什麼影響): 因爲普通帖子發出來超過 48 小時就會被年齡過濾器(AgeFilter)攔在候選池外,很多創作者就想:如果我把三天前或上個月寫過的老帖子直接點一下“普通轉發(Repost / Retweet)”,能不能靠這筆新轉發把老帖子重新推給全站讀者?
  • 代碼已證實的真相(已知): 我們在正文第 24 章用代碼完整還原了這筆轉發會撞上的 5 道關卡:① 能過年齡關(AgeFilter):因爲 age_filter.rs 查的是這筆新轉發自己的 tweet_id(今天剛生成的,不到 48 小時),不會因爲老帖原文(存在 retweeted_tweet_id 裏)超齡而砍掉它;② 但過不了陌生人破圈關(OONRetweetReplyFilter):oon_retweet_reply_filter.rs 會無條件移除所有“轉發者不在讀者關注名單內”的普通轉發(is_retweet),所以在普通推薦管線裏,你自己轉發自己的老帖,進不了未關注你的陌生人的候選池;③ 也過不了已讀老粉關(previously_seen_posts_filter.rs):已讀過濾器會同時查 tweet_id 和 retweeted_tweet_id,以前看過你原帖的老粉絲,今天這筆轉發會被直接攔下,只有上次漏看的老粉或剛關注你的新粉才能刷到(此外還會和你今天發的新帖搶 0.625 同作者權重,且拿不到冷啓動扶持)。39
  • 代碼還看不見的盲區(待查): 你名下到底有多少百分比的粉絲上次漏看了那篇老帖、今天點一次 Repost 具體能撿回多少次漏看曝光,取決於你賬號粉絲的上線重合度。
  • 給創作者的實操結論(判斷): 直接點“普通轉發(Repost)”自己的老帖,只適合做“跨時區補漏”(比如中午發的乾貨,半夜點一次轉發餵給海外時區沒看過的粉絲和今天新漲的粉絲);如果你想讓老幹貨突破 48 小時限制重新推給全站“未關注你的陌生人”,千萬別點普通 Repost,必須用“帶評論引用(Quote Post,配一段當下的新使用場景)”! 因爲 Quote 帖在代碼裏 is_retweet = false,能像全新原創帖一樣暢通無阻地推給全站陌生人!

25 代碼裏的 PushToHomeSource 或長視頻窗口,能不能被我們用來當成普通圖文帖繞過 48 小時限制的後門?

  • 先說人話(這在問什麼、有什麼影響): 有些仔細翻過代碼目錄的人發現:在 For You 首頁最頂層流水線裏,有一個叫 PushToHomeSource 的特殊通道,它居然不經過普通候選帖的 48 小時 AgeFilter 年齡檢查!還有前面說的視頻庫有 14 天甚至 30 天窗口。於是有人問:“我們創作者能不能用什麼暗號或操作,把自己的普通舊文章塞進 PushToHomeSource 裏,強行繞過 48 小時限制上首頁?”
  • 代碼已證實的真相(已知): 在 for_you_candidate_pipeline.rs 和 push_to_home_source.rs 裏,PushToHomeSource 確實與常規打分流 ScoredPosts 並列,它是根據服務端請求裏專門傳入的 push_to_home_post_id 參數去拉取指定帖子的,不走普通候選的 AgeFilter;而長週期窗口(4 天、14 天、30 天)則明確綁定在視頻索引數據集上。30 50 39
  • 代碼還看不見的盲區(待查): X 內部系統到底在什麼條件下才會往 push_to_home_post_id 裏塞入某條帖子的 ID(比如是不是系統級精選推送或特定通知聯動),上游觸發代碼並未公開。
  • 給創作者的實操結論(判斷): PushToHomeSource 是系統內部服務端傳入的參數通道,普通創作者在發帖界面沒有任何按鈕或技巧能手動把自己塞進去;視頻的 14 天窗口也救不了純圖文帖。想讓舊圖文重新上首頁,唯一靠自己就能 100% 掌控的正道就是上一題講的 Quote Post(帶評論引用翻新)。

26 安全與風控模塊裏寫的“公開默認規則”,是不是線上每個賬號每一秒都在執行的唯一鐵律?

  • 先說人話(這在問什麼、有什麼影響): 在安全與防限流章節裏,我們查出了很多具體的數字:比如“最近 5 條帖子裏有 3 條涉黃就給賬號貼標籤”、“視頻滿 64 贊和 512 贊觸發專項安檢”等。大家會問:這些數字在線上是寫死的唯一標準,還是後臺也能隨時偷偷改?
  • 代碼已證實的真相(已知): 首先,我們完整比對了 5ed7963(10 月 28 日)和 606b254(10 月 29 日)兩份最新快照:安全打標、5 帖聚合、外鏈 bot 和視頻/回覆審查代碼,在兩份快照間覈對到的規則與結構沒有變化;可見性過濾模塊雖然把規則抽成了列表並改用 ClientSwitch 集合表達,但展開覈對全部 14 組規則列表後,攔截邏輯和先後順序一致(這是把規則逐組展開對照的結論,不是逐字比對)。其次,README.md 和代碼註釋也明確說明:像 postToUserLabelRules.strato 裏的 5 帖聚合規則,除了代碼裏的默認 JSON(defaultRulesJson),還支持通過配置開關讀取 configuredRulesJson 動態覆蓋,且部分核心反垃圾 bot 規則與大模型提示詞(Prompts)並未開源。76 79 51 54
  • 代碼還看不見的盲區(待查): 線上配置中心當下有沒有針對特定高風險地區或特定賬號羣體動態修改過 configuredRulesJson,以及未開源的那部分 bot 規則長什麼樣,外人無法從公開倉庫看到。
  • 給創作者的實操結論(判斷): 公開代碼裏的安全規則(如 5 帖中有 3 帖涉黃、置頂壞鏈接封 7 天、外鏈 v2 查評論區、CJK 中文重複檢測)是我們能親眼看到的真實防線底牌,踩上去極大概率出事;但同時千萬別拿這些默認數字去搞“精準卡線擦邊(比如以爲每發 2 條敏感帖插 3 條水貼就絕對封不到我)”,因爲線上隨時可以用動態配置覆蓋窗口大小!

27 一旦帖子或賬號被貼了“侮辱標籤”或“賬號限流標籤”,是不是連未關注我的路人點進我主頁也看不到了?

  • 先說人話(這在問什麼、有什麼影響): 什麼是“安全標籤(Safety Label)”?就是系統發現某條帖子有辱罵(比如 FOSNR_ABUSE_INSULTS),或者發現某個賬號發垃圾/涉黃(比如 SPAM_HIGH_RECALL、NSFW_HIGH_PRECISION),給帖子或賬號貼上的“違規封條”。很多人一聽說自己被貼了標籤,就以爲:“完了,所有沒關注我的陌生人,不管是在搜索框搜我、點別人轉發的鏈接、還是直接點進我的個人主頁,全都看不到我的帖子了!”事實真的這麼絕嗎?
  • 代碼已證實的真相(已知): 在 visibility-filtering/rules/levels.rs 和 vf_candidate_hydrator.rs 裏,X 把安全攔截分成了好多扇完全不同的“門(檢查入口)”:
    • 第一扇門叫 TimelineHome(給已經關注你的老粉絲刷首頁用的門):這扇門對很多標籤(比如 FOSNR_ABUSE_INSULTS 侮辱標籤,以及多項賬號級限流標籤)壓根沒有配置直接移除(Drop)規則!所以你的老粉絲刷首頁時照樣能看到你;
    • 第二扇門叫 HomeRecommendations(專門把你的帖子推薦給“還沒關注你的陌生人”的 For You 推薦大門):在這扇門上,只要檢測到上述標籤,系統就會對作者本人以外的所有人(NonAuthors 或 NonFollowers)直接執行移除(Drop)! 而在官方透明度後臺的代碼(underTheHoodLabels.strato)裏,對這些標籤的官方效果說明寫的也是:“不向未關注你的非粉絲推薦該帖/該賬號(Do not recommend… to non-followers)”。77 75
  • 代碼還看不見的盲區(待查): 至於搜索結果頁、別人直接點進你的個人主頁(Profile Timeline)、對話詳情頁或直接打開帖子鏈接等其他頁面,各自掛載了哪個安全級別、在不同客戶端版本下怎麼展示,公開倉庫並未提供全站所有頁面的完整調用圖。
  • 給創作者的實操結論(判斷): 看懂這兩扇門的區別,你就明白了兩件大事: 第一,這些常見標籤的真正殺招是**“切斷 For You 首頁向陌生人推薦你的水龍頭(只保留言論自由,不給破圈推薦流量)”**,而不是把你的賬號從地球上抹掉; 第二,懷疑自己被限流時,千萬別去找一個已經關注你的老粉絲問“你還能不能看見我發的帖”——因爲老粉絲走的是 TimelineHome 那扇門,他能看見你,根本證明不了你在陌生人推薦門(HomeRecommendations)那邊沒被一刀砍掉!要查就用官方的 Under the Hood 工具查!

28 寫帖子批評別人時,到底什麼樣的句子或語言會被自動貼上 FOSNR_ABUSE_INSULTS(侮辱限流標籤)?

  • 先說人話(這在問什麼、有什麼影響): 上一題剛說了,一旦帖子被貼上 FOSNR_ABUSE_INSULTS(辱罵與人身攻擊標籤),這篇帖子在陌生人推薦流(HomeRecommendations)裏就會被直接攔截移除,徹底失去破圈流量。那寫犀利測評、行業批評或反駁別人時,到底什麼情況會觸發這個標籤?用中文寫和用英文寫待遇一樣嗎?
  • 代碼已證實的真相(已知): 打開 Grox PTOS 的安全標籤自動寫入代碼 grox/flows/ptos/task_write_safety_post_annotations_result_sink.py(#L175-L268),在這條自動打標流水線裏,要寫下 FOSNR_ABUSE_INSULTS 必須同時滿足三個硬條件:① PTOS 大模型先把帖子判定爲 HateOrAbuseInsultsWithTarget(針對特定目標的仇恨或侮辱攻擊);② 帖子的語言必須被識別爲英語(English);③ 作者不是高 PageRank 大號或灰標認證號(且非測試賬號)。76 77
  • 代碼還看不見的盲區(待查): 第一,PTOS 大模型內部用來區分“正常尖銳批評”和“人身攻擊侮辱”的提示詞(Prompt)沒有開源;第二,除了這條要求英語的 PTOS 自動分支外,後臺還有沒有其他未公開的多語言自動規則或人工舉報審覈通道會寫同一個標籤,在公開庫裏看不到。
  • 給創作者的實操結論(判斷): 如果你經常用英文發帖(或者發中英雙語混排帖被系統識別爲英語),在寫產品銳評或反駁別人時要格外注意措辭——只針對測試數據、產品缺陷和邏輯漏洞開火,絕不要帶針對個人的髒話或人格侮辱詞彙;同時,雖然這條特定自動分支寫了英語條件,但用中文發帖同樣不能搞人身攻擊,因爲一旦招來讀者反手點舉報(Report 係數 -234.0,量級遠大於正向項)或觸發其他風控,照樣得不償失。

29 帖子要是被貼了 LOW_QUALITY(低質量)或 MISINFO(不實信息)標籤,真的會被鎖死點贊和轉發按鈕嗎?

  • 先說人話(這在問什麼、有什麼影響): 有時我們在 X 上會看到某些帖子外面蒙了一層半透明的警告遮罩(Interstitial),點開後發現底下的點贊、轉發、評論按鈕全都是灰色的,根本點不了!網上傳言:“只要帖子被貼了 LOW_QUALITY 或 MISINFO 標籤,就會對所有非粉絲彈出警告,並且把點贊和所有分享按鈕全部鎖死!”
  • 代碼已證實的真相(已知): 打開 visibility-filtering/rules/tweet_rules.rs、rule_spec.rs、verdict.rs 和 limited_actions_policy.rs 覈對後,真相是這樣的:
    1. 誰會看到警告遮罩?所有人(Everyone)! 這條規則針對 2019 年 4 月 1 日之後發佈的、帶帖子級 LOW_QUALITY 或四種不實信息標籤(MISINFO_CIVIC、MISINFO_GENERIC、MISINFO_MEDICAL、MISINFO_CRISIS)的帖子,受衆明確寫的是 Everyone(連已關注你的粉絲也一樣會看到警告遮罩,不只是非粉絲);
    2. 到底鎖死哪幾個按鈕?看標籤類型和來源(source)!
      • 如果是帖子級 LOW_QUALITY 標籤,直接啓用最嚴厲的 NonCompliant(不合規) 限制策略——在測試配置裏,它會把回覆、普通轉發、點贊、表情回應、私信發送、收藏、置頂、系統分享和複製鏈接等 11 個互動按鈕全部鎖死!
      • 如果是四種 MISINFO 標籤,程序會先讀取標籤身上的 source 字段:比如當 source 爲 limited_replies 時,只啓用 ConversationControl(僅鎖死“回覆”按鈕,點贊和轉發照常能點);但如果 MISINFO 標籤缺失了 source 字段,在最後組裝階段(verdict.rs#L77-L83)代碼會自動退回(Fallback)啓用最嚴厲的 NonCompliant 全套 11 項按鈕鎖死!78
  • 代碼還看不見的盲區(待查): 線上某條具體被貼標的帖子到底帶了什麼 source、以及線上實時配置給每個限制等級具體勾選了哪幾個按鈕,取決於服務端動態下發的策略。
  • 給創作者的實操結論(判斷): 這裏最需要大家放寬心的一點是:千萬別把這裏觸發全套按鈕鎖死的“帖子安全標籤 LOW_QUALITY”,和我們前面講外鏈時提到的“網址域名信譽評級 LOW_QUALITY”搞混了! 平時你發一條字數少、寫得普通的日常動態,絕對不會被貼上這個跟造謠(MISINFO)同級別的公共利益安全標籤。

30 觸發賬號級 NSFW_HIGH_PRECISION 標籤的“最近 5 條裏有 3 條涉黃(3/5 規則)”,到底是怎麼數的?純文字帖和一條放 4 張圖的帖子怎麼算?

  • 先說人話(這在問什麼、有什麼影響): 什麼是“3/5 賬號聚合規則”?平時如果你偶發一條帶敏感圖片的帖子,系統最多隻給那一條帖子貼個成人標籤;但如果你連續發敏感內容,觸發了這條“5 條裏有 3 條”的紅線,系統就會直接給你的整個賬號貼上 NSFW_HIGH_PRECISION(高精度成人賬號) 標籤。這個標籤在陌生人推薦入口(HomeRecommendations)會把你的帖子攔下來——它管的是這一個入口、這一類讀者,不是全站封死;它自己的有效期怎麼算,跟置頂壞鏈接那條路的 7 天是兩回事(見第 31、32 條),不能併成一句“全號限流 7 天”。 很多創作者一直沒搞懂:這“最近 5 條裏有 3 條”,到底是數我最近上傳的 5 張圖片?還是隻數我最近發的 5 條帶圖/帶視頻的帖子?
  • 代碼已證實的真相(已知): 打開 safety-label-user-agg/postToUserLabelRules.strato(#L395-L425)和 safetyLabelToUserLevelAggregationV2Processor.strato,公開默認配置寫得一清二楚:windowSize: 5(窗口大小 5)、minimumMatchingPosts: 3(最少匹配 3 篇)、maxPostAgeDays: 60(60 天內)、mediaOnly: false(只數媒體帖 = 否)! 這段代碼實際的數法是:按時間倒序從你的個人時間線(userTimeline)裏取出最前面的最多 5 條帖子,然後數這 5 條帖子裏有幾條身上帶着 NSFW_HIGH_PRECISION 標籤!這意味着三個確定的事實:
    1. 按“幾條帖子”數,不按“幾張圖”數:如果你在同一條帖子裏一口氣放了 4 張敏感圖,它在這條規則裏只算 1 條帖子(不會因爲 4 張圖就當場算 4 條觸發封號);
    2. 純文字帖也佔 5 條窗口裏的名額:因爲 mediaOnly 默認是 false,如果你中間發了兩條不帶圖的純文字帖子,它們照樣佔掉前 5 條窗口裏的 2 個位置;
    3. 轉發(Retweet)老帖也會算進去:如果前 5 條裏有一筆你剛點的普通轉發,程序會調用 originalTweetForRetweet 去查被轉發原帖身上的安全標籤,並用這筆新轉發的時間算 60 天窗口!而且代碼用的是 take(5)(最多取 5 條),哪怕新號總共只發了 3 條帖子且全帶標,當場就滿 3 條觸發,不需要等湊滿第 5 條才查!79 80
  • 代碼還看不見的盲區(待查): 上游 userTimeline 接口在遇到刪帖、分頁時的實時返回細節,以及線上是否對特定賬號通過 configuredRulesJson 把 mediaOnly 動態改成了 true,在靜態代碼裏看不到。
  • 給創作者的實操結論(判斷): 第一,如果某期內容確實包含敏感圖片,同一批敏感圖合成 1 條多圖帖,只佔窗口裏的 1 個名額;拆成 3 條單圖帖連發,就可能湊滿 3/5 觸發賬號標籤。這是在講計數方法,不是在教繞規則——觸發看的是標籤事件本身,拿窗口當配方反覆試探,線上配置一變就翻車;第二,千萬別手欠去轉發(Repost)別人或自己以前被貼過敏感標籤的老帖子,因爲轉發會把原帖的敏感標籤直接帶進你當前前 5 條的計數窗口裏!

31 什麼是“賬號限流標籤”?什麼是“10 分鐘延遲”和“7 天 TTL 有效期”?到了第 8 天流量會自動恢復嗎?

  • 先說人話(先把“標籤、有效期、作用、影響”四個概念徹底講透): 先把這四個詞串起來,用大白話把整個過程順一遍:
    1. 什麼是“標籤(賬號級安全標籤 Account Label)”? 就像違章停車會被貼罰單一樣,當你的賬號觸發了系統紅線——比如剛剛第 30 題講的**“最近 5 條帖子裏有 3 條涉黃(觸發賬號級 NSFW_HIGH_PRECISION 標籤)”,或者第 39 題要講的“把帶劣質/失效外鏈的帖子設成了個人主頁置頂(觸發賬號級 SPAM_HIGH_RECALL 垃圾標籤)”——系統就會在後臺數據庫裏,直接往你的賬號ID頭上**貼一張隱形的“違規封條”,這就叫賬號級標籤。
    2. 這個標籤具體有什麼作用?對你的流量有什麼影響? 一旦你的賬號頭頂上貼了這張封條,在它生效期間,當推薦系統準備把你的新帖送進“未關注你的陌生人首頁推薦池(HomeRecommendations)”時,安檢門一看你賬號頭上有這張封條,就會把帖子在這個入口攔下來(Drop)。 反映在你眼前的現象就是:已經關注你的老粉絲在關注流裏還能看到你,但你的陌生人推薦流量(For You 破圈曝光)會大幅下滑!
    3. 什麼是“10 分鐘延遲(10-minute delay)”? 假設你今天不小心連發了第 3 條帶敏感圖的帖子,湊夠了“5 條裏有 3 條”的觸發線。這張賬號封條是在你發出第 3 條帖子的第 1 秒鐘就立刻貼到你頭上嗎?不是!後臺負責把“單篇帖子標籤”彙總升級成“整個賬號標籤”的傳送管道(Forwarder),專門設置了一個 10 分鐘的排隊延遲(delay = 10 minutes)。也就是說,從你第 3 條帖子被打標,到整個賬號真正被貼上封條開始限流,中間至少隔着這段排隊延遲。系統另有一個 20 分鐘的 maxLag 服務目標,管的是“最多落後多少”;但具體哪一秒真正寫到賬號上,沒有逐筆的實際記錄,不能把這段時間當成一個 10 到 20 分鐘的倒計時來用。
    4. 什麼是“7 天 TTL 有效期(7-day Time-To-Live)”? TTL 是程序員術語,翻譯成大白話就是**“這張封條的自動過期壽命”**。封條不是終身的:置頂壞鏈接那條路寫進去的標籤,代碼裏明確寫了從寫入那一秒起加 7 天到期;3/5 聚合這條路,正文記載的公開 TTL 同樣是 7 天。但兩條路的觸發事件、計數方法和作者條件各不相同,第 32 條專門交代過,不能把它們併成一個“全站通用的 7 天窗口”。
  • 代碼已證實的真相(已知): 打開 safetyLabelToUserLevelAggregationV2Forwarder.strato、safetyLabelToUserLevelAggregationV2Processor.strato 和 PinnedLowQualityOrBadUrl.bot 源碼可以確認:
    • 延遲參數:聚合轉發器明確設置了 10 分鐘 delay 以及 20 分鐘 maxLag(最大延遲服務目標);
    • 7 天倒計時起點:置頂外鏈垃圾標籤這條路,寫入時的過期時間公式寫得很明確,是 CurrentTimeMs() + 7天(從系統真正把標籤寫入你賬號數據庫的那一秒鐘起,往後加 7 天);3/5 涉黃聚合這條路,正文記載的公開 TTL 也是 7 天,但那是它自己的設置,兩條路不是一條統一的公式;
    • 不重複無限疊加:在 3/5 涉黃聚合規則(postToUserLabelRules.strato)裏,默認把“當前已經揹着 NSFW_HIGH_PRECISION 賬號標籤的作者”排除在外(即在 7 天受罰期內不會因爲同規則每次跑又無限往後順延 7 天)。79 80 74
  • 代碼還看不見的盲區(待查): 第一,10 分鐘延遲和 20 分鐘最大延遲是系統設定的目標值,線上服務器繁忙時具體哪一秒寫入、哪一秒清理過期標籤,沒有公開實時監控日誌;第二,滿 7 天封條過期摘除之後,第 8 天你的真實曝光能恢復到原來的多少成,公開代碼裏沒有歷史對照數據。
  • 給創作者的實操結論(判斷): 搞懂了這套“貼封條 → 攔陌生人推薦 → 7 天自動過期”的完整機制,你遇到流量異常時就有了兩條明確的行動指南:
    1. 如果不小心踩雷觸發了賬號標籤:標籤在身期間,你的新帖在陌生人推薦入口會被攔,重磅長文的破圈效果會打折。先修整賬號、清理問題置頂鏈接或違規帖;要不要因此推遲髮長文,看內容本身的時效,不必圍着標籤的到期日排日程——到期和恢復不是一回事(見第 2 條);
    2. 等標籤過期之後:你的賬號只是恢復了“允許重新進入陌生人推薦池”的資格,系統沒有任何“到期自動給你流量補償”的代碼——過期之前發過的老帖子因爲已經超過了 48 小時年齡線(AgeFilter)不會起死回生;新發的帖子,重新走正常的召回與推薦。

32 除了“最近 5 條裏有 3 條”,系統裏還有沒有別的通道會給賬號貼上成人限流標籤?

  • 先說人話(這在問什麼、有什麼影響): 有些做擦邊或藝術攝影內容的創作者看完第 30 題的 3/5 規則後,心裏打起了小算盤:“既然它只查最近 5 條,那我每次發完 2 條擦邊圖片帖,就緊接着連發 3 條正經的早安純文字帖把前 5 條窗口刷掉,是不是就永遠不會被貼賬號級成人標籤了?”
  • 代碼已證實的真相(已知): 去翻代碼庫,你會發現“5 條裏有 3 條”根本不是系統裏唯一一條抓成人賬號的防線!
    1. 在同一個 postToUserLabelRules.strato 文件裏,其實還寫着另一條叫 possibly_nsfw_account 的規則(雖然它在公開默認 JSON 裏設成了“在 10 條窗口裏要求匹配 11 條”這種數學上不可達的軟停用狀態,但線上隨時可以通過 configuredRulesJson 動態改回比如 10 條裏匹配 4 條來激活它);
    2. 更重要的是,在 botmaker-rules/scarecrow/ 目錄下,還活着另一條完全獨立的自動打標通道(NsfwTweetMediaProcessor.bot、ApplyNsfwUserLabel.df 與 ApplyNsfwUserLabelOrCreateReport.df):這條通道根本不管什麼“最近 5 條帖子窗口”,而是直接按帖子 ID 把媒體涉黃事件塞進一個叫 HLL 的計數器裏,專門檢查**“在 1 天(24 小時)之內是否超過了 2 筆”**!一旦超過並滿足模型分數與作者條件,同樣會直接把賬號送去打成人標籤或人工審覈!76 79 80
  • 代碼還看不見的盲區(待查): 除了公開代碼裏能看到的這幾條規則,X 內部還有多少條未開源的自動規則和人工巡查標準,以及各條規則在線上的觸發比例,並未全部公開。
  • 給創作者的實操結論(判斷): 千萬別耍小聰明去搞“發 2 條敏感圖+插 3 條水貼卡窗口”的套路!因爲你躲得過 postToUserLabelRules 的 5 帖窗口,躲不過 ApplyNsfwUserLabel.df 的“24 小時內超 2 筆”計數!正常做非成人內容的創作者,則要注意連轉推別人的擦邊內容都要剋制,避免一天之內多次觸發媒體涉黃事件。

33 視頻帖拿到第 64 個贊和第 512 個讚的那一秒鐘,系統是不是必定會啓動一次安全大檢查?

  • 先說人話(這在問什麼、有什麼影響): 我們在正文第 20 章揭露了一個真相:網上吹噓的“視頻拿到 64 個贊和 512 個贊會觸發兩輪流量獎勵池”,在代碼裏其實是三條視頻違規安全審查任務(SpecialVideo 動態閃現審查、MediaInjected 夾帶違規畫面審查、AdultContentLeadingFrames 長視頻前 10 秒涉黃審查)的啓動門檻!那是不是每支視頻剛點到第 64 個贊或第 512 個讚的那一秒,安檢機器人都100%會跑一遍?
  • 代碼已證實的真相(已知): 在 grox/flows/ptos/ 目錄下,我們能看到這三條視頻安檢流水線各自監聽不同的 Kafka 消息隊列入口(generators.py),並且全都配了 60 秒去重限流緩存(task_rate_limit.py)。當任務送進來時:
    • SpecialVideo 和 MediaInjected 要求視頻帖子當前的點贊數 >= 64(deluxe_fav_count_threshold 默認值);
    • 當點贊數 >= 512 時,MediaInjected 會開啓大模型思維鏈深度推理(use_reasoning = true),而針對 30 秒以上長視頻裁前 10 秒畫面的 AdultContentLeadingFrames 則會在滿 512 贊時免除“先前必須出現過 AdultContent 嫌疑分類”的前置條件。51 52 53
  • 代碼還看不見的盲區(待查): 公開代碼展示的是“安檢消費端收到任務後怎麼按 64 贊和 512 贊做判斷”,而上游負責往 Kafka 隊列裏發送檢查請求的生產端(Producer)到底是按什麼頻率、在哪些點贊節點觸發發送的,上游生產代碼並未公開。
  • 給創作者的實操結論(判斷): 不管上游是卡着第 64/512 個贊準時送檢,還是每隔幾分鐘抽樣送檢,對我們創作者來說最核心的認知只有一條:64 贊和 512 贊是“視頻火起來之後的深度違規安檢線”,絕不是“流量獎勵解鎖線”! 只要你的視頻(以及你 Quote 引用的別人視頻)乾乾淨淨,沒有在前 10 秒搞擦邊、也沒有在中間某幾幀偷偷閃現違規二維碼或色情畫面,過幾百讚的安檢都不用怕。

34 視頻安全審查到底是怎麼抓“隱藏違規畫面”的?把違規畫面藏在第 11 秒能躲過去嗎?

  • 先說人話(這在問什麼、有什麼影響): 有些搞灰產或擦邊引流的人,聽說系統有條規則是“把 30 秒以上的長視頻裁切前 10 秒去做成人審查(AdultContentLeadingFrames)”,就自以爲找到了漏洞:“那我把前 10 秒做成正經風景畫面,把擦邊或違規引流二維碼藏在第 15 秒閃現一下,是不是就能完美騙過 AI 安檢了?”一旦被抓到,會有什麼後果?
  • 代碼已證實的真相(已知): 翻開 grox/flows/ptos/ 目錄下的源碼,系統抓違規視頻根本不是隻有“裁前 10 秒”這一招,而是佈下了三張天羅地網:
    1. 動態突變幀捕捉(SpecialVideo):專門用 motion_reveal 算法掃描整支視頻裏“畫面突然劇烈變化的那幾幀(motion_reveal_frames)”——哪怕你在正常視頻中間只閃現了 0.5 秒的違規畫面或二維碼,也會被精準揪出來送審;
    2. 黑名單參考庫比對(MediaInjected):把抽出來的視頻幀拿去和官方已確認的“違規/紅外/垃圾視頻參考庫”做深度特徵比對(滿 512 贊還開啓大模型思維鏈推理),一旦命中就定性爲 SpamManipulatedMedia(惡意操縱媒體),送進公共寫入池,走一般 Spam 分支的作者條件,再決定寫哪些標籤——不是這條任務直接給賬號貼上某個具名標籤。
    3. 雙模型交叉會審(Cross-validation):針對成人內容,系統會同時跑 PTOS 大模型和另一個獨立的 sex-and-nudity 視覺模型做交叉驗證,最後按確認的違規類別寫下成人或垃圾標籤。76 51 52 53
  • 代碼還看不見的盲區(待查): X 內部的黑名單違規視頻參考庫裏存了哪些樣本、視覺大模型的具體提示詞(Prompt)以及交叉驗證的判罰分數線,屬於平臺保密的反作弊資產,並未公開。
  • 給創作者的實操結論(判斷): 千萬別信任何“前 10 秒放風景、第 11 秒放違規內容就能過審”的鬼話!因爲 motion_reveal 抓的就是中途突變畫面。正常創作者只要保證自己的視頻(以及 Quote 引用的視頻)全程無違規插幀即可安心發佈。

35 我在別人的熱門帖子底下留言,自己又接着回覆了自己兩句,就會被當成“蓋樓垃圾號”把評論分清零嗎?

  • 先說人話(這在問什麼、有什麼影響): 什麼是“多層自回自評垃圾過濾(TaskMultiStepReplySpamFilter)”?很多賣課或搞推廣的人,喜歡去大 V 的熱帖底下搶一樓留言,然後在這條留言底下自己回覆自己蓋起三四層樓(第 1 層留鉤子、第 2 層放截圖、第 3 層放引流微信號)。爲了打擊這種行爲,系統專門寫了一個過濾器:一旦判定你是在別人底下惡意蓋樓發垃圾廣告,就會把你那幾條回覆的評論區排序分(ReplyRankingScore)直接寫成 0.0 分(沉到評論區最谷底沒人能看見)! 那如果我們普通創作者在大 V 帖子底下正常討論技術問題,一句話沒寫完、自己又接着回覆了自己一條補充說明,會不會被誤傷清零?
  • 代碼已證實的真相(已知): 打開 task_multi_step_reply_spam.py 和 classifier_multi_step_reply_spam.py 源碼,系統把**“第一步:檢查樓層結構”和“第二步:大模型看內容定性”**分得清清楚楚:
    1. 哪些情況連審查都不會進(直接豁免)?
      • 如果你是在**你自己發的主帖(Root Post)**底下連續回覆自己寫串文(Thread),100% 直接豁免不查!
      • 如果被你回覆的那個原帖作者粉絲數不到 1,000 人,不查!
      • 如果你只回復了別人 1 條(沒有在自己評論下再回自己形成三層樓),不查!
    2. 就算進了審查,還有三道防誤傷保護: 只有當你在“粉絲 >= 1000 的別人帖子”下“自己回覆了自己”,纔會把對話送給 Grox 大模型看(如果對話超過 10 層,只抽最前面 5 層+最後面 5 層+當前回覆,每條最多看 2 張圖)。大模型看完後,必須明確判定你是在發垃圾推廣、且必須把你最新那條回覆圈進去,剔除別人後至少還剩 2 條你自己的垃圾回覆,程序纔會真正動手罰你!66 67
  • 代碼還看不見的盲區(待查): 大模型內部用來區分“正常分兩樓補充技術細節”和“分兩樓發垃圾引流廣告”的具體提示詞(Prompt)沒有公開。
  • 給創作者的實操結論(判斷): 在自己的帖子底下寫串文(Thread)100% 安全;去千粉大 V 底下正常討論問題、哪怕分兩層樓補充真實數據和報錯日誌,大模型能看懂你在正常交流,完全不用怕。唯一要戒掉的,就是在別人的熱門評論區裏一層接一層地自己回自己貼賣課廣告或引流名片!

36 一旦評論被判爲蓋樓垃圾、ReplyRankingScore 被寫成了 0.0 分,會連累我的整個賬號或大 V 的原帖嗎?

  • 先說人話(這在問什麼、有什麼影響): 緊接着上一題,萬一有人真的在千粉大 V 的評論區蓋樓發推廣被抓了,系統寫下的那個 ReplyRankingScore = 0.0(評論排序分歸零)到底有多大破壞力?會不會把人家大 V 的原帖熱度搞垮?或者把我自己整個賬號以後發主頁帖子的權重也清零?
  • 代碼已證實的真相(已知): 在 classifier_multi_step_reply_spam.py(#L157-L175)和 task_multi_step_reply_spam.py(#L151-L198)裏,代碼寫得非常剋制:① 解析大模型結果時,程序用硬代碼只接受 index > 0 的樓層,從物理上100% 保護了第 0 層(大 V 的原帖 Root Post)絕不會被誤傷,同時也會把對話裏其他無辜路人的評論全部剔除;② 最終寫入 ReplyRankingScore(score=0.0) 並嘗試打上 RiskyHighVizReply(高曝光風險回覆)標籤的,僅僅是被模型圈出來的那幾條你自己的垃圾回覆 ID!67
  • 代碼還看不見的盲區(待查): 下游負責渲染帖子詳情頁評論區的服務在讀到 ReplyRankingScore = 0.0 後,是把它直接摺疊進“顯示更多可能含垃圾內容的回覆”裏,還是單純排在最後一名,下游評論區展示代碼未在公開庫中完整列出。
  • 給創作者的實操結論(判斷): 這項懲罰是精準的“外科手術式打擊”——只把那幾條違規蓋樓的評論按進水底(寫 0 分),既不會連累無辜的原帖博主,也不會把你整個賬號發原創帖的 For You 主頁分數清零。

37 如果一條回覆沒有被貼上 RiskyHighVizReply 標籤,是不是說明它的評論分數(ReplyRankingScore)也沒被清零?

  • 先說人話(這在問什麼、有什麼影響): 在上一題的代碼裏,當系統抓到蓋樓垃圾回覆時,會先後幹兩件事:第一件事是嘗試給這條回覆貼一個叫 RiskyHighVizReply 的風險標籤;第二件事是把它的 ReplyRankingScore(評論排序分)寫成 0.0 分發出去。有些大號博主就會問:“如果我是高權重賬號,豁免了第一個風險標籤,是不是連第二個 0 分懲罰也一起躲過去了?”
  • 代碼已證實的真相(已知): 打開 task_write.py(#L39-L79)和 task_multi_step_reply_spam.py(#L151-L198)對照執行順序就能發現:“貼 RiskyHighVizReply 標籤”和“把評論分數寫成 0.0 分”在代碼裏是互相獨立的兩個步驟!負責貼標籤的輔助函數(Helper)內部確實額外檢查了高 PageRank/信用分、灰標和測試賬號豁免;但是,就算這個輔助函數因爲豁免條件沒有貼標籤就返回了,外層的主函數依然會繼續往下走,照樣把 ReplyRankingScore(score=0.0) 發佈到緩存、Kafka 和 Strato 數據庫裏!(當然,真正的高 PageRank V2 或灰標號在更早的 TaskMultiStepReplySpamFilter 入口處就已經被跳過了,這裏是針對中間信用分邊界的獨立邏輯。)66 67
  • 代碼還看不見的盲區(待查): 單條具體回覆在線上數據庫裏的標籤狀態與內部 ReplyRankingScore 數值,普通用戶在前端界面上無法直接看到。
  • 給創作者的實操結論(判斷): 在官方 Under the Hood 報告裏沒看到帖子風險標籤,並不等於你在別人評論區刷屏的回覆沒有被寫 0.0 分沉底。老老實實寫有價值的評論,纔是唯一不沉底的辦法。

38 我發外鏈時,能不能光憑網址長什麼樣(比如是不是短鏈接),看出它會不會被 X 判爲 LOW_QUALITY(低質量網址)?

  • 先說人話(這在問什麼、有什麼影響): 什麼是外鏈的 LOW_QUALITY 或 BAD 評級?X 後臺有一個龐大的“網址信譽黑名單庫(URL Reputation)”。當你發一條帶外部鏈接的帖子時,審查機器人(LQ_Tweets_With_LQ_URL_Verdict_At_Mention_To_NonFollower_v2.bot)會順着你這根鏈接的跳轉鏈條(redirectionChain)一路查過去:只要中間任意一跳的網址被信譽庫標爲 LOW_QUALITY(低質量),且最終落地的網頁不在 GOOD(優質)或 WHITELIST(白名單)裏,機器人就會直接給你這條帖子貼上 SPAM_HIGH_RECALL(高召回垃圾帖) 標籤——哪怕你把外鏈藏在一樓評論區裏,最新版 v2 機器人也照抓不誤,直接把帖子從陌生人推薦流裏移除! 那我們創作者在發鏈接前,能不能肉眼看出哪個網址會被 X 判爲 LOW_QUALITY?
  • 代碼已證實的真相(已知): 從 v1、v2 外鏈機器人及置頂外鏈機器人的源碼(botmaker-rules/scarecrow/bot/)可以確認:機器人自己並不看網址字符串長短,而是直接讀取內部網址信譽服務返回的評級枚舉(BAD、LOW_QUALITY、GOOD、WHITELIST);並且最新版 v2 已經徹底刪掉了舊版 v1“排除回覆貼(isReply)、排除轉發貼(isRetweet)以及必須 @ 陌生人”的豁免條件!76 73 74
  • 代碼還看不見的盲區(待查): X 內部的網址信譽庫到底把全球哪些域名標成了 LOW_QUALITY 或 WHITELIST、多久更新一次名單,這份內部域名清單並未公開。
  • 給創作者的實操結論(判斷): 雖然我們看不到內部域名名單,但有三條鐵律能幫我們避開 99% 的外鏈雷區:
    1. 徹底放棄“把外鏈塞進一樓評論區就能躲避審查”的幻想(v2 時代放評論區和放正文一樣受審);
    2. 儘量直連高信譽大平臺或正規主域名(如 GitHub、Substack、YouTube、正規備案官網),少用不知名的野雞免費短鏈接服務做二次跳轉(因爲一旦那個免費短鏈域名被黑產濫用標爲 LOW_QUALITY,哪怕你最終落地頁是正規博客,只要最終頁沒進 X 的頂級白名單,中間這一跳就會把你連累死!);
    3. 發帖前親手點開鏈接測一遍,確保沒有跳去過期被篡改的死域名。

39 如果我不小心把帶壞鏈接的帖子設成了主頁置頂、觸發了帶 7 天有效期的賬號標籤,我馬上“取消置頂”能立刻解封嗎?

  • 先說人話(這在問什麼、有什麼影響): 我們在正文第 27 章講過一個極其兇險的機器人叫 PinnedLowQualityOrBadUrl.bot(置頂劣質鏈接審查機器人):當你把一條帖子設爲個人主頁置頂(Pin)時,如果裏面帶的鏈接被查出是 BAD 或 LOW_QUALITY(比如你置頂了一條兩年前的舊帖,裏面掛的個人網站域名早就過期被博彩網站搶注了),系統就會直接給你的整個賬號貼上 SPAM_HIGH_RECALL(高召回垃圾賬號) 封條,讓你接下來 7 天內發的所有新帖都進不了陌生人推薦流! 很多創作者問:“萬一我中招了,我一發現流量不對勁,立刻把那條置頂帖取消置頂(Unpin)或者刪掉,我賬號頭上的 7 天封條會不會馬上自動消失?”
  • 代碼已證實的真相(已知): 打開 botmaker-rules/scarecrow/bot/PinnedLowQualityOrBadUrl.bot(#L2-L44)源碼從頭讀到尾,裏面的邏輯只有單向的一條線:當檢測到用戶修改置頂帖(pinnedTweetIds 的修改後 after 值存在且不等於修改前 before 值),且解析出新置頂帖裏的鏈接含 BAD 或 LOW_QUALITY 時,直接調用 SetUserLabel 寫入有效期爲 7 天(CurrentTimeMs() + 7天) 的 SPAM_HIGH_RECALL 賬號標籤。在這份規則文件裏,根本沒有寫任何“當用戶把問題帖子取消置頂時,同步刪除該賬號標籤”的代碼分支!74
  • 代碼還看不見的盲區(待查): 至於 X 後臺有沒有其他未開源的定時複查任務,或者通過人工客服申訴能不能提前手動摘掉這個標籤,在公開倉庫裏看不到。
  • 給創作者的實操結論(判斷): “請神容易送神難”!代碼裏只有換上壞鏈接置頂時“貼 7 天封條”的自動代碼,沒有取消置頂時“撕封條”的自動代碼! 所以,如果真的中招了,雖然你肯定得第一時間把問題置頂帖撤下來防止 7 天后再次觸發,但這 7 天多半隻能等它到期——公開代碼裏沒有自動摘除的分支,能不能提前解除,公開資料答不了。最好的辦法就是:在每次點下“置頂”按鈕之前,花 5 秒鐘把帖子裏的鏈接點開檢查一遍!

40 中文帖子到底重複多少個字、或者複製粘貼幾次,纔會被抓進 COPYPASTA_SPAM(複製粘貼垃圾)名單?

  • 先說人話(這在問什麼、有什麼影響): 什麼是 COPYPASTA_SPAM?“Copypasta”在英文網絡俚語裏就是“到處複製粘貼的刷屏文案”。如果你爲了省事,把同一段推廣文案、或者同一句評論複製粘貼發了好多遍,系統裏專門抓重複文本的機器人就會給你貼上 COPYPASTA_SPAM 垃圾標籤。很多人問:“中文又不像英文那樣用空格分詞,系統抓得到中文重複嗎?到底重複幾個漢字、發幾次纔算違規?”
  • 代碼已證實的真相(已知): 打開 botmaker-rules/scarecrow/bot/BBQDuplicateTextProd.bot(管主帖)和 BBQDuplicateTextRepliesProd.bot(管評論區回覆),代碼裏明明白白列出了專門針對中日韓漢字(CJK 字符)的檢測任務名稱:duplicate_text_characters_cjk 和 duplicate_text_characters_cjk_replies!只要上游定時任務把一批高度雷同的帖子打包成一個“重複帖子簇(tweetIdCluster)”送過來,且作者不是測試號、高 PageRank 或灰標號,機器人就會給這些帖子統統寫上 COPYPASTA_SPAM 標籤!81
  • 代碼還看不見的盲區(待查): 這兩個 .bot 文件是從“收到上游已經打包好的重複帖子簇(tweetIdCluster)”纔開始執行的;至於上游那個 duplicate_text_characters_cjk 定時任務內部是規定“連續 20 個漢字相同”還是“餘弦相似度超過 85%”、以及“重複發滿 3 次還是 5 次”纔打包送審,那段上游 SQL/離線查詢代碼並未開源。
  • 給創作者的實操結論(判斷): 千萬別以爲寫中文沒有空格就能逃過複製粘貼檢測!但正常創作者也完全不用風聲鶴唳——你在不同文章里正常使用同一個行業術語、或者固定的個人署名格式,絕不等於刷屏;只要戒掉“拿同一套話術模板去十幾個帖子底下批量複製粘貼引流”的毛病,就根本不會撞到這個槍口上。

41 帖子一旦被貼上 COPYPASTA_SPAM(複製粘貼垃圾)標籤,在推薦流裏會被扣多少分、還是直接屏蔽?

  • 先說人話(這在問什麼、有什麼影響): 緊接着上一題,假如某條帖子真的因爲批量複製粘貼,被上面的機器人貼上了 COPYPASTA_SPAM 標籤,接下來這個標籤在推薦系統裏是怎麼發作的?是扣 50% 分數,還是像 SPAM_HIGH_RECALL 那樣直接在陌生人推薦流裏一刀砍死?
  • 代碼已證實的真相(已知): 在公開的 botmaker-rules 目錄裏,我們能 100% 看到機器人把 COPYPASTA_SPAM 這個標籤寫進數據庫的代碼動作;但是,當我們拿着 COPYPASTA_SPAM 這個名字去搜公開的 Home Mixer、VM Ranker 和 visibility-filtering(可見性過濾規則庫)時,卻沒有在公開列表裏看到直接讀取 COPYPASTA_SPAM 的那一行代碼。76 81
  • 代碼還看不見的盲區(待查): 爲什麼上游拼命打這個標籤,下游公開代碼裏卻沒出現它的名字?正如官方在 README.md(#L440-L447)裏專門聲明的:爲了防止黑產針對性繞過風控,公開倉庫並沒有放出全部的反垃圾規則與下游消費服務。這個標籤極可能由未開源的外部召回過濾層或信用分扣減服務直接消費。
  • 給創作者的實操結論(判斷): 工程師絕對不會閒得沒事幹寫兩個專門抓中文和英文重複帖子的生產環境機器人(Prod.bot)放在那裏擺設。雖然下游具體扣多少分沒公開,但看到 BBQDuplicateTextProd.bot 的存在,就足以斷絕一切“靠羣控腳本批量複製粘貼文案漲粉”的念頭。

42 爲什麼說“誘導互動(Engagement Bait)”連高權重賬號和灰標大號都不給豁免?平時文末提問怎麼寫才安全?

  • 先說人話(這在問什麼、有什麼影響): 什麼是“互動誘導(Engagement Baiting / Farming)”?就是帖子本身沒什麼乾貨,純粹靠話術勾引讀者刷點贊、刷評論、刷轉發來騙算法權重(比如“看到這張圖 3 秒內點贊今年必發財”、“想要的在評論區扣 888 我私發你”)。很多大 V 以爲:“我的賬號權重高(高 PageRank),平時發點小擦邊或小廣告系統都對我網開一面,搞點‘扣 1 領資料’應該也沒事吧?”
  • 代碼已證實的真相(已知): 打開 Grox PTOS 的安全標籤寫入代碼 task_write_safety_post_annotations_result_sink.py(#L233-L248),你會看到一段專門針對大號的“尚方寶劍”: 對於其他普通的垃圾違規類別,代碼確實會先檢查 if not is_high_pagerank_or_grey_badge(如果不是高 PageRank 大號或灰標號才貼罰單);唯獨當大模型判定你的帖子屬於以下三大互動作弊罪名之一時——① SpamEngagementBaiting(互動誘餌)、② SpamEngagementFarming(互動農場刷量)、③ SpamCardManipulation(惡意操縱預覽卡片騙點擊)——代碼直接把 should_label_for_spam 設爲 true,完全無視你的高 PageRank 和灰標身份,照樣當場給你貼上 SpamHighRecall 垃圾標籤(直接從陌生人推薦流裏移除)!54
  • 代碼還看不見的盲區(待查): PTOS 大模型在後臺到底用哪幾句具體的提示詞(Prompt)來劃定“正常呼籲讀者討論”與“惡意互動誘導”的界限,該文件(prompts.py)未開源。
  • 給創作者的實操結論(判斷): 不管你的賬號粉絲再多、權重再高,在“騙贊騙評(Engagement Bait)”面前都沒有免死金牌! 那平時寫完乾貨,怎麼在結尾引導讀者評論才既安全、又能用上回復這一項?做法就是**“問具體場景,別要機械口令”**:
    • ❌ 高危寫法(機械口令):“想要這份 OCR 測試腳本的,先點贊關注,然後在評論區扣‘666’,滿 100 人我統一發!”
    • ✅ 安全且高權重的寫法(專業場景討論):“你們公司在處理中文發票自動入賬時,最常報錯的是稅額欄還是購買方稅號?如果遇到過更奇葩的印章遮擋案例,歡迎在評論區貼出來,我挑代表性的樣本加進下一輪複測!”

43 發帖子帶 # 話題標籤(Hashtag)到底好不好?爲什麼說最多別超過 4 個?

  • 先說人話(這在問什麼、有什麼影響): 很多從 Instagram、小紅書或抖音轉過來的創作者,發每條帖子都習慣在末尾塞滿十幾個 #AI #科技 #創業 #副業 #乾貨分享 這樣的話題標籤,覺得標籤越多被搜到和推薦的概率越大;而另一派老玩家則警告說:“X 算法最討厭 # 標籤,帶 1 個標籤就會被判定爲垃圾號降權!”到底聽誰的?
  • 代碼已證實的真相(已知): 在公開源碼裏,我們找到了關於 # 標籤的三塊拼圖,剛好拼出完整真相:
    1. 帶標籤絕不是“零價值或必降權”:在 Phoenix 推薦模型的用戶歷史行爲特徵清單(history_id_lists.py 與 id_list_features.py)裏,專門有一項叫 CLICK_HASHTAG(用戶點擊過的話題標籤歷史)——說明系統在算讀者興趣時,確實會看他平時點過哪些 # 標籤;
    2. 代碼裏提取標籤的硬上限是 4 個(MaxHashtagsPerTweet = 4):在 SimClusters 興趣社區的實體抽取器 TweetEntityExtractor.scala 裏,寫死了常量 MaxHashtagsPerTweet = 4——它在提取你帖子裏的標籤時,最多隻拿前 4 個,從第 5 個標籤開始往後直接丟棄不看!
    3. 胡亂堆砌標籤確實有專屬罪名(SpamHashTagAbuse):在 PTOS 安全審查的違規分類(state.py)裏,專門設有一項 SpamHashTagAbuse(話題標籤濫用),一旦被模型判定爲亂塞無關標籤蹭熱度,就會被貼上 SpamHighRecall 垃圾標籤,斷送陌生人推薦流量!54
  • 代碼還看不見的盲區(待查): 在主計分表裏並沒有“加 1 個標籤加幾分”的直接公式;至於帶 1 個精準標籤和不帶標籤在線上各大召回通道里的細微流量差異,沒有公開的線上對照報告。
  • 給創作者的實操結論(判斷): 這三塊代碼拼在一起,給我們的實操鐵律再清晰不過了:平時發普通觀點或教程,完全可以 1 個 # 標籤都不帶(靠正文前 4,000 字和首圖,Grox 多模態模型足夠看懂你在聊什麼);只有當你的帖子確實屬於某個明確的行業大會、開源項目或特定固定欄目時,自然地放上 1 到 2 個(這條抽取路徑最多讀前 4 個,第 5 個起就不讀了)精準相關的 # 標籤即可,永遠不要在文末堆砌一排無關熱搜詞!

44 當我們發“長 Post”或“Article(專欄文章)”時,AI 到底讀到了我們寫的哪一部分文字?

  • 先說人話(這在問什麼、有什麼影響): 當你寫了一篇 8,000 字的深度長文(無論是用普通長 Post 發,還是用 Article 專欄編輯器發),後臺的 Grox 多模態大模型(mm_emb)必須先讀懂你這篇文章在講什麼,才能生成“語義向量(Semantic ID)”去幫你匹配感興趣的陌生讀者。大家最關心的是:AI 是把我的 8,000 字從頭到尾一字不落地全讀完了,還是隻讀了前面一截?
  • 代碼已證實的真相(已知): 在公開的 grox/ 目錄源碼裏,我們覈實了三件確定的事:
    1. 在數據映射器 post_mapper.py 裏,程序把上游傳入的 post_metadata.text 賦給了帖子對象的 full_text 字段;如果是一篇 Article,還會在 article_metadata 裏額外裝入 Article 標題(title)、封面圖和正文內嵌媒體(注:在公開的 article_metadata 數據結構裏,沒有列出一個單獨叫 article_body 正文全文的字段);
    2. 在新版 V8.2 閱讀器(renderer_v82.py) 裏,程序會對 post.full_text 執行嚴格的 Python 字符切片——只截取前 4000 個字符(MAX_POST_TEXT = 4000);如果同時帶有 Article 元數據,還會並列追加讀取 Article 標題的前 200 個字符(MAX_ARTICLE_TITLE = 200)!
    3. 我們在本地用內存對象直接跑了 10 項函數實測驗證:在 V8.2 裏,第 4,000 個字符往後的文字改動完全不會改變輸出文本;而舊版 V5 閱讀器(renderer.py) 則沒有寫這道 4,000 字符切口。87 88
  • 代碼還看不見的盲區(待查): 線上生產環境的上游 Strato 服務在面對一篇萬字 Article 時,到底有沒有把 Article 的正文塞進 post_metadata.text 裏傳過來,或者有沒有通過其他未公開的內部通道讀取 Article 全文,以及線上哪些模型用 V8.2、哪些用 V5,這部分上游代碼未開源。
  • 給創作者的實操結論(判斷): 爲了確保在任何閱讀器路徑下 AI 都能 100% 抓準你的文章主題,請死守兩條寫作鐵律:① 寫長 Post 時,務必在前 4,000 個字符以內把研究對象、核心結論和關鍵專業詞全部亮出來;② 寫 Article 專欄時,務必把前 200 個字符的 Article 標題和外層導語寫得乾貨滿滿,千萬別起《深夜的一點感悟》這種讓 AI 一頭霧水的文藝空洞標題!

45 讀者在時間線上點長 Post 的“展開全文(Show more)”,和點進卡片打開一篇“Article 專欄”,在算法眼裏算同一種閱讀嗎?

  • 先說人話(這在問什麼、有什麼影響): 很多創作者糾結髮長 Post 還是發 Article,是因爲擔心:“讀者看長 Post 只需要點一下‘展開全文(Show more)’就能在時間線上順着往下滑;而看 Article 卻要專門點進卡片跳到另一個閱讀頁面。這兩種點開閱讀的動作,在算法算那個 0.4 分的‘點擊後深度停留(CLICK_DWELL_TIME)’和 0.006 的‘連續停留秒數(DWELL_TIME)’時,待遇一樣嗎?”
  • 代碼已證實的真相(已知): 打開通信協議定義文件 recsys.proto 和特徵映射文件 constants.py 可以看到:系統在底層協議裏把這些動作分得非常細——普通點擊帖子是編號 29(CLIENT_TWEET_CLICK),點擊長帖的“展開全文”是獨立編號 45(CLIENT_TWEET_SHOW_MORE_EXPAND),進入詳情頁曝光是 72,詳情頁停留是 103;同時頁面類型裏也專門定義了 PAGE_ARTICLE(Article 正文頁)和 PAGE_ARTICLE_PREVIEW(預覽頁)。此外,在服務端 Rust 工具代碼(util.rs)裏,能明確看到把連續停留時間 DWELL_TIME 從毫秒除以 1000 轉換成秒的代碼。90 91 98
  • 代碼還看不見的盲區(待查): 從手機客戶端捕捉到讀者“點開 Article 頁面”或“點展開全文”,到上游日誌聚合服務把時長算進 DWELL_TIME 和 CLICK_DWELL_TIME(閾值 10.0)那兩個訓練數據槽位裏,中間的客戶端計時起止規則與上游聚合代碼並未放進公開倉庫(官方在 phoenix/README.md 中已聲明生產數據源與內部遙測未開源)。
  • 給創作者的實操結論(判斷): 雖然客戶端底層怎麼歸因計時沒開源,但在最終的價值打分模型(phoenix_scores.rs)裏,既沒有單獨給“展開全文”設特權分,也沒有單獨給“打開 Article”設特權分,最終統一認的都是預測出來的閱讀停留與互動概率。所以我們不用去賭“哪個按鈕在計時器裏佔便宜”,而是按內容結構選格式。

46 把同一篇三千字乾貨從“長 Post”改成發“Article 專欄”,能不能靠格式本身直接讓曝光翻 5.7 倍?

  • 先說人話(這在問什麼、有什麼影響): 網上之前流傳過一張很火的圖表,說“2026 年在 X 上發 Article 專欄的瀏覽量中位數是發普通帖子的 5.7 倍”!於是很多創作者不管寫長寫短,哪怕只有一千字也硬塞進 Article 編輯器裏發,以爲只要套上 Article 這個殼子,算法就會自動給 5.7 倍的流量加成。
  • 代碼已證實的真相(已知): 第一,我們檢索了 Home Mixer 和 VM Ranker 涉及候選召回、初篩和最終打分的 103 個源碼文件,在最終計分輸入 CandidateScoringInputs(inputs.rs)和加權函數(scoring.rs)裏,根本沒有 is_article 這個字段,沒有任何“只要是 Article 就乘以 5.7 倍或額外加分”的代碼!第二,我們去核查了那份“5.7 倍”數據的原始出處(第三方機構 NotPeople 的 8 月樣本報告),發現人家統計的 42 篇 Articles 背後,每篇 Article 平均配套發了 6 到 28 條普通帖子(共計 843 條導流帖)去給它做摘錄推廣和引流,而且拿來做對比基準的恰恰就是那些簡短的日常導流帖!94 96
  • 代碼還看不見的盲區(待查): 線上深度學習模型在讀取內容特徵後,會不會對帶 Article 標題結構的候選帖產生細微的隱性預測偏好,或者線上是否存在未公開的小流量實驗,無法僅憑靜態代碼完全排除。
  • 給創作者的實操結論(判斷): 所謂“5.7 倍曝光”,本質上是**“1 篇精心打磨的旗艦 Article + 連續十幾條帶圖短帖矩陣導流”**共同砸出來的綜合運營結果,絕不是算法代碼裏寫死了 5.7 倍格式乘數!三四千字以內能一氣呵成講完的單一問題直接發 長 Post;上萬字的多章節手冊發 Article,並務必模仿那批高手的做法,單獨發一條或多條帶核心結果圖的導讀 Post 去引用推廣它!

47 什麼是 Article 的“64 贊拉圖門檻(is_high_fav)”?V5 和 V8.2 兩個閱讀器讀圖片爲什麼不一樣?

  • 先說人話(這在問什麼、有什麼影響): 我們在正文第 17 章講透了一個讓無數發 Article 的創作者恍然大悟的真相:當你直接用 Article 編輯器發了一篇圖文並茂的專欄文章時,爲什麼有時候感覺 AI 好像根本沒看懂你放在 Article 裏的封面圖和正文插圖?這背後的“搬運工 64 贊門檻(is_high_fav)”和“V5/V8.2 閱讀器挑圖差異”到底是怎麼配合工作的?
  • 代碼已證實的真相(已知): 在 grox/ 目錄的源碼裏,圖片進入 AI 大模型要過兩道關:
    1. 第一關(搬運工 MediaLoader 的 64 贊門檻):在 grox/core/data_loaders/media_loader.py(#L130-L170 與 #L293-L303)裏,負責從數據庫拉取圖片數據的搬運工爲了節省算力,設了一個判斷條件叫 is_high_fav(高贊帖判斷),其公開默認門檻在 config.py 裏設爲 64 個贊(deluxe_fav_count_threshold = 64)!在這條搬運路徑上,只有當帖子滿足了 is_high_fav(滿 64 贊)等條件時,程序纔會進入專門去拉取 Article 封面圖(cover_media)和 Article 正文內嵌圖(article_metadata.media) 的代碼分支!(注:這隻管這條媒體拉取路徑,絕不代表 Article 要滿 64 贊纔有推薦資格。)
    2. 第二關(V5 與 V8.2 兩代閱讀器的挑圖差異):我們在本地直接調用兩代閱讀器的原函數做了實測——舊版 V5(renderer.py) 會按“Article 封面圖 → 普通帖子附件 → Article 內嵌圖”的順序讀圖(若預算設爲 1 張則只拿走 Article 封面圖);而新版 V8.2(renderer_v82.py) 的挑圖函數 _collect_post_media 只去翻“普通帖子的圖片附件欄(post.media)”,壓根沒寫代碼去讀 Article 的專屬封面圖和內嵌圖!如果圖片只放在 Article 編輯器裏,V8.2 函數返回的圖片列表直接是空的(0 張圖)!88 89
  • 代碼還看不見的盲區(待查): 線上生產環境裏,上游數據服務在調用 V8.2 之前會不會把 Article 的封面圖複製一份塞進 post.media 字段裏,以及線上各個下游模型消費 V5 向量和 V8.2 向量的具體比例,未在公開倉庫中披露。
  • 給創作者的實操結論(判斷): 不管線上上游有沒有做額外複製,我們用下面這 3 招實操動作,就能把能控制的部分都控制住: ① Article 的標題(前 200 字)塞滿核心關鍵詞(確保在未滿 64 贊或 V8.2 沒讀到圖時,AI 光靠標題就能精準匹配受衆); ② Article 的封面圖放核心信息圖(確保走 V5 或滿 64 贊後第一順位讀到乾貨); ③ 發完 Article 後,立刻單獨發一條“導讀長 Post”,並把最核心的那 1 張結果對比圖直接作爲“普通圖片附件(post.media)”掛在這條導讀 Post 上——這樣從第 0 個贊開始,就能繞開 64 贊門檻,讓 V8.2 把你的前 4,000 字導讀和首圖喫得乾乾淨淨!

48 爲什麼說發完 Article 之後千萬別頻繁撤下改稿?ArticleTweetContent 規則在攔什麼?

  • 先說人話(這在問什麼、有什麼影響): 很多完美主義創作者發完一篇長 Article 後,發現裏面有個標點或措辭不順眼,就點進編輯器修改。但在 X 的產品設計裏,修改一篇已發佈的 Article 時,系統會先把這篇 Article 從“已發佈(Published)”撤下來變成未發佈草稿狀態,等你改完再次點發布後才恢復。這中間撤下改稿的幾十分鐘,在推薦系統的安檢門裏會發生什麼?
  • 代碼已證實的真相(已知): 在可見性過濾系統 visibility-filtering/rules/tweet_rules.rs(#L247-L252)和 levels.rs 裏,有一條專門針對 Article 的硬規則叫 ArticleTweetContent:只要一條帖子關聯了 Article,並且該 Article 當前的狀態不是 Published(比如處於 Draft 草稿、SoftDeleted 軟刪除或狀態缺失),在 TimelineHomeHydration 安全級別下就會直接執行過濾移除(Drop)!此外,如果是設爲僅訂閱者可見的付費 Article,通用過濾器 IneligibleSubscriptionFilter 會攔截未付費訂閱讀者,且媒體接口(article_client.rs)也會對無權限者隱藏圖片。92 93
  • 代碼還看不見的盲區(待查): 當你在線上點下“重新發布(Republish)”的那一秒,各個分佈式緩存節點需要隔多少秒或多少分鐘才能把狀態全部同步刷新回 Published,取決於線上緩存配置。
  • 給創作者的實操結論(判斷): 千萬別在 Article 發佈後的推薦期裏頻繁撤下來慢慢改稿! 因爲在你撤下改稿的這段“未發佈空窗期”裏,一旦觸發 ArticleTweetContent 規則,你的帖子就會被當成未發佈草稿直接攔截隱身。建議在草稿箱裏預覽檢查好代碼塊、公式和錯別字後再一次性正式發佈;萬一必須改,改完務必第一時間確認它已經重新變回 Published(已發佈)狀態!

49 創作者在後臺看到的“瀏覽量(Views)”,能不能用來判斷有多少人真正讀完了我的長文或 Article?

  • 先說人話(這在問什麼、有什麼影響): 發完一篇長 Post 或 Article 後,大家最喜歡盯着帖子右下角的那個“瀏覽量(Views,比如 5 萬次觀看)”看。很多人以爲:“顯示 5 萬 Views,就代表有 5 萬個讀者點開了我的長文並把它讀完了!”如果拿這個數字來做內容復盤,會掉進什麼坑裏?
  • 代碼已證實的真相(已知): 根據 X 官方幫助文檔(View counts)的定義以及源碼(engagement_counts_hydrator.rs 與 recsys_batch.py)的字段區分:前臺公開顯示的 Views(對應一般 view_count)是一個極其寬泛的曝光計數——只要讀者在時間線上匆匆劃過你的帖子(哪怕連“展開全文”都沒點、1 秒鐘就划走了)也算 1 次 View;同一個讀者早晚刷到兩次算 2 次 Views;別人點進你主頁看、搜索看到、甚至你自己點開看自己的帖子,統統都會重複累加進這個 Views 裏! 它既不是“去重後的獨立讀者人數”,也不是前面冷啓動查的內部 view_count_on_home(純首頁推薦曝光),更不等於模型內部訓練用的 DWELL_TIME(閱讀停留秒數)或 CLIENT_TWEET_RECAP_DWELLED(深度閱讀標記)。59 91
  • 代碼還看不見的盲區(待查): X 創作者後臺(Analytics)目前並沒有向普通創作者開放“單篇長文的平均閱讀秒數”、“滑到底部完讀率百分比”或“內部 CLICK_DWELL_TIME 達標人數”這些內部模型訓練指標。
  • 給創作者的實操結論(判斷): 平時做內容復盤和格式對比時,千萬別把表面虛高的總瀏覽量(Views)當成“讀完文章的人數”! 要想判斷一篇深度長文到底有沒有被真正讀進去、有沒有打動目標受衆,請重點看另外三個更實在的指標:① 收藏數(Bookmarks,代表讀者覺得有用、想存下來反覆查);② 複製鏈接數(讀者把鏈接拷走發給別人——這一項的係數在表裏最大,但係數乘的是預測概率,不能換算成值多少分);③ 點進主頁後的淨增關注數。看這三個數,是因爲它們說明讀者真的用了、存了、認了你;至於內容能推多遠,代碼裏沒有承諾。

研究範圍與驗證記錄

本指南最後修訂日期爲 2026 年 10 月 29 日(美國洛杉磯時間)。全文基於公開算法庫源碼拆解、23 頁技術覈查報告與第 7 版修訂稿整合而成:

  • 核心代碼基準:主報告基準固定於 Git 提交 5ed796374ea48ee26058aab66ab10c266bea2bef(2026-10-28 UTC),並將 10 月份的參數與架構變動一路追查覈對至最新公開提交 606b254b45be798bfaecfa8c23f5a9c51bc8000c(2026-10-29 UTC)。文中涉及跨日的關鍵提交均同時標出 UTC 時間與洛杉磯當地時間(PDT),官方更新說明日期則嚴格按 README.md 原文保留。
  • 歷史參數快照覈對:針對 10 月份權重變化,我們沿着同一個文件 home-mixer/params/param.rs 逐一比對了 20 個歷史提交快照,並將同一提交下 Home Mixer 與 VM Ranker 兩處默認值的異同並列呈現;針對 606b254 的可見性規則重構,我們將重構前後的 14 組規則列表與字段全部展開做了一致性覈對,確認入口規則與執行順序完全一致。
  • 本地代碼重寫與函數實測驗證:
    1. 原技術調研對排序與過濾核心邏輯用 Python 進行了等價重寫驗證,共通過 143 項斷言測試(Assertions),覆蓋 26 個源碼文件的一致性覈對;
    2. 成文階段針對同作者候選計數、長短帖穿插、對話卡片組裝(convo_marshaller.rs)及後置對話去重,額外完成了 22 項局部斷言測試(覈對 8 個源碼文件);針對轉發與停留加權計算,完成了 14 項加權斷言測試(覈對 4 個源碼文件);
    3. 針對 CREAD 停留時間重建與 CLICK_DWELL_TIME 二分類閾值(輸入 9, 10, 10.0001, 20),在本地 CPU 上直接調用了原始 Python/JAX 純函數驗證邊界;
    4. 針對 長 Post vs. Article 專題,對 Home Mixer 的 sources、filters、scorers、params、candidate_pipeline 及可見性、行爲協議接口進行了涵蓋 103 個文件的有界檢索;並對 V5 與 V8.2 內容理解處理器編寫了輕量內存對象測試,直接調用原函數完成了 10 項輸入輸出實測檢查(全部通過,驗證了 4,000 字符截斷、200 字符 Article 標題共存以及 V5/V8.2 對 Article 封面與內嵌圖的抓取差異;對比兩個提交間的 14 個內容路徑文件,12 個文件二進制 blob 完全一致,另 2 個僅新增機構徽章字段)。
  • 嚴謹性聲明:上述本地斷言與函數檢查均用於 100% 確認公開源碼的數學邏輯與分支條件,我們絕不將不同階段的局部斷言次數簡單相加吹噓成“官方線上整合測試”,也不在缺乏線上特徵開關、未開源前端遙測與未公開模型權重的情況下,替任何單篇帖子捏造所謂的“官方推薦總分”或“保底曝光倍數”。文中的報價溝通、會議紀要工具測試、中文發票 OCR 測評與租房交接表,均爲幫助理解的說明性情境與算例,不是作者親歷的實測記錄。

參考資料

代碼鏈接固定到文中所用的提交;第三方文章是被覈查的對象,技術結論以相應的源碼和官方資料爲依據。

[1] V8.2 第一個可用媒體及視頻幀。

[2] 新版加權計分與作者多樣性。

[3] Hootsuite 的一般帖子頻率建議 2025 年 4 月 18 日。

[4] 被覈對的 X Algorithm Playbook 頻率解讀。

[5] 模型輸入與推薦流程。

[6] X 官方長貼與 Articles 定義及分發建議。

[7] 被覈對的 Gridlok 原文 2026 年 4 月 3 日。

[8] 被覈對的 SocialPilot 原文 頁面標爲 2026 年 9 月。

[9] 被覈對的 Bangerkit 原文 2026 年 10 月 8 日。

[10] X 官方 Premium 說明。

[11] 公開更新日期、固定提交與時區。

[12] 公開默認的同步方式,以及 Home Mixer 與 VM Ranker 的使用路徑。

[13] CREAD 的多門檻訓練與停留時間重建。

[14] 點擊停留二元目標、ld 召回分支與不同的信號定義。

[15] 同一路徑的十月互動係數歷史。

[16] FairShare 初篩在十月的新增與啓用。

[17] 10 月 28/29 日快照中的新功能、開關及視頻路徑。

[18] 對話模塊與祖先帖子的實際選擇。

[19] 串文去重在評分之後。

[20] 已看過濾也檢查父帖與轉發原文。

[21] 權重與作者多樣性公開默認。

[22] 時間窗口與特定來源上限 不等同每日發文配額。

[23] X 官方串文展示說明。

[24] 回覆候選過濾的範圍與開關。

[25] Hootsuite 長單帖與串文小實驗 2024 年 1 月 31 日。

[26] 2023 年官方 Heavy Ranker 文件。

[27] 目前兩處係數、概率乘法及互關的適用條件。

[28] 停留事件與點開後閱讀是不同目標。

[29] 實際轉發新增一條關係網召回路徑。

[30] 原作者與轉發者的粉絲圈、回覆例外及附帶內容。

[31] 候選召回讀取的是當前讀者的歷史。

[32] 長停留目標進入召回訓練及推理。

[33] 讀到底召回的公開時間、訓練分支與適用範圍。

[34] 索引窗口與召回數據集:生產資料不等於實際送出曝光。

[35] 冷啓動資格、實驗分組與資料邊界。

[36] 冷啓動的 Beta 抽樣與個人化二次選擇。

[37] 點贊事件的索引更新門檻、節流與年齡邊界。

[38] 1fav、32fav、搜尋與回覆索引的實際生產條件。

[39] 48 小時到底檢查誰:候選 ID、來源窗口與轉發原文。

[40] 收藏與相似內容的後續召回。

[41] 收藏的三個位置:融合、個人後續召回與沉浸式訓練。

[42] 互相關注的回覆預測條件加成。

[43] 個人頁點擊與關注作者是不同目標。

[44] 作者簡介與內容表示。

[45] 負向預測與讀者屏蔽靜音的硬篩選。

[46] 長度與換行資料的建立及傳遞。

[47] V8.2 文字截斷的局部範圍。

[48] 視頻目標與十秒資格的不同範圍。

[49] 視頻超過十秒的實際索引資格與三個 builder。

[50] 視頻索引的窗口、Evergreen 命名與不經同一十秒檢查的分支。

[51] 64 個讚的特殊視頻資格與後續檢查。

[52] 視頻對照檢查中的 64 與 512 各自代表什麼。

[53] 長視頻開頭檢查與 512 門檻的其他資格。

[54] 互動誘導、hashtag 濫用及正常 hashtag 特徵。

[55] 閾值 10 的二元目標與標籤函數。

[56] 其他停留目標與推理輸出。

[57] 冷啓動候選篩選及後續選擇。

[58] 冷啓動數值默認。

[59] 前臺觀看數的官方定義。

[60] 冷啓動目標名次、作者多樣性與最後展示。

[61] FairShare 的來源分組、比例分配與模型候選上限。

[62] 新讀者條件不能變成新作者養號規則。

[63] 舊原文與新轉發候選的年齡及去重。

[64] 編輯版本被取代的判斷。

[65] 回覆內容的模型評估與公開範圍。

[66] 多層自我回復垃圾檢查的完整資格。

[67] 回覆分類器的保護條件與零分寫入範圍。

[68] 引用原文與對話祖先的可見性依賴。

[69] 外部網址的公開特徵與安全規則。

[70] 跳轉鏈中的低品質網址。

[71] 置頂問題網址與賬號標籤。

[72] Under the Hood 官方入口與報告讀法。

[73] 低品質網址 v1 與 v2 的實際條件。

[74] 問題置頂網址的七日賬號標籤。

[75] 特定賬號標籤如何影響推薦資格。

[76] 安全規則的公開範圍與 10 月 29 日重構覈對。

[77] 侮辱標籤的套用條件、讀者範圍與入口差異。

[78] LOW_QUALITY/MISINFO 警告、source 與互動政策。

[79] 最近五筆中三筆的賬號標籤聚合默認。

[80] 賬號聚合的事件、timeline、轉發與到期時間。

[81] 重複文字 cluster 到 COPYPASTA_SPAM 的處置。

[82] Under the Hood 的報告資格與資料期間。

[83] V8.2 的長帖文本和 Article 標題分別如何截斷。

[84] Home 模型中的互動計數輸入與融合函數。

[85] DPP 的內容多樣性選擇及其後續分數處理。

[86] OON 乘數、作者多樣性與乘數應用時機。

[87] Article 與 NoteTweet 身份、正文輸入字段及上游映射。

[88] V5 與 V8.2 內容和媒體處理差異。

[89] Article 媒體獲取的上游條件。

[90] 點擊、展開、詳情停留與 Article 頁面標識。

[91] 閱讀標籤到訓練與服務的已知鏈路及缺口。

[92] Article 發佈狀態和媒體可見性的規則範圍。

[93] 訂閱資格和 Article 媒體讀取權限。

[94] 候選來源、格式字段與最終預測融合的檢查範圍。

[95] Longer Post 的回覆與引用使用方式。

[96] 2026 年 8 月 Article 瀏覽量觀察樣本,非同稿格式實驗。

[97] 歷史 Article 收益安排與當前獎勵計劃,不能替代推薦係數。

[98] 停留值的單位證據與點擊停留的上游缺口。