Tech Blog

作品詳細を「行き止まり」にしない — 「この作品が好きな人へ」で、次の一本へ送る

レコメンド UX embedding 回遊 設計

はじめに

自作の映像・音楽プラットフォームで、作品の詳細ページに「この作品が好きな人へ」という似た作品の一覧を足した。今見ている作品に近いものを、詳細の下に並べる機能だ。

技術の芯は、意味検索のために作った索引の使い回しにすぎない。専用のベクトルDBを足さずに意味検索を実装した話は 「字面」でなく「意味」で探す に書いた。この記事はそこではなく、その索引を「詳細ページの回遊」にどう効かせ、かつ本体を壊さずに足したかという設計の話だ。

作品詳細ページ下部の「この作品が好きな人へ」。似た作品を類似度つきで並べ、次の詳細へ送る(ポートフォリオ用・作品はデモデータ)


作品詳細は、行き止まりになりやすい

カタログを見て回る体験では、利用者は一覧から詳細へ入り、そこで「借りるか、やめるか」を決める。問題は、「これは違うかな」となったときだ。詳細ページに次の手がかりが無ければ、利用者は一覧まで戻るか、そのまま離脱する。

詳細ページは、放っておくと行き止まりになる。せっかく一作に興味を持って踏み込んでくれた人を、次の候補に出会わせないまま帰してしまう。

【行き止まり】一覧 ─▶ 詳細 ─(刺さらない)─▶ 戻る/離脱   … 次に出会わない

【回遊】     一覧 ─▶ 詳細 ─(刺さらない)─▶ 似た作品 ─▶ 次の詳細 ─▶ …
                                              └───────── 回遊が続く

やりたいのは、詳細の一番下に「じゃあ、これはどう?」を必ず置くこと。次の一本を、目の前に差し出すことだ。


同じ索引を、「この作品に似た作品」の顔で引く

ここで、意味検索のために作った索引がそのまま効く。全作品はすでに 意味ベクトル(作品の内容を数値の並びにしたもの。近い内容どうしはベクトルも近い)になっている。意味検索は「クエリ文のベクトル」に近い作品を返した。似た作品は、クエリが文ではなく”今見ている作品そのもの”になるだけだ。今の作品のベクトルを索引に問い合わせ、近い順に返す。入口が違うだけで、走る仕組みは意味検索と同じ一つの関数だ。

そして、ただ並べるのではなく 類似度(%) を各作品に添えた。「なぜこれを薦めるのか」を、数字で見せる。推薦がブラックボックスだと「なぜこれ?」と不信を招くが、近さを見せれば納得して次へ進める。

// 基準作品のベクトルに近い作品を、近い順に返す(この作品が好きな人へ)
List<Map.Entry<Integer, Double>> ranked = index.topSimilar(baseVector, limit * 4 + 1);
for (var entry : ranked) {
    if (entry.getKey() == filmId) continue;          // 自分自身は除外
    var film = filmMapper.selectById(entry.getKey());
    if (film == null) continue;
    if (baseIsCd != (film.artist() != null)) continue; // 同じメディア種別だけ(後述)
    items.add(Map.of("film", film, "score", round(entry.getValue()))); // 類似度つき
}

意味検索・おすすめ・この機能は、同じ索引の三つの顔だ。同じ索引を「履歴の重心」で引けば「あなたへのおすすめ」になる話は 視聴履歴の「重心ベクトル」で、おすすめを作る に書いた。


推薦は、本体を壊してはいけない

ここが、この機能で一番気をつけたところだ。推薦はあくまで付加情報であって、詳細ページの主役ではない。

似た作品の計算は、失敗しうる。作品のベクトルがまだ生成されていなければ結果は0件になるし、内部の呼び出しがエラーを返すこともある。このとき、推薦の失敗が詳細ページ本体を巻き込んで壊すのは最悪だ。利用者は作品を見に来たのであって、推薦を見に来たのではない。

だから、推薦セクションは「あれば嬉しい、無くても困らない」に徹させた。0件やエラーのときは、セクションごと黙って消える。詳細ページ本体(あらすじ・レンタル情報・予約ボタン)は、推薦が出ても出なくても常に無傷だ。

詳細ページ本体(あらすじ・レンタル情報・予約)  ← 常に表示・推薦の成否に依存しない
        └─ この作品が好きな人へ(付加情報)
              ├─ 結果あり ─▶ 出す
              ├─ 0件(ベクトル未生成)─▶ セクションごと非表示
              └─ API失敗 ─▶ セクションごと非表示(本体は壊さない)

もう一つ、同じメディア種別のものだけを出すようにした(映像の詳細に映像、CDの詳細にCD)。意味の近さだけで引くと、映像を見ているのに音楽CDが「似ている」として紛れ込む。この「意味が近い=出してよい、ではない」という埋め込みの素直さの罠は ベクトル検索は「意味が近い」を勝手に混ぜてくる にまとめた。付加情報だからこそ、余計なものを出して詳細ページの筋を濁さない。


推薦は主役ではなく、次への橋

作ってみて腹落ちしたのは、この機能の価値は「賢い推薦」そのものではない、ということだ。価値は、行き止まりだった詳細ページに、次への橋を一本架けたことにある。

  • 回遊は、賢いアルゴリズムより先に、「次を置く」という一手で生まれる。目の前に候補があるかどうかが、戻るか進むかを分ける。
  • そして橋は、渡れなくても本体を壊さない。推薦が0件でも失敗でも、詳細ページはそのまま立っている。付加情報は、主役の邪魔をしない範囲でだけ足す。

同じ索引を、検索にも、おすすめにも、この回遊にも使い回せた。だが機能ごとに違ったのは、アルゴリズムではなく置き方の作法だった。検索は主役として前に出し、この推薦は脇役として詳細の邪魔をしない。同じ道具でも、主役か脇役かで設計は変わる——それが、この機能で学んだことだった。


関連する記事

気軽にメッセージください

仕事の依頼、案件紹介、ご感想・ご質問なんでもお待ちしております。 高い志をもった同士の皆様と繋がることを切に願っております。 これからも人生を掛けたチャレンジを続けていきます。 何卒よろしくお願い致します。