見出し画像

カレンダーを操作するチャットボット - Function calling を使って

ChatGPTのFunction callingを使うデモの2つめです。
すぐ試してみたい方はこちら。


日時の取り扱って面倒

「あさっての夜7時から飲み会」
「来週水曜日から2泊3日で北海道旅行」

こんな感じの入力で正確な日時を特定してカレンダーに記入されたらいいなあ。Function calling 使えばできる。

ChatGPTは今がいつなのか知らない

「あさって」や「来週」というのは現在の日時がわからないと意味をなしませんがChatGPTは今の日時を知りません。
現在時刻をrole: systemで与えます。

//JavaScript

const currentDate = new Date();
const isoString = currentDate.toISOString();

//タイムゾーンどうするかは問題だけれど今回はUTCで固定してしまう

const systemMessage = {
  role: 'system',
  content: `The current time is ${isoString}.Time zone must be fixed to UTC.`
 }

タイムゾーンをどうするかは大きなテーマです。入力言語や場所から推測させることはできますが、ユーザーに選択してもらうほうが実用的だと思います。今回はデモなのでUTCで固定しました。

関数の定義

ポイントは、開始日時(start)、終了日時(end)のフォーマットをdescriptionで具体的に書く。
時間が定まらない場合にそなえて終日フラグ(allDay)を用意。

#JSON  
{
  "name": "add_event",
  "description": "Add an event to the calendar.",
  "parameters": {
    "type": "object",
    "properties": {
      "title": {
        "type": "string",
        "description": "Indicate what the event is, where it is, and with whom."
      },
      "start": {
        "type": "string",
        "description": "Event start date and time, ISO 8601 extended format, e.g. 2023-06-23T21:19:38"
      },
      "end": {
        "type": "string",
        "description": "Event end date and time, ISO 8601 extended format, e.g. 2023-06-23T21:19:38"
      },
      "allDay": {
        "type": "boolean",
        "description": "Indicates an all-day event. If the start or end time is unknown, set \"allday\" to true."
      },
      "timezone": {
        "description": "If timezone is set, all timestamps are returned as local-time and data is returned starting at 0:00 local-time.",
        "type": "string"
      }
    },
    "required": ["title","start","timezone","allDay"]
  }
}


ChatGPTからの返信の具体例

以下のように"次の日曜日、ディズニーランドに遊びに行く"と入力があると、

#JSON

"messages": [
  {
    "role": "system",
    "content": "The current time is 2023-08-04T01:38:57.357Z.Time zone must be fixed to UTC."
  },
  {
    "role": "user",
    "content": "次の日曜日、ディズニーランドに遊びに行く"
  }
]

返信は次の通り。具体的な日時を指定していないにも関わらず、日にちを2023-08-06と特定し、時間については終日フラグをtrue と設定できています。素晴らしいですね。

#JSON
#GPT-3.5

"message": {
  "role": "assistant",
  "content": null,
  "function_call": {
    "name": "add_event",
    "arguments": "{\n  \"title\": \"ディズニーランドに遊びに行く\",\n  \"startStr\": \"2023-08-06\",\n  \"allDay\": true,\n  \"timezone\": \"UTC\"\n}"
}

カレンダーへの表示

カレンダーはFullCalendar を利用しました。使い方の詳細は公式ドキュメントに譲りますが、設置部分のコードを以下に示します。

document.addEventListener("DOMContentLoaded", function() {
    const calendarEl = document.getElementById('calendar');
    calendar = new FullCalendar.Calendar(calendarEl, {
      timeZone: 'UTC',
      themeSystem: 'bootstrap',
      initialView: 'dayGridMonth',
      headerToolbar: {
        left: 'prev,next today',
        center: 'title',
        right: 'dayGridMonth,timeGridWeek,listMonthCustom'
      },
      firstDay: 1,//Monday
      views: {
        listMonthCustom: {
          type: 'listMonth',
          duration: { days: 365}
        }
      },
      navLinks: true,
      events: [],
      eventTimeFormat: { // like '14:30:00'
        hour: '2-digit',
        minute: '2-digit',
        hour12: false
      }
    });
});

ChatGPTから返信されたデータをカレンダーに追加します。

const arguments = JSON.parse(message.function_call.arguments);
  
if(message.function_call.name === "add_event"){
  const event = {
   title: arguments.title,
    start: arguments.startStr,
    allDay: arguments.allDay
  }
  if(arguments.endStr){
    let end = new Date(arguments.endStr);
    if(arguments.allDay){
      end.setDate(end.getDate() + 1);
    }
    event.end = end
  }
  calendar.addEvent(event);
}

今後

追加以外に編集や削除も考えてみたのですが、人力で操作したほうが確実で実用的だと思いました。

GPT-4だとどんな動きになるか近いうちに試してみたいと思います
試してみました。


この記事が気に入ったらサポートをしてみませんか?