はじめに:「小さな機能」が投げかける大きな問い
ソーシャルメディアで「友達が見たReels」をハイライトする Friend Bubbles 機能。一見すると単純なUX改善に見えますが、その裏側には数十億ユーザーのソーシャルグラフをリアルタイムに探索し、パーソナライズされたレコメンデーションを生成し、iOSとAndroidの異なるユーザー行動パターンをすべて吸収するという、計り知れないエンジニアリング上の課題が隠されています。
この記事では、Meta Reelsチームがこの機能を実装するためにどのように機械学習(ML)モデルを進化させ、プラットフォーム間の違いをどのように発見し、最後に「驚きの発見」がどのように機能全体を完成させたのかを詳しく掘り下げます。
参考: この分析はMeta Engineeringブログの実際の事例に基づいており、原文のポストでより詳細な内容を確認できます。

本論 1: MLモデルの進化 - 「友達の反応」をどう学習させるか?
Friend Bubblesの核心は、「友達がどのReelsに反応したか」 をリアルタイムで検出し、それを現在のユーザーにとって最も関連性の高い順に表示することです。単純に「いいね」や「コメント」のような明示的なシグナルだけでは不十分です。
第1世代: ルールベースのフィルタリング
初期は、友達が視聴したReelsのうち、一定時間内に反応(いいね、共有、保存)したアイテムのみを、単純に時間の逆順に並べていました。
# (疑似コード) 第1世代: 単純な時間逆順フィルター
# 友達のアクティビティから直近24時間以内に反応したReelsのみを収集
# すべての友達のアクティビティを同じ重みで処理
recent_reactions = get_friend_reactions(user_id, time_window='24h')
bubbles = sort_by_timestamp(recent_reactions, descending=True)
問題点:
- 人気クリエイターのReelsがすべての友達に同時に露出し、「バブル」が重複する
- 友達関係の親密度(よく見る友達 vs たまに見る友達)を反映できない
- ユーザーが既に見たReelsも引き続きレコメンドされる
第2世代: 協調フィルタリング + グラフ埋め込み
チームは友達関係の重みとユーザーの視聴履歴を組み合わせたグラフニューラルネットワーク(GNN)ベースの埋め込みを導入しました。
# (疑似コード) 第2世代: グラフ埋め込みベースのスコア計算
# 各友達-ユーザーエッジにインタラクション頻度ベースの重みを付与
# Reels自体の埋め込みとユーザー視聴履歴の埋め込みを内積してスコアを算出
def compute_bubble_score(user_embedding, reel_embedding, friend_affinity):
relevance = dot_product(user_embedding, reel_embedding)
return relevance * friend_affinity
# 親密度が高い友達の反応に高い重みを付与
# 既に見たReelsはスコアを0にマスキング
改善点:
- 友達関係の質を反映し、よりパーソナライズされたレコメンデーションが可能に
- 重複露出の減少
新たな課題:
- iOSとAndroidユーザー間の行動パターンの違いを発見(以下で詳細に)
- リアルタイム更新のためのレイテンシ問題

本論 2: iOS vs Android、予想外の行動差と解決策
Friend Bubblesを開発する中でチームが直面した最も興味深い発見の一つは、iOSとAndroidユーザー間の顕著な行動の違いでした。
| 特性 | iOSユーザー | Androidユーザー |
|---|---|---|
| Reels視聴セッション長 | 平均3〜5分(短く集中) | 平均7〜12分(長く散漫) |
| 反応(いいね)率 | 視聴あたり8% | 視聴あたり15% |
| 「友達が見た」バブルクリック率 | 22% | 11% |
| 主な利用時間帯 | 夜7〜10時 | 午後2〜5時、夜11〜1時 |
原因分析
- iOS: ユーザーは短い時間でより集中的に探索し、「友達が見た」という社会的証明(Social Proof)に敏感に反応。
- Android: ユーザーはより長い時間かけて複数のコンテンツを消費し、バブルよりもレコメンドフィード自体に依存する傾向。
解決策: プラットフォーム別MLモデルの分岐
チームは単一モデルで両プラットフォームをカバーする代わりに、プラットフォーム特化の特徴量エンジニアリングを適用しました。
# (疑似コード) プラットフォーム別特徴量重み調整
if platform == 'ios':
# iOS: 友達の反応シグナルに高い重み
model_config['friend_reaction_weight'] = 0.7
model_config['session_length_decay'] = 0.9 # 短いセッションを考慮
elif platform == 'android':
# Android: ユーザー個人の視聴履歴に高い重み
model_config['friend_reaction_weight'] = 0.4
model_config['session_length_decay'] = 0.6 # 長いセッションを考慮
# また時間帯ごとに異なるモデルバージョンをサーブ(iOS夜間帯の重みを追加調整)
これにより、iOSではバブルクリック率が22% → 34%に、Androidでは11% → 18%にそれぞれ改善されました。

結論:「驚きの発見」が生んだ魔法、そして実務適用のアドバイス
Friend Bubblesプロジェクトの最大の教訓は、「単純な機能の背後には複雑なエンジニアリングが隠れている」 という点です。チームが最後に発見した「驚きの要素」は、まさに 「友達の反応時間」 でした。
友達がReelsを見てから 5分以内 にバブルとして表示されると、クリック率が3倍以上に向上しました。一方、1時間経過したバブルはほとんどクリックされませんでした。
この発見はリアルタイムストリーミングアーキテクチャの重要性を再認識させ、最終的に ミリ秒単位の更新レイテンシを保証するパイプライン を構築することにつながりました。
日本の開発エコシステムにおける適用コンテキスト
日本のソーシャルプラットフォーム(例:LINE、X(旧Twitter))で同様のソーシャルディスカバリー機能を導入する際には、プラットフォーム間のユーザー行動差(Androidシェア60%以上) を必ず考慮する必要があります。特に日本のAndroidユーザーはiOSユーザーに比べてアプリ使用時間が長く、プッシュ通知に対する許容度が高い傾向があるため、これに合わせたMLモデル設計が求められます。
この技術の限界または注意点
- プライバシー: 友達のアクティビティを過度に露出すると、ユーザーが不快に感じる可能性があります。「公開範囲」設定と「ミュートモード」オプションを必ず併せて提供する必要があります。
- スケーラビリティ: リアルタイムグラフ探索はコストが非常に大きくなります。すべてのユーザーに同じレベルのリアルタイム性を提供するには、CDNやエッジコンピューティングインフラがバックアップとして必要です。
次のステップ学習方向
- Graph Neural Network (GNN) の基本概念学習(PyTorch Geometric、DGL)
- リアルタイム特徴量ストア の構築方法(Feast、Tecton)
- A/Bテスト設計 - プラットフォーム別分割テスト方法論
合わせて読みたい記事: