10X の推薦を作るチームと ML platform

10X ソフトウェアエンジニアの @metalunk です。ネットスーパー、ネットドラッグストアのプラットフォームである Stailer 事業で、機械学習(ML)と検索を専門として働いています。

2024年4月からいま(2024年8月)までの5ヶ月間で6つの推薦機能をリリースできました。この成果を支えたのはチームと ML platform(機械学習の基盤システム)です。このブログではチームの取り組み、ML platform の機能、および具体的な成果についてご紹介します。

このブログは技術ブログの体ではありますが、さまざまな業界、職種の方に読んでいただくことを目指して執筆しました。

(3) 章, (5) 章だけは機械学習に取り組んでいる人向けの内容を含みますので興味のない方は読み飛ばしてもらって結構です(機械学習に取り組んでいなくても興味のある方はぜひ読んでください)が、それ以外は IT 業界のみならず小売業界の方にも読んでいただけると思います。

(1) 5ヶ月間の成果

はじめに、この5ヶ月間で上げた成果を列挙します(つかみです。詳しくは (4) 章で取り上げます)

  1. レジ前推薦でパーソナライズモデルをリリースし、レジ前推薦の売り上げ 10x(カート追加率 3.2x, カート追加点数 2x, 単価 1.6x)
  2. 関連商品推薦のあたらしいモデルをリリースし、カート追加率 3x
  3. セレンディピティの高い、一緒にどうぞ推薦をリリース
  4. 次の検索キーワード推薦のリリース
  5. 人気順をリリースし、もっともカート追加率が高い並び順に
  6. 代替商品推薦のリリース

これで推薦枠は、レジ前推薦、ランキング、商品詳細、次の検索キーワード推薦、代替商品推薦の5箇所になりました。

そして、これらの成果は、2024年4月に始動したお客さま体験チームによって生み出されました。

(2) お客さま体験チームの取り組み

お客さま体験チームは、ML と検索で合わせて2人、アプリエンジニア 1人、デザイナー 1人、PM(プロダクトマネージャ)1人、QA(品質保証)1人の合計6人チームで、ものを出すのに十分かつ最小構成のチームです。

チームのミッションは「店舗の提供価値(商品や配達)を最大限にお客様に伝えるための機能やインターフェースを開発する」とあり、その手段は自分たちのスキルセットを考慮すると検索、推薦、UI(ユーザインターフェース)改善です。

「思いっきり変えていこう」

お客さま体験チームでは、仮説を立てる -> 分析をする -> デモを作ってみんなで触って修正する -> コードを書いてリリースする -> 分析をして新たな仮説を立てる、というサイクルを高速に回せています。この章では、サイクルを高速に回すことに貢献したことを紹介します。

(2.1) 必要最低限のチーム構成

このチームで出してきたもののほとんどがチーム内で完結して作成可能でした。そうすることで、他チームにお伺いを立てる必要なく、チーム内でガンガン進めることができました。

また、少人数であることも高速にものごとを進められる理由です。自分たちが取り組んでいるような、小さく作って試して(もしかしたら失敗して)改善するサイクルを高速に回すには、最小限の人数で取り組むことが肝心です。

(2.2) デモの活用

お客さま体験チームではデモがうまく活用されています。

10X の ML platform には、ML 機能のデモをまあまあかんたんに作り、社員だけが見られる環境に超かんたんにデプロイする仕組みがあります。すべての ML 機能開発でまずデモを作り、みんなで触って定性評価を実施し、修正するサイクルを回しています。

このような活動をしている理由は、ML 機能開発では定性評価が重要だと信じているからです。

ML 機能は本番に出してしまえばカート追加率などの KPI を定量評価できますし、インターリービングテスト(後述)でモデル同士の比較もできます。しかし、そのためには本番に出す必要があり、改善サイクルが早くても2週間はかかるでしょう。

しかし、社内デモなら一日の中でチームにデモを見せて反応をもらい、改善をした新しいデモをデプロイすることができます。このサイクルを回す速度が肝心です。

特に、自分たちのような ML 機能開発の初期フェーズにいる場合は、まったく新しい推薦機能を作ることが多く、体験そのものの確認のためにもデモは重要です。実際に、みんなでデモを触った結果、UI デザイン時にイメージしていた推薦と異なったため、デザインを修正することにしたこともありました。

さらに、自分たちで開発している Stailer を、普段の生活で使っている社員が多くいるため、ドッグフーディング(自分たちが作っているものを自分たちで使うこと)ができます。パーソナライズモデルのデモをしたときは、本番データで学習したモデルを社内のサービス利用者に使ってもらい、有益な感想を得ることができました。社内に(CEO をはじめとする)ヘビーユーザからライトユーザまでいる環境は ML 機能開発にとってかなり便利です。

パーソナライズしたレジ前推薦のデモ。みんながデモを使って Notion に感想を書いていってくれる(ありがとう)

しかし、定性評価には落とし穴があります。それは、悪い推薦がひとつでも見つかったときに直したくなってしまうことです。これはデモのお触り会でも起き得ますし、もしかしたら QA(品質保証)チームによる確認でも起きるかもしれません。

ML 機能は一般的な機能のように仕様を完璧に決めることができないため、推薦結果を完璧にすることは不可能です。ダメな推薦はどうしても起きうるものとして、期待値調整をしてデモを使うことが大切だと思います。

「デモは改善のためのものであり、ダメなところを洗い出すのが目的ではありません」だとか「厳密な評価は本番での定量評価を実施するため、デモ時点ではゆるめにリリース判断を実施しましょう」などの共通認識をチームで持つことが有効です。

(2.3) インターリービングテストの活用

お客さま体験チームでは積極的にインターリービングテストを利用しています。ほぼ常に本番アプリのどこかしらでインターリービングが動いている状態です。

インターリービングテストとは、評価手法のひとつです。こちらの記事でわかりやすく説明されています: A/Bテストよりすごい?はじめてのインターリービング - Gunosyデータ分析ブログ

用途は、たとえば推薦モデルのパラメータが悩ましい場合に2パターンのモデルを作って比較したり、新しい推薦モデルを作ったときに既存のモデルと比較したりです。

インターリービングテストの実装は stailer-recommender という推薦用のサーバの実装だけで完結するので、A/B テストよりも簡単に実施できますし、結果が出るのも早いです。

つまりお客さま体験チームでは、リリース前の定性評価にはデモを利用し、リリース後の定量評価にはインターリービングテストを活用しているわけです。

ものごとを評価するときには定性評価か定量評価か、より適している方があるはずです。どちらも使える状態にし、両輪で改善を回せているのが数多くの成果に繋がっていると思います。

(2.4) ダッシュボードの活用

このチームでは施策を出したらすぐにダッシュボードを作って KPI を追っています。

このおかげでインターリービングテストの実施 -> ダッシュボードで施策の評価 -> 次の仮説を作る、というサイクルが繋がります。

ちなみに、作る側(筆者はプログラマです)としては自分で評価までやるつもりで実装していますが、リリースして一週間くらい置いてからクエリ書こうかな〜とのんびりしていると PM が勝手にダッシュボードを作ってしまいます。

チーム内にダッシュボード作りたがり屋さんがいるようです

先にダッシュボードを作られないよう注意しています

(2.5) 改善サイクルの重要性

これまで述べてきた通り、お客さま体験チームは高速に改善サイクルを回すことに工夫を凝らしてきました。

そして、検索、推薦、UI の開発には、改善サイクルを回すことが必須です。なぜなら、推薦、検索、UI の完璧な仕様を一発で決められる人は存在しないからです。

例えば、レジ前推薦でもっともカート追加率が高いモデルはどんなモデルでしょうか?購入履歴から推薦するとしたら、購入回数が多いものでしょうか?それとも最近買ったものでしょうか?この問いに答えられる人はいません。経験がある自分たちは多少知っていることがありますが、それでも完璧には答えられません。

検索についても同様に無理でしょう。コンピュータサイエンスのひとつの研究分野である情報検索の問題について、答えを一発で出そうなどおこがましいことです。

UI の答えを一発で出すのも無理です。お客さまが抱える課題やサービスの利用環境・利用方法は多種多様であり、デザイナーやエンジニアが想像で “普通に使える” UI を作るのはとても難しいです。

仮でもいいから動くプロトタイプを作った上で、自分たちや実際のお客さまに実利用を想定して触ってもらい、想像通り上手くいった箇所・いかない箇所を素早く改善していくプロセスが良い UI を作るためには必要不可欠です。

この通り、これらの分野では一発で仕様を決めるのではなく、試しながら改善サイクルを回すのが良いアプローチです。さらに、改善サイクルを高速に回すことで高速に事業を進化させることができます。この事実は、これまでのインターネット業界の経験によって知られていることです。

(余談)2010年代のインターネット業界は、この改善サイクルを高速化することに力を注いできたと考えています。例えば、アジャイル、DevOps、CI/CD、A/B テスト、Docker、Kubernetes、クラウド、MLOps などの技術や手法は、2010年代に広く普及し、直接的にも間接的にも、改善サイクルを高速化することに寄与してきました。BigTech やスタートアップによってリードされてきたこれらの技術や活動は、2010年代のインターネット業界の進化の根源であると理解しています。

(2.6) 推薦だけじゃないお客さま体験チーム

このブログでは、お客さま体験チームの成果のうち推薦にまつわるものだけを紹介しています。

他にも UI 改善、SEO 対策、検索改善など、ここで紹介できていない多くの改善を実施しました(みんなすごい!)

チームビルディングは鳥貴族 新橋店でスタートアップビール。テラス席が最高です

(3) Stailer の ML platform

この章では、お客さま体験チームの成果を支えた ML platform について説明します。

機械学習に取り組んでいる方向けの内容を含みますので、興味のない方は読み飛ばしてください。

(3.1) 前提: ネットスーパー、ネットドラッグストアにおける推薦

ML platform について説明する前に、事業領域の特性について説明します。ネットスーパー、ネットドラッグストアでの推薦は、一般的な EC サービスでの推薦と性格がいくつかの点で大きく異なるからです。

Stailer での推薦の KPI はカート追加率、カート内商品点数のどちらか、または両方になることが多いです。前者は一般的な EC サービスでもよく利用されると思いますが、後者のカート内商品点数はほとんど使われないでしょう。

しかしネットスーパー、ネットドラッグストアでは、少量の買い物をたくさんの人がしてくれるよりも、大量の買い物を少人数がしてくれる方が利益が出やすい構造になっているため、カート内商品点数の増加は重要です。そして、ネットスーパーで一度に大量の商品を購入することは普通であり、あるサービスでは一度の買い物で平均30点もの商品が購入されています。この点で一般的な EC サービスと大きく異なります。

また、ネットスーパー、ネットドラッグストアではひとりのお客さまが高々一日一回しか購入しない点も特殊です。この性質のおかげで、トレーニング、推論は高々一日一回だけでよいことが多いです。

例えば、商品ページで「一緒に購入されている商品」として出している推薦枠(通称: 一緒にどうぞ推薦)では推薦内容の推論は一日一回実行される ML pipeline で済ませてあり、Serving 時にはすでに推論済みでデータベースに入っている推薦内容を取得して表示するだけです。このおかげで技術的にシンプルであり、壊れにくいです。

さらに、商品のラインナップが大きく変化しないことも特徴です。一日に100万品が出品されるサービスでは、新商品を売る推薦のために多くの工夫がいると思いますが、Stailer ではその必要がありません。

サービスの特性を利用し、手を抜けるところはうまく手を抜きながら、ネットスーパー、ネットドラッグストアらしい良い推薦を目指しています。

(3.2) ML platform の機能

Stailer の ML platform は2022年に作られました。リリース時に書いたブログに当時の ML platform の設計について書いてあります: 10X のコスパ重視 MLOps - 10X Product Blog

リリースしてからもちょっとずつ改善を重ねています。新しい ML pipeline(機械学習のトレーニングを実施する機構)を作るときに新しい component を作ったり、大規模データを扱うようになったタイミングで既存の汎用 component を高速化したり、CI が遅くてイライラしたときに CI を高速化したりという調子です。

いま本番で動いている ML pipeline は8つになりました。いいペースで増えています。Stailer を利用しているパートナー数は13社あるため、毎日 104 pipelines が動いているわけです(Weekly の pipeline もありますが)。この規模になると ML pipeline なしで管理するのは無理ですから、当初から ML platform を作る判断をした過去の自分たちに感謝しながら、毎日 suceeded の点灯を眺めています。

(3.2.1) ML デモ機能

お客さま体験チームで活用している、ML platform のデモ機能について説明します。

設計時点でこのデモ機能が目指したことはこの通りです。

ML デモ機能の DesignDoc より

ML デモ機能のアーキテクチャをざっくり説明します。

モデルのトレーニングは本番と同じコードベースで branch を切って開発してもらいます。dev 環境で ML pipeline を動かしたら dev 環境の Elasticsearch なり Firestore なりにデータが作られるので、デモサーバからはそれらを参照します。

デモのために ML pipeline を作るのはちょっとハードルが高いですが、例えば Elasticsearch に index を作る汎用的な component を再利用することができたり、本番に移植するときにほとんど修正がいらなかったりと良い点もあります。また将来、データサイエンティストが作ったデモを MLOps エンジニアが本番移植することになったとき(よくありますよね)、統制が効いていることは助けになるはずです。

各社いろんなスタイルでデータサイエンティストと MLOps エンジニアの協業を工夫していると思います。自分たちの場合は、基本的にはデータサイエンティストに ML pipeline まで書いてもらうが、MLOps エンジニアが一緒に設計をしたりペアプロするなどして手厚くサポートするのがちょうどいいと思っています。

DesignDoc にあった、デモのトレーニング方法の Pros/Cons 比較

デモサーバは CloudRun で動かします。その上で動かす Web アプリケーションは好きなように書いてもらったらいいのですが、いまのところすべて Streamlit で作られています。マークダウンのように書くだけで、いい感じに見やすい画面が出来上がるので重宝しています。

デモの画面。二つのモデルを Side by side で比較できる

また、社内からしか閲覧できないようにするには Google Cloud の IAP (Identity-Aware Proxy) を利用しています。社員なら誰でもポチポチでデモを見てもらえるのが素晴らしいです。

このインフラを構築するには、IAP のいろいろを設定し、たくさんの CloudRun を動かし、複雑なネットワークの設定を作る必要があるわけですが、これらのインフラはすべて Terraform で管理されています。Terraform の仕組み作りとサポートをしてくれた SRE チームのおかげです。

(3.2.2) Serving は Elasticsearch か Firestore

「ネットスーパー、ネットドラッグストアにおける推薦」の章でも書いた通り、Stailer の推薦は Training pipeline で推論してしまって Serving 時は保存された推薦データを出すだけ、というパターンで実現できるものが多いので、Serving 時に推論するモデルはまだありません。

その背景には、新しい推薦面に出すモデルはベースモデルとなるような、シンプルで基本的なモデルとする戦略を取ってきたこともあります。これからはすでにある推薦面のモデルを高性能なモデルで置き換えることが増えてくるため、Serving 時に推論するモデルを作ることになるかもしれません。

(3.2.3) Vertex AI Pipelines の工夫(小ネタ)

ある component がコケたときに、ログが stdout に吐かれて Cloud logging に sync されるようになっていますが、ログだけ見たときに、そのログがどの pipeline のどの component から吐かれたのかわからない問題がありました。(ありますよね?)

仕方がないので、すべての component の環境変数に KFP のメタデータを書いておいて、ログを吐くときはそれをメタデータに入れる実装をしました

実装イメージ

from kfp import dsl
from kfp.dsl import Metrics, PipelineTask


def set_vertex_ai_pipelines_env_vars(kfp_task: PipelineTask) -> PipelineTask:
    kfp_task.set_env_variable(_ENV_PIPELINE_JOB_NAME, dsl.PIPELINE_JOB_NAME_PLACEHOLDER)
    kfp_task.set_env_variable(
        _ENV_PIPELINE_JOB_RESOURCE_NAME, dsl.PIPELINE_JOB_RESOURCE_NAME_PLACEHOLDER
    )
    kfp_task.set_env_variable(_ENV_PIPELINE_JOB_ID, dsl.PIPELINE_JOB_ID_PLACEHOLDER)
    kfp_task.set_env_variable(
        _ENV_PIPELINE_TASK_NAME, dsl.PIPELINE_TASK_NAME_PLACEHOLDER
    )
    kfp_task.set_env_variable(
        _ENV_PIPELINE_TASK_EXECUTOR_OUTPUT_PATH,
        dsl.PIPELINE_TASK_EXECUTOR_OUTPUT_PATH_PLACEHOLDER,
    )
    kfp_task.set_env_variable(
        _ENV_PIPELINE_TASK_EXECUTOR_INPUT, dsl.PIPELINE_TASK_EXECUTOR_INPUT_PLACEHOLDER
    )
    kfp_task.set_env_variable(
        _ENV_PIPELINE_JOB_CREATE_TIME_UTC, dsl.PIPELINE_JOB_CREATE_TIME_UTC_PLACEHOLDER
    )
    kfp_task.set_env_variable(
        _ENV_PIPELINE_JOB_SCHEDULE_TIME_UTC,
        dsl.PIPELINE_JOB_SCHEDULE_TIME_UTC_PLACEHOLDER,
    )
    kfp_task.set_env_variable(_ENV_PIPELINE_ROOT, dsl.PIPELINE_ROOT_PLACEHOLDER)
    return kfp_task


def export_vertex_ai_pipelines_env_vars() -> dict:
    return {
        _ENV_PIPELINE_JOB_NAME: os.getenv(_ENV_PIPELINE_JOB_NAME),
        _ENV_PIPELINE_JOB_RESOURCE_NAME: os.getenv(_ENV_PIPELINE_JOB_RESOURCE_NAME),
        _ENV_PIPELINE_JOB_ID: os.getenv(_ENV_PIPELINE_JOB_ID),
        _ENV_PIPELINE_TASK_NAME: os.getenv(_ENV_PIPELINE_TASK_NAME),
        _ENV_PIPELINE_TASK_EXECUTOR_OUTPUT_PATH: os.getenv(
            _ENV_PIPELINE_TASK_EXECUTOR_OUTPUT_PATH
        ),
        _ENV_PIPELINE_TASK_EXECUTOR_INPUT: os.getenv(_ENV_PIPELINE_TASK_EXECUTOR_INPUT),
        _ENV_PIPELINE_JOB_CREATE_TIME_UTC: os.getenv(_ENV_PIPELINE_JOB_CREATE_TIME_UTC),
        _ENV_PIPELINE_JOB_SCHEDULE_TIME_UTC: os.getenv(
            _ENV_PIPELINE_JOB_SCHEDULE_TIME_UTC
        ),
        _ENV_PIPELINE_ROOT: os.getenv(_ENV_PIPELINE_ROOT),
    }

Vertex AI Pipelines の内部の不具合でコケる(こちらにはどうしようもない)こともよくある印象です。ほとんどの場合はリトライするしかないし、リトライしたらだいたい動くため、自動リトライの設定を入れることにしました。当初はたまにコケたときにもすぐに気付きたい思いからリトライの設定をしていませんでしたが、アラートがオオカミ少年化してしまうのでこれも致し方なしです。

実装イメージ

create_index_task.set_retry(num_retries=1, backoff_duration="60s")

(4) リリースした推薦機能の紹介

お客さま体験チームでこれまでにリリースした推薦機能と、もし評価が済んでいる場合はその成果をお伝えします。

(4.1) レジ前推薦でのパーソナライズモデル

レジ前推薦ではしばらく多腕バンディット問題の ε-greedy 法を動かしてきました。このアルゴリズムは強化学習アルゴリズムのひとつであり、レジ前で売れる商品を探索しながら報酬(売り上げ)の最大化を目指します。このモデルはパーソナライズモデルではありませんでした。

この度、お客さまの購入履歴をベースにしたパーソナライズモデルを開発し、リリースしたところレジ前推薦における売り上げが 10x しました。その内訳はカート追加率 3.2x, カート追加点数 2x, 単価 1.6x です。

大好きな 10x グラフ

これが最初のパーソナライズモデルであったため、ベースモデルとしてシンプルなアルゴリズムを動かしましたが(まずはシンプルなアルゴリズムをベースモデルとして動かすのは機械学習のベストプラクティスです)、想像以上の威力があり、驚きました。

いまはネットスーパーでの推薦におけるパーソナライズモデルが発揮する力を思い知り、新しいモデルの開発を進めているところです。

筆者のアカウントでのレジ前推薦。ライフのジンギスカンが美味しすぎて毎回買っちゃう

(4.2) 関連商品推薦

商品ページにおける「関連する商品」の推薦モデルを新たにリリースしました。この推薦枠ではもともと、同じカテゴリの商品を出すルールベースの仕組みが動いていましたが、それを置き換えました。

この推薦では、より関連性の高い、類似している商品を推薦することで、お客さまに買い物の選択肢を増やしてもらうことを目指しています。

プライムジャワカレー中辛に対する関連商品推薦。同じプライムジャワカレーの辛口や、プライムじゃないジャワカレーの中辛が推薦されて、買い物の選択肢が広がる

リリースの結果、新しい関連商品推薦は既存の推薦(同じカテゴリの商品)に対して 3x のカート追加率を達成することができました。

オレンジ色のグラフが 3x

(4.3) 一緒にどうぞ推薦

前述の関連商品推薦に続き、商品ページに一緒にどうぞ推薦をリリースしました。

このモデルはアソシエーション分析を利用したシンプルなアルゴリズムで、ベースモデルと言えるものです。推薦の狙いはあわせ買いの促進によるカゴ点数増加です。

ウイスキーのジャックダニエルに対する関連商品推薦と一緒にどうぞ推薦。それぞれ違う特徴の推薦がされていておもしろい

おでん出汁に対する一緒にどうぞ推薦。おでんの具材が集まっていて素晴らしい推薦

このモデルは関連商品推薦に比べるとカート追加率が低いですが、これまで Stailer で実現できていなかったセレンディピティの高い推薦(偶然の出会い。もともと買うつもりじゃなかった商品を買っていただく推薦)を提供できていると思います(まだ分析が済んでいない)

(4.4) 次の検索キーワード推薦

これは検索結果の一番下の「関連キーワードで探す」枠で次の検索キーワードをおすすめする仕組みです。

「きゅうり」の次の検索キーワード推薦。みなさん冷やし中華始められたんでしょうか?冷しゃぶでしょうか?

この機能は一度の注文で30点もカートに追加するネットスーパー、ネットドラッグストアならではの推薦です。検索結果で欲しいものを見つけられなかったお客さまには、代わりの商品が見つかるようなキーワードを、欲しいものが見つけられたお客さまには、次に欲しい商品が見つかるようなキーワードを推薦することを目指しています。

特に、季節性のキーワードに対して良い検索結果を返せない問題を解決することも狙っています。例えば年末になると「おせち」という検索キーワードが増えますが、お客さまが想定した検索結果を返せないことが多いです。お客さまは「かまぼこ」がヒットすることを期待しているかもしれませんが、かまぼこに「おせち」がタグ付けされていないとヒットしません。

しかしこのとき、次の検索キーワード推薦があれば、「おせち」に対して理想の検索結果が表示できなくても、「次は “かまぼこ” で検索するのはどうですか?」と推薦できます。理想的にはお客さまの欲しい検索結果を一発で返したいですが、できることから一歩ずつです。

この推薦は筆者が個人的に大好きな機能です。推薦されるキーワードが思いもよらないけれど納得感があるものが多いのが面白いです。そして、多くのお客さまの行動が他のお客さまのガイドとなるのが素晴らしいです。

(4.5) 人気順

カテゴリ内の商品を人気順に並べ替えられるようにしました。

「ハーゲンダッツ」カテゴリの人気順。新商品に王道バニラが割って入る構図。筆者はクッキー&クリーム派です

リリース後に評価してみると、提供しているソートの中でもっともカート追加率が高いソートになりました。

(4.6) 代替商品推薦

これは、売り切れ商品に対して代わりになりそうな商品を推薦する機能です。

執筆時点でリリースされていないので dev アプリのスクショです

モデルは関連商品推薦に使っているものとほぼ同じです。たくさんのモデルを作ってきたため、既存のモデルをちょっと変えて別の推薦で使うことができるようになってきました。

まずはベースモデルとして、最低限の価値ある状態でリリースしました。これから新しいモデルによってこの推薦精度を向上させる予定です。

(5) 余談: 検索と推薦の技術の境目

こんなに長いブログを書いておいてまだ余談があるのかと言われそうですが、一万文字を超えたら行くところまで行こうという気持ちになってまいりました。

この章も機械学習に取り組んでいる方向けの内容ですので、興味のない方は読み飛ばしてください。

近年、技術の発展により検索技術と推薦技術の境界があやふやになってきていると思っています。

もともと(2010年代)は検索技術は全文検索をベースとした技術、推薦技術は ML をベースとした技術だったと思いますが、いまや検索で ML 技術を利用するのは当たり前になってきていますし、逆に推薦で検索システムを利用することも普通だと思います(こっちは元々そうかもしれません)

特に注目すべき技術がベクトル検索(kNN, ANN)です。ベクトル検索の黎明期には自分たちでトレーニングした Deep モデルの中間層をベクトルとして利用していましたが、いまでは汎用的な LLM から API 経由で embedding を取り出す使い方は普通のように思えます。

また、近傍探索には Faiss などのライブラリを利用していましたが、その周辺システムは整っておらず、自分たちで独自のシステムを構築する必要がありました。その後 Google Cloud による Matching Engine 等の SaaS が登場し、いまではもともと全文検索エンジンであった Elasticsearch にベクトルを indexing して検索することができるようになっています。おかげで全文検索とベクトル検索を組み合わせたハイブリッドな検索がひとつのソフトウェアの上で実現できるようになりました。

この通り、検索技術と推薦技術は互いにもとの境界を超えており、それにともない技術者たちも両方の知識を得る必要があるわけです。

10X ではこの変化を受け入れるために、検索エンジニアと推薦 (ML) エンジニアを明確に分けないことにしています。といってもしばらくは自分ひとりだったため、単に自分がどちらもやっているだけでした。しかし今年の1月に仲間が増え、いまは検索と推薦に2人で取り組んでいます。そしてお互いに得意分野はありつつも、分け隔てなく開発しています。

10X のエンジニアはもともとサーバもアプリも両方書くような人が多かったので、そういう文化なのかもしれません。

(6) おわり

2024年4月からの5ヶ月間でリリースした6つの推薦機能について書きました。そして、その成果の根源である、お客さま体験チームと ML platform について解説しました。

いま Stailer の売り上げのうち推薦によるものは 10% くらいだと思います。2.5年前の入社当時からすると 10x していると思いますが、まだまだでできること、やりたいことは山のように残っています。お客さまが推薦経由でカート追加する割合をもっと増やすことで、もっと便利なネットスーパー、ネットドラッグストアにできると考えています。

10X での自分の仕事は、お客さまがかんたんに商品を見つけられるようにすることです。これからも検索と推薦の技術を駆使し、理想のネットスーパー、ネットドラッグストアを作っていきます。