Blog

2024.10.25

Engineering

グループ開発: 自炊の習慣化を支援するアプリ「Meow Menu Maker」

Jianqi Pan

Engineer

はじめに

本記事は、2024年夏季インターンシッププログラムで勤務された岡本さん、村木さん、木内さんによる寄稿です。

Preferred Networksでは、8/26〜9/20の4週間、2つのテーマでグループ開発インターンを実施しました。

サービス開発を行うテーマでは、多様なバックグラウンドを持つ10名の学生に3つのグループに分かれて参加していただきました。

今回のお題は「LLMをチャット以外の形で活用したアプリケーション」でした。メンターのアドバイスの下、インターン生自身がアイディアを出し、ブレストを行い、協力しながらサービスを実装しました。

本記事では、チームBが開発したアプリについてご紹介します。

アプリケーション名、概要

私達はMeow Menu Makerというアプリケーションを開発しました。

Meow Menu Makerは、「自炊の習慣化」という課題を解決するアプリです。

Meow Menu Maker アプリの概要

私達は自炊に必要な工程を大きく4つに区分してそのそれぞれの工程において必要な機能をアプリの機能として実装することで、先に挙げた課題を解決するためのアプリケーションを開発しました。

自炊に必要な工程

自炊に必要な4ステップそれぞれにおいて改善ポイントと解決策を考え、それぞれに対して順番に実装を行いました。

自炊に必要な4ステップ 改善ポイント 解決策
献立を決める バリエーションを考慮した献立を作成するのが面倒 LLMにより、バリエーションを考慮した献立の提案
献立のアイデアが思い浮かばない LLMにより、ユーザーの好みに合わせた献立を提案
過去に作成した料理の中からお気に入りのレシピを思い返すのが難しい お気に入り登録機能を追加し、後からお気に入りのレシピを見返せるように工夫
作り方を調べる 献立管理や予定管理アプリから他の媒体に作り方を調べに行くのが面倒 YouTube APIを利用した検索により、レシピが自動的に検索される
買い物に行く 買い物に行く際に買う食材を把握することが困難 (Future Work)食材の在庫を把握して、献立に沿った自炊に必要な追加食材リストの提案
何回も買い物に行く手間は避けたい
料理を作る 手間のかかる料理は作るのが面倒 LLMへのプロンプトに料理にかかる手間を制御できる項目を追加することでユーザーやタイミングに合わせた料理の提案

上記に加えて、習慣化のモチベーションを高めるために、下記の機能を実装しました。

  1. 作成した料理を時系列順に表示して確認できる機能
  2. 猫のアバターを用意して、料理をするごとにアバターが変化したり、猫のコメントが変化したりする仕様を追加することで、ユーザーの意欲を高めるための機能
  3. 過去三日間の達成度合いを%で表示することによって、ユーザーがどの程度継続的に自炊できているのかをすぐに確認できるようにする機能

機能紹介

前項の観点から、自炊を習慣化するために必要となる多くの機能を実装しました。まず、ユーザーが設定した好みに応じて、LLMが献立表を作成します。それぞれの献立に応じて、Youtubeからレシピが提案されます。

ユーザーは好みに応じて、一日の三食それぞれに対する胃への負担の度合いや、各献立において手間をかけたいかどうか、料理のジャンルは和食、洋食、中華のどれがいいかなどを設定することが可能です。

また、過去にお気に入りに追加した料理の内容は、献立作成の際にプロンプトに組み込まれるため、時間の経過とともに、ユーザーの好みが献立に反映されます。

料理をするまでのフロー

料理をするまでのフロー

次に、ユーザーが料理を作成し、アプリ上で記録すると、猫のアバターの画像が変化し、喜んだ表情へと変化します。猫の表情は6段階用意されており、ユーザーの料理の頻度に応じて、6段階のいずれかの表情の猫が表示されます。このようにして、ユーザーが猫を育成するような感覚で、自炊を習慣化することを狙いとしています。

料理後のフロー

料理後のフロー

また、献立の推薦や、ユーザーのインセンティブ設計に関していくつかのサブ機能があります。まず、提案された料理を作りたくない場合、献立を再生成できます。再生成には、三つの方法を用意しました。ユーザーが作りたい料理を手動で入力する「手動入力」、今ある食材から作れる料理を再提案する「食材入力」、ユーザーの好みの設定を反映してランダムに再提案する「ランダム生成」の三種類です。

再生成の画面

再生成の画面

ユーザーの自炊のインセンティブを高めるための工夫として、猫の満腹度の表示と、ユーザーの過去の料理に応じた猫の発言を実装しました。また、一目で作る料理がわかるように、各献立には生成AIで動的に生成した料理画像を表示するようにしました。

猫の吹き出しと料理画像

猫の吹き出しと料理画像

技術的・開発プロセス的アピールポイント

技術スタックは以下のようになります。

技術スタック

ユーチューブAPIによるユーザビリティ

YoutubeのWebサイトで料理名で検索をすると、必ずしもレシピの紹介動画が出るとは限らず、ショート動画などもレコメンドされてしまうという課題がありました。

この問題を解決するため、レシピの推薦には、Youtube Data APIを利用し「料理名 レシピ」というクエリで動画を50個取得した後に、動画を適切にフィルタリングしました。動画の長さやお気に入りの数などを用いることで、自炊に関係のない動画は排除するなど、直接ユーチューブで検索するよりもユーザビリティが向上するような工夫も施しました。

また、推薦された10個のレシピを毎回APIから取得しないようにしつつ、ユーザーが選んだ一つのレシピをログに残す必要があったため、DBの設計を工夫しました。具体的には、レシピテーブルに取得した10個の動画のIDを記録し、履歴のテーブルと予定されている献立のテーブルを分離しました。これにより、自炊のスケジュールを管理するアプリであることよりも、自炊を継続しやすくするためのアプリであるということが仕様上はっきりとするという効果もありました。

画像のローディング時間

料理画像は料理名を元にDall-E2に生成させているので、愚直に実装するとローディング時間が長くなってしまうという課題がありました。この課題の解決のために、料理画像は全userで(料理名が同じであれば)共通のものを用いることにしました。これにより、一度生成された画像であれば、Dall-E2を介することなく表示できるためローディング時間が削減できました。また、バッチ処理で0時になったらあらかじめ次に表示する料理名と料理画像を生成しておくことで再生成しないかぎりはローディング時間を削減できます。

Dall-E2で生成される料理画像の質の担保

料理画像の質的にはDall-E3を用いたかったのですが、rate limitの関係でDall-E2を用いることになりました。しかし、この場合プロンプトに”{料理名}の画像を生成してください”だけ入力するとかなり質が低いものができてしまうという問題がありました。

この問題に対しては、プロンプトを2段階に分け、「LLMで料理の画像を生成するための説明プロンプトを生成させる→生成した説明プロンプトを用いてDall-E2で画像を生成させる」といった二つのステップを踏むことで、各料理画像を生成するためのプロンプトが具体的になり、適切な画像が生成される確率が大幅に上がりました。以下は、プロンプト改善前と後のおにぎりの画像です。

プロンプトの工夫による画像の変化

プロンプトの工夫による画像の変化

猫のアバターの画像生成

猫のアバターはDall-E3で生成しました。アプリの仕様上だんだんふくよかになっていき、表情も明るくなっていく猫の画像を生成したかったのですが、なかなか思い通りの画像が生成されませんでした。

具体的には、 猫のアバターの雰囲気が画像ごとに統一されないことや、”だんだん太っていき元気になっていく猫を生成して”のようなプロンプトでは、最初から太っている猫が生成されるなど意図通りではない画像が生成されるなどの問題がありました。

解決策として、6種類の猫を一つの画像で生成させました。6枚の画像生成を別々に行うと猫の雰囲気が明らかに異なってしまうので、6種類の猫を一枚の画像で生成させました。

  • 初めに生成する猫のイメージを以下のように細かく指定しました。

初めに生成する猫のイメージを以下のように細かく指定しました

  • 猫の画像6枚全てに対してどのような画像が欲しいかの説明を詳細につけました。

猫の画像6枚全てに対してどのような画像が欲しいかの説明を詳細につけました

感想

  • (村木)LLMを用いたWebサービス開発は初めてで、仕様面,技術面ともに苦労することがありました。まず仕様面については、LLMの適切な使用についてです。例えばアバターの変化も動的にLLMに生成させるという案が出ていましたが、アバターの変化のコントロールが難しく、静的に生成したものをアルゴリズムでユーザーの自炊具合に応じて出すようにしました。このようにLLMを使うべきところとそうでないところの決定に時間を使いました。また、技術面に関してはLLMを使うところでローディング時間が大きくかかってしまうところがかなり懸念点でした。ここはもう少しパフォーマンスチューニングができたと思います。
  • (木内)LLMは出力の制御が難しく、アプリ内でロバストに動いて欲しい機能で利用することには不向きであり、一方で、ある程度出力に柔軟性が許される局面においては、アプリの利用者にとって斬新な経験や印象を与えるのに有効であることを実感しました。今回のアプリでLLMを利用した場面では、料理の画像生成や献立表の作成などにおいては出力を制御することに苦労しましたが、猫が献立表に反応する機能や、ユーザーの過去の料理の情報を整理して新たな料理を提案する機能については、細かい制御を必要とせずにユーザー体験に大きなインパクトを与えることができました。これからも生成AIを効果的に利用して、様々なサービス開発に取り組んでいきたいです。
  • (岡本)LLMをチャット以外の形で活用したアプリケーションというテーマでの開発をするにあたり、特にプロンプトチューニングなどでLLMの出力を高めることを目指しましたが、出力の制御に苦労しました。他にもテーマ策定からアプリの仕様決定を行ったので、その議論における意識合わせの方法に関しても今後に生かせる知見を得られたと感じております。今回のインターンでの経験を生かして今後サービス開発などを行っていきたいと考えております。

メンターからのコメント

チームBの皆さんは、「LLMを用いた生活を豊かにするアプリ」というテーマを、全ての人にとって身近である「食」という観点で分析し、自炊の習慣化を促進するアプリを開発しました。

ただ自炊の面倒なプロセスをLLMで効率化するだけではなく、アバターの育成など遊び心のある要素を取り入れたことによってユーザーが料理をするモチベーションを高めた点が面白く、アプリに大きな個性を与えていたと感じます。

また、短い期間の中でコンセプトの決定に時間をかけたことで、ユーザーにとって必要な機能を漏らさず盛り込めた点が素晴らしいと思いました。とても完成度の高いアプリに仕上がったと思います。4週間お疲れ様でした!

  • Twitter
  • Facebook