Open7

オムライスクエスト実現のためのプロトタイピングを実施する。

tadokunotadokuno

オムライスクエストを行うためのアプリを作成するが、アプリの構成としては以下のようなものになる。

クエストの開始時点から、オムライスを探し当ててクエストを完了するまでの一連の流れをサポートする。

開始時点

  • オムライス指数が出ている駅のリストを出す
  • 地図上に駅とその駅の指数が表示されている
  • どこがいいのかをサジェストされる(オムライスの妖精)
  • しつこく行くように通知が来る

目的の駅に到着

  • 駅周辺の地図が表示される
  • 過去のオムライスを食べた場所が地図上に光る
  • どの方向に進めばいいのかをサジェストされる(オムライスの妖精)

店の前に到着

店に入ってオムライスを食べる時

tadokunotadokuno

技術要素

  • オムライス指数の算出
  • Web上でのリスト表示
  • Web上でのマップ表示
  • オムライスの妖精をAIで実装する

オムライス指数の算出は優先度が高く、ロジックを決めてしまえばLineBOT等でも実装できるので、プロトタイプを作成してみる。

https://sizu.me/tadokuno/posts/fvni8fcr5czd

LineBOTとして実装する。
中身は、GoogleのAPIで取得する数値と、GeminiのAIを使って取得する情報の2つとする。

数値として取れる情報

  • 喫茶店が多い
  • 町中華が多い
  • 洋食屋が多い
  • スナックが多い
    Google Places API Nearby Search

感覚値もしくは行かないと分からない

  • 古い商店街がある
  • 古い飲食ビルがある
  • 道が入り組んでいる
  • 飲食店に限らず、古い店が生き残っている
  • 大型チェーン店が少ない
  • 古いショーケース、食品サンプルが飾っている店がある

プロトタイプでは、項目を減らす。

数値として取れる情報は以下の2つとする

  • 喫茶店が多い
  • 町中華が多い

感覚値は、以下の4つ

  • 古い商店街がある
  • 道が入り組んでいる
  • 飲食店に限らず、古い店が生き残っている
  • 古いショーケース、食品サンプルが飾っている店がある

各項目10ポイントとして、合計60ポイント
さらに、80/60を掛けて80ポイントにする。

tadokunotadokuno

Google Places APIの研究

駅の近隣を検索するので、Nearby Searchを使う。
従来のものと、新版のものがあり、従来ではTypeにrestraunt のような単純なキーワードしか使えないが、新版では、mexican_restrauntのようなものも使える。どこまで使えるのかは資料が無いので、実験してみる。

新版では、pagetokenがサポートされていない。
なので、20件までしか取れない。20件が最大値であると考える。
それぞれのパラメーターで詳細を検討する。

Gemini 1.5 flashを使って、感覚値をAIに出してもらう。

少し言葉を変える。
古い商店街の存在感: 10点満点 (shoutengai)
道が入り組んでいる度合い: 10点満点 (michi)
飲食店に限らず古い店が生き残っている度合い: 10点満点 (furui-mise)
古いショーケースや食品サンプルが飾ってある店の存在感: 10点満点 (shoku-sample)

として、駅を指定したときに、その周辺がどのようなものかを判定させる。

API 仕様

入力: 駅名
出力: JSON
{
"shoutengai": 得点,
"michi": 得点,
"furui-mise": 得点,
"shoku-sample": 得点
}

Geminiを使うと、なぜか戻り値の形式が正しいJSONにならず、パースできない。

tadokunotadokuno

全体設計

LineBOTで作ってみるる。

入力: 駅名
出力: 各要素の得点と、その合計

実行環境をどうする

GASでやれば、GoogleのAPI使いやすいかなと考えてその環境を作ったが、Places APIはリストに出てこなかった。外部APIを呼ぶのであれば、Node.jsで作ってローカルでテストして、それをホストできるものの方がよいと考えて、Netlifyにする。

CLIが使いやすい。

Node.jsを使って、LineBOTを実装する。
とりあえず、テストする。

NetlifyでLineBOTをホストする。

感覚値はGPT-4oの最新版で

とりあえず、得点は60点満点として、
20点: 店の数
40点: 感覚値

としてBOTを作る。
店の数は、Google Places APIを使う
感覚値は、GPT-4oの最新モデルを使う。

コードはJavaScriptで作って、Netlifyを使う。

作成は出来たが、ここで問題が。Places APIは比較的すぐにレスポンスがあるが、GPTの方は結構時間が掛かって、Netlifyのサーバーレス関数の処理時間の上限である10秒を超えてしまう場合がある。
結構な頻度で、Lineから応答が無くなっている。

また、loading animationを付けた。

GPT-4oは結構お金が掛かりそう 思ったよりお金はかからない。

tadokunotadokuno

Node.jsで、まずはローカルで動くものを作る。
ローカルで関数の動作確認をする。

Line のWebhookになる関数は、ローカルで文法エラーのみチェックする。

それらすべてのGitHubに上げて、それとnetlifyのプロジェクトを同期させる。

GitHubへのコミットは、VSCodeのextensionを使う。Node.jsの環境はWSLにあるので、それらのコードをVSCodeで編集できるように設定する。

いままではローカルのWSLでしかNode.jsのコードを動かしていないので、この一連の作業の流れを作るのには結構時間が掛かった。
VSCodeとGitHubの連携についてはちょっとしたエラーが出ているが、とりあえず使えているので調べるのは後回しにする。

tadokunotadokuno

ホスティング先の変更とTypeScriptへの変更

Cloudflareに変更したい。
このコマンドは忘れないようにい。

bun add @line/bot-sdk crypto-js @types/crypto-js
bun run deploy
bunx wrangler secret put CHANNEL_SECRET

結果、process.env の参照の所で、Cloudflareのデプロイにエラーが出てしまう。

とりあえず、netlify+JavaScriptで完了しておく。

tadokunotadokuno

フィードバック

友人に趣旨説明をして使ってもらった。
あの町ならオムライス指数高そう、と想像してLineBOTに聞いてみたら確かに高かったということで盛り上がった。
誰かと一緒に使うと楽しいということを発見。

あと、同期の皆さんにも使ってもらった。Discordの簡単なメッセージでの説明だったので、ちょっと変な感じになってしまった。これは自分の問題。