ChatGPTのFunctionCallingっぽいのをノーコードツールでやってみた

# はじめに
FunctionCallingでいろいろと実装してみて、これってノーコードツールでできないのかな？と思ったので、試行錯誤してみた記録です。

## FunctionCallingとは
![スクリーンショット 2023-10-26 23.17.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/27192/0beeeda0-34d7-3e30-0312-63fa64a5228b.png)

ちょっと違いますね！
FunctionCallingは2023/6/13のアップデートで追加された機能で、
ChatGPTが指定された関数を**実行する判断をしてくれる**機能です。

## 実行する判断をしてくれる？
ここが使うまでは直感的にはわからなかった部分なのですが、このFunctionCallingが機能するには以下の実装が必要です。
- ChatGPTに渡すプロンプトに関数の情報（関数の名前、どういう情報を与えたらどういう情報を返す関数なのか、利用するときに必須な情報はなにか等々）を記述する
- ユーザーからの問いかけに対して、「これは関数を利用して応えた方が良さそうだな！とChatGPTが判断します
- 「判断した」という情報を元に、その関数を、**自分のサーバー**で実行します

ChatGPTが関数を実行するのではなく、ChatGPTの「関数を実行しよう！」という判断を元に、**自分で処理を書く**、というのが重要なポイントです。

## FunctionCallingのスゴさ
私も最初は、え〜！？自分で書くの！？と思ったのですが、
関数の情報を与えているので、関数の引数を指定して呼び出す判断をしてくれます。

たとえば、天気予報を取得する関数get_weatherを用意しており、get_weather(天気予報を知りたい場所)という呼び出しで、その場所の天気予報が取得できるとすると、
ChatGPTはユーザーとの会話から、自然に「どこの地域の天気予報が知りたいのか」を読み取り、「get_weather(天気予報を知りたい場所)って感じで関数を呼び出して！」と教えてくれる訳です。

詳しくはこちらの記事を読んでください
https://qiita.com/Haru141/items/b86afc15c883e2fda423

## スゴくない方の使い方ならノーコードでも出来そう
上記を実装するには、プログラムを書く必要があり、withMakeというノーコードツールでいろいろ試した結果、そのままではできなさそうでした。

もっと単純化して、関数実行時に引数を指定しないのであれば、もしかしてできるかも？と思ったので試してみました。

# 実装
## 前提
- ノーコードツールの[Make](https://www.make.com/en)を利用します
- LINEBot + ChatGPTについては説明を省きます
- [天気予報API](https://weather.tsukumijima.net/)を利用します

## モジュールの構成
![スクリーンショット 2023-10-26 22.59.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/27192/143d851a-c7a4-cc60-392a-37bb62f81b8e.png)

### ポイント解説
#### 最初のChatGPTのプロンプト
![スクリーンショット 2023-10-26 23.00.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/27192/e8115b0d-41b7-922e-3a03-e26b9fd5cffd.png)

#### Routerで場合分け
ChatGPTが「今日の天気を聞かれている！？」と思ったときの返信は「get_weather」とだけする。とプロンプトに設定したので、ChatGPTの応答が「get_weather」だけだった場合に、Routerで場合分けをしてさらに処理を繋いでいきます。

![スクリーンショット 2023-10-26 23.00.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/27192/53be88a3-62cb-818b-cc3f-240a77da4469.png)

#### 擬似FunctionCallingの処理
![スクリーンショット 2023-10-26 23.01.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/27192/dd5731e8-d6c8-1cca-2398-5008ced3d425.png)
URLはいったん固定にしています

![スクリーンショット 2023-10-26 23.01.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/27192/3d94606b-0de5-4536-4d4a-4d7ca9ee3950.png)
天気予報APIから返却されたデータをそのままChatGPTに渡し、天気予報士らしくわかりやすくまとめてもらいましょう

![スクリーンショット 2023-10-26 23.06.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/27192/b6d96a14-618c-2a36-54e3-2081fb8e33df.png)


今日の天気以外（get_weather以外）は下の分岐に入るので、ChatGPTの返答をそのままLINEBotとして返します
![スクリーンショット 2023-10-26 23.11.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/27192/ac335c61-bf0b-6c8a-4805-646f802764e8.png)

# どうでしょうか？
ChatGPTはリアルタイムの情報や専門知識が取得できないのがネックですが、この方法だと、外部のAPIなどを使って情報をまとめることができるので問題を克服できそうですね！

# 改良版
ここまで実装してみて、引数をつけて実行もできる気がしてきたので以下に書いてみます
上記からの変更点だけ記載します。

## モジュールの構成
![スクリーンショット 2023-10-27 0.35.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/27192/86e9df05-9d8f-d129-1bf6-aba24d11ed5d.png)

### ポイント解説
#### 最初のChatGPTのプロンプト
![スクリーンショット 2023-10-27 0.37.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/27192/57bfa37c-1d77-16e1-e5af-fbd9b2f21cd6.png)

```
あなたは経験豊富な気象予報士です。気象の質問をされたら質問に答えてください。

期待する返信は以下のような形式のJSONデータです
{
  get_weather: 使う,
  city_id: 400040,
  contents: なし
}

### 返信データの説明
get_weather:ユーザーから天気予報を尋ねられたときには「使う」それ以外は「使わない」と入力。
city_id:ユーザーから特定の地点の天気予報を尋ねられた場合はその地点IDを入力。地点が不明な場合は「400040」と入力。
contents:天気予報を尋ねられていない場合は質問の返答を入力。それ以外は「なし」と入力

### 地点IDの対応表
東京:130010
大阪:270000
福岡:400010
```

#### JSONをパース
ChatGPTから送られるJSON形式のデータをパースします
![スクリーンショット 2023-10-27 0.38.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/27192/2fb7434b-abc9-953a-b9f7-8694b0cece69.png)

#### Routerで場合分け
![スクリーンショット 2023-10-27 0.39.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/27192/3a47757e-bbf9-12f1-fb94-8b91ce1c3fe0.png)
「使わない」の場合は、内容をそのまま返信する

#### 天気予報APIにクエリ付きでアクセス
![スクリーンショット 2023-10-27 0.40.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/27192/5c91b820-6cb8-0748-fa04-4e9b00115ad2.png)

#### 結果!
こんな感じで、東京と大阪それぞれの天気予報が取得できるようになりました
![スクリーンショット 2023-10-27 0.41.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/27192/642fd340-0f86-e47e-56d0-a644e0f38c7b.png)
![スクリーンショット 2023-10-27 0.43.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/27192/8f6ae7e4-15db-25a2-beae-76913059004c.png)

本当はプロンプトに地点IDの対応表なんて載せたくないんですが、ChatGPTさんに地点IDの入力を任せると、的外れな回答になるパターンが非常に多いので、対応表を載せる形で対応しました。
作ってみてわかりましたが、プロンプトにFunctionCallingの説明をズラズラ書くよりもプロンプトを短くできる場合もありそうですね。

いろいろと応用の効く形にできると思うので、チャレンジしてみてください！！