LoginSignup
2
0

[LINE WORKS] GPTとFunction Callingを使ってカレンダーに予定を入れてくれるアシスタントbotを作ってみる

Posted at

はじめに

OpenAIのAPIを使って、LINE WORKSのカレンダーに予定を登録してくれるアシスタントbotを作ってみました。

OpenAIのGPTとFunction Callingの機能で、会話の中で予定作成が必要な場面が出たら、自動でLINE WORKSカレンダーの方に予定を追加してくれるアシスタントです。

image.png

ソースコード

動くところ

output.gif

仕組み

GPTによって自然な会話を生成しながらも、スケジュールの話をするとあらかじめ登録しておいた add_schedule Functionを呼び出して、LINE WORKS APIの「Calendar API」を使って、その予定を自動で登録。

基本カレンダーの予定の登録 - LINE WORKS API

lineworks.py
def create_event_to_user_default_calendar(summary: str, start_time: str, end_time: str, user_id: str, access_token: str):
    """Create an event to user default calendar
    """

    url = "{}/users/{}/calendar/events".format(BASE_API_URL, user_id)

    headers = {
          'Content-Type' : 'application/json',
          'Authorization' : "Bearer {}".format(access_token)
        }

    params = {
      "eventComponents": [
          {
              "summary": summary,
              "start": {
                "dateTime": start_time,
                "timeZone": "Asia/Tokyo"
              },
              "end": {
                "dateTime": end_time,
                "timeZone": "Asia/Tokyo"
              }
          }
      ]
    }
    form_data = json.dumps(params)

    r = requests.post(url=url, data=form_data, headers=headers)

    r.raise_for_status()

add_schedule
def add_schedule(title, start_time, end_time, user_id, access_token) -> str:
    lineworks.create_event_to_user_default_calendar(title, start_time, end_time, user_id, access_token)
    return "予定をカレンダーへ登録しました。\n\nタイトル: {}\n開始日時: {}\n終了日時: {}".format(title, start_time, end_time)

実際のOpenAIのChat APIの呼び出し部はこちら。
ポイントとしては、あらかじめシステムスクリプトとして現在時刻を渡しておくことで、相対的な時間指定 (「2時間後」「明日」「来週火曜」など) が可能。

会話部
def chatWithGPT(text: str, api_type: str, model: str, user_id, access_token) -> str:
    dt_now = datetime.now(timezone(timedelta(hours=9)))
    system_script = """現在の時刻は{}です。予定の登録を依頼されたらカレンダーに登録します。
    現在の時刻から依頼された時間が午前なのか午後なのかを判断して過去の時間に予定が入らないよう適切に処理してください。
    その他の返答は2000文字以内にしてください。""".format(dt_now)

    functions = [
        {
            "name": "add_schedule",
            "description": "予定をカレンダーへ登録する。",
            "parameters": {
                "type": "object",
                "properties": {
                    "title": {
                        "type": "string",
                        "description": "予定のタイトル。これは空欄とすることはできない。"
                    },
                    "start_time": {
                        "type": "string",
                        "description": "予定の開始日時。形式は \"YYYY-MM-DDTHH:mm:ss\" とする。これは空欄とすることはできない。既定値は現在の日時から1時間後の正時間とする。"
                    },
                    "end_time": {
                        "type": "string",
                        "description": "予定の終了日時。形式は \"YYYY-MM-DDTHH:mm:ss\" とする。これは空欄とすることはできない。既定値はstart_timeから1時間後の日時とする。"
                    }
                },
                "required": ["title", "start_time", "end_time"]
            },
        }
    ]

    if api_type == "azure":
        response = openai.ChatCompletion.create(
            deployment_id=model,
            messages=[
                {"role": "system", "content": system_script},
                {"role": "user", "content": text},
            ],
            functions=functions,
            function_call="auto"
        )
    else:
        response = openai.ChatCompletion.create(
            model=model,
            messages=[
                {"role": "system", "content": system_script},
                {"role": "user", "content": text},
            ],
            functions=functions,
            function_call="auto"
        )
    logger.info(response)
    res_msg = response.choices[0]["message"]

    reply_text = ""
    if res_msg.get("function_call"):
        function_name = res_msg["function_call"]["name"]
        function_args = json.loads(res_msg["function_call"]["arguments"])

        if function_name == "add_schedule":
            reply_text = add_schedule(function_args["title"],
                                      function_args["start_time"],
                                      function_args["end_time"],
                                      user_id,
                                      access_token)
    else:
        reply_text = res_msg["content"].strip()

    logger.info(reply_text)
    return reply_text

まとめ

Function Callingは、こういった機能間の連携でうまく使える機能だと感じました。

こういうのを作ってみると、AIが仕事を支援するのが当たり前になるような未来が具体的に見えてきます。

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0