snaqme Engineers Blog

おやつ体験メーカー snaq.me エンジニアによる開発プロダクトブログ

MVPから始めるデータ基盤の構築 ~AWS MWAAを利用した安定運用に至るまで~

こんにちは、スナックミーでデータエンジニアをしている加藤です。

スナックミーではここ最近、データ利用に対する注目度が高まってきています。 それに伴い構築を開始したデータ基盤が安定運用できるようになってきたので、今回はこのデータ基盤について構築当初から安定運用までを振り返ってみたいと思います。

データ基盤の重要性

簡単にデータ基盤について書いておきます。

意思決定のための分析や現状をモニターするためなど、様々なデータ利用の用途に対応するためには利用しやすい形でデータが整備されている必要があります。

整備がなされていないと、どうやって目的のデータを取得して良いかわからなかったり、データを取得したいのにクエリが重すぎてかけることが実質不可能になってしまったり、データ利用の効率や広がりに悪影響しかありません。

そうしたデータの効率的な利用や整備されたデータの蓄積・管理のためには、ある程度コストを投下してデータ基盤を構築することが重要になると考えています。

構築前: 整備されていなかった状態

かなり簡略化していますが、構築前は以下のような構造になっており、下に挙げるようないくつかの問題が発生していました。

重たいクエリ・取得できないデータ

弊社ではデータの社内での可視化にRedashをメインに使用していました。 そしてRedashのデータソースとして主に、本番DBとして稼働しているAuroraとログ系などを集積しているS3をAthena経由でクエリできるようにしているものがありました。

そのため、Auroraに対してクエリをかける場合はものによってはクエリが重く負荷をかけてしまったり、Athenaの場合は元がログなどの非常に大量のデータであるため重すぎてRedashで可視化することが難しかったりしていました。

業務アプリ用DBと分析用DBの違い

次にデータを分析しようとなった場合の必要なデータの形式の違いの問題もありました。

例えば以下の画像のようなユーザーの会員ステータスを管理するテーブルがあった場合、アプリケーションのDBでは今の状態が分かることが重要で過去データは特に必要にならないケースも多いです。 大して、例えばユーザーの会員動向を分析しようとする場合にはそうしたステータスデータもヒストリカルにログデータとして扱いたいことが多々あります。

もちろん、アプリケーションDBにおいてもログのような形を取って最新のものだけ扱ったり、別途履歴テーブルを用意したりすれば解決するかもしれませんが、必要に迫られる頻度が少ないデータソースについてはそうした対策を取っておらず、分析的に扱いづらいデータがいくつもありました。

独自に集計されたスプレッドシートの山

上の構成図のところでスプレッドシートが登場していることに気づいた人もいるかもしれません。 スプレッドシート、便利ですよね。扱いも簡単だし、共有もすぐにできるし。

けれど、多重参照や複雑な関数の入れ子が発生すると途端に職人技が必要になるものへと変貌します。

弊社でも、Redashからダウンロードしたデータをスプレッドシートで再集計して管理する、などといったことが行われていました。

結果的に、同じようなデータがやや異なる集計ロジックによって重複してしまったり、値を定数で入れてしまったために元の値がなんなのか分からなくなってしまったりということが発生していました。

ローカルを交えたMVP的な動き

さてここからは実際に構築へ向けて動き出してからの話になります。

しかしながら、どんなアーキテクチャにするのか?どの技術リソースを使うのか?テーブル構造はどんな戦略でいくのか?などなど、考慮すべきことがたくさんあります。 加えて、構築に時間はかかるけれどデータを利用したい側の需要は待ってくれません。構築に時間をかけるほどに本番DBに負荷はかかり続け、スプレッドシートは量産されていきます。さらには社内的な理解を得るためにも早急にMVP的なものを作って動かしていく必要があると感じていました。

そこで、以下のような構成でMVPとして、速さ優先で実稼働させることを意識しました。

Redashから各人が各々データを引き出していたところを、RedashAPI経由でローカルPCでデータを取得し、加工・整理してからスプレッドシートAPIスプレッドシートに格納しています。そしてこれを早朝などにバッチ処理として実行し、最終的なデータの可視化にはGoogle DataPortalを利用しました。これにより、データをグラフィカルにダッシュボードとしてモニターすることができるようになりました。

またスプレッドシートに再格納する際、データウェアハウス・データマートとしての区別・構造を意識してデータ整備も併せて行なっていたため、分析用途で大規模なデータを取得する場合にも役立つことがありました。

そして何より、この形で爆速でMVPとして動き始めることができたことで、データ利用者側の需要やどういう可視化が必要とされていて、そのためにはどのようなテーブル構造が適しているのかなど、利用面の調査を兼ねることができたのが大きかったです。時間をかけて基盤を作っても誰にも使われないのでは意味がありませんからね。

当然いくつも問題点はあって

  • 結局本番DBには接続してしまっている
    • これについては、この処理の実行を早朝にすることで、ひとまず常時負荷がかかる状態は回避することにしました。
  • スプレッドシートの増加
    • スプレッドシートの数だけ見ればそうなんですが、ロジックによって管理されているのでどのデータソースからどのシートへとデータ挿入されているのかが追えるという点でそこまで大きな問題ではないと考えていました。
  • セキュリティ面
    • これが一番ですね。ローカルPCでゴニョゴニョしてしまっている点については、いったん仕方ないと受け入れて目をつぶることにしました。

AWS MWAAを活用したデータ基盤の構築

そんなこんなでMVPの運用をしてイメージを固めつつ、実際の基盤構築を並走して行いました。 見出しにもある通り、ワークフローエンジンにはAirflow (AWS MWAA) を利用し、ウェアハウス製品にはBigQueryを利用することに決めました。

MWAAを選んだ理由としては、初期のキャッチアップコストはかかるものの拡張性が高く、データのやりとりに関する管理がしやすいことが最大の利点でした。また弊社ではほとんどのリソースがAWS上に存在しているので、MWAAを利用すれば種々のサービスとの接続がしやすいことも魅力でした。

ウェアハウスについても今となってはRedshift serverlessが候補に上がりますが、当時はコスト的にBigQuery一択だった感じですね。

少し記事が長くなってしまったので、構築の困った点やポイントなどはまた記事を分けて書こうと思いますが、現在は以下のような構成になっています。

課題を解決した点は以下です。 - 本番DBからは夜間バッチでBigQueryにデータをコピーし、後続ではコピーされたBigQueryからデータを取得するようにしているので、本番DBには負荷がかからなくなった - ログ系など、S3に大量に収集されていた非定型含むデータもAWS Lambdaでの処理を挟むことで扱いやすくなった - データマートの整備によって、各人ごとにバラバラだった集計処理を一元化した - Redashでのアクセスについても、重たいクエリであってもウェアハウスに対してであればデータが取得しやすくなった

などです。加えて開発面で言えば

  • SQLによる処理について、コードを全て一元管理できるようになった
  • データウェアハウス、データマートの拡張については、非常に簡単に行えるようになった
  • 全体を一つのワークフローで管理するようになったことで、これまで一切考慮できていなかった冪等性やリトライ、エラー検知がやりやすくなった

基盤管理しているデータは日に日に増えており、今では5つのチーム (5つのダッシュボード)、約300テーブルほどのデータマートが運用されています。

データが扱いやすくなったことで、各チームのMTGで必ずダッシュボードを見る習慣をつけてもらったり、そこから現状の把握や次の施策への考察が生まれたりなど、より良い循環が生まれていると感じています。

今後もさらにデータ基盤を拡張させていき、データ利用を促進していきたいと思っています。

最後に

今回はデータ基盤の構築について振り返ってみました。 記事中でも書きましたが、現状動いているデータ基盤については別に記事を書いて詳細を説明していこうと考えています。

データ周りの業務はうまく各チームと連携できれば、実際の意思決定と密接に関わることができるので非常にやりがいを感じられる分野です。

スナックミーではデータ周りの開発業務を担当してくれるデータエンジニア募集しています! 興味があればぜひお話しを聞きにきてください!

meety.net

engineers.snaq.me

おやつの出荷作業の歴史

snaq.meでは一人ひとりの嗜好に合わせて8種類のおやつをお届けしています。

パーソナライズ = 自分好みのおやつをセレクトしてくれる

と感じれる一方

  1. 選ぶのが難しそう
  2. 出荷作業が面倒臭そう
  3. 作るのが大変そう

など裏側のオペレーションは思っているよりタフな仕事が多いです

1~3において全て内製してシステムを開発し、今回は 2 の 「出荷作業が面倒臭そう」という観点について遍歴を書いていきたいと思います。

サービス当初 2016年3月 ~

サービス当初はお届け後に評価はできることを最低スコープとして考えいたため、

  • 商品
  • 配送商品

を登録できる基幹システムは最低限構築していました。登録できる後に行うことフローとしておやつをピッキング(出荷作業)になります。当時のピッキング

  • ロケーションID不使用 (どの場所にどのおやつがあるかという住所のようなもの)
  • 机におやつを広げ基幹システムと照らし合わせながら一つひとつ目視しながらピッキング

というフローでやっていたので、数十BOX発送準備するだけでも1日かかっていました。

ロケーションID・短冊時代

全て手動で行っていた当初から少しずつシステム化していきましたが、ピッキングに関してはまだ手動になります。その中でも進化したところが、基幹システムと照らし合わせながらピッキングしていた時代から短冊を片手にピッキングする時代へと変化しました。

この短冊には

  • 最低限のユーザー情報
  • アサイン(商品を選ぶところ)情報
  • ロケーションID
  • メモなど

が記入された短冊を用意してました。

このことにより、ピッキングの効率は少し上がり、ミスも少し減ってきましたが、まだまだアナログ感満載でした。というのも短冊と宛名ラベルの一致が必須だったため、目視の作業は変わらず心理的安全性は決して高いものではありませんでした

音声ピッキング時代

上記のようなピッキング作業では効率の部分やミス、作業自体の難易度から音声ピッキングの導入の話が社内で上がってきました。

音声ピッキングとは

個々のバーコードを読み込むことでユーザー毎にどの商品を選ぶか音声を流しピッキングしていくこと

このことにより、音声に従っていくので、ピッキングミスがほぼなくなり、初めの方でも数時間でピッキングの概要を掴めるようになります。

音声ピッキング導入により1日で出荷できる数を数千個まで上げることが可能になりました。

音声ピッキングの他のメリットは

  • 在庫をリアルタイムで把握可能
  • 欠品商品の把握
  • 個別に同梱資料を振り分けられる

などになります。

複数在庫エリア時代

ありがたくもユーザー数が増えてくると1箇所の在庫スペースだとどうしても捌ける数にも限界があります。理由は物理的なスペース、1人あたりの出荷効率から1箇所で出荷できる数に限度があるため、一人当たりの対応数はある閾値で下り坂になります。そうなると用途などに分けてピッキングすることが必要でした。

そこで運用し始めたのが複数在庫エリアになります。

詳しいことは以下をご覧ください

labs.snaq.me

まとめ

ピッキング作業は手動から音声ピッキングへ社内で開発し進化を進めています。

オペレーションチームと日々関わると、オペレーションチームはどうやって効率を上げ、無駄なコストはないか、ミスなき運用はできないのかなど考えているのでシステム作る側もその思考についていくのに必死になる時があります。というのも改善をエンジニア同様日々繰り返しているので今日話した仕様は来週になるとアップデートしていたりします。そのため、日々のコミュニケーションを大事にしないとすれ違う物を作りかねないのです。そのくらいスピード持ちながら、考えています。 また、オペレーションチームは上記外にユーザーさんのことを考え仕事をしています。どうやったらオペレーションの観点から体験向上に繋がるのか、こういう取り組みをすると喜ぶのかなどの視点も持ちながら行っています。

オペレーションとエンジニアではいい意味で異なるところがあります。例えば、オペレーションはおやつというリアル目に見えるもの扱い、エンジニアはコードやデータを扱うのでどうしてもアプローチが異なる場合が多くあります。その中で、しっかりスクラムを組みそれぞれの強み活かしながら開発していくことでこのピッキングシステム以外にもさまざまな物をオペレーションと開発しています。

まだまだ、道半ばですがオペレーションチームと一緒におやつと面白くしていきませんか? 少しでも興味を持った方はぜひ一度カジュアルにもお話ししましょうー

弊社では 「おやつと、世界を面白く。」 一緒に面白くしたい仲間をお待ちしてます!!

meety.net

engineers.snaq.me

入社半年、「クイック&フレンドリー」なカスタマーサポートを支えてきて感じたこと

 こんにちは、スナックミー エンジニアの兼崎です!4月に新卒で入社し、もうすぐ半年が経ちます。その間、私は主にカスタマーサポートチーム(以下 CS)が利用する、社内向け管理画面の開発を担当してきました。
 そこで今回は、半年間エンジニアとしてCSを支え、感じたことについて記載していければと思います☺︎

CSの役割

 スナックミーにおいて、CSは「クイック&フレンドリーなカスタマーサポートを通じて、お客様との長期的且つ強力なリレーションシップ形成に寄与する」という役割を担っています。特に「クイック&フレンドリー」というところが、スナックミーらしい、強みとなるポイントだと思っています。

なぜエンジニアが必要なのか

 そんなCSのお仕事に、専任になるほどエンジニアの出番はあるの?とお思いかもしれません。私は始めそう思っていましたが、想像以上にやることはありました笑

 例えば1つ、エンジニアは、「クイック&フレンドリー」の「クイック」の部分を、よりクイックににするという役割を担っています。まだまだ成長過程のスナックミー、サービスや機能の追加・アップデートは頻繁にあります。多くの方にサービスを利用していただくようになれば、お問い合わせの数も増え、CS業務を効率化する必要が出てきます。

クイックにすること以外では、このようなこともエンジニアの仕事です。

  • サービスの変化にシステムを対応させる
  • システム的なお問い合わせの対応
  • 画面の分かりにくさ、操作のしづらさが誘発するミスを防ぐ

最近、新しいCSメンバーが加わった機会に、業務に慣れた社員とは違った画面の見方であったり、初見では理解し難い文言の存在が明らかになってきました。それがミスにつながる事例があったので、今後は直感的に操作できるように改善していければと思っています。

エンジニアの役割は一見地味ですが、速く、正確であることはユーザー体験的には重要なことなのです。

半年携わってみて感じていること

 入社当初から変わらず思うことは、CSやエンジニアだけでなく社内全体の雰囲気が良いということです。 スナックミーで働いている人は皆優しくて、挑戦・失敗することに対して寛容です。そんな環境が整っているので、私自身萎縮することなく、安心して発言や行動ができていています。

 開発に関しては、初めの頃はわからないことだらけで苦労していました。 CSが普段何をしているのか、なぜそれをするのか、どのような仕様であるべきなのか、データはどこにあるのかなど...。 当初と比べると、今は「わかる」と「できる」がかなり増えています。大体のことができるようになったので、今後はより「速く」「多く」アウトプットを出していくことが課題です。

 そんな中、CSからの信頼が厚くなってきていると感じるようにもなりました。CSからの調査依頼に対してできるだけ速く反応したり、先輩にエスカレーションせずに解決できるようになってきたからかもしれないです。
 これは余談なのですが、CTOの三好さんは対応がびっくりするほど速くて、slackにはよく「爆速」スタンプがついています笑  やはり、「速い人」は信頼されますね。私も見習いたいです。

今後

 いずれは「CRE」になりたいと思っています。CREとは、Customer Reliability Engineering(CRE : 顧客信頼性エンジニアリング)のことで、お客様のサービスへの不安をゼロにし、信頼して利用していただくことを目標とする役職です。SREとよく似ているのですが、対象がサービスか、顧客か、という点で異なります。

 現状、私はエンジニアとしてコードを書いていることが多く、管理画面の改善箇所などはいつもCSが具体的に挙げてくださっています。 今後はよりアクティブに、エンジニアの視点から、お客様が安心してスナックミーを利用できるようなカスタマーサポートにしていきたいです。

まとめ

 今回は、半年間エンジニアとしてCSを支えてきて感じたことについて書かせていただきました。 私自身、エンジニアとしても、スナックミーメンバーとしても、社会人としてもまだまだ未熟と感じるところはありますが、「CSもスナックミーの価値の一つである」と感じていただけるよう、できることを精一杯やっていこうと思います。

弊社では 「おやつと、世界を面白く。」 一緒に面白くしたい仲間をお待ちしてます!!

meety.net

engineers.snaq.me

おやつの商品開発と「データ」による裏側

こんにちは、スナックミーでデータエンジニアをしている加藤です。

スナックミーでは多種多様なおやつの中からユーザー一人一人に合った8つのおやつをお届けするサービスをメインに展開しています。

そんなたくさんのおやつ達は、定期便の商品を主に担当する商品開発チームによって日夜、考案・試作され、より多くのユーザーさんに楽しんでもらえるように開発が行われています。

今回はこの商品開発をさらに良いものとするための、データを扱う立場からの関わりや取り組みについて紹介していこうと思います。

スナックミーの商品開発

スナックミーでは常時数百近いSKUを展開しており、さらには毎週月曜日に新商品を打ち出すというサイクルが回っています。 これらの美味しいおやつは非エンジニアである商品開発チームによって開発されており、ユーザーさんからいただいた評価やコメントなどを元に様々な商品が生み出されています。

ありがたいことに多くのユーザーさんから評価などをいただいており、その結果、データを確認するために度々エンジニアへとSQLによるデータ抽出依頼が飛んでくる状況が続いていました。

そこで開発の効率化・高度化のために、ここ数ヶ月商品開発チームと連携して様々なことに取り組んできました。

シンプルなデータの可視化・ダッシュボード化

取り組みのファーストステップとして、商品開発チーム用のダッシュボードを作成し、現状の見える化を進めました。 データをいつでも簡単に、かつ一元的に確認できる体制を作ることで、まずは現状がどうなっているのかを正しく把握しやすくすることから始めました。

例えば上の画像のようにユーザーさんからいただいた各おやつの評価などを可視化し、モニターできるようなダッシュボードを作成していきました。

最初のうちは非常に単純な数字の可視化ばかりでしたが、次第に商品開発チーム側からも「もっとこういう値が見たい!」や「こういう点から考えるためのデータが欲しいんだけど」などといった声をいただけるようになり、商品開発チームにとって意味のあるダッシュボードへと進化していきました。

商品を様々な視点で見るための指標の考案・提供

より良いおやつを開発していくためには、だんだんと単純な数字の可視化だけでは不十分に感じることが多くなっていきました。 なぜなら「より良い」ことを考える上での基準が複数あるからです。

例えば、おやつの評価について言えば、最も単純な指標としては平均点があるでしょう。 しかし、

  • 万人受けする全体的に評価の高いおやつ
  • 一部の人からはものすごく良い評価を得られるが、別のある人に取ってはあまり良くない

を同列に平均点だけで考えるのは果たして正しいでしょうか? おそらく平均点だけで言えば万人受けするおやつが高くなるはずですが、ユーザーさん一人一人にとってより良いおやつの開発を目指す上では、2つめの一部の人から高い評価を得るおやつも「違った視点では良いおやつだ」と判断をくだせる必要があります。

また評価だけでなく、

  • 生産のしやすさ・発注量の増加幅
    • とても評価が高く人気のおやつでも、ほんのわずかにしか作れずお届けできる量が限られていては困ります
  • 割れや欠けの発生しにくさ
    • どんなに美味しくても、おやつの強度に問題があり、お届けの途中で毎回粉々になってしまうのではがっかり感が大きくなってしまいます
  • 季節感やシーズンとのマッチ
    • 春夏秋冬やイベントごとなど、いつ食べるのかという点も無視できません

といった様々な要素が関与してきます。 しかし、これらを全て一つずつ見えるようにしたところで、今度は逆に商品開発チームが目を通すべきデータが多くなりすぎてしまい、いずれ確認することすら億劫になってしまうことは容易に想像がつきます。

そこで、いくつかの視点から複合的な指標を考案し、対象を絞ったデータを商品開発チームには注視してもらうようにしました。

上の画像は、ある「別の視点での良さ」を可視化した複合指標のダッシュボードです。 これにより、平均評価だけでは分からなかった点まで議論できるようになりました。

コミュニケーション密度を上げ、要望を吸い上げやすい体制を作る

上であげたような指標の整備と合わせて、定期ミーティングではどのおやつがどの指標に対してインパクトを与えると仮定しているのか?またその結果はどうだったのか?といった形で振り返りなどを進めるようにしています。

そうすることで、おやつごとに求める良さを整理し、より解像度を上げた振り返りと今後の開発への活用ができるようになってきていると感じています。

このように、整備したデータを提供する側から積極的にコミュニケーションを取るようにし、データ利用の促進や商品開発チームが求めているデータがどういうものなのかを確認しやすい体制を作っています。

今後に向けて

ここまでいくつか紹介してきましたが、こうしたアクションは大量のデータが扱いやすく整備されていることを前提にしています。 データ基盤の構築によって、ここ最近で様々なアクションが取りやすくなってきましたが、まだまだ進化の余地のある領域だと思っています。

個人的には、(知識的に比較的明るい) 統計解析や数理モデリングによる分析の高度化や、機械学習による商品開発の補助についても今後進めて行けたらと思っています。

最後に

今回はスナックミーの商品開発について、データエンジニアの視点から書いてみました。 まだまだできること、やれていないことも多く今後の伸び代は非常に大きいです!

もしデータドリブンな商品開発やおやつに興味のある方がいらしたら、ぜひお話しを聞きにきてください!お待ちしています!

meety.net

engineers.snaq.me

おいしいおやつの定期便snaq.meマイページの変遷

snaq.meでプロダクトマネージャーをしている渡邉(@nabepiyoo)です。

私からは、技術的な詳細というよりはマイページがどのように変わってきて、それがユーザの皆さんのおやつ体験をどうお手伝いできるのかという話をさせていただければと思います。普段はマイページの課題が何なのか、どんなことをすれば喜んでいただけるのか、データを見つつ優先順位をつけながらチーム一丸となって開発を進めています。

マイページというとどういうものを思い浮かべるでしょうか?

住所情報等の変更手続きができたり、月々の支払い情報が確認できたり、お問合せフォームがあるとか、そのようなことを思い浮かべられたのではないかと思います。お菓子はスーパーやコンビニ、百貨店、街の洋菓子屋さん、和菓子屋さんなどなど、いろんなところで買うことができます。おやつを定期便でお届けするビジネスモデルでユーザの皆さんにご満足いただけるよう、2016年の開始当初からマイページは大きく変化してきました。

2016年に公開されたsnaq.meマイページの歴史

2016年3月にスナックミーは初めてsnaq.meというサービスを公開しました。 初回発送に合わせて評価機能を追加

当時、評価機能を初回発送に併せてリリースしています。今と比べるとだいぶ粗いかもしれませんが、当初からユーザの皆さんにご満足いただけているかどうかを測る重要な仕組みがありました。

2017年当時の評価機能
2017年当時の評価機能

そこから何度もバージョンアップを繰り返し、6年経った今、私たちはおやつを評価するだけでなく、お届けしたおやつを見れたり、特に大好きだったおやつを記録することができるおやつ手帳、高く評価したおやつは大袋をリクエストする機能などをご提供しています。これがこの6年で起きた進化です。

2022年に公開したおやつ手帳
2022年に公開したおやつ手帳

届けてほしいに応えるためのリクエスト機能

snaq.meのマイページでたくさんのユーザさんにご利用いただいている機能の1つにリクエスト機能があります。

2016年のリクエスト機能

こちらも2016年からラインナップ※ にあるおやつが並んでいて、届けてほしいおやつに対してリクエストをすることができるようになっています。

2017年のリクエスト機能
2017年のリクエスト機能

こんなによくご利用いただいているのであれば、きちんとしたUIを整備してお使いいただけるようにしようということで何度もバージョンアップしています。

※ snaq.meにはラインナップという概念があります。お届けできる期間が限られるおやつがあるということです。常時70種類ほどのおやつがラインナップに存在しています。

現在のリクエスト機能

そして2022年には、バイヤーイチオシのおやつという特定のおやつをピックアップしたコーナーも出来ました。従来から多くのおやつが並んでいたのですが、それならイチオシのおやつはどれなの?という疑問にお応えするような形になっています。

好き嫌いを考慮してお届けする

ユーザさんとインタビューをしていると、snaq.meを始める前に苦手なものが届いたらどうしようと思っていたというお声をいただくことがあります。

しかし、snaq.meでは2016年からマイページで好き嫌いをご登録いただくことができます。

好き嫌いは人それぞれで、同じようなおやつをお好みの方でも苦手なものは異なっていたりします。

シンプルに嫌いな原料や成分などで登録することができたり、好きなジャンルを設定することができます。

ですからsnaq.meでは毎回8個のおやつを好き嫌いを考慮して、苦手なものが入らないように、なおかつ毎回同じようなものにならないような仕組みでおやつを選んでお届けしています。

ただ、好き嫌いをご登録いただいていない状態だと苦手なものが入ってしまう可能性はあるので、ユーザの皆さんはこの機会に設定されているかどうかご確認いただけると幸いです。

よりおやつに触れたくなるホーム画面へ

2017年のマイページ
2017年当時のマイページ

私たちはこうしてマイページを変化させてきたわけですが、改めて気づいたことがあります。

おやつはデジタルには存在しないということです。お手元に届くまではおやつについて頭の中で変換する必要があります。

ですからホーム画面に来ると何か分かりやすく新しいおやつの情報を知ることができるとか、クリアしていくことでお届けするおやつがより好みになっていくチャレンジができたり、こんなおやつがあったな、また食べたいなと思い出していただけるように表現し始めたのが2022年です。

先ほどお伝えしたような評価やリクエスト、好き嫌い登録といったものはチャレンジに含まれており、これらを行なっていただくことで、自然と好きなものがお届けされるような仕組みになっています。

8月には夏まつりをデジタルでも直営店でも行いまして、期間中にはホームの背景が夏まつり仕様になっていました。

2022年夏まつり期間のマイページ
2022年夏まつり期間のマイページ

2016年当時のマイページから、現在ユーザの皆さんがご覧いただいているマイページはほんの少し綺麗になりました。なるべく直感的に理解でき、子供の頃に待ち遠しかったおやつの時間のように楽しい体験をしてもらえるようなマイページを届けるということを今snaq.meでは実は行っています。

今後も引き続き、おやつに触れたくなるようなマイページを整えていきます。

最後に

そんなスナックミーではもりもりコードを改善し、開発していきたいエンジニアを募集中です。 採用の最新情報はこちらにありますので、ご興味ある方はご確認ください!

engineers.snaq.me

何でも良いので話したいよという方はカジュアル面談でお話ししましょう😄 meety.net

ユーザーに最適なおやつを届ける「アサイン」の歴史

こんにちは、スナックミーでデータ周りを担当するエンジニアをしている加藤です。 スナックミーでは、ユーザーのみなさんにお届けするおやつを様々な情報をもとに選定することをアサインと呼んでいます。

過去にもこのアサインに関する記事がいくつか書かれていますが、今回は少し俯瞰した目線で、その遍歴とこれからについて書いていこうかなと思います。

おやつを選定する「アサイン」

スナックミーでは、ユーザーごとに適したいくつかのおやつを選定してお届けするサービスを展開していますが、この「適したおやつ」を見つけるためには非常に多くの情報を扱う必要があります。

  • 好きなおやつは入れてほしいし、嫌いなおやつは入れないでほしい
  • できれば避けたい成分は入っていてほしく無い
  • リクエストしたおやつは入れてほしい
  • 過去に食べて苦手だったものは避けたい

などなど。 こういった情報から適したおやつを選定するためのアルゴリズムを弊社では独自に開発しており、これをアサイアルゴリズムと呼んでいます。

現在進行形でこのアルゴリズムは進化し続けており、より適したおやつ選定となるように開発が続けられています。

手作業によるアサイ

概要のところで多くの情報を扱う必要があることを書きましたが、サービス開始当初はなんと手作業にてアサインが行われていました。ユーザーのデータを1件ずつ確認し、どういう商品が良いか、どういう組み合わせが良いかを決めていくという非常に属人性が高くかつ時間のかかる作業だったわけです。

仮に1人1分で終えたとしても、ユーザーが500人もいれば8時間以上もかかる作業になります。 現在はありがたいことにさらにユーザー規模が拡大しているため、手作業で行おうとすればとてもじゃないですが1日では終わらないですね・・・。

アサイアルゴリズムのシステム化

当初から急務としてアサインのシステム化が進められ、およそサービス開始3ヶ月にしてシステムのβ版が導入されました。

その後も改良が続けられ、最終的にはAWS Batch上で動くシステムによっておよそ2000人のユーザーへのアサインが5~10分程度で完了するようになりました。

フルリプレイスとアーキテクチャの更新

しかしユーザー数のさらなる増加への対処や、度重なる改修による開発困難性の増加もあり、アサイアルゴリズムのフルリプレイスが行われました。

アーキテクチャからコードの構成まで議論を重ねて考え直し、1月ほどかけてリプレイスを実施しました。

結果的にはアルゴリズムの速度も開発容易性も増加し、現在もアサイン周りの改良を続けていますが、これまでよりも少ない工数で実装できていると感じています。

このアサインの改善については以下の記事で詳しく紹介しています。 labs.snaq.me

また、現在のアサインのアーキテクチャについてはこちらの記事も見てみてください。 labs.snaq.me

「おやつ得点」の導入

上記のリプレイスと合わせてもう一つ大きな動きがあり、それが「おやつ得点」という考え方の導入です。 詳細なアルゴリズムを紹介することはできませんが、ユーザーにとってより最適なおやつをを探すために、データベース上に大量に蓄積されているユーザーの過去のアクション (評価、リクエストなど) データから、ユーザーごとに各おやつの好みの度合いをスコア化し、これをアサインに導入しました。

こうしたML的なアルゴリズムとの融合によっても、ユーザーによりよいおやつをお届けすることを目指しています。

今後に向けて

ここまでざっくりとアサインの遍歴をたどってきましたが、アサインを大まかに表すと

  • 上限の決まった箱 (snaq.meであれば8つのおやつを選定します)
  • いくつかの情報を持ったユーザー
  • いくつかの情報を持ったおやつ
  • 好みなど満たすべき制約条件

が登場する最適化問題を解くことに他なりません。

ただし、その満たすべき条件は非常に多岐に渡ります。

  • 嫌いなもの・苦手なものが入らないこと
  • 好きを優先しつつ、バランスよく入ること
    • いくらクッキーが好きでも、クッキーばかり8つは流石にがっかりしますよね。
  • ユーザー1人1人の最適化と全ユーザーの最適化を同時に満たすこと
    • ある人は好きなものばかり、でも別のある人は嫌いなものばかりではいけません。
  • 好みの優先と在庫の消化を調和させること
    • 好きなおやつを入れることが最優先ですが、現実問題、在庫の多少を無視することはできません。

などなど・・・

今あげたものの他にもいくつかの条件が存在します。これをどんな方法でどれくらいの時間で解くかがアサインなわけです。

その解法は画期的なアルゴリズムかもしれませんし、MLをメインに据えた方法かもしれません。いずれにしろアサインはまだまだ完成形ではなく、日々改良を続けて行く必要があります。

近い将来、さらなる発展を遂げたアサインはどんな形になっているでしょうか? もしかすると人間には理解できない無数のパラメータによって管理されている未来もあるかもしれません。 とにかくワクワクが止まりませんね!

最後に

今回はスナックミーにおけるアサインの遍歴について紹介しました。 過去幾度もユーザーの声やデータをもとに改善が続けられ、色々な課題を解決してきたアサインですが、まだまだ課題は山積みです。

ユーザーにどんなおやつをお届けするかは弊社のサービスの根幹にあたる部分なので、今後も常にどんな形が良いかを考え改善していきたいと思います。

また、そんなアルゴリズムを一緒に開発してくれるとエンジニアをスナックミーでは募集中です!ぜひお待ちしています!

meety.net

engineers.snaq.me

FastAPI schemaの考え方

こんにちは
今回はFastAPIのschemaの考え方を書いていきたいと思います。

FastAPIではpydantic を採用しており、pydanticを利用してschema設定していきます。 今回でいうschemaはDBのschemaではなく、I/Oのリクエスト・レスポンスのschemaの考え方になります。

schemaを考えていくときに押さえていきたいこと

型の設定

昨今、型設定できない開発は開発スピード、不具合の原因、心理的安全性など多方面で良いことがないです。(型に縛られすぎるのも本末転倒なのでほどほどに) そのため、型設定できる方法があるのであれば、導入を考えたい。pythonでは mypy がありますので、mypyを用いて型のチェックをしていきます。

mypyは、プログラムの実行前に型チェックを行います。この型チェックはPythonの型ヒントという記法で書かれた情報をもとにしているので、型ヒントがない場合は、チェックがほぼ行われないので注意が必要です。

$ pip install mypy
box: int = 1
snaqme_price: dict[str, int] = {"box_fee": 1880, "delivery_fee": 330, "discount": 1000}

def total_delivery_fee(box: int) -> int:
    return snaqme_price["delivery_fee"] * box

このような int型やdict型などはさまざまなパターンで肩を決めることが可能です。 mypyに関しては別途詳しく書いていきます

ドメイン

schema管理する上でこのドメインで考えていくことが他の2つより大事だと考えています。 例えば、ユーザー情報を考えていく場合

・ 名前
・ メールアドレス
・ 住所
・ 電話番号
・ 決済情報
・ 生年月日
・ 好きなこと
・ 嫌いなこと
など

上記のような属性があった場合

ユーザーbase
・ 名前

ユーザー基本情報
・ メールアドレス
・ 住所
・ 電話番号
・ 決済情報
・ 生年月日

ユーザーの嗜好
・ 好きなこと
・ 嫌いなこと
など

のように分けられるかと思います。 この分け方が絶対と言いたいわけではなく、ユーザー情報という何も考えず一つのスキーマとして管理し続けるとどんな情報が入っているのかぱっと見わからなくなってしまいます。ユーザー情報 としている部分も将来的には分割が必要になり、肥大化されていく予想がつきます。 そのために細かく分けすぎず、大きく分けすぎずが良いと考えています。データベースと違い、FastAPIのレスポンスなどのスキーマは変更しやすいので、気軽にスタートできるのも特徴の一つになります。

レスポンスとリクエストの区別

スキーマとして管理できているがレスポンスとリクエストを根本から分けていくことで開発を進めやすくなると思います。ここで疑問になってくるのが、レスポンスとリクエストに関して同様なスキーマが存在しする場合どうするか?というところです。

私の考えでは無理に共通化させない、レスポンスはレスポンス、リクエストはリクエストと分ける。同様なものを共通化することは大事になってくる部分は多いと思いますが、レスポンスとリクエストに関しては共通化することで動作に不具合が生じさせる一つの原因になりかねない可能性があると考えています。
理由としては、レスポンスとリクエストは思いのほかコンテキストスイッチが発生しうるためです。コンテキストスイッチが発生する時にスキーマを考えていく場合どうしても片方のスキーマの存在を忘れがちになると思います。

なので、極力共通化しなくても良いと考えています。

まとめ

ざっくりではありますが、FastAPIでのschemaの考え方を共有させていただきました。 schemaの考え方に正解は存在しませんが、アンチパターンは存在しています。アンチパータンは開発スピードや心理的安全性を高められないため、アンチパターンが存在していると思っています。 いろんなschemaの考え方があると思いますので、ぜひ、いろんな方のスキーマの考え方を共有してもらえるとありがたく思います。

弊社では 「おやつと、世界を面白く。」 一緒に面白くしたい仲間をお待ちしてます!!

meety.net

engineers.snaq.me