ForYou(個人向けレコメンド)
ログインしているユーザー 1 人に対して「次に遊ぶならこれ」を出す枠。scenariosScreenV2 の「あなたにおすすめ」セクションで本番稼働中。
0. レコメンドの概要
| 項目 | 内容 |
|---|---|
| 入力 | ForYouRequest{ UserID, Common{ K, Candidates?, ExcludeAlreadyPlayed } } |
| 出力 | Response{ Items, ModelVersion, RecommendationID }。各 Item は scenarioID + score + reasons |
| mobile / web 画面 | scenariosScreenV2 の「あなたにおすすめ」セクション (i18n key: ScenarioScreen.RecommendedForYou) |
| 本番経路 | scenariosScreenV2 → scenarioscreen.recommendedForYou → Recommender.Recommend(ForYouRequest{...}) |
| Admin Preview | adminForYouScenarios (/recommendation/preview、単数 userId、SuppressLogging=true) |
| 観測 | BigQuery recommendation_assignments に FOR_YOU の assignment ログが流れる (observation) |
| 新 pipeline 投入状況 | ✅ prd 投入済 (MOBL-4295 経由) |
1. 評価関数の設計
spec §3.3 の for_you_score(u, s) = score(u, s) をそのまま実装している。つまり Surface 固有の式は持たず、Base Scoring の出力を score 降順に並べるだけ。
PreFilter
ForYouStrategy.PreFilter でやっているのは 2 つだけ:
Common.Candidatesを渡されたらその集合に絞る (空集合に落ちたら即終了)Common.ExcludeAlreadyPlayed=trueのとき、user_scenario_status.PLAYEDベースの既プレイ判定で除外する
Candidates の絞り込みを先にやっておくと、その後に必要な PlayedScenarioIDs の DB アクセスを省ける場面がある。
Base Scoring
basescoring.Scorer.ScoreMatrix(viewer=UserID) を呼ぶだけ。1 × M の score 行列が返ってくる。
Aggregate
行列の 1 行目をそのままコピーする Identity Aggregator。FOR_YOU は viewer が 1 人なので集約のしようがない。PerUserScores は nil。
PostRerank
items をそのまま返す no-op。MMR や難易度ペナルティは入れていない (Quick Match で実装した MMR を移植する余地はある、§3 の課題参照)。
2. 現状の実装ファイル
| 関心 | ファイル |
|---|---|
共通型 (ForYouRequest) | backend/internal/usecase/recommendation/types.go |
| Strategy 実装 | backend/internal/usecase/recommendation/surfaces/for_you.go |
| Registry 登録 | backend/internal/usecase/recommendation/surfaces/registry.go |
| 「あなたにおすすめ」呼び出し元 | backend/internal/usecase/scenarioscreen/recommended_for_you.go |
scenariosScreenV2 resolver | backend/internal/adapters/graph/scenarios_screen.resolvers.go |
| Admin Preview resolver | backend/internal/adapters/graph/recommended_scenarios.resolvers.go (AdminForYouScenarios) |
| Admin Preview UI | javascript/apps/admin/src/app/recommendation/preview/page.tsx |
| 既プレイ判定 | backend/internal/usecase/played_scenario_ids.go |
3. 既知の課題 / 未実装項目
- [ ] PostRerank が no-op。Quick Match の MMR (カテゴリ / タグ多様性) を FOR_YOU にも持ってきて、似た作品ばかり並ぶ問題を緩和したい (MOBL-4286 で QuickMatch には導入済み)
- [ ] 難易度ペナルティ (spec §3.4)
- [ ]
reasonsの自動生成 (popular / similar_to_X / because_of_tag、現状は空配列で返している) - [ ] Base Scoring に Content-based サブモデルを足す (MOBL-4292)。プレイ履歴がほぼ無いユーザー (
PlayedCount=0) では内積が安定せず、score の信頼性が落ちる