TECH PLAY

形態素解析

イベント

該当するコンテンツが見つかりませんでした

マガジン

技術ブログ

株式会社リクルートは、日本国内で HR・販促事業を行う事業会社です。リクルートでは、満足度No1(*1)を誇る飲食店予約・グルメ情報サイト『ホットペッパーグルメ』を運営しています。 『ホットペッパーグルメ』では、ユーザーが飲食店を検索する際の「0件ヒット」問題を解決するため、 Amazon OpenSearch Service (以下、OpenSearch Service)を採用し、Hybrid Search 機能を実現しました。約6ヶ月の取り組みにより、検索における0件ヒットを90%削減し、検索経由の予約数を10%向上させることに成功しています。 本ブログでは、『ホットペッパーグルメ』における検索改善の取り組みについて、チャレンジから導入効果までをご紹介します。 課題 『ホットペッパーグルメ』では、ユーザーが飲食店を探そうと検索しても、検索結果が0件になるケースがありました。行きたいお店があるのに見つけられず、ユーザーと飲食店のマッチングの機会を逃してしまう状況です。これはユーザー体験の低下だけでなく、検索から予約への転換機会の損失にもつながる重要なビジネス課題でした。 0件ヒットが発生する背景として従来の検索技術である Lexical Search には限界があり、ユーザーの意図を正しく理解できないケースがありました。 Lexical Search について : Lexical Search(字句検索)は、入力されたキーワードと完全に一致する文字列を検索する手法です。しかし入力ミスに弱いという課題がありました。ユーザーが「寿司」と入力しようとして「寿し」や「すそ」と入力してしまうと、検索結果を取得できません。また、日本語はスペースで単語を区切らない言語のため、セグメンテーションエラーが発生しやすいという日本語特有の課題もありました。 Vector Search の限界 : Vector Search(ベクトル検索)は、テキストを数値ベクトルに変換し、意味的な類似度で検索する手法です。タイポや言い換えに強いという特徴がありますが、固有名詞の検索で精度が低下するという課題がありました。店舗名のような固有名詞を検索する際、意味的に近い別の店舗が上位に表示されてしまいます。また、位置情報などのノイズにより、検索意図とは異なる結果が返される意味的なずれも発生していました。 検索手法 Lexical Search Vector Search 完全一致キーワード ○ × タイポ耐性 × ○ 言い換え対応 × ○ 固有名詞の精度 ○ × 日本語セグメンテーション × ○ 一般的に、ユーザーは検索結果の上位に高い関心があるため(*2)、 特にTop-1の検索結果を改善する方針 としました。 OpenSearch Service を活用した Hybrid Search の実現 これらの課題を解決するため、『ホットペッパーグルメ』では Lexical Search と Vector Search を組み合わせた Hybrid Search を採用しました。またそれを支える基盤として、OpenSearch Service を採用しました。 OpenSearch Service を選定した最大の理由は、Full-text Search と Vector Search を単一のサービスで実現できる Hybrid Search 機能の統合です。また、フルマネージド型サービスとしてインフラ管理の負荷を軽減できる開発・運用の容易さも重要な選定ポイントでした。さらに、OpenSearch Ingestion による Managed ETL や言語別テキスト解析プラグインなど AWS がサポートするプラグインが充実しており、豊富な周辺機能を活用できます。Blue/Green デプロイによる無停止でのスケーリングも、運用の安心感を確保する上で大きなメリットでした。 アーキテクチャと実装 Two-tower Model Architecture 『ホットペッパーグルメ』では、検索クエリと店舗情報をそれぞれ別のエンコーダーで処理する Two-tower Model Architecture を採用しました。 Two-tower Model は、Query Encoder と Document Encoder という2つの独立したエンコーダーで構成されています。Query Encoder はユーザーが入力した検索クエリ(例:「東京 寿司」)をベクトルに変換します。一方、Document Encoder は店舗情報をベクトルに変換します。店舗情報には、店舗名、住所、メニュー、説明文、キャッチコピー、レビューなど、検索に関連する情報が含まれます。埋め込みのスコープについても検証を行いました。店舗名や住所といった基本情報のみを使用するパターンと、メニューや説明文、キャッチコピーといったコンテンツフィールドを含めるパターンを比較し、検索精度への影響を評価しています。 モデルの学習には対照学習を採用しました。学習データとして、ユーザーの検索ログと LLM で生成した合成ペアを組み合わせて使用しています。ユーザーログからは実際の検索行動に基づくクエリと店舗のペアを抽出し、LLM 生成の合成ペアにより学習データのカバレッジを拡大しました。ベースモデルには日本語 BERT を採用し、『ホットペッパーグルメ』のドメインに特化したファインチューニングを実施しています。汎用的な埋め込みモデルと比較して、店舗名のようなドメイン固有の用語に対する検索精度が向上しました。埋め込みの次元数は512次元を採用しています。 日本語テキストの形態素解析には Sudachi を使用し、split_mode: A(最小単位での分割)を設定しています。これにより、日本語特有の複合語や固有名詞を適切にトークン化し、検索精度の向上に寄与しています。 導入プロセス Built-in Hybrid Search(第1フェーズ) 最初のステップとして、AOS の標準機能である Built-in Hybrid Search を導入しました。Built-in Hybrid Search は実装が容易であり、検索基盤の構築よりもモデル改善に集中できるというメリットがありました。 Built-in Hybrid Search では、OpenSearch が Lexical と Vector の検索結果を取得し、それぞれのスコアを正規化した後、単一のスコアにマージしてから Reranking を行います。この仕組みにより、短期間で Hybrid Search を導入し、効果を検証することができました。 一方で、運用を通じて課題も見えてきました。一度スコアがマージされると、スコアの差異が何に起因するのかを把握できなくなります。Lexical Score が高く Vector Score が低い場合、それがタイポによるものなのか、言い換えによるものなのか、あるいはレアな固有名詞によるものなのか、判断できません。どちらのシグナルを重視すべきかは検索意図に依存するため、固定のマージ重みでは対応しきれないケースがありました。この学びから、Reranker には統合されたスコアではなく、Lexical Score と Vector Score を個別に渡す必要があるという結論に至りました。 Custom Hybrid Search(第2フェーズ) Built-in Hybrid Search の課題を解決するため、Custom Hybrid Search を開発しました。 Custom Hybrid Search では、Lexical Score と Vector Score を別々に保持し、マージ前の個別スコアを Reranker に渡すことで、より精緻なランキングが可能になりました。また、ユーザーログや検索意図などの追加シグナルを Reranking に活用しています。スコアの統合には LightGBM による適応的なスコア統合とランキングを採用し、機械学習モデルによる動的なスコア統合を実現しています。アーキテクチャは Planner → Executor → Merger & Reranker の構成となっており、検索意図に応じた柔軟なランキングを実現しています。Custom Hybrid Search の導入により、Top-1 検索精度が最大2倍改善しました。 段階的なリリース戦略 新しい検索システムの導入にあたり、A/B Test Router を用いたトラフィック制御を実施しました。当初は新規システムに10%、既存システムに90%のトラフィックを振り分け、この比率を段階的に調整しながら A/B テストにより効果を検証しました。A slot / B slot による並行検証を行い、新システムの安定性と効果を確認した上で、トラフィック比率を徐々に増加させていきました。 成果 ビジネス成果 : Custom Hybrid Search を本番環境に導入した結果、検索経由の予約数が10%改善し、0件ヒット検索が90%削減されました。これらの改善により、ユーザーと飲食店のマッチング機会が大幅に増加し、サービス全体の価値向上につながっています。 技術的成果 : 運用面でも多くのメリットが得られました。Blue/Green デプロイによる無停止でのスケーリングで運用負荷が軽減され、Plugins や OpenSearch Ingestion を活用することでランキングモデルの改善サイクルを加速できています。フルマネージド型サービスとしてインフラ管理の負荷が軽減されたことで、運用の安心感も確保できました。 まとめ 本ブログでは、『ホットペッパーグルメ』における OpenSearch Service で実現された Hybrid Search を活用した検索改善の取り組みをご紹介しました。 Lexical Search と Vector Search を組み合わせた Hybrid Search により、それぞれの検索手法の強みを活かしながら弱点を補完し、0件ヒット問題を大幅に改善することができました。また、Built-in Hybrid Search から Custom Hybrid Search への段階的な進化により、Top-1 検索精度を最大2倍改善し、検索経由の予約数10%向上という成果を達成しています。 OpenSearch Service の採用により、Lexical Search と Vector Search を組み合わせた Custom Hybrid Search の構築、開発・運用の容易さ、Blue/Green Deployment による安定した運用を実現できました。 こうした検索基盤の進化は、新たなユーザー体験の創出にもつながっています。2026年1月22日にリリースした 「席押さえ」機能 は、現在地周辺のお店をマップから探し、「今すぐ席を押さえる」ボタンをタップするだけで、予約なしで席を確保できるアプリ限定機能です。リアルタイムな「空席情報」と「位置情報」を地図 UI 上でマッチングするこの検索体験も、OpenSearch Service で実現しています。 Reference (*1)2025年6月時点 株式会社東京商工リサーチ調べ (*2) Google検索のClick Trough Rateは、Top1が27.6% backlinko 社調べ AWS re:Invent 2025 – Build Advanced Search with Vector, Hybrid, and AI Techniques (ANT314) Amazon OpenSearch Service BlackBelt 『ホットペッパーグルメ』「席押さえ」機能を全国で提供開始
こんにちは、AIテクノロ ジー グループのエンジニアの吉田です。 本記事は Enigmo Advent Calendar 2025 の 18日目の記事です。 普段は検索システム全般、 機械学習 システムのMLOps、AI関連の機能開発を担当しております。 この記事では「AIでさがす」サービスのリニューアルについて紹介します。 「AIでさがす」サービスとは 「AIでさがす」サービスは、 BUYMA のWebサイトおよびアプリで提供している、AIを活用した商品提案サービスです。 実際の機能は以下からご利用頂けます。( BUYMA アカウントでのログインが必要となります。) 「AIでさがす」サービス ユーザーが文章で質問すると、AIが質問内容を理解し、おすすめの商品を提案します。例えば「春のデートにぴったりなワンピースを教えて」といった質問に対して、AIが回答文とともに具体的な商品を紹介します。 従来のキーワード検索では見つけにくかった商品や、ユーザー自身が気づいていなかった新しい商品との出会いを提供することで、 BUYMA でのショッピング体験をより豊かにすることを目指しています。 ※商品画像はモザイク加工しております。 リニューアルの背景 旧システムは、ChatGPT API を活用した商品提案サービスでしたが、主な課題が3点ありました。 BUYMA の知識不足 ChatGPT が一般的な知識で回答を生成するため、 BUYMA ならではのトレンドや商品特性を反映できない。 根拠の不明確さ ChatGPT の回答に 参照元 がない。 検索キーワード生成の精度 形態素解析 ツールの MeCab を併用していましたが、文脈や意味を理解した検索キーワード生成ができない。 また、リリースから2年が経過し、本格的にバージョンアップが必要なタイミングでもありました。 ※旧システムの詳細は こちらの記事 で紹介しております。 ちょうどチームメンバーが社内ドキュメントのAI検索システムを開発しており、この仕組みを BUYMA の多数の記事コンテンツに適用すれば、より BUYMA らしい商品提案が可能になると考えました。 そこで、今回のリニューアルでは、 BUYMA 内の記事コンテンツ群をベースに会話するエージェントを作成しました。これにより、 BUYMA ならではの知識を持ったAIが、より BUYMA でおすすめしたい商品を提案できるようになりました。 システム変更前後の比較 旧システムと新システムの違いは以下の通りです。 旧システムでは、ChatGPT が一般的な知識で回答を生成し、 MeCab による単純な 形態素解析 で検索キーワードを生成していました。そのため、 BUYMA ならではの文脈を理解した商品提案が難しい状況でした。 新システムでは、 BUYMA 内記事コンテンツを参照した Vertex AI Search が回答文を生成し、Gemini が文脈を理解した検索キーワードを生成します。その結果、より BUYMA らしい商品提案が可能になりました。 それぞれの処理フローは以下の通りです。 旧システム処理フロー BUYMA 基幹システムから「AIでさがす」 API にリクエスト 「AIでさがす」 API がユーザーの質問を ChatGPT API に送信 ChatGPT が回答文とおすすめアイテムリストを生成 アイテム名を MeCab ( 形態素解析 )で解析し、検索キーワードを生成 検索 API で商品情報を取得し、ユーザーに表示 新システム処理フロー BUYMA 基幹システムから「AIでさがす」 API にリクエスト 「AIでさがす」 API がユーザーの質問を Vertex AI Search に送信 Vertex AI Search (事前に BUYMA 内記事コンテンツをインポート済み)が回答文を生成 質問文と回答文を Gemini に送信し、検索キーワードを生成 検索 API で商品情報を取得し、ユーザーに表示 アーキテクチャ ー特徴 1. Vertex AI Search Vertex AI Search を利用して、インポートした BUYMA 内記事コンテンツをベースに会話を行うエージェントを構築しました。 BUYMA 内記事コンテンツのインポート 約4000件の記事をデータストアにインポート プロンプト設計 「ファッション ECサイト BUYMA のショッピングアドバイザー」として定義し、ユーザーの質問に対して最適な商品を提案する形で回答を生成 2. Gemini Gemini を活用する事により、会話内容から商品検索キーワードを生成する機能を作成しました。 プロンプト設計 「 ECサイト の検索キーワードを生成する専門家」として定義し、会話の文脈を理解して検索キーワードを生成 MeCab との違い MeCab は単語の分解のみだが、Gemini は文脈を理解してブランド名・カテゴリ名・モデル名を組み合わせた検索キーワードを生成 実装時の課題・解決策・工夫した点 Vertex AI Search の幻覚への対応 初回質問時に Vertex AI Search が過去から質問が続いているような幻覚を見る場合がありました。当初は初回と2回目以降の会話を共通のプロンプトで行っており、「ユーザーの過去の質問履歴」の項目に入っている文言の有無から初回なのか、2回目以降の会話なのかを判断する指示を出していました。ところが、「過去」という文言に引きずられてなのか、初回なのに過去の質問をAI側が捏造して、その続きとして回答する場合が稀にありました。 プロンプトテンプレートを初回用と2回目以降用の2種類に分け、初回用のプロンプトからは「ユーザーの過去の質問履歴」の文言自体を削除する事によって対応しました。 敵対的クエリへの対応 敵対的クエリ(不適切な質問)の場合、Vertex AI Search の API からのレスポンスフォーマットが通常とは異なるものになり、要約が生成できないにもかかわらず、無理やり商品紹介を行ってしまいました。 敵対的クエリーのフォーマットを検知した場合は、要約失敗として扱い、商品紹介を行わないように修正しました。 この場合以外でも稀に異なるフォーマットのレスポンスになる場合があり、サービス継続に支障が出ないように都度改善を行いました。 Gemini のライブラリ移行 もともと使用していたライブラリがサポート終了を迎えるため、社内では実績がない新しいライブラリに移行する必要がありました。移行後、従来使用していた Gemini モデルが初期設定では使用できず、次世代のモデルを試したところレスポンスタイムが大幅に遅くなってしまいました。新しいライブラリという事もあり、AIツールではなかなか解決できず、最終的には Google サポートに問い合わせして解決に至りました。 得られた学びとノウハウ AIツールの活用と限界 「AIでさがす」のバックエンド API の リポジトリ は、ほぼ全部作り直したのですが、AIツールを活用する事によって、 工数 を節約する事ができました。Terraform 関連のリソース修正、テストケース作成やMOCK用のフロントエンド実装等においてもAIツールにより大幅な 工数 削減ができました。 一方で、Gemini のライブラリ移行など、ドキュメントの記載やインターネット上での知見が少ない領域ではAIツールでは解決できず、結果的に公式サポートへの問い合わせが必要でした。 AIの不確定な挙動への対応 Vertex AI Search の幻覚や部分的な失敗など、AIサービス特有の不確実性に対して、初回用と2回目以降用でテンプレートを分けるなど、細かな調整が重要でした。また、プロンプトだけではどうする事もできない場合があり、そのような場合は後処理でルールベースのロジックを追加する必要がありました。 効果測定 リニューアル後、以下のような指標が上昇しました。 1スレッドあたりの質問数の平均 会話の継続性が向上し、ユーザーが複数回質問を続けるようになりました。 1ユーザー1日あたりの質問数 利用頻度が向上し、ユーザーがより積極的に機能を活用するようになりました。 検索URLに遷移された回数 商品検索への誘導効果が向上し、実際の商品閲覧につながるケースが増加しました。 これらの結果から、 BUYMA 内記事コンテンツを根拠とした回答の提供と、文脈を理解した検索キーワード生成により、ユーザーの満足度と利用価値が向上したと考えられます。 直近の対応/今後の展開・課題 金額絞り込み機能の追加(今月対応) ユーザーからの要望が多い金額絞り込み機能の対応をしました。価格帯に関する質問に対して適切な商品提案ができていない課題があったため、Gemini で検索 API 用の金額フィルタークエリを生成することで対応しました。 コンテンツの拡充 現在は BUYMA 内記事コンテンツのみを Vertex AI Search にインポートしていますが、今後は YouTube での発信内容も追加する予定です。記事以外のコンテンツも活用することで、より幅広い情報をユーザーに提供できるようになります。 継続的なメンテナンス AIのライブラリやモデルは随時更新されていくため、継続的なメンテナンスが課題となります。特に Gemini や Vertex AI Search などのサービスは進化が早く、新しいモデルへの対応や非推奨ライブラリ/バージョンから移行など、定期的な見直しが必要です。 まとめ 本記事では、「AIでさがす」サービスのリニューアルについて紹介しました。 旧システムでは ChatGPT と MeCab を使用していましたが、 BUYMA 特有の知識不足や根拠の不明確さなどの課題がありました。リニューアルでは Vertex AI Search と Gemini を採用し、 BUYMA 内記事コンテンツを根拠とした回答生成と文脈を理解した検索キーワード生成を実現しました。 実装時には敵対的クエリへの対応やAIサービス特有の不確実性への対処など様々な課題に直面しましたが、ロジックでの細かい制御やAIツールの活用により解決できました。リニューアル後は会話継続性や利用頻度、商品検索への誘導効果が明らかに向上しています。 明日の記事は同じAIテクノロ ジー グループの髙橋さんです。お楽しみに。 株式会社 エニグモ すべての求人一覧 hrmos.co
こんにちは。検索領域でエンジニアをやっております、shinpeiです。 本記事は 連載企画:メルカリ初の世界共通アプリ「メルカリ グローバルアプリ」の開発舞台裏 の一環として、メルカリグローバルアプリの検索バックエンドをスクラッチで開発することに伴い、大事にした設計のポイントをご紹介します。また今回の新たな要求を契機に既存の検索基盤の拡充が必要だったのでそれについても書かせていただきました。 グローバルアプリでの検索の要件と課題 先日、弊社からの発表の通り、メルカリはグローバルアプリの提供を開始しました。これに合わせて、検索もグローバルな検索を作るべく準備をすすめてきました。 グローバル展開にむけたアプリと基盤の再構築 で紹介したようにグローバルアプリを提供するにあたりバックエンド基盤の再構築を行っています。基盤を活かしながら必要な部分は新しく作り直すアプローチをとっており、検索バックエンドもそれに合わせて再設計を行いました。最低要件は、3年で50カ国展開。出品数は累計40億です(2025年9月時点)。日本事業(日本のお客さま向けメルカリアプリ)の検索との違いは複数ありますが、主なものは以下です。 複数国展開をするための多言語対応 検索対象として、アイテムモデルとプロダクトモデルとの両立 越境事業においてフォーカスしていく際のエンタメホビー領域に特化できるような独自の検索結果チューニング 1.は日本語以外を扱うための要件です。世界展開となれば、言語の壁は避けては通れない課題です。全文検索はそれぞれの言語自体を処理する必要があります。中国語のクエリ、英語のクエリ、フランス語のクエリ。これらを商品情報とマッチさせる必要があります。現在は日本で出品された日本語の商品をメインに扱っていますが、長期的には日本語以外の商品を扱う可能性も考慮する必要がありました。 2.は検索エンジンで検索対象として扱うデータモデルの話です。アイテムとは、現在のメルカリの主流である、単一の商品が検索対象となるようなデータモデルです。一方、プロダクトモデルとは、一つの検索対象だけど、例えば色違い(バリアント)が複数存在させることができるようなデータモデルです。C2Cの商品はアイテムモデルで対応できるのですが、B2Cの商品の一部はバリアントを持つため、プロダクトモデルが必要になります。メルカリはC2Cマーケットプレイスとしてスタートしたため、日本事業の検索では今もなお、アイテムモデルで動いていますが、グローバルアプリではアイテム、プロダクト双方を同等に扱える必要があります。 3.はグローバルアプリは検索結果を独立してコントロールしたいという意味です。グローバル展開を考えたときに国ごとのチューニングや事業の方向性に合わせた柔軟性が必要になります。例えば、クエリを自分たちで組み立てて、自由に検索結果をチューニングもできるように作る必要があります 。検索は日本事業と越境事業両方で重要な機能であり、開発の優先度やリソースなどい違いに影響を受けないようにすることも重要です。 Vertex AI Search for Commerce の採用 日本事業の検索ではElasticsearchを使っています。グローバルアプリでは日本にある商品全体を扱う予定だったので、売上に比べてデータ量が桁違いに大きい状態です。売上とコストを両立させるにはElasticsearchの再利用くらいしか思いつきませんでしたが、多言語対応や独立性の確保、リリースまでの時間と開発リソースを考えると、どうしてもその前の交通整理に長い時間がかかります。どうやるか思案していた時に、思いがけず案に上がってきたのがGoogleが提供してるVertex AI Search for Commerce(以下、VAIS:C)です。今回の例では以下の点で魅力的でした。 フルマネージドな小売サイト向け検索サービス リクエストベースの課金モデル(トラフィックがなければ課金されない) 多言語対応あり 入力するデータはプロダクトモデル(バリアントあり) ある程度の検索結果チューニングが可能 ユーザーイベントベースの検索結果最適化あり グローバルエンドポイント(世界中から使える) これだ!と思いました。要件とVAIS:Cができることを見比べていただければわかりますが、グローバルアプリにとって必要な要求をほぼ満たしており、ネックなのはコストだけです。そこで我々が立てた戦略は以下です。 VAIS:Cを導入し、素早くスモールスタートする トラフィックが伸びてきて、ペイできないレベルになれば、Elasticsearchに切り替える この方法であれば、Elasticsearch側をグローバルアプリに適用するために必要な準備期間も稼げると思いました。一方で、ビジネス側の懸念は現在の日本事業の検索と、同様の売り上げを得る検索結果をだすことができるかどうか、でした。そこはやってみなければわからなかったので、A/Bテストを行うことになりました。 簡単にVAIS:Cを説明しますと、商品情報と、ユーザーイベントを入れると、最適な検索結果が返ってくるというものです。最適化に必要となるユーザーイベントは、Google Analytics 4(以下、GA4)で収集したものが前提となってましたが、スキーマさえ合わせれば独自イベントの入力も可能でした。メルカリはGA4ではなく、独自のイベント基盤を持っているため、なんとか変換して動かしました。(Google Cloud Japanの皆様には多大なるご協力をいただきまして、大変お世話になりました。) 結果的には、我々の商品情報と、なんとか変換したユーザーイベントでは、日本事業の検索よりも結果が劣ることを確認できました。また、後述するいくつかの要件を満たすことが難しいこともわかりました。ですが、このリスクを補ってあまるメリットがあるのも事実です。(これを全部、私一人でできてるのですから!)検索エンジンが変わることでのリスクは合意した上で、グローバルアプリの初期リリースはVAIS:Cで行う、と決めました。 新しい検索バックエンドの設計 検索エンジンの目処が立ったので、次はバックエンドの話です。ここでは、特にこだわった点をご紹介します。 私は7年前、現在の日本事業の検索システムの設計にも関わっていました。当時は理想や期待を込めて設計しましたが、実際に運用を続ける中で「これは設計から見直した方がいい」と感じる部分も多く、今回はそれらを改善する形にしています。 データモデルに依存したAPI データを取得するタイプのインターフェースは”どんなデータ”を対象とするかでガラッと設計が変わります。汎用的になものを作ろうとすると、抽象化が進みすぎて、余計わかりにくくなってしまいがちです。対象が無限に増えるわけではないので、汎用化はせずに、たとえばProductをSearchするためのエンドポイント、というふうに割り切りました。Productのデータモデルは決まっています。タイトルがあって、商品の説明があって、値段があって、、、と、どこに行っても同じです。 柔軟な処理を可能にするプラグイン機構 ElasticsearchやSolrなどにもあるように、検索クエリや結果に対して独自の処理を加えたいというニーズはどの検索システムにもあります。日本事業の検索開発でも、これまで多くの条件分岐(if文)がコードに埋め込まれ、整理が難しくなっていました。そこで、今回のグローバルアプリ向け検索バックエンドでは、クエリの前処理・後処理をフックできるプラグイン機構を導入しています。検索機能の開発者は、必要な処理をプラグインとして追加するだけで拡張が可能です。多くのソフトウェアでも似たような仕組みが使われていますが、結局この方法に行き着くよな、という実感があります。 検索エンジン機能の実装と抽象をわける 基本的なロジックは抽象層にまとめ、実装部分は切り替え可能な構成にしています。もともと、VAIS:CとElasticsearchの両方で動く必要がありましたが、この要件がなくても同じ設計にしたと思います。というのも、検索エンジンの世界はまさに“戦国時代”で、Vector検索に強い新しいエンジンなど、次々と登場しています。現在はElasticsearchを使っていますが、将来的に他の選択肢が有力になる可能性もあります。このため、抽象化しておくことで、後々の移行や比較コストを大きく減らせると考えてます。 その他 グローバルアプリでは、もともとバックエンド全体に関する設計方針が明確にあります ( グローバル展開を支える基盤の裏側 を参照)。このおかげで、何がどこにあるかが、ある程度明確になってます。特に大事だと思うのは、BFFの切り分けです。BFFはここにあるよ(逆にいうと、ここにしかないよ)というのは、見る箇所が限定できるので探索のコストが減るのです。これまでのマイクロサービスでは、どこの誰が検索APIを叩いて、それをお客さまに出しているかをこちらから把握するのは困難でした。検索バックエンドでも、ドメイン特化のノウハウがあります。何をどこに実装するかを明確に提示してるのは新しい検索バックエンドの特徴です。バックエンド全体の設計でも、期せずして同じようなことをしているのは、これまでの苦痛が似ているからだと思います。だれでもなんでもどこにでも作れるというのは、メンテナンスコストを上げる結果になっているという経験則だと思います。 プロダクトオーナーからの想定外の要求で冷や汗 最初はVAIS:Cを使うとはいえ、長期的にはElasticsearchに切り替えなければなりません。私はこれまで、Elasticsearch as a Service (以下、EaaS) という、 ECK などをベースに作った社内のElasticsearchホスト基盤を開発&運用してきました。チームの活躍で、グループ内のほぼすべての検索サービスはEaaSの上で動いてると言えるところまで来ています。関連するエコシステムも充実させてきました。カスタマイズ性も高く、実際、メルカリの複数のビジネスで使われていることがその証左です。グローバルアプリの準備期間中、責任者である@Suwenさんと直接話す機会が多く、EaaSはなんでもできるので安心してください、と伝えてました。そこで何度もフィードバックされたのが、以下のような点です。 「日本事業のこの検索機能、グローバルアプリでも使いたいな」「日本事業のこの機能、グローバルアプリだったらこういうふうにカスタマイズしたらいいよね」 さぁ、ここで私の過去の記事を読んでいただけたみなさまなら、私が冷や汗を流した理由がおわかりですね?EaaSは、Elasticsearchの提供が主であり、その上に作られた機能の再利用までは責任を持っていません。もちろん、プラットフォームとして、機能の再利用性を無視していたわけじゃありません。Elasticsearchにはプラグイン機構があり、実際にそのプラグインを用いた機能なら再利用できます。しかしメルカリではJavaエンジニアは少数派で、Elasticsearchプラグインの開発はほぼ進みませんでした。機能のほぼ全てはGoのマイクロサービスに作り込まれています。以下に、課題感を説明するのに使ったスライドの一部を晒します。日本事業の作り込んだ検索機能資産が使いたいけど、使えないという状態です。 実はこの問題は以前にもぶつかってました。広告事業からも、EaaSを使ってもらっていたのですが、ビジネス側からの期待値は、EaaSを使えば、日本事業の検索と同じクオリティの検索結果がでてくると思われていたのです。実際には、EaaSは日本事業の検索と同じ検索結果を提供するわけではないので、この時は日本向けに作られたシノニムや日本語形態素解析などのライブラリを広告チームのバックエンドから再利用してもらう形で落ち着きました。この頃にスライドを書き、日本の検索チームへ、Goで作られた検索機能の再利用性を高めるべきだとの問題提起はしてきました。が、当時の日本事業の優先度的には、再利用性にリソースを割いてもらうことはなかなか難しかったのです。 All for oneで検索基盤の拡充へ 私はここからは迷走しました。日本事業の開発や優先度を邪魔しない範囲で、なんとか機能の再利用化を進める案を捻り出そうとしました。一時は、必要な機能をElasticsearchプラグインで書き直すか、とまで考えていました。ここで肝となった問題点を整理します。 EaaSは最初から複数事業での利用を見据えた設計であるが、その上に作った日本事業の検索サービスは日本事業に強く結合しているため、他事業からの再利用が困難である 日本事業の検索は7年運用してきたコードベースであり、前述のとおり、うまく整理されていないなどの負債がある 日本事業の検索は引き続き重要であり、このコードベース自体を再利用できるように改変しつつ、日本事業向けの開発を同時並行するのは困難 グローバルアプリの技術責任者である@deeeeetとも議論を重ねて、以下のような案を出しました。いまあるEaaSの上に、再利用可能な機能を一個ずつ切り出して使用するというものです。 日本事業側にも問題と案を再掲示し、議論を重ねました。最終的に、グローバルアプリの優先度が上がったこともあり、日本事業側からも積極的に動いてくれて、日本事業の検索機能を再利用するための新しい層を作ることが決まりました。この層に関しては、主導権があるわけではないので、私からはEaaSというプラットフォームが大事にしているところをなるべく共有して、いまのところ共通した方針のもと一緒に作っています。具体的には以下です。 Platformがその下で使われてるオープンソースソフトウェアに必要以上の制約を加えないこと ここでいうオープンソースソフトウェアとは、我々の場合はElasticsearchです。Elasticsearchには我々がただ使ってないだけで、まだまだたくさんの可能性があります。これを現時点では使わないからという理由で上のプラットフォームを経由すると使えなくなるのは本末転倒だと思ってます。実はここは議論になりやすい点で、制約を加えた方が不可測事態が避けられて、メンテが楽になるという話もありますので、慎重な説得と周りの理解が必要です。 各ビジネスドメインから独立して使えること 共通基盤を作って、それを複数のオーナーから利用する時に問題になるのは機能の開発優先度だと思います。事業Aは規模が小さいから後回し。事業Bのオーナーは発言力があるから、優先。。などなど、いわゆる”政治”になりやすいところだと思います。完全な独立は不可能ですが、これをなるべく避けるためには、基盤への開発が開かれていることが重要です。開かれていると言っても、自由に作れるとはまた違います。ブログの前段で説明した通り、どこでもだれでもいじれると収拾がつかなくなってしまいます。それを解決する一つの手はプラグイン機構です。どこをどうフックするかはまだまだ議論していく必要があるのですが、基本的な方針に関しては同意できています。 こうして、現在のグローバルアプリの検索は、VAIS:CとEaaSの上に作られた新しい仕組みとのハイブリッドで稼働しています。 まとめ 今回はグローバルアプリでの新たな検索要求に対してどのような方針で対処したのかについて書かせていただきました。従来の日本事業の検索とは毛色の違う要求をこなすために、フルマネージドの検索サービスである、VAIS:Cを一時的に導入しました。また、グローバルアプリの開発要求を起点に議論が広がり、社内検索基盤を拡充させることで、今後の要求についても対処できるように基盤を作っていることについても触れさせていただきました。具体的な多言語対応方法など、今回、書ききれなかった部分もあるので、また次回以降でご紹介できればいいなと思ってます。 参考 ”メルカリの検索基盤の変遷について” https://engineering.mercari.com/blog/entry/20220207-776318b784/ 月間2000万人が使う メルカリ検索機能のアーキテクチャ https://findy-tools.io/articles/mercari-elasticsearch/38

動画

該当するコンテンツが見つかりませんでした

書籍