VOICE 22 イベントレポート

こんにちは、ボイスサービス部の ymd (@y_am_a_da) です。 今回は私と、 Cookpad inc (UK) の Global CTO である miles (@tapster) が VOICE 22 に登壇をしてきたのでそのレポートです。

VOICE 22 とは

2018 年から開催されている世界的な対話型 AI *1 に関するカンファレンスです。2021 年までで世界で 10 万人以上が参加しており、この界隈の中では非常に大きなカンファレンスであると言えます。 世界的な情勢もありここ数年はオンラインのみでの開催となっていましたが、今年は久しぶりにオンラインとオフライン混合での開催となっていました。

対話型 AI に関わるベンチャーの CEO や、音声ユーザーインターフェースのデザインに関わるデザイナー、対話型 AIを活用するサービスを開発するエンジニアなどが様々な観点から発表をしていました。

www.voicesummit.ai

クックパッドは海外展開にも注力しており、世界 74 ヶ国 32 言語で展開をしています。私の所属するボイスサービス部でも複数の国でサービスを展開しており、今回のイベントではそのサービスを運営して得られた知見をもとに音声対話型 AI やスマートスピーカーが料理のシーンをどのように変えられるのか、その可能性について "Introduce VUI to Make Everyday Cooking Fun" というタイトルで発表をいたしました。

ボイスサービス部の ymd Cookpad inc (UK) の Global CTO である miles

登壇資料はこちらになります。

参加者について

今回登壇やブースを出展していた企業は大まかに 2 種類に分類することができました。

  • 対話型 AI を簡単に導入できるサービス
  • 音声コンテンツを生成するサービス

また、登壇者以外の来場者の層は、私達と同じようにスマートスピーカーや対話型 AI 向けにサービスを提供している開発者であったり、他にも対話型 AI のプラットフォーマー、対話的 AI の導入を検討している企業など様々でした。 全体的に、いわゆる開発者向けのカンファレンスではなく、もう少し幅広い対象を意識したイベントとなっていました。

登壇やブース出展していた企業を上記の分類ごとにもう少し詳しく紹介していきたいと思います。

対話型 AI を簡単に導入できるサービス

いわゆる Alexa や Google Assistant のような対話型 AI を導入できるサービスです。ここでの導入先は例えばコールセンターのオペレーター、レストランなどの予約受付システム、銀行の窓口業務などがあたります。 すなわち、人間が仕事でやっているコミュニケーションのうち、機械に任せられるところは機械に任せようというのを目標としたサービスです。

コミュニケーションにかかる人件費の削減や効率性を主に押し出していますが、それだけではなく、ユーザーとのコミュニケーションをデータとして可視化、分析できるようなダッシュボードを用意し、ユーザーとのコミュニケーションを改善するためのツールを提供しているようなところも多々ありました。 また、エンジニア向けの API の提供はしているものの、全体的に作り込まれたノーコードでの制作ツールを提供していることが多く、そのことからもエンジニアを抱えていない企業を強くターゲットとして意識している印象でした。

音声コンテンツを生成するサービス

いわゆる Text-to-Speech と呼ばれる技術を用いてテキストから発話データを生成するサービスです。ただ読み上げデータを作るだけではなく、多言語翻訳であったり声質の変換だったりにも対応しているサービスもありました。また、テキストだけではなく発話を入力にすることも可能なサービスもありました。

主な利用シーンとしては、 Podcast やスポーツの実況、動画コンテンツなどにつける注釈のようなものを想定しているようでした。例えば、ブログを文章で書けばそれをそのまま Podcast のコンテンツにも流用できる。というような具合です。 日本でも以前から類似のサービスはありますが、例えば Podcast のコンテンツを生成した音声で制作する発想はなかったのでそういったユースケースの話には新鮮さを感じました。

終わりに

今回登壇していた企業を見るとほとんどがいわゆるモバイルアプリケーションなどの延長線上ではなく、労働力の置き換え手段として音声アシスタントやその周辺技術を捉えている雰囲気を感じました。おそらくマーケットの大きさやマネタイズポイントのわかりやすさからそういったサービスが現状では大きく成長をしているのだと考えられます。自分自身はアプリケーションの延長線上として捉えている部分が大きかったため良い刺激になりました。

また、登壇者ではなく来場者の方には私達と同じように音声アシスタントプラットフォーム上に向けたサービスを開発している方も多く、ネットワーキングの時間で色々と情報を交換できてそちらも非常に有意義な時間となりました。

今回まとめた中には含まれませんでしたが、他にもいくつか面白い発表があったのでここでまとめて紹介します。

  • コロナ禍により対話型 AI の利用者数はかなり伸びたという話
    • 感染症予防の対策により非接触型のニーズが高まり、窓口に行って話をするのではなく、モバイルデバイスからチャットボットや音声アシスタントとやり取りをすることを好むユーザーが増えたとのこと
  • 車内でのインタラクティブな音声広告の話
    • いわゆる Voice Advertising と呼ばれるインタラクティブな音声広告がここ数年で広まりつつありますが、それを車載の音声アシスタントに搭載した。という内容でした。今どのあたりを走行しているのか認識することができるので、例えば近所のスーパーで起きているセールを提案する。などが事例として紹介されていました。まだまだ成長途中のマーケットですが、既存の広告媒体と比較して非常に高いエンゲージメントを誇っており、説明では既存のデジタル広告の平均 CTR は 0.6 % であるものの、自社の広告はエンゲージメントが平均 12% であると発表していました。 *2
  • Alexa を使った新たなデバイスなどの話
    • 主に Alexa Inovators と呼ばれる方々の開発している製品についていくつか紹介がされていました。特に Labrador という製品が面白かったです。 Alexa で操作ができる自律走行可能なワゴンカートなのですが、専用のトレイを利用して簡単な荷物の積み下ろしに対応しており、日本の家屋にマッチするサイズ感かはさておき、日々の家事が大変な人にはとても便利そうに見えました。 *3

弊社ではこのように色々な技術スタックを持ったエンジニアが数多く在籍しております。絶賛エンジニア募集しておりますのでご興味ありましたらぜひこちらのサイトをご覧ください。

info.cookpad.com

*1:音声アシスタントやチャットボットのようにテキストや発話での自然言語を使ってインタラクションが可能な AI を指しています。

*2:過去の記事ですが以下の記事にも書かれています techcrunch.com

*3:こちらに詳しいですwww.youtube.com

クックパッドマートにおける item-to-item レコメンデーションの変遷

こんにちは。研究開発部の深澤(@fufufukakaka)です。

本記事ではクックパッドマートにおける item-to-item レコメンデーションについて、その概要とアルゴリズムの変遷についてお話したいと思います。

item-to-item レコメンデーションとは

レコメンデーションにはいくつかタスクが存在しますが、今回はその中でも item-to-item レコメンデーションについてお話します。

item-to-item レコメンデーションでは、「ある商品について、その商品を軸におすすめできるアイテム」を表出します。表現の仕方はサービスによって様々ですが、よく この商品を買っている人にはこちらもおすすめです , この商品に関連する商品 などと表現されています。

さて、その item-to-item レコメンデーションの中にも実は更に種類があります。それは商品間のスコア(距離,類似度,etc) をどの軸で表現するか、です。大きく分けて以下の2種類になるかと思います。

  • ある商品について、その商品に関する行動データ(商品a を買った後によく商品b が買われている、など) を利用してスコアを計算する行動データを使った方式。 この商品を買っている人にはこちらもおすすめです といったレコメンドを実現する際に選択されます
    • 行動データを使って似ている商品を出すことを目的としたモデルもあります
  • 商品名や商品画像を使って商品間の類似度を使うコンテンツデータを使った方式。この方式でおすすめ商品を表出している場合は この商品に関連する商品 に適したレコメンドになります

今回は item-to-item レコメンデーションかつ行動データを使ったモデルの話になります。

クックパッドマートにおける item-to-item レコメンデーション

クックパッドマートでは早くから item-to-item レコメンデーションが取り入れられています。

レコメンドモデルによって算出されている「よく一緒に購入されている商品」

各商品の詳細ページ下部に、この商品を買っている人におすすめ といったセクションがあります。ここで出ている 6 商品は機械学習モデルによって毎日更新されています。この機能は2020年に追加され、いくつかモデルの変遷を経て現在、こちらの機能はクックパッドマートの売上においてある程度の貢献を果たすに至っています。

ここからは実際にどのような変更があったのかをお話します。

アルゴリズムの変遷

Item2Vec 時代

初めは Item2Vec でレコメンドを実装していました。Item2Vec は https://arxiv.org/abs/1603.04259 で提案された手法です。僕は前職の先輩方が使っていたのを見て使いはじめました。

Item2Vec は単語の意味ベクトルを獲得する Word2Vec をレコメンドに応用したもので、Word2Vec が単語を対象にするのに対して、Item2Vec では商品を対象にし、商品ごとの意味ベクトルを獲得します。これによって商品Aと商品Bの距離が計算でき、「商品Aに距離が近い商品群」が取得できます。

"距離"の意味合いは学習のさせ方によって異なります。当初は1回の注文で一緒に購入された商品を軸に学習させました。具体的には order を context、その order に含まれる item_id を word とみなして Word2Vec の文脈で扱います。

Item2Vec の魅力はとても簡単なコードでレコメンドが実装できる点にあると思います。gensim を駆使することで数行でレコメンドの大枠が整います。例えば user_id, order_id, item_id, cv_datetimeという dataframe から学習させたい場合には

from gensim.models import word2vec

# df.columns = ["user_id", "order_id", "item_id", "event_timestamp"] のようになっていると仮定します
order_product_dict = (
  df.groupby(["order_id"])["item_id"]
  .apply(lambda x: [str(v) for v in x.tolist()])
  .to_dict()
)

# word2vec_params というパラメータを集約した yaml or json を事前に読み込んでいると仮定します
item2vec = word2vec.Word2Vec(
  order_product_dict.values(),
  vector_size=word2vec_params["vector_size"],
  window=word2vec_params["window"],
  alpha=word2vec_params["alpha"],
  sample=word2vec_params["sample"],
  epochs=word2vec_params["epochs"],
  ns_exponent=word2vec_params["ns_exponent"],
  min_alpha=word2vec_params["min_alpha"],
  hs=0,
  negative=1,
  sg=1,
  seed=42,
  min_count=1,
  workers=4,
)

このようなコードでレコメンドモデルの学習自体は完了します。 推薦したいときは most_similar 関数でコサイン類似度に基づいて、クエリとなる商品と "距離" の近い商品を指定した数だけ取得できます。

item2vec.wv.most_similar(target_product_id, topn=10)

このように Item2Vec による推薦は gensim に乗っかることでかなり簡単に実装できます。このモデルを使ったレコメンドが 2020年9月頃からアプリに載り始めました。その後、以下のような変更・施策を試してきました。

  • 編集距離を用いた名寄せ
    • 当初はキャンペーン用に商品が複製+prefix に SALE など文字列が付いた、実体は同じだけど違う id の商品がたくさんありました。これを編集距離ベースで名寄せしていました。現在は複製されずにセールの運用が可能になったため、あわせてこちらも退役させています
  • 直近出品された商品の中から推薦する枠を混ぜる
    • 学習データを1年分としているのですが、直近出品された商品をフィーチャーする目的として枠を用意していました。具体的には6商品を普通に推薦し、3商品を直近枠として混ぜていました。現在、RecVAE に変わったタイミングで6商品のみとなり、このタイミングで外しました(まだ実装自体は残っています)
  • 特定のカテゴリの商品には予め決めたレコメンドを出す
    • これは Item2Vec に限った話ではないですが、例えばワイン系の商品のレコメンドではワインによく合う(だろうとこちらが考えて決めた)おつまみリストを出すようにする、という施策を試しました。相談を受けて試してみたところ、有意な変化が見られず、そのまま元に戻しました

Item2Vec からの転換

Item2Vec での運用は非常に手軽だったため、アルゴリズム本体以外の細やかな変更を色々試せました。が、ずっと思っていた心残りがありました。オフラインテストでの精度指標があまり高くなかったのです。

Metrics Value
Hit@10 0.149
MRR@10 0.0549
NDCG@10 0.0604
Precision@10 0.0176
Recall@10 0.1012

これはある時点でのデータを抽出して Item2Vec での学習を実施した際の結果です。NDCG@10 が 0.06 となっていますが、これは感覚的にはとても良い数字とは言えないものでした。

Item2Vec を倒すために Matrix Factorization・特徴量をいくつか混ぜた Factorization Machine 系のものをニューラルベースで実装し試したのですが、精度指標が多少上回っても推薦の偏りが強くなったり(Coverage が下がってしまった) となかなか満足いくアルゴリズムが出せずにいました。

RecBole による実験

そんなことを考えつつ過ごしていたときに、以下のブログでも紹介した RecBole を知り、これを PoC だけでなく実践で試してみようと考えました。

techlife.cookpad.com

RecBole についての紹介は前述した記事で記載した紹介を引用します。

RecBole は中国人民大学・北京大学の研究室が共同で始めたプロジェクトのようで、去年の11月に arxiv に登場しました。今年の8月に提供しているモジュールがv1を迎えて、本格的に色々な人が利用するようになったようです。 RecBole 最大の魅力は、上述してきた再現性の難しいレコメンドモデルを統一したインタフェースで実装し、比較を容易にしているところにあります。そして実装されているモデル、適用できるデータセットの数が凄まじいです。モデルは現時点で70以上(モデルリストがすごい )、データセットは20以上のものについて即座に試せます。どれくらい即座に試せるかと言うと

pip install recbole
python run_recbole.py --model=<your favorite model> --dataset_name ml-100k

これだけで、レコメンド界隈の中で最も有名なベンチマークである MovieLens-100k データセットに対して70以上のモデルを即座に(追加の設定が必要なやつもありますが)試せます。これだけのモデル・データを試すことができる環境はそうないと思われます。また70以上の収録されているモデルたちは全て PyTorch ベースで丁寧に再実装が行われており信頼性は非常に高いです。predict 関数などの基本的なインタフェースは統一されており、実験のし易い環境が整えられています。

RecBole は user に対する item への推薦を仮定しているため、item-to-item のレコメンドで RecBole を適用するためにはログを変形する必要があります。 具体的には user1: item1,item2 というログが得られたらこれを変形して item1→item2, item2→item1 というように関連して購入されたと思われるセッション内でペアをつくり、各アイテムを user とみなしたデータを作ります。 実際には「あるユーザがその日購入した商品履歴」を軸にしてペアを作っています。

こうしたデータを作り、RecBole で実験を行ったところ、以下の結果を得ました。

Name hit@10 mrr@10 ndcg@10 precision@10 recall@10
RecVAE 0.3264 0.1368 0.1358 0.0617 0.1864
MacridVAE 0.3111 0.1537 0.1352 0.0661 0.1612
EASE 0.2598 0.1352 0.1123 0.0657 0.1298
NeuMF 0.2884 0.1102 0.1115 0.0546 0.1554
NNCF 0.2598 0.1072 0.0995 0.0528 0.1277
ItemKNN 0.2339 0.1039 0.0954 0.0461 0.123
NGCF 0.2116 0.1017 0.0786 0.0436 0.0914
BPR 0.2069 0.1014 0.0765 0.0458 0.0847
MultiDAE 0.2095 0.0949 0.0755 0.0427 0.0907
DGCF 0.18 0.0909 0.0619 0.0386 0.0653
Item2Vec 0.149 0.0549 0.0604 0.0176 0.1012
SLIMElastic 0.1672 0.0861 0.0597 0.0419 0.054
LightGCN 0.1734 0.0881 0.0593 0.037 0.0604
DMF 0.1732 0.0843 0.0586 0.0392 0.0585
CDAE 0.1524 0.083 0.0517 0.0336 0.0462
SpectralCF 0.1543 0.0804 0.0502 0.0336 0.0446
LINE 0.1331 0.0732 0.0419 0.0315 0.0282
Pop 0.1174 0.0424 0.0315 0.0234 0.0332
ENMF 0.073 0.0355 0.0211 0.0184 0.0111
GCMC 0.003 0.0011 0.0015 0.0003 0.003

30モデル弱を実験し、RecVAE など VAE 系が NDCG@10 で 0.13 程度を達成しました。 これは Item2Vec の成績と比較するとかなりよかったので、RecVAE と Item2Vec をオンラインで比較してみることにしました。

RecVAE について

RecVAE はユーザとアイテムのヒストリーを行列にした上で、 Variational Auto-Encoder というニューラルネットワークで圧縮・復元の学習を行い、ユーザとアイテムのヒストリー行列を正確に復元できるように学習したモデルです。 Multi-VAE の構造を元にしつつ composite-prior の導入や Encoder 層の改良を行っています。

Paper-With-Code のレコメンドに関するリーダーボードで NDCG による評価が行われている Movielens 20M (https://paperswithcode.com/sota/collaborative-filtering-on-movielens-20m) では、RecVAE は 2019 年に発表されたモデルでありながらまだ 3位の位置を保っており、かなり強いモデルです。

先程のブログでも紹介した、社内のデータを使った実験でも殆どのケースで RecVAE は上位に入っていました。

インターリービングによるオンラインテスト

オンラインでの比較にはABテストが実施されることが一般的ですが、今回は実験的な意味合いも含めてインターリービングを実施しました。

インターリービングとは推薦システムなどランキングを出力するタイプのアルゴリズムに関して適用できる手法で、比較したい2つのランキングアルゴリズムの出力を混ぜて一つのランキングを出力します。その混ぜたランキングについてユーザが何らかのアイテム(アイテムα)にコンバージョンした際、どちらのアルゴリズムによって出力されたアイテムなのかという観点から各アルゴリズムにポイントを割り振り、アルゴリズムA・Bのどちらが一方より優れていたか、をクエリ(アイテムα)ごとに出します。

インターリービングが ABテストと最も異なっている点は、群を分けることなく同じユーザ群を使った実験が可能で、群差を気にする必要がない点です。また、同じユーザに直接アルゴリズムA, Bを提示して暗黙的な直接比較を要求するので、ABテストよりもはっきり結果が出やすい点が特徴的です。CVR など性能を定量的に測れない(相対的にしかわからない)などデメリットも多いですが、前述したメリットに着目して実施してみることにしました。

今回は Pairwise Preference multileaving(PPM) を使ってランキングを生成してみました。こちらのライブラリ(mpkato/interleaving) を利用すると以下のように実装できます。

In [1]: import interleaving

In [2]: a = [1, 2, 3, 4, 5]

In [3]: b = [4, 3, 5, 1, 2]

In [4]: method = interleaving.PairwisePreference([a, b])

In [5]: interleaved_ranking = method.interleave()

In [6]: type(interleaved_ranking)
Out[6]: interleaving.ranking.PairwisePreferenceRanking

In [7]: interleaved_ranking
Out[7]: [4, 1, 2, 3, 5]

In [8]: interleaved_ranking = method.interleave()

In [9]: interleaved_ranking
Out[9]: [4, 1, 3, 2, 5]

評価するときは以下のようになります。

In [10]: my_ranking = interleaving.PairwisePreferenceRanking([a, b], 
                 contents=interleaved_ranking)  # ランキングクラスを復元する

In [11]: interleaving.PairwisePreference.evaluate(my_ranking, [0, 1])  # アイテム4と1がクリックされたとする
Out[11]: [(0, 1)]  # ランキングAが勝ったことを示す

2022年2月~3月で Item2Vec・RecVAE のランキングを混ぜてアプリに表出し、そのデータを集めました。結果は以下のようになりました。

Name Value
RecVAE 勝利数 1295
Item2Vec 勝利数 1149
引き分け回数 899

これについて Binomial sign test (有意水準 5%) を行い、RecVAE が有意に Item2Vec より優れていることがわかりました。

RecVAE と Item2Vec の比較(定性評価)

2022年 3月頃のレコメンド結果からいくつかのケースを抽出して考察してみます。現時点(2022/10/05)でクローズされていない商品にはリンクをつけております。

ケース1. アトランティックサーモン

クックパッドマートの中でも非常に人気な商品であるアトランティックサーモン (https://cookpad-mart.com/products/1592) について、RecVAE と Item2Vec のレコメンドをそれぞれ見てみました。

Item2Vec は比較的同一系統の商品を提案していますが、RecVAE はサーモンと併せて使えそう・ついでにこちらも、といった観点で食材を提案している様子が見て取れます。

ケース2. 有機じゃがいも

続いて、【有機】じゃがいも400g(https://cookpad-mart.com/products/7520) という商品のレコメンドを確認します。

Item2Vec はこちらでも同系統(といってもじゃがいもばかり出しているのではなく、有機という特徴を捉えている)の商品を出しており、RecVAE はそれとは対照的な商品推薦を行っています。

ケース3. ささみ

最後に お徳用 ささみ 大袋 約500g (https://cookpad-mart.com/products/1605) の推薦結果を確認します。

やはりここでも、同様の傾向が見られました。Item2Vec は行動データを使ったモデルではありますが、クエリとなる商品に対して置き換え可能な商品候補を上位に出す傾向が強そうなことがわかります。

Item2Vec は Word2Vec の仕組みを転用しているため、周辺の商品から出現しそうな商品を予測することで獲得した重みを使った推薦を行っています。「私はカレーが好きです」という文章があったら、カレーの代わりにシチューなどが単語として入り得ますが、そうしたときにカレー・シチューが単語として近いベクトルを持つようになるといったイメージです。

Item2Vec ではこれがどうなるかというと、「ブロッコリー・ささみ・ピーマン」という商品履歴があった際に、これが「ブロッコリー・鶏むね肉・ピーマン」となってもタンパク質を重視したヘルシーな商品の並びという意図は変化しなさそうです。このようなときに、ささみと鶏むね肉は近いベクトルを持つことになります。こうしたことが起きていると考えると、Item2Vec の推薦傾向が、行動データを通じて似ているアイテムを出す、というものであることが納得できるかと思います。

RecVAE の内部でどのような学習がなされているか、Item2Vec よりも学習の仕組みが複雑であるため詳細に考察を述べることは難しいのですが、VAE によって商品履歴を復元する過程で「この商品にフラグが立っていたらこちらにもフラグが立つだろう」という推論がうまく行えているのだろうと思います。

レコメンドのアーキテクチャ

この結果を受けて現在レコメンドモデルは RecVAE (in RecBole) となっています。アーキテクチャは以下のとおりです。

レコメンドのアーキテクチャ図

  • レコメンドは日次バッチで更新されます。一連の流れは Kuroko2 という社内ジョブ管理システムによってキックされます
  • まず Redshift から 3ヶ月分のカート追加イベントを取得します (Queuery を使用して取得します)
  • Hako によって定義された ECS 環境が立ち上がり、カート追加イベントを受け取って RecBole を使った RecVAE の学習が行われます
    • およそ 3時間程度で学習が完了します
  • 全アイテムに対するレコメンドリストを出力し、S3 に格納します
    • このとき、オフラインテストのメトリクス群も取得し、S3 に保存します
    • オフラインテストのメトリクスは社内ツールの Metrics Tracer というメトリクス監視ツールに取り込まれます。このツールを使って機械学習モデルに関する簡単な監視をしています
  • レコメンドリストをクックパッドマートの DB に取り込みます
  • 最終的に Backend サービスから API でレコメンドが配信され、アプリに表示されます

RecVAE (in RecBole) に変えてみて

オフライン・オンラインでの評価でいずれも良い成績を見せた RecVAE ですが、実際のコンバージョンにも大きく寄与しています。

変更後、それまでの水準から比較するとおよそ4,5倍ほどレコメンド経由でのカート追加数が増加しました。 その分学習にかかる時間や計算リソース、学習コードの複雑さは若干増しましたが、それを上回るメリットが得られたなと感じています。

今回のレコメンドでは期待されるものが Item2Vec ではなく RecVAE という結果になりましたが、「この商品に関連している商品もどうですか」などといった関連商品を表示する文言とともに表示される枠であれば Item2Vec もシチュエーションに適合して良い成績を残したと考えられます。

RecBole で実装したおかげで追加されるモデルとの比較実験を行う環境が簡単に用意できるので、今後もオフラインテストのメトリクスを監視しつつ新しいモデルをどんどん試していこうと思います。

まとめ

本記事ではクックパッドマートにおける item-to-item レコメンデーションの変遷の概要をお伝えさせていただきました。 様々な試行錯誤を経てクックパッドマートにおけるレコメンドの重要性は強くなっています。また、レコメンド以外にもクックパッドマートには様々な機械学習の技術が用いられており、日々進化しています。

この記事を読んでいただきありがとうございました。 機械学習の技術をプロダクトで活かしたい方がいらっしゃいましたら、ぜひ新卒・中途採用にご応募ください。

info.cookpad.com

Androidアプリ開発を効率的に行うための仕組み

こんにちは、サーバーサイドエンジニアをしつつ、最近はAndroid開発初学者のhyogaです。 入門してからそろそろ1年経とうとしているので、もう初学者と言えないかもしれないですね。

クックパッドでは、開発を効率的に行うために、様々な仕組みやツールが導入されています。 この記事ではクックパッドでのAndroidアプリの開発中からアプリのリリースまでに使われる以下のような仕組みやツールについて広くお伝えできればと思います。

Flipper

Flipper

Meta社の作っているFlipperというツールです。 クライアント側でセットアップし、使いたいPluginごとの対応が必要ですが 対応さえ済んでしまえばFlipperを開くだけで、以下の内容などが見れるようになります。

ネットワークViewerでは、 APIリクエストをmockして特定のAPIリクエストでエラーを起こしたり、レスポンスを任意の値に置き換えたりすることができます。 APIリクエストエラー時の挙動が簡単に確認できたりして、とても便利ですね。

APIレスポンスを書き換えている様子 モックされたAPIレスポンスにより部分的にエラーになっている様子

他にもShared Preferencesの内容を確認して、書き換えたりもできます。 クックパッドのAndroidエンジニアの中では必須ツールになっています。

Shared Preferencesの中身を書き換えている様子

開発者用のデバッグツール

デバッグビルド版にのみサイドメニューに導線が現れる

社内で開発されている開発用のデバッグツールです。 クックパッドAndroidアプリは マルチモジュール化されています。 このデバッグツールもその中の1つのモジュールとして提供されており、 デバッグビルド版でのみ使うことができます。

この開発者ツールでは、以下のような事ができます

  • APIの接続先(ステージング/プロダクション)の切り替え
  • ログインしているユーザの行動ログの閲覧
  • ログインしているユーザの簡単な切り替え
  • A/Bテスト用のツールのA/Bパターンの切り替え
  • などなど...

これにより、エンジニア以外でも特殊なツールなしにデバッグや動作確認が容易になっており、とても便利です。

また、この開発者ツールはリリース版ビルドには含まれないので、実験的に新しい機能や ライブラリを導入して試すような使われ方もしています。

Android StudioのFile and Code Templates

クックパッドAndroidアプリでは、VIPERっぽい*1アーキテクチャを用いて実装されています。 VIPERアーキテクチャでは、1つの画面を実装するために InteractorRouting などといったたくさんのファイルを用意する必要があり、あたらしい画面を実装するたびに、同じ似たようなコードを書くのはなかなか手間がかかります。

クックパッドAndroidアプリのVIPERベースのアーキテクチャ*2

そこでクックパッドでは、 Android StudioのFile and Code Templates機能を使い、必要なファイル群をガガっと生成することができるようにしています。 基本的に新しい画面を実装する時は、このファイル群を編集していく形になります。

生成されたファイル群

少し細かい工夫ポイントは、Templatesを使った時点でビルドが可能な状態になっていることです。

生成されたContractファイル

これによって、Interactor、 ViewModelといったデータの取得部分から実装する必要がなくなり、Viewから実装する選択肢を取れるようになりました。 Jetpack ComposeだとPreviewで簡単にViewを確認できるということもあり、個人的にはとても嬉しいです。

ちなみにTemplatesは .idea/fileTemplates/ 以下に配置しており、クックパッドAndroid アプリを開発するエンジニアが共通して同じものを使えるようにGitリポジトリに含めています。 *3

.idea/fileTemplates/

haneda: 開発中のアプリを簡単にインストールできる仕組み

クックパッドでは、GitHub Enterpriseを使っておりPR上でコードレビューなどをします。 クックパッドAndroidアプリのリポジトリでは、 PRを出すとCIによってビルドされたアプリがhaneda(社内のアプリ配信サービス)から配信され、 社員は手元の端末にPRの変更が適用されたアプリをインストールすることができます。

最新のビルドだけでなく過去のビルドなどもインストールできたり、クックパッドAndroidアプリだけでなく、クックパッドで開発されている全てのアプリがhaneda上で配信されているので、クックパッドのメンバーが社内の開発中アプリにアクセスしやすくなっています。

ブラウザで開くとQRコードが表示されて便利

社内の誰でもQRコードから開発中のアプリをインストールできることはとても便利です。 エンジニア以外の人も開発中のアプリをインストールして動作確認したりドッグフーディングすることができます。

おわりに

どうでしたでしょうか? この他にも

  • アプリにbeta機能として特定の機能を追加できるFeature Flag
  • マルチモジュール構成になってるアプリの特定のモジュールだけを別アプリとして切り出すことのできる仕組み*4
  • Markdownで管理された行動ログのログ定義から実装コードを自動生成できる仕組み*5

など日々エンジニア主体でAndroidアプリ開発を効率的に行う仕組みの改善や導入がおこなわれています。

クックパッドは、DroidKaigi 2022にゴールドスポンサーとして協賛しています!会期中は会場でブース出展しますので、興味を持っていただけた方はぜひブースにお越しください。 オフラインでもオンラインでも他の話も聞いてみたい!などあれば気軽にご連絡お待ちしてます!!

info.cookpad.com twitter.com