Skip to content

Surface 別 解説 ​

GraphQL enum RecommendationSurface の 6 種類について、Surface ごとに「何を推すのか」「どこで使われているのか」「どう scoring しているのか」「今どこまで実装が進んでいるのか」を 1 ファイルにまとめる。

TIP

Base Scoring + Surface Strategy の 2 層構造と全体設計は 仕様 (spec) を、技術選定の経緯は 技術選定 (technology-choices) を読む。各 Surface ファイルでは「その Surface 固有の話」だけを書き、共通仕様はリンクで参照する (重複させない)。

現状の Surface 一覧 ​

SurfacedocAdmin PreviewStrategy.AggregateStrategy.PreFilterStrategy.PostRerank本番投入 (新 pipeline)
FOR_YOUfor-you.md✅ adminForYouScenarios✅ Identity✅ defaultPolicy (Candidates + 既プレイ除外)⚠ no-op✅ prd 投入済 (scenariosScreenV2 の「あなたにおすすめ」、MOBL-4295)
QUICK_MATCHquick-match.md✅ adminQuickMatchScenarios (複数 userID)✅ Least Misery + 履歴シグナル統合 greedy✅ 全員未プレイ / 人数一致 / locale / 無料 / 90 分以内 / release only / ジャンル✅ MMR + N≥1 ハード制約 (MOBL-4286)✅ prd 投入済 (asynq matchmake 経路、SuppressLogging=false)
SIMILARsimilar.md✅ adminSimilarScenarios (scenarioId + viewerIds[])✅ <p_context, p_candidate> 内積 (ScenarioSimilarityBatch)、未学習時は viewer mean フォールバック✅ self-exclusion + 人数フィルタ (±2、1 人用除外) + locale 積集合 (viewer 0 で skip) + 2 人以上プレイ済み除外✅ half-half ミックス (全員未プレイ ⇔ 1 人プレイ済み)✅ prd 投入済 (Scenario.similarScenarios / Query.similarScenarios、UZU-4294)
EVENT_DETAILevent-detail.md❌ 未 expose❌ stub (not implemented yet)⚠ 共通ルールのみ⚠ no-op❌ 未投入
AUTHORauthor.md❌ 未 expose❌ stub (not implemented yet)⚠ 共通ルールのみ⚠ no-op❌ 未投入
COLLECTIONcollection.md❌ 未 expose❌ stub (not implemented yet)⚠ 共通ルールのみ⚠ no-op❌ 未投入

入口の 2 系統 ​

新 pipeline (pipeline.Recommender) からの呼び出し方は 2 通り:

  • Registry 経由 (staged Strategy): FOR_YOU / SIMILAR / (将来の EVENT_DETAIL / AUTHOR / COLLECTION)。SurfaceStrategy interface の PreFilter → Aggregate → PostRerank を順に呼ぶだけ。backend/internal/usecase/recommendation/surfaces/registry.go
  • 直接 delegate: QUICK_MATCH 専用。V/F/P 加減算と MMR と N≥1 ハード制約を 1 ステップで同時に効かせる統合 greedy なので、PreFilter/Aggregate/PostRerank には分解できない。pipeline.Recommender が QuickMatchRequest を型 assertion して strategy/quick_match パッケージに直接 dispatch する (strategy-decisions 2026-04-28)

本番で動いている別系統 (新 pipeline 未経由) ​

surface 別 doc には載らないが、新 pipeline を通らない旧実装が本番で現役の箇所がある:

  • SearchScenarios(orderBy: RECOMMENDED) (backend/internal/adapters/graph/scenario_query.resolvers.go) → usecase.RecommendationSortedScenarios() (タグ preference + popularity + 乱数)。Web 検索の「おすすめ順」。Surface には分類されない別系統

Surface 追加時の手順 ​

新しい Surface (例えば EVENT_DETAIL) を実装するときの作業順:

  1. recommendation/types.go に Request 型 (EventDetailRequest) を定義して、SurfaceRequest interface を満たす
  2. recommendation/surfaces/event_detail.go に EventDetailStrategy (SurfaceStrategy 実装) を足す
  3. recommendation/surfaces/registry.go の Build switch から該当 surface の stub error を消し、新 Strategy を返すように差し替える
  4. backend/internal/adapters/graph/schema/recommended_scenarios.gql に adminEventDetailScenarios query を足す
  5. backend/internal/adapters/graph/recommended_scenarios.resolvers.go に admin resolver を足す
  6. Admin Preview UI (javascript/apps/admin/src/app/recommendation/preview/page.tsx) のモード切替に追加する
  7. このディレクトリの該当 doc (event-detail.md) を実装に合わせて書き直す
  8. 一覧表 のステータス列を更新する