AI 予定生成カレンダーアプリ – day 14

30 days AI challenge

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

今日のアプリは、休日の予定を AI が考えてくれるカレンダーアプリです。

アプリ概要

アプリ上にはカレンダーが表示され、ユーザーが空き時間を登録の上 AI 生成ボタンをクリックすることで、AI がその日の予定を細かく考えてくれます。データベースにデータを登録しているため、あとから予定を確認することも可能です。

このように AI が細かく旅程(予定)を考えてくれます。一度生成した予定を再生成する機能もあります。

技術観点

今回使っている Gemini では、なぜかおすすめするスポットや予定が重複することが多々ありました。特に上野や東京国立博物館を勧めがちでした笑

そのため、既存の予定を取得し、その結果も AI へのプロンプトに組み込み、重複するスポットを避けるような仕組みにしています。

public async Task<List<ScheduleEvent>> GenerateSchedulesAsync(
    List<AvailableTime> availableTimes, 
    List<ScheduleEvent>? existingSchedules = null)
{
    var schedules = new List<ScheduleEvent>();
    existingSchedules = existingSchedules ?? new List<ScheduleEvent>();

    foreach (var availableTime in availableTimes)
    {
        // 既存予定を考慮したプロンプト生成
        var prompt = CreatePrompt(availableTime, existingSchedules, schedules);
        var response = await _geminiService.GetChatResponseAsync(prompt, ...);
        schedules.AddRange(ParseScheduleResponse(response, availableTime));
    }
    return schedules;
}

// プロンプト内で重複を避ける指示を加える
private string CreatePrompt(AvailableTime availableTime, 
    List<ScheduleEvent> existingSchedules, 
    List<ScheduleEvent> generatingSchedules)
{
    var allExistingLocations = existingSchedules.Concat(generatingSchedules)
        .Select(s => s.Location)
        .Distinct()
        .ToList();
    
    var avoidLocationsText = allExistingLocations.Any() 
        ? $"【避けるべき場所】n{string.Join("n", allExistingLocations)}"
        : "";
    
    return $@"...{avoidLocationsText}...";
}

終わりに

実はこのブログを書いている 1 時間前 ~ 10 分程前に miyacle.com のサイトがダウンしていました。。(その障害復旧に追われていた土曜日でした、といっても 1 時間程で復旧しましたが)。

原因としては、なぜかブログデータの保存先データベースとして使用している MySQL が落ちており、起動に失敗していたことが原因でした。

そんなこともありましたが、今日の AI の学びとしては、同じモデルを使用して同じプロンプトを使用すると回答が重複してしまう、似た結果になるということですね。

AI の出力は結果が毎回異なる点が特徴ではありますが、今回はデータベース内のデータを取り込むことでよりカスタマイズした(意図した)結果を表示することができました。

本日も閲覧いただきありがとうございました。明日もよろしくお願いします。

コメント

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