2026/08/14

XアルゴリズムOSSコード解読

Xの「For You」アルゴリズム全コード解読:バズの数式とスコアリング重みの真実

X(旧Twitter)の「おすすめ(For You)」フィードを制御する公式オープンソースリポジトリ(xai-org/x-algorithm)で、2026年8月13日に最新の本番コードとパラメータが公開された。この記事では、RustやScala、Pythonで記述されたリポジトリを直接読み解き、投稿の評価を決めるスコアリング数式、アクション別の具体的な重み係数、ブルーバッジ(Premium)の本当の効果、そして連投減衰の正確なメカニズムまで全貌を解説する。

1. 「いいね」の10倍効くアクションとは?スコアリング重みの全実数値

Xのフィード表示におけるスコア算出ロジックは、home-mixer/scorers/ranking_scorer.rs 内で Final Score = Σ (weight_i × P(action_i)) という単純な加重和として実装されている。ここで P(action_i) は、閲覧者がその投稿に対して特定のアクションを起こす確率を機械学習モデル(Phoenix)が予測した数値だ。

home-mixer/params/param.rs 内で定義されている本番用デフォルト重み(production default)を抽出すると、従来「インプレッションを伸ばすために重要」と信じられていた噂とはまったく異なる実数が浮かび上がる。

ユーザーアクション スコア重み 「いいね率10%」と等価な確率 特徴・備考
コピーリンク共有 20.0 0.25% 全アクション中最大。外部への拡散価値を最重視
相互フォロー間の返信ブースト +15.0 0.25% 返信重み5.0と合算で実質20.0の破格扱い
返信(Reply) 5.0 1.0% いいねの10倍の評価
引用(Quote) 5.0 1.0% 返信と同等の評価
DM共有 5.0 1.0% プライベート空間への持ち出しを評価
著者フォロー 4.0 1.25% 新規ファン獲得シグナル
一般共有 2.0 2.5% SNS内シェア
リポスト(RT) 1.0 5.0% いいねの2倍
いいね(Favorite) 0.5 10.0% 最下位クラスの低い配点
滞在時間(秒) 0.004 / 秒 12.5秒 30秒滞在でいいね率24%相当の加点

数字を見れば一目瞭然だが、単なる「いいね(0.5)」をいくら集めてもスコアはほとんど伸びない。それに対して「コピーリンク共有(20.0)」や「返信(5.0)」、「相互フォロー間での返信(20.0)」は桁違いの重みが設定されている。また、プロフィールのクリック(ProfileClickWeight = 0.0)や単に一瞬立ち止まっただけのフラグ(DwellWeight = 0.0)は現在完全に無効化されているのも興味深いポイントだ。

2. 通報「-234.0」の恐怖とアカウントDROPの二次被害

ポジティブな加点の一方で、ユーザーからのネガティブフィードバックに対する減点(マイナス重み)は絶対値が極めて大きく設定されている。

通報(-234.0)、ミュート(-58.8)、興味なし(-43.2)、ブロック(-31.2)という数値は一見すると「通報1件でいいね468件分が吹き飛ぶ」ように見える。しかしソースコード内のコメントには、「全体の中で発生頻度が極めて低いアクションのため、適切なバランスを取るべく係数を大きく調整している」と明記されている。つまり確率値にかけるための数値設計なのだが、それでも1万人に2人(0.021%)の割合で通報予測が立つだけで、いいね率10%のポジティブ評価が相殺される計算になる。

さらに深刻なのは二次被害だ。ネガティブフィードバックが蓄積すると、非同期で動くアカウント評価サービス agathasafety-label-user-agg がアカウントに対して悪質フラグを書き込む。その結果、リクエストパスの最終段階にある visibility-filtering/rules/registry.rs の判定ルールによって、個別の投稿スコアが高くてもアカウント単位で「DROP(非表示)」処理されてしまう。煽りや釣りで返信数を稼ごうとすると、通報とミュートを誘発してアカウントごとシャドウバン相当の状態に陥るリスクがある。

3. 「1日何本投稿すべきか?」連投減衰と既読化リセットの仕組み

連投によってタイムラインを占有する行為を防ぐため、home-mixer/scorers/ranking_scorer.rs では著者多様性減衰(Author Diversity Decay)が組み込まれている。

// 著者多様性減衰のスコア補正計算 (ranking_scorer.rs)
// k: その候補スロート内で同一著者が既に露出した回数
let decay = 0.5;
let floor = 0.25;
let multiplier = (1.0 - floor) * decay.powi(k) + floor;
// 1本目: 1.0, 2本目: 0.625, 3本目: 0.438 ... 5本目以降: 0.25固定

過去には「数時間あけて投稿すれば減衰がリセットされる」という説があったが、コードを解析した結果これは間違いであることが判明した。減衰の指数 k は、リクエスト発生時に閲覧者の候補プールに残っている自分の投稿数をもとに毎回計算される。そして候補プールから投稿が消えるリセット条件は「時間の経過」ではなく、スコアリング前に行われる PreviouslySeenPostsFilter による**既読化(すでに画面に表示されたこと)**だ。

ユーザーがXを開く頻度によって、1日に許容される効率的な投稿本数は異なる。1日1回しか開かないフォロワーに対しては、何時間あけて投稿しても1日の全投稿が同一スロートに乗り、2本目以降は即座に減衰を受ける。一方で、とにかく総インプレッション量を最大化したい場合、5本目以降は減衰が 0.25(1/4)で下げ止まる(floor)ため、投稿本数を増やすほど全体の積算インプレッション自体は増え続ける。ブランディング重視で1本あたりのエンゲージ率を高めたいなら1日1〜2本、総露出量を追い求めるなら1日5〜15本と、目的にあわせた割り切りが必要になる。

4. ブルーバッジ(認証)はスコアを上げるのか? PageRankの正体

「課金してブルーバッジ(X Premium)を取得すると表示が優遇される」という話の真相はどうだろうか。スコアリングエンジン home-mixer の内部を探しても、投稿オブジェクトに認証フラグを見て直接スコアを掛け算するコードは存在しない。

しかし、グラフ構造からアカウントの信頼度を計算する user-cred-v2(Scala実装)を読み解くと、認証の大きな影響が判明する。

// validUserInfoPipe から Premium アカウントを抽出しテレポート質量のシードにする
val normalizedUniform = getNormalizedUserMassPipe(
  validUserInfoPipe.filter(u => !u.isNearZero && u.isPremium).map(u => UserMass(u.id, 1.0))
)
// prior = (1 - β) * normalizedUniform + β * normalizedEngagement

PageRankアルゴリズムにおいて、ランダムウォークのジャンプ先となる「テレポート質量」の50%が、Premiumアカウント(Blue/Gold/組織認証)のみに均等分配されている。非認証アカウントはこの初期質量を0でスタートするため、他者からのリンク伝播だけで信頼度を稼がなければならない。つまりブルーバッジは「スコアリングの数値を直接底上げするブースト機能」ではなく、「アカウントの信頼度 PageRank を高め、スパム判定フィルタで落とされないための安全装置」として働いているのが実態だ。

アルゴリズムを味方につけるこれからのX運用

xai-org/x-algorithm の本番コード解析から得られた結論は非常に明快だ。単なる「いいね」を集めるテクニックや、プロフィールへの誘導を繰り返す手法は、アルゴリズムの計算式においてほとんど評価されない構造になっている。

これからインプレッションを伸ばすために最も重要なのは、読んだ人が思わず誰かに「DMやコピーリンクで共有したくなる」ような深い情報を提供すること、そして相互フォローの関係を大切にして「お互いに返信を交わす会話の場」を作ることだ。ネガティブフィードバックの破壊力を意識しつつ、本質的な価値のある発信を続けていこう。