X(旧 Twitter)の「おすすめ(For You)」フィードを構築するコードが、「xai-org/x-algorithm」として公開され、2026 年 8 月 13 日の更新では、それまで公開リポジトリに含まれていなかった 「スコアリングに使われる重みの具体的な数値」 と 「投稿をフィードから除外する仕組み(visibility filtering)」 も追加されました。
つまり、「X はどんな投稿をおすすめに出そうとしているのか」を、実際のコードと数値からある程度読み解けるようになったわけです。もちろん、これだけで X のすべてがわかるわけではありませんが、なかなか興味深い内容だったので、できるだけわかりやすく整理してみます。
あ、ちなみに私個人はあまり X での露出とかに興味はないです。Twitter 歴が無駄に長いもので、元々日常の適当なつぶやきを垂れ流す場としてしか使っておらず、いちいちどんな投稿が表示されやすいのかな~ なんて考えて投稿したこともない。とはいえ、一応お仕事的にお客様から X でのマーケティングについて聞かれることもある立場なので、こういうアルゴリズムの理解自体はしておかないとなということでドキュメントを読んでおります。
そうそう先日ちょっと気になって Grok さんに自分の X アカウント分析してもらったんすよ。そしたら「専門分野や日常ネタでたまにエンゲージメント高い投稿をしてるけどサッカー観戦中の短い連投みたいなのはエンゲージメント低いからやめな(意訳)」と言われました...... なんかすまん
— Yoshiki Kato (@burnworks) July 24, 2026
最近はTwitter(X)もきちんとビジネスやブランディングに結びつくように戦略的に運用しましょうとか言われるんですが、拡張プロフィールにも書いている通り私の運用方針は超適当ですので仕事とかで知ってフォローしてくださった方には申し訳ないと思っております...... pic.twitter.com/FtHMZN4l4q
— Yoshiki Kato (@burnworks) July 24, 2026
余談が長くなったので本題に。
まずは結論から
細かい仕組みはあとで説明するとして、まずは公開されたコードから読み取れるポイントをおおまかにまとめます。
投稿の評価は、基本的に次の計算で決まります。
- 「その投稿を見た人が、いいねや返信などの行動を取る確率」×「行動ごとに決められた重み」の合計
たとえば、ある投稿を見た人が返信する可能性や、誰かに共有する可能性を X 側が予測し、それぞれに決められた点数を掛けて合計するイメージです。
行動ごとの重み(Weight)は home-mixer/params/param.rs にデフォルト値として定義されています。
主なものを大きい順に並べると、次のようになります。
| アクション | 重み |
|---|---|
| リンクをコピーして共有 | 20.0 |
| 返信(リプライ) | 5.0※ 相互フォロー相手の 「リプライでもリポストでもない投稿」 には +15 → 実質 20.0 |
| DM で共有 | 5.0 |
| 引用 | 5.0 |
| 著者をフォロー | 4.0 |
| 共有(シェア) | 2.0 |
| リポスト | 1.0 |
| いいね | 0.5 |
| 投稿のクリック | 0.4 |
| 外部リンクを開く | 0.2 |
| 画像拡大 / 動画再生 / VQV | 各 0.05 |
| 滞在時間(連続値) | 0.004 |
| 滞在(dwell) / プロフィールクリック | 0.0 (現時点で無効) |
反対に、報告やミュートなどには「マイナスの重み」が設定されています。
| ネガティブアクション | 重み |
|---|---|
| 報告(report) | -234.0 |
| 著者をミュート | -58.8 |
| 「興味がない」 | -43.2 |
| 著者をブロック | -31.2 |
| 滞在しなかった | -0.02 |
この表を見るかぎり、X が高く評価しやすいのは、次のような投稿だと考えられます。
- 思わず返信したくなる投稿(特に相互フォローの相手によるもの)
- 誰かに送りたくなる投稿(リンクのコピーや DM での共有)
- 自分の言葉を添えて引用したくなる投稿
- 「この人をフォローしたい」と思わせる投稿
- いいねやリポストも評価されるが、上記の行動より重みは小さい
- 報告やミュートなどには大きなマイナスの重みがある。ただし、実際の件数を単純に差し引くのではなく、閲覧者ごとに予測された確率へ掛けられる
ただし、この数字をそのまま見て、「リンクのコピーは、いいねの 40 倍も重要なのか。なら、リンクをコピーされる投稿を狙えばいい」と考えるのは短絡的すぎです。重みの数字だけでは判断できない理由があるので、その点もあとで説明します。
ということで、ここからは仕組みをもう少し詳しく見ていきましょう。
1. おすすめフィードができるまで
まず、公開されたリポジトリをもとに、おすすめフィードが組み立てられるまでの全体像を見てみます。その処理は、大きく 2 つの流れに分かれています。
- リクエストパス:
home-mixer/が、候補となる投稿を集め、必要な情報を補い、不要なものを除外し、点数を付け、表示する投稿を選び、広告などと組み合わせます。これは、おすすめの画面が読み込まれるたびに実行される処理です。
- ラベリングパス:
grox/は文章や画像・動画の分類、agatha/はブロックや報告の割合をもとにしたアカウント評価、bdsm/は不自然な行動の検出、user-cred-v2/はフォロー関係やエンゲージメントのつながりをもとにした PageRank の計算、といった役割を担います。そこで作られたスコアやラベルをvisibility-filtering/が読み、投稿を表示してよいか判断します。
この 2 つの処理は連携しています。ラベリングパスは、投稿やアカウントに「表示して問題がないか」を判断するための材料をあらかじめ用意する側、リクエストパスは、その情報も参照しながら候補を絞り込み、おすすめの並び順を組み立てます。
つまり、投稿は点数だけでおすすめに表示されるわけではありません。リクエストパスでは、投稿をランキングして並び順を決めますが、順位を決めたあとにも visibility-filtering/ に問い合わせます。そこで「表示しない」と判定された投稿は、どれだけ点数が高くても候補から除外されます。また、スコアを付ける前にも別のフィルターがあるため、投稿は処理の前後で複数のチェックを受けることになります。
ここまでが、おすすめフィードを組み立てる処理の全体像です。
一点だけ、公開されている数値の扱いについて注意点です。
param.rs の先頭には、mirrored from config feature-switch defaults; last sync 2026-08-12 というコメントがあります。README では、本番で使われる主要なデフォルト値を、設定システムから定期的に同期していると説明されています。ただし、あくまでデフォルト値です。実際の X では、A/B テストなどによって別の数値が使われる可能性もあるため、リポジトリ内の数値がすべての利用者に常に適用されるとは限りません。
では、次のセクションから具体的なスコアを見ていきましょう。
2. スコアはどう計算されるか
ranking_scorer.rs を読むと、投稿の最終スコアは、単純な足し算だけではなく、いくつかの調整を経て決まることがわかります。
1) 重み付けの合算
まず Phoenix というモデルが、「この人は、この投稿にいいねするか」「返信するか」「共有するか」 といった行動の確率を予測します。その確率に先ほどの重みを掛け、すべて合計します。予測値がない項目は 0 として扱われます。なお、滞在時間など一部の項目では、確率ではなくモデルが予測した連続値に重みを掛けます。
大事なのは、実際に付いた 「いいね」 の数をそのまま足しているのではなく、その投稿をこれから見る人が、どんな反応をしそうかを予測している、という点です。
2) 同じ人の投稿が続きすぎないように調整
同じ投稿者の投稿が複数候補に入った場合、2 件目以降のスコアには次の係数が掛かります。
multiplier = (1 - floor) × decay^k + floor
decay = 0.5, floor = 0.25
k は、その投稿者の何件目の投稿かを示す数字です(0 始まり)。係数は 1.0 → 0.625 → 0.4375 → 0.34375 → 下限 0.25 と下がっていきます。
簡単に言えば、同じ投稿者の投稿ばかりがおすすめを埋めないよう、同じ候補内に複数の投稿が入った場合、2 件目、3 件目とスコアの低い投稿ほど不利になる仕組みです。
3) フォロー外の投稿は 0.75 倍
フォローしていないアカウントの投稿には、原則として 0.75 の係数が掛かります。README で 「Out-of-Network Discount(ネットワーク外投稿への割引)」 と説明されているもので、コード上ではその係数が OonWeightFactor として定義されています。
さらに、EnableOonRescoreForInNetworkRepliesRetweets という設定があります。これは、フォローしている相手の投稿であっても、リプライやリポストなら Out-of-Network Discount を適用するかどうかを切り替えるものです。公開コードではデフォルトが true なので、これらの投稿にも同じ 0.75 の係数が掛かります。
つまり、元のスコアが同程度であれば、フォローしている相手による、「リプライでもリポストでもない投稿」 が相対的に有利になります。なお、コード上で特定のトピック ID (topic_ids) が指定された 「トピック向けリクエスト」 では、割引係数が 0.5 になります。これは特定の話題に関連する投稿を取得する 「内部的なリクエスト」 であり、「ハッシュタグ付きの投稿」 などという意味ではないので注意してください。
4) 表示回数の少ない投稿への露出補正
一方で、まだ表示回数の少ない投稿が一方的に不利にならないための調整もあります。
表示回数が基準値(デフォルトでは 1000)未満、投稿者のフォロワー数が上限(デフォルトでは 1000)以下、リプライやリポストではない、といった条件を満たす投稿が対象です。実験グループによっては投稿から 24 時間以内という条件も加わります。
条件を満たす投稿すべてを一律に押し上げるのではなく、その中から基本的に 1 件を選び、一定の順位帯まで引き上げる仕組みです。フォロワーが少なく、まだ十分に表示されていない投稿にも、見つけてもらえる機会を作ろうとしているわけですね。
5) 似た投稿が並びすぎないようにする
スコアが決まったあと、vm-ranker/ が 「DPP(Determinantal Point Process / 行列式点過程)」 という方法で投稿を並べ替えます。
なにやら難しそうな用語ですが、やっていることは比較的シンプル。似た内容の投稿がタイムラインに続けて並ばないよう、スコアを少し下げてでも、さまざまな話題が混ざるように調整します。この処理の対象は上位 150 件です。
3. 相互フォローの相手は強くなる
2026 年 7 月、相互フォロー相手の投稿を見えやすくし、「友人が返信欄に現れにくい」という問題を改善するために導入された変更 (以下ポスト参照) については、docs/BIDIRECTIONAL_BOOST_CHANGE.md に導入の経緯とコードの差分がまとめられています。
We're rolling out a small tweak to boost visibility of your posts to your mutuals (people who you follow back).
We noticed this data was missing from the algo and it made your friends appear less in your replies. This resulted in the reply section feeling more like a...
— Nikita Bier (@nikitabier) July 13, 2026
変更内容は、相互フォローの相手による 「リプライでもリポストでもない投稿」 に限り、閲覧者が返信する予測確率の重みを上乗せするというものです。
bidirectional_boost_eligible() は、その投稿がこの上乗せの対象になるかを判定する関数ですが、条件を見ると、「リプライでもリポストでもない」「投稿者と閲覧者が相互フォローである」という 2 つを満たす必要があります。
この仕組みは、最初から現在の設定で一斉に導入されたわけではありません。7 月 10 日に 0 / 5 / 10 / 15 / 20 の値で A/B テストを開始し、7 月 13 日には 20 が広く適用されました。ところがその後、7 月 24 日には 15 に引き下げられています。これに関しては、ワールドカップ 2026 の開催中、関連投稿の多くがフォロー外のアカウントから発信されていたために、本来見たい議論が十分に表示されない、というフィードバックが寄せられたことが調整理由のひとつとして挙げられています。
記事執筆時点のデフォルト値は 15。返信の基本的な重み 5.0 に加算されるため、相互フォロー相手の 「リプライでもリポストでもない投稿」 では合計 20.0、要するに「返信確率に掛ける重みが通常の 4 倍」になります。投稿全体のスコアがそのまま 4 倍になる、という意味ではありません。
これらの数字を見るかぎり、X が 「一方的にフォローしている有名人」 だけでなく、「実際につながりのある相手との会話」 をかなり強く重視しようとしていることがうかがえます。
4. 点数を付ける前に除外される投稿
ここまでスコアの話をしてきましたが、実はすべての投稿に点数が付くわけではありません。ランキングの候補に入る前に、条件に当てはまる投稿は機械的に除外されます。
home-mixer/filters/ に並んでいる主な条件は次のとおりです。
- 48 時間より古い投稿(
AgeFilter) - すでに表示・配信された投稿(複数のフィルタで重複して除外)
- フォロー外アカウントのリポストとリプライ(
OONRetweetReplyFilter) - ブロック・ミュートしているアカウントや、ミュートキーワードに該当する投稿
- 閲覧者自身の投稿
- 購読者限定で、閲覧する権限がない投稿
さらにランキングが決まったあとにも、visibility-filtering/ が投稿ごとに ALLOW(表示)、INTERSTITIAL(警告などを挟んで表示)、DROP(除外)のいずれかを返します。DROP になれば、その投稿は表示されません。
スレッドの元投稿、引用元、リポスト元が DROP になった場合、関連する投稿も連鎖的に除外される仕様です(AncillaryVFFilter)。
また、「フォロー外の人へのおすすめにだけ適用され、結果として DROP しか返さない」ルール群もあります。つまり同じ投稿でも、フォロワーには見える一方で、フォローしていない人のおすすめには出ない、ということがあり得ます。
5. 重みの数字だけを見ちゃいけない
param.rs では、重みの定義の直前に次のコメントが置かれています。
These weights reflect a combination of how much an action is valued in ranking and typical propensities of these actions across the X network (e.g. negative feedback is overall rare).
日本語訳:これらの重みは、ランキングにおいてその行動がどの程度評価されるかと、X 全体でその行動が通常どのくらい起きるか(たとえば、ネガティブな反応は全体としてまれであること)の両方を反映しています。
ここは今回の数字を読むうえで特に重要な部分と考えられます。つまり、重みは、あくまで 「その行動が起きると予測した確率」 に掛ける数字であり、重みが大きいからといって、その行動だけを狙えばよいわけではない、という理解が必要です。
- 「リンクをコピーして共有」の重みは
20.0と突出していますが、それだけ実際には起こりにくい行動だとも考えられます。仮に起きる確率が0.0001なら、重みが20でもスコアへの影響は0.002程度になります。 - 報告の
-234.0も同じで、そもそも報告はめったに起きない行動です。ただし、報告される確率が高いと判断された投稿は、いいねされる確率が高くても、そのプラスを打ち消される構造になっています。やはり、お行儀は大事です。 - 要するに 「重みの大きい行動を増やせば投稿が伸びる」 という単純な話ではないということ。重要なのは、その投稿を見た人が反応する確率をモデルがどの程度高く予測するかです。
もうひとつ重要なポイントが、この予測は見る人ごとに変わるという点です。
スコアリングには、閲覧者、つまりその投稿を実際に見る人の直近の行動履歴(モデル上では最大 1024 件分の履歴トークン) が使われます。投稿そのものに全員共通の絶対的な点数が付くのではなく、「この人に、この投稿が合いそうか」が計算されているわけです。
同じ投稿でも、見る人によってスコアは変わります。したがって、「これをすれば誰に対しても必ず伸びる」という万能な攻略法は存在しない、と考えたほうがよさそうです。
6. 投稿するときに参考になりそうなこと
公開コードだけを見て何でも断定することはできませんが、その構造から比較的明確に読み取れる点をまとめると以下のようになります。
- 同じような予測スコアなら、「リプライでもリポストでもない投稿」 が相対的に有利:
リプライとリポストは、フォロワーに対しても 0.75 倍になります。ただし、実際の順位は各アクションの予測確率にも左右されるため、「リプライでもリポストでもない投稿」 なら常に上位になるという意味ではありません。 - 同じおすすめ候補内に、同じ人の投稿が複数あると減衰する:
同じ投稿者の投稿は、スコア順で 2 件目が 0.625 倍、3 件目が 0.4375 倍になります。投稿間隔そのものを見ているわけではないため、「短時間の連投」に限った処理ではありません。 - 相互フォローの関係は明確に影響する:
返信の重みが 4 倍になるのは、相互フォロー相手の 「リプライでもリポストでもない投稿」 だけです。 - ミュート、ブロック、報告は大きなマイナス要因になり得る:
これらには大きなマイナスの重みがありますが、実際の件数を単純に差し引く仕組みではなく、閲覧者ごとに予測された確率へ掛けられます。またagathaは、ブロック / 報告といいねの割合からアカウント単位のラベルを付け、それが表示可否の判断にも使われます。ひとつの投稿だけでなく、アカウント全体に影響する可能性があります。 - 外部リンクを開く行動の重みは 0.2:
リンク付きであることだけを理由に一律で減点する明示的な処理は、公開されたコード内には見当たりません。ただし、リンクの有無がモデルの予測へ間接的に影響する可能性までは否定できません。 - VQV の重みには動画時間などの条件がある:
MinVideoDurationMsは10,000msに設定されており、VQV(動画の質の高い視聴)の重みが適用されるのは、動画が 10 秒を超え、かつ閲覧者のフォロワー数が 1 万人未満の場合です。ちょうど 10 秒の動画には適用されません。 - 48 時間を過ぎると候補から外れる:
公開されたおすすめのパイプラインでは、48 時間より古い投稿はランキング前のフィルタで除外されます。 - フォロワー数をそのまま加点する重みは見当たらない:
一方で、フォロワー数がまったく使われていないわけではありません。表示回数の少ない投稿を引き上げる条件に使われるほか、VMRanker にも投稿者のフォロワー数が渡されます。また、フォロー関係などをもとにした PageRank(user-cred-v2)は、投稿やアカウントの表示可否に関わるラベルを作るシステム群のひとつです。
7. 「おすすめに表示される方法」 のすべてが公開されたわけではない
ここまで読むと、「結局、何をすればおすすめに表示されるのか、その条件をすべて知りたい」 と思うかもしれません。しかし、公開されたコードから大まかな傾向は読み取れても、「この条件を満たせば必ず表示される」 という答えまではわかりません。
ここまで書いたとおり、おすすめの順位は見る人ごとの行動予測によって変わるうえ、A/B テストで異なる設定が使われることもあります。また、表示してよい投稿かを判断する仕組みにも、公開されていない部分があります。
リポジトリでは、仕組みを意図的に攻略されるリスクを理由に、grox が使う LLM のプロンプト(j2 ファイル)や、botmaker に関するルールの一部は公開されていないと説明されています。
その一方で、自分のアカウントや投稿にどのようなラベルが付いているかを確認できる 「Under the Hood」 というツールが試験提供されています。
これは手作業で付けられたラベルの有無も確認でき、公開コードと実際の判定を照らし合わせるためのツールという位置づけです。ただし、このツールで確認できるのは、主に表示に影響するラベルの状況です。おすすめでの順位や、表示を保証する条件がわかるわけではありません。
まとめ
文章が長くなったので最後にまとめ。
公開されたコードから比較的明確に言えるのは、X のおすすめフィードでは、返信、引用、他の人への共有、投稿者のフォローに、いいねやリポストより大きな重みが設定されていることです。同時に、報告やミュートなどのネガティブな反応にも、大きなマイナスの係数が設定されています。ただし、いずれも実際の反応件数を単純に足したり引いたりする仕組みではありませんし、重みの数字には「その行動がどれくらい起こりにくいか」も織り込まれています。数字の大小を、そのまま投稿の優先順位や攻略法に置き換えることはできません。
また、相互フォローへの上乗せが 2 週間という短い期間で 20 から 15 に変わったように、パラメータは実験によって今後も変わる可能性は高いです。
ということで、ここまで長々と書いてきました。今回、X のアルゴリズムに関するコードが公開された一番の意義は、「おすすめフィードを攻略する答え」 がわかることではありません。これまで体感やうわさで語られてきた仕組みを、一次情報で確かめられるようになったことだと思います。「外部リンクを貼ると不利」「フォロワーが多い人ほど有利」 といった通説を、公開されたコードと照らし合わせて検証し、考え直す。そのための材料として読むのが、このリポジトリの最も実用的な使い方になるでしょう。
参照元
- xai-org/x-algorithm(Apache License 2.0)
- home-mixer/params/param.rs:各パラメータの本番デフォルト値
- home-mixer/scorers/ranking_scorer.rs:スコア合成と各種調整の実装
- home-mixer/scorers/author_cold_start.rs:表示回数の少ない投稿を引き上げる処理
- home-mixer/util/candidates_util.rs:VQV の重みが適用される条件
- docs/BIDIRECTIONAL_BOOST_CHANGE.md:相互フォローへの上乗せを導入した経緯と差分
※ 初稿は 2026 年 8 月 13 日時点のリポジトリ内容に基づき、2026 年 8 月 19 日に当時のコミットと最新の main ブランチを照合して記述を確認しています。パラメータなどは変更される可能性があるため、最新情報は上記リポジトリをご確認ください。