Crowdy 混雑予想 AI アプリ – day6

30 days AI challenge

本記事は 2026/02/01 ~ 2026/03/01 の間毎日 AI アプリケーション開発(AI を搭載したアプリ開発 or AI を使用した開発)をテーマに 30 days AI challenge を行う 6 日目のブログポストです。

今日は 2/6 も残すところ 1 時間を切っているのでブログ記事の内容はシンプルに行きましょう。30 days challenge は毎日行うことを目的としており日付はまたぎたくないので。

今日作成したのは、混雑予想 AI アプリ Crowdy です(突然まともなネーミング)。

アプリの概要

今日のアプリは AI が混雑予想をしてくれます。

わたしはあまり混雑を好まないので、できればすいているタイミングでお出かけをしたいです。そんな時に便利なのがこの AI アプリ。

日付と時間、目的地を入力するだけで AI 君が混雑状況を分析してくれます。

例えば、日曜日のお昼時に東京ディズニーランドを指定してみると。さすがに日曜日ですから混んでいることが予測されます。

このアプリの良いところは、混雑状況を視覚的にわかりやすく表示してくれるだけでなく、根拠を示してくれるところ、そして、混雑度が低い代替案を提示してくれるところです。

ディズニーランドを指定すると葛西臨海公園が出てくるので、それっぽい結果が出てきていると考えられます(似たような属性の近場の場所をお勧めと出すようにしています)。

実装について

今回も、ユーザーからの入力を AI に渡し、プロンプトで JSON 形式として返すようにし、JSON をコネコネして結果を出力しています。

AI 生成らしいそれっぽい変数名マシマシです。今日は特にコードの精査は行っていないので動けばヨシです。

うまくデータが取れない場合は混雑度を “ふつう” として表示する実装はいけてないですが、ここは AI のせいにします。

try
        {
            _conversationHistory.Add(new Content
            {
                Role = "user",
                Parts = new List<Part> { new Part { Text = prompt } }
            });

            var response = await _geminiService.GetChatResponseAsync(prompt, _conversationHistory);

            // JSON部分を抽出
            var jsonMatch = System.Text.RegularExpressions.Regex.Match(response, @"\{[\s\S]*\}");
            if (!jsonMatch.Success)
            {
                return new CrowdyAnalysisResult
                {
                    CrowdLevel = 3,
                    CrowdText = "ふつう",
                    Emoji = "😐",
                    Color = "#CCCC00",
                    Reasons = new List<string> { "AI応答形式エラー" }
                };
            }

            var jsonResponse = jsonMatch.Value;
            using var jsonDoc = JsonDocument.Parse(jsonResponse);
            var root = jsonDoc.RootElement;

            var result = new CrowdyAnalysisResult
            {
                CrowdLevel = root.GetProperty("crowdLevel").GetInt32(),
                CrowdText = root.GetProperty("crowdText").GetString() ?? "ふつう",
                Emoji = root.GetProperty("emoji").GetString() ?? "😐",
                Color = root.GetProperty("color").GetString() ?? "#CCCC00",
                Reasons = root.GetProperty("reasons")
                    .EnumerateArray()
                    .Select(item => item.GetString() ?? "")
                    .ToList()
            };

            // 混雑度が4以上の場合、代替案を提示
            if (result.CrowdLevel >= 4)
            {
                result.Alternatives = await GetAlternativesAsync(destination, dateTime);
            }

            return result;
        }

代替案の分析箇所も同じようにユーザーインプットをシステムプロンプトと織り交ぜて AI に渡し、JSON で結果をもらっています。

おわりに

AI アプリは作って満足になりがちですが、やはり使ってこそ意味を成すのでこれまで作ったアプリもぼちぼち使っていきたいと思います。

ただし、今のところ local で動かしているだけなので、来週にはどこかに公開しようと思います(AI token 問題、API token 問題もあるので、どこまで公開するのか、どのように制御するのかを考え中)。

今日も残すところ 30 分しかないのでこの辺で。今日も閲覧いただきありがとうございます!

コメント

タイトルとURLをコピーしました