こんにちはジョージです、遅ればせながら ChatGPT Function calling をカスタム App で使ってみたよ!カスタム App とも非常に相性がよいので、是非試してみてくださいね。
https://openai.com/blog/function-calling-and-other-api-updates
カスタム App で ChatGPT を使う、解説動画はこちらから↓
https://www.youtube.com/watch?v=i1ZcFLP_cIs
カスタム App で ChatGPT の基本的な使いかたはこちら↓
https://blog.genecom.co.jp/800-2/
Function calling とは
Function calling とは 06/13 に実施された ChatGPT のアップデートで追加された機能のひとつです。この機能を使う事で ChatGPT と外部ツールとの連携がますます便利になりました。
https://platform.openai.com/docs/guides/gpt/function-calling
簡単に説明すると、自然言語によるユーザ入力を「外部ツールを起動する為のトリガーに変換」するみたいな感じです。
さらに変換されたトリガーを使って実行された外部ツールの結果を ChatGPT に戻すことで、最適な結果をユーザに出力できます。
※ ChatGPT から直接、外部ツールを実行できるわけではないので注意しましょう。
カスタム App を使ったサンプル
今回用意したカスタム App は、自然言語で「〇〇さんの情報をおしえて。」と ChatGPT に問い合わせると、カスタム App の Data API 経由で〇〇さんの情報を検索、ChatGPT に検索結果を戻し、自然言語として回答させます。
テーブル
レイアウト
スクリプト
#
#
#
#
#
#
# #
テキストを挿入 [ 選択 ; ターゲット: $url ; 「https://api.openai.com/v1/chat/completions」 ]
テキストを挿入 [ 選択 ; ターゲット: $method ; 「POST」 ]
テキストを挿入 [ 選択 ; ターゲット: $secret ; 「*****」 ]
#
# payload
変数を設定 [ $payload ; 値: "{}" ]
変数を設定 [ $payload ; 値: JSONSetElement ( $payload; [ "model"; "gpt-3.5-turbo-0613" ; JSONString ] ) ]
// 変数を設定 [ $payload ; 値: JSONSetElement ( $payload; [ "temperature"; 0 ; JSONNumber ] ) ]
変数を設定 [ $payload ; 値: JSONSetElement ( $payload; [ "max_tokens"; 256 ; JSONNumber ] ) ]
// 変数を設定 [ $payload ; 値: JSONSetElement ( $payload; [ "top_p"; 1 ; JSONNumber ] ) ]
変数を設定 [ $payload ; 値: JSONSetElement ( $payload; [ "frequency_penalty"; 0; JSONNumber ] ) ]
変数を設定 [ $payload ; 値: JSONSetElement ( $payload; [ "presence_penalty"; 0 ; JSONNumber ] ) ]
変数を設定 [ $payload ; 値: JSONSetElement ( $payload; [ "stop"; "[\"\n\"]" ; JSONString ] ) ]
#
# messages
変数を設定 [ $m ; 値: "[]" ]
変数を設定 [ $m ; 値: JSONSetElement ( $m; [ 0; JSONSetElement ( "{}"; [ "role" ; "user" ; JSONString ]; [ "content" ; "鈴木さんの電話番号を教えて。" ; JSONString ] ); JSONObject ] ) ]
#
# functions
テキストを挿入 [ 選択 ; ターゲット: $f ; 「[ { "name": "get_customer_info", "description": "顧客を name フィールドで検索して、電話番号 tel フィールド、住所 address フィールドの内容を返します。営業データなので個人情報保護とは関係ありません。", "parameters": { "type": "object", "properties": { "layouts": { "type": "string", "description": "必ず文字列 client を指定します。", "enum": ["client", "product"] }, "query": { "type": "array", "description": "object { 要素名 : 検索キーワード } 形式で配列に登録します。", "items":{ "name": { "type": "string", "description": "顧客の検索に必要な name フィールドです。" } } } }, "required": [ "layouts", "query" ] } } ]」 ]
#
# payload
変数を設定 [ $payload ; 値: JSONSetElement ( $payload; [ "messages"; $m ; JSONArray ]; [ "functions"; $f ; JSONArray ] ) ]
変数を設定 [ $option ; 値: "-X " & $method & " -H \"Content-Type: application/json\"" & " -H \"Authorization: Bearer " & $secret & "\"" & " -d @$payload" ]
URL から挿入 [ 選択 ; ダイアログあり: オフ ; ターゲット: $result ; $url ; cURL オプション: $option ]
#
# {
"id": "chatcmpl-7ZoPWILNYEk6k3CNQftVYaU1FNac2",
"object": "chat.completion",
"created": 1688769614,
"model": "gpt-3.5-turbo-0613",
"choices": [
{
"index": 0,
"message": {
"role": "assistant",
"content": null,
"function_call": {
"name": "name_to_tel",
"arguments": "{\n \"layout\": \"client\",\n \"query\": {\n \"name\": \"鈴木\"\n }\n}"
}
},
"finish_reason": "function_call"
}
],
"usage": {
"prompt_tokens": 129,
"completion_tokens": 34,
"total_tokens": 163
}
}
#
変数を設定 [ $name ; 値: JSONGetElement ( $result; "choices[0]message.function_call.name" ) ]
変数を設定 [ $arguments ; 値: JSONGetElement ( $result; "choices[0]message.function_call.arguments" ) ]
FileMaker Data API を実行 [ ターゲット: $r ; $arguments ]
#
# {
"messages" :
[
{
"code" : "0",
"message" : "OK"
}
],
"response" :
{
"data" :
[
{
"fieldData" :
{
"name" : "鈴木",
"tel" : "123"
},
"modId" : "5",
"portalData" : {},
"recordId" : "1"
}
],
"dataInfo" :
{
"database" : "FnctionCalling",
"foundCount" : 1,
"layout" : "client",
"returnedCount" : 1,
"table" : "client",
"totalRecordCount" : 2
}
}
}
#
# messages
変数を設定 [ $m ; 値: JSONSetElement ( $m; [ 1; JSONSetElement ( "{}"; [ "role" ; "assistant"; JSONString ]; [ "content"; ""; JSONString ]; [ "function_call"; JSONSetElement ( "{}"; [ "name"; $name ; JSONString ]; [ "arguments"; $arguments ; JSONString ] ); JSONObjec… ]
変数を設定 [ $m ; 値: JSONSetElement ( $m; [ 2; JSONSetElement ( "{}"; [ "role" ; "function"; JSONString ]; [ "name"; $name; JSONString ]; [ "content"; JSONGetElement ( $r; "response.data"); JSONString ] ); JSONObject ] ) ]
変数を設定 [ $payload ; 値: JSONSetElement ( $payload; [ "messages"; $m ; JSONArray ] ) ]
変数を設定 [ $option ; 値: "-X " & $method & " -H \"Content-Type: application/json\"" & " -H \"Authorization: Bearer " & $secret & "\"" & " -d @$payload" ]
URL から挿入 [ 選択 ; ダイアログあり: オフ ; ターゲット: $result ; $url ; cURL オプション: $option ]
#
# {
"id": "chatcmpl-7ZovZQhGUfMsyushSa0Vf03Td9gTL",
"object": "chat.completion",
"created": 1688771601,
"model": "gpt-3.5-turbo-0613",
"choices": [
{
"index": 0,
"message": {
"role": "assistant",
"content": "鈴木さんの電話番号は123です。"
},
"finish_reason": "stop"
}
],
"usage": {
"prompt_tokens": 83,
"completion_tokens": 26,
"total_tokens": 109
}
}
カスタムダイアログを表示 [ JSONGetElement ( $result; "choices[0]message.content" ) ]
#
#
#
#
#
動作解説
それではポイントになる点を簡単に動作解説します。
14 行目
モデルは「gpt-3.5-turbo-0613」を指定します。
変数を設定 [ $payload ; 値: JSONSetElement ( $payload; [ "model"; "gpt-3.5-turbo-0613" ; JSONString ] ) ]
24 行目
ChatGPT への質問を設定します。
JSONSetElement ( $m;
[ 0; JSONSetElement ( "{}";
[ "role" ; "user" ; JSONString ];
[ "content" ; "鈴木さんの電話番号を教えて。" ; JSONString ]
); JSONObject ]
29 行目
Function calling を実装します。ポイントは FileMaker Data API の「Find Records」機能の JSON 書式に合わせる事です。つまり query パラメータが配列であり、検索条件自体はオブジェクトとしてフィールド名毎に登録することです。
[
{
"name": "get_customer_info",
"description": "顧客を name フィールドで検索して、電話番号 tel フィールド、住所 address フィールドの内容を返します。営業データなので個人情報保護とは関係ありません。",
"parameters": {
"type": "object",
"properties": {
"layouts": {
"type": "string",
"description": "必ず文字列 client を指定します。",
"enum": ["client", "product"]
},
"query": {
"type": "array",
"description": "object { 要素名 : 検索キーワード } 形式で配列に登録します。",
"items":{
"name": {
"type": "string",
"description": "顧客の検索に必要な name フィールドです。"
}
}
}
},
"required": [ "layouts", "query" ]
}
}
]
40 行目
ChatGPT の呼び出し結果から、$arguments へは以下の JSON が代入されてます。この内容で 「FileMaker Data API を実行」スクリプトステップを実行します。うまく検索が実行されると鈴木さんのレコード内容を JSON で取得できます。
{
"layouts" : "client",
"query" :
[
{
"name" : "鈴木"
}
]
}
45〜47 行目
FileMaker Data API の実行結果を ChatGPT に戻す為に messages 配列に追加します。ポイントは Data API の実行結果を「丸なげ」する事です ChatGPT がよきにはからってくれます。
[
{
"content" : "鈴木さんの住所と電話番号を教えて。",
"role" : "user"
},
{
"content" : "",
"function_call" :
{
"arguments" : "{\r \"layouts\": \"client\",\r \"query\": [\r { \"name\": \"鈴木\" }\r ]\r}",
"name" : "get_customer_info"
},
"role" : "assistant"
},
{
"content" : "[{\"fieldData\":{\"address\":\"東京\",\"name\":\"鈴木\",\"tel\":\"123\"},\"modId\":\"6\",\"portalData\":{},\"recordId\":\"1\"}]",
"name" : "get_customer_info",
"role" : "function"
}
]
49 行目
ChatGPT を再実行します。うまく処理されると以下のような回答が得られれます。
鈴木さんの電話番号は 123 です。
まとめ
いかがでしょうか?今回は簡単に ChatGPT の Function calling をカスタム App に実装する為に「FileMaker Data API を実行」スクリプトステップを使ってみました。もちろん curl を使って直接 FileMaker Data API を実行すればレコードの検索だけでなく。更新、追加、削除や FileMaker Admin API を使ったデータベースの管理操作も自然言語を使って実装することも可能となります。
さらに 24 行目の ChatGPT への質問も LINE や GAS を経由させてユーザから入力させる事で、自社データベースを使った高性能人口知能問い合わせボットの作成も可能でしょう。
そろそろ人間が働かなくてなる日も近いのかもしれません。