こちらで公開されていたもの。
x.com/XEng/status/1965226798…
以下、GPT-5 Proの全文も貼っておきます。
了解。このzipの中身を直接読んで、X(旧Twitter)の推薦(とくにホームの「おすすめ / For You」)がどう動いているか、仕組み→どんな信号(キー)で決まるか→どのコードに書いてあるかの順で噛み砕いて解説します。
※このアーカイブは一部の長いパスが ... で省略表示されているファイルもあります(可視化用に省略されているだけで、役割は把握できます)。
1) 全体アーキテクチャ(ざっくり地図)
ホーム推薦は大きく言うと 候補生成 → 特徴量付与(feature hydration)→ モデルスコアリング → ルール/多様化の再ランク → 可視化・配信 の多段構成です。
候補生成(Candidate Generation)
フォロー内(In-Network)とフォロー外(Out-of-Network, OON)の両方から投稿候補を集めます。
主要コンポーネント:
TweetMixer・CR-Mixer が各種ソースからかき集め
検索系 Earlybird、グラフ・埋め込み系 UTEG / SimClusters / TwHIN など
特徴量付与
投稿・作者・閲覧者・関係性・安全性など、推定のための数百の特徴量を付けます(後述の「何がキーか」で詳述)。
代表的な宣言は home-mixer/.../model/HomeFeatures.scala
モデルスコアリング
gRPC経由でNavi と呼ばれる予測サービスに特徴量を渡し、「いいね・RT・返信・良質クリック・滞在・ブックマーク・動画再生・共有・ネガティブ」等の複数タスクの確率を返してもらいます。
それらを重み付きで合算して最終スコアを作ります(後述)。
再ランク(Heuristics & Listwise Re-ranking)
ルールで微調整:OONの減衰、返信の扱い、マルチタスク正規化、作者/ソース多様性の確保、重複の抑制、ユーザの「もっと見る/減らす(Control AI)」の反映など。
可視性/安全性フィルタ
visibilitylib のルールエンジンでNSFWやスパム、ブロック/ミュート、報告・ヘルスラベルに基づく非表示・ダウングレードを適用。
2) 何が「推薦されるキー」なのか(重要信号の実体)
内部では Feature(特徴量) と Param(重みや閾値などのパラメータ) の2層で決まります。モデル入力の特徴量が最重要キーで、次に重み付けや再ランクのパラメータが大きく効きます。
A. モデルが見る主な「特徴量(Features)」
宣言の密集地:home-mixer/.../model/HomeFeatures.scala と src/.../timelines/prediction/features/recap/RecapFeatures.scala。代表カテゴリと具体例は:
閲覧者↔作者の関係性・ソーシャル証拠
RealGraph によるフォロー内親密度スコア(RealGraphInNetworkScoresFeature、home-mixer/.../store/RealGraphInNetworkScoresStore.scala)
「誰がいいね/RTしたか」の証拠(ValidLikedByUserIdsFeature、RetweetedByEngagerIdsFeature)
著者が保護アカウント/認証/フォロワー数 等(AuthorIsProtectedFeature、AuthorFollowersFeature ほか)
内容の近さ(埋め込み・グラフ)
SimClusters(コミュニティ埋め込み)/ UTEG(User-Tweet-Entity Graph)/ TwHIN(知識グラフ埋め込み)
これらは主に CR-Mixer の類似度エンジンで候補を作る段に登場
例:cr-mixer/.../similarity_engine/SimClustersANNSimilarityEngine.scala
cr-mixer/.../candidate_generation/UtegTweetCandidateGenerator.scala
ポスト(ツイート)自体の属性
返信かRTか引用か(IsRetweetFeature, InReplyToTweetIdFeature など)
年齢(新しさ)、URLやメディアの有無/種類(HasImageFeature, HasVideoFeature, MediaCategoryFeature など)
言語(TweetLanguageFromTweetypieFeature)、話題/エンティティ(SemanticAnnotationIdsFeature)
閲覧者の文脈
使用言語集合(UserUnderstandableLanguagesFeature)、最近のエンゲージメント履歴、過去に見た作者やメディアクラスター(ImpressedTweets, ServedAuthorIdsFeature)
安全性・ヘルス
作者/投稿の安全ラベル(AuthorSafetyLabels 等)
visibilitylib が参照する安全レベル/ルール(visibilitylib/.../VisibilityLibrary.scala)
これらの特徴量は DataRecord に詰めて予測サービスへ渡されます(NaviModelScorer.scala)。
B. 予測スコア(マルチタスク)と重み付け
home-mixer/.../scorer/PredictedScoreFeature.scala がどの予測を読むかを定義。対応する生の定義は src/.../prediction/features/recap/RecapFeatures.scala に列挙されています。主に:
ポジティブ系:PREDICTED_IS_FAVORITED(いいね), ...IS_RETWEETED, ...IS_REPLIED,
...IS_GOOD_CLICKED_V1/V2(良質クリック), ...IS_TWEET_DETAIL_DWELLED_15_SEC(詳細面滞在),
...IS_PROFILE_DWELLED_20_SEC(プロフィール滞在), ...IS_BOOKMARKED, ...IS_SHARED, ...IS_VIDEO_PLAYBACK_50 など
ネガティブ系:PREDICTED_NEGATIVE_FEEDBACK_V2, ...IS_REPORTED, ...STRONG_NEGATIVE_FEEDBACK, ...WEAK_NEGATIVE_FEEDBACK など
home-mixer/.../scorer/NaviModelScorer.scala で各タスクの予測値 × 重みを合算して ScoreFeature / WeightedModelScoreFeature に格納します。重みは ScoredTweetsParam.Scoring.ModelWeights(同パッケージ内の ScoredTweetsParam.scala)のFeature Switchで調整可能。
要するに、「どの行動をどれだけ価値とみなすか」を重みで決め、その重みで各タスクの予測確率を合算して最終スコアにします。
C. ルール/再ランクで効く「パラメータ(Params)」
home-mixer/.../product/scored_tweets/param/ScoredTweetsParam.scala に多数の FSParam(Feature Switch Param) があり、挙動を細かく動的にチューニングします。特に効くもの:
OutOfNetworkScaleFactorParam
フォロー外候補のスコアに乗算する減衰係数。実装は home-mixer/.../scorer/RescoringFactorProvider.scala の RescoreOutOfNetwork
ReplyScaleFactorParam
返信の減衰係数(RescoreReplies)
MTL Normalization(Alpha/Beta/Gamma)
マルチタスクのスケール差を正規化(RescoreMTLNormalization)
作者/ソース多様性
EnableCandidateSourceDiversityDecay, CandidateSourceDiversityDecayFactor, AuthorDiversityDecayFactor などで同じ作者/同じ候補源の連発を抑える(CandidateSourceDiversityListwiseRescoringProvider.scala, ImpressedAuthorDecayRescoringProvider.scala)
Control AI(ユーザが「もっと見る/少なく」した話題を反映)
EnableControlAiParam, ControlAiShowMore/ShowLessScaleFactorParam(ControlAiRescorer.scala)
各種フィルタのON/OFF・閾値
例:OutOfNetworkCompetitorURLFilter.scala(フォロー外で競合URLを含む投稿を除外)、
QualifiedRepliesFilter.scala(返信の質を条件でふるい分け)、
RetweetSourceTweetRemovingFilter.scala(RTと元ツイの重複回避)、
GrokAutoTranslateLanguageFilter.scala(自動翻訳キャッシュ状況×言語での露出制御)など
3) 候補生成のソース(どこから集めるか)
In-Network(フォロー内)
タイムラインランカー/Earlybird の in-network 取得、相互作用の強さ(RealGraph)など。
例:product-mixer/.../TimelineRankerInNetworkCandidateSource.scala、home-mixer/.../RealGraphInNetworkScoresStore.scala
Out-of-Network(フォロー外)
Earlybird 検索:tweet-mixer/.../candidate_source/earlybird_realtime_cg/EarlybirdRealtimeCGTweetCandidateSource.scala
SimClusters ANN:cr-mixer/.../candidate_generation/SimClustersInterestedInCandidateGeneration.scala
UTEG(User-Tweet-Entity Graph):cr-mixer/.../candidate_generation/UtegTweetCandidateGenerator.scala
関連ツイート/動画/トピック:cr-mixer/.../candidate_generation/RelatedTweetCandidateGenerator.scala / RelatedVideoTweetCandidateGenerator.scala / TopicTweetCandidateGenerator.scala など
構成(ミックス)
home-mixer/.../product/scored_tweets/candidate_pipeline/ 配下に InNetwork, Uteg, Backfill, PopularVideos, Lists, ContentExploration 等の候補パイプライン設定が並びます(ScoredTweets*CandidatePipelineConfig.scala)。
4) スコアリングと再ランク(どう並べ替えるか)
Navi モデル呼び出し:home-mixer/.../scorer/NaviModelScorer.scala
DataRecord(HomeFeatures群)→ gRPC → 予測(RecapFeaturesに対応)を受け取る
重み付き合算で ScoreFeature を生成
ヒューリスティクス & リストワイズ再ランク:home-mixer/.../scorer/HeuristicScorer.scala
Out-of-Network 減衰:RescoreOutOfNetwork
返信減衰:RescoreReplies
MTL 正規化:RescoreMTLNormalization
多様性:CandidateSourceDiversityListwiseRescoringProvider.scala、ImpressedAuthorDecayRescoringProvider.scala 等
Control AI(ユーザ操作の反映):ControlAiRescorer.scala
重要度の低いスコアのTop-K 抽出も別フィルタで(TopKFilter.scala)
安全性/可視性:visibilitylib/
SafetyLevel やラベルに応じて非表示/要確認/ダウングレードなどのアクションを返すルールエンジン。
5) どのコードに何が書いてあるか(道案内)
ここからが「どのコードにあるか」の回答本体です。相互参照しやすいよう役割ごとにまとめます。
ホーム推薦の“本丸”まわり
エントリ/プロダクト構成
home-mixer/server/src/main/scala/com/twitter/home_mixer/
.../product/scored_tweets/(For You の中核)
パイプライン設定:ScoredTweetsProductPipelineConfig.scala、.../candidate_pipeline/ScoredTweets*CandidatePipelineConfig.scala
スコアリング:scoring_pipeline/ScoredTweetsModelScoringPipelineConfig.scala、scorer/NaviModelScorer.scala, scorer/HeuristicScorer.scala, scorer/RescoringFactorProvider.scala, scorer/*ListwiseRescoringProvider.scala
特徴量定義:model/HomeFeatures.scala(超重要)
モデルの予測タスク定義
src/scala/com/twitter/timelines/prediction/features/recap/RecapFeatures.scala
パラメータ(Feature Switch)
home-mixer/.../product/scored_tweets/param/ScoredTweetsParam.scala(OON/Reply係数、MTL正規化、作者/ソース多様性、Control AI など)
home-mixer/.../param/HomeGlobalParams.scala(グローバル系)
候補生成
TweetMixer(検索/近傍)
tweet-mixer/server/src/main/scala/com/twitter/tweet_mixer/
例:candidate_source/earlybird_realtime_cg/EarlybirdRealtimeCGTweetCandidateSource.scala
CR-Mixer(埋め込み/グラフ)
cr-mixer/server/src/main/scala/com/twitter/cr_mixer/
例:candidate_generation/UtegTweetCandidateGenerator.scala
candidate_generation/SimClustersInterestedInCandidateGeneration.scala
similarity_engine/*TwHIN*, *SimClustersANN*, *UserTweetEntityGraph*
フィルタ/可視性
安全性ルール:visibilitylib/src/main/scala/com/twitter/visibility/VisibilityLibrary.scala
個別フィルタ例:
.../filter/OutOfNetworkCompetitorURLFilter.scala(競合URL)
.../filter/QualifiedRepliesFilter.scala(返信の質)
.../filter/RetweetSourceTweetRemovingFilter.scala(RT重複)
.../filter/GrokAutoTranslateLanguageFilter.scala(言語/翻訳)
関連データ・信号
RealGraph(作者–閲覧者の強さ)
src/scala/com/twitter/interaction_graph/(学習/スコアリング)
home-mixer/.../store/RealGraphInNetworkScoresStore.scala(取得)
ユーザ行動ストリーム(UUA)
unified_user_actions/README.md
共通フレームワーク(パイプラインDSL)
product-mixer/(ProductMixer本体とコンポーネント群)
6) まとめ(動作の要点)
候補は フォロー内×検索 と フォロー外×埋め込み/グラフ を多系統で集める。
たっぷりの 特徴量 をつけて Navi(gRPC)で 複数行動の発生確率を推定。
重み付き合算で一発スコア、さらに OON/返信/多様性/ControlAI などのルールで再ランク。
可視性/安全性 は最終段でフィルタリング/ダウングレードされる。
7) 次の読み解きヒント
重み(ModelWeights) の実値は ScoredTweetsParam.scala の FSParam 群(デプロイ時に切り替え可能)で追えます。
「なぜこの投稿が出た?」は、候補の FeatureMap(ScoreFeature, WeightedModelScoreFeature, ServedTypeFeature, SourceSignalFeature など)を見るとどのソース/理由/重みで浮いたかが辿れます。
「フォロー外が多い/少ない」を作るのは OutOfNetworkScaleFactorParam。
作者や候補源の連発抑制は *Diversity* 系の Listwise Rescorer が担当。
必要なら、このzipから主要なFeature名一覧や、ScoredTweetsParam.scala にあるチューニング可能なパラメータ名の抜き出し表も作れます。設計の観点では「どの信号をどれだけ価値と見なすか(重み)」と「どの分布にしたいか(多様性/比率/安全性)」がキモ、という理解でOKです。
Today, as part of our effort to make our platform transparent, we are open-sourcing the latest code used to recommend posts on the For You timeline.
Our algorithm is always a work in progress. We will continue to refine our approach to surface the most relevant content to our community.
github.com/twitter/the-algor…