40
38

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

お題は不問!Qiita Engineer Festa 2023で記事投稿!

ChatGPTの新機能「Function Calling」にはやはりPostmanが便利

Last updated at Posted at 2023-06-14

2023年6月13日、OpenAIはGPTの新バージョンの追加、大幅値下げと合わせて、Chat Completions APIを使った新機能「Function Calling」を発表しました。

これは簡単に説明すると、ChatGPTのAPIを呼んで、ユーザーの質問を元に自分が持っている機能(Function)のうちどれをどのように呼ぶべきかをChatGPTに解釈させ、さらに結果をChatGPTに渡せばユーザーに返すフレーズを作ってくれる、というものです。すでにデータベースや情報サービスを持っている方がターゲットになるかと思います。

このような外部連携は、今までであればChatGPTプラグインを作って提供したり、プロンプトエンジニアリングをがんばって機能を連携させて実現していたものですが、それがシンプルなAPIだけでできるようになったというのは画期的です。さらに、OpenAIが公式にサポートしているということもあり、正確性はかなり上がる、というようにOpenAIのシェイン・グウさんも話しています

本エントリでは、APIコールの扱いが簡単になるツールPostmanを使って、この新機能を試してみます。

準備

まずOpenAIにサインアップしてAPIキーを取得します。

次に、Postmanデスクトップ版をダウンロードします。ユーザー登録をしておくと、ブラウザでWebバージョンを使うことができるので便利です。ダウンロードが完了したらPostmanアプリを起動します。

Postmanには世界中のAPIのカタログが備わっており、例に漏れずOpenAIのAPIも登録されています。Postmanアプリ画面の上部中央にある検索フィールドで「OpenAI」を検索してみましょう。そうすると一番上に、バッジの付いたOpenAIのワークスペースが出てくるのでこれを選択します。
Screenshot 2023-06-14 at 9.50.02 PM.png
そして、ワークスペースのAPIコレクション「OpenAI」の右端にある「・・・」を押すと出てくるメニューから「Create a fork」を選びます。Forkというのは、カタログに登録されているAPIコレクションをコピーして、自分のワークスペースに持ってくる操作です。一旦自分のワークスペースに持って来れば、好きなようにパラメータや設定を変更して保存することができるようになります。
Screenshot 2023-06-14 at 10.02.47 PM.png
Forkしたコピーを識別するラベル(Fork label)、ワークスペース(Workspace、これはデフォルトで各自に用意されているMy Woekspaceを選びましょう)を指定したら、「Fork Collection」ボタンを押します。
Screenshot 2023-06-14 at 10.08.36 PM.png
今度は画面上部の「Workspaces」メニューから「My Workspace」を選んで自分のワークスペースに移動します。
Screenshot 2023-06-14 at 10.17.06 PM.png
ワークスペースの中にあるコレクションの階層を「OpenAI」→「Chat」→「Create chat message completion」とたどって出てきた項目が、今回使用するChat Completions APIです。
Screenshot 2023-06-14 at 10.22.28 PM.png
準備の仕上げとして、エントリ冒頭で取得したOpenAIのAPIキーを設定します。PostmanにはEnvironmentという設定で、あちこちで使用する値を変数として格納しておくことができます。まずは画面左端のナビゲーションから「Environments」を選択し、リストの左上にある「+」ボタンを押して新しいEnvironmentを作成します。

Envronmentの名前として「ChatGPT Test」と入力して、テーブルの最初の行に、変数(Variable)として「token」、タイプ(Type)に「secret」、現在値(Current value)に取得したAPIキーを入力します。APIキーは取扱注意の秘密情報ですので、変数を「secret」タイプにしておけば表示がマスクされるので安心です。最後に「Save」ボタンを押して保存することを忘れないでください。
Screenshot 2023-06-14 at 10.34.42 PM 1.png
このEnvironmentの設定を実際に使うときには、画面右上のEnvironment切り替えメニューからここで作成した「ChatGPT Test」に切り替えておく必要があります。
Screenshot 2023-06-14 at 10.42.49 PM.png

OpenAIのサンプルをそのまま試してみる

では、まずこちらのページのサンプルをPostmanを使ってコールしてみましょう。このサンプルは、ユーザーが天気について問いかけたときに、現在の天候を返す機能の呼び出し方をChatGPTに作らせるというものです。

再度コレクションから「Create chat message completion」を選ぶと、リクエストの編集画面になります。Chat Completions APIはPOSTメソッドの呼び出しなので、パラメータは「Body」タブに切り替えた上で、画面下部のエディタを使ってJSON形式で入力します。サンプルの通り、次のデータをペーストしてみてください。
Screenshot 2023-06-14 at 10.48.08 PM.png
messagesがユーザーが入力した質問のテキスト、functionsがこのAPIを使用する開発者が用意する機能(Function)の仕様を定義したものですね。この例では1つしかFunctionを指定していませんが、複数指定しておけばChatGPTがユーザーの質問に対して最もよく合うFunctionを選んで、パラメータの指定までやってくれるというわけです。

{
  "model": "gpt-3.5-turbo-0613",
  "messages": [
    {"role": "user", "content": "What is the weather like in Boston?"}
  ],
  "functions": [
    {
      "name": "get_current_weather",
      "description": "Get the current weather in a given location",
      "parameters": {
        "type": "object",
        "properties": {
          "location": {
            "type": "string",
            "description": "The city and state, e.g. San Francisco, CA"
          },
          "unit": {
            "type": "string",
            "enum": ["celsius", "fahrenheit"]
          }
        },
        "required": ["location"]
      }
    }
  ]
}

「Send」ボタンを押すと、OpenAIのサーバにAPIリクエストが送られます。レスポンスはこのような感じです。
Screenshot 2023-06-14 at 10.59.00 PM.png
注目すべきポイントは、ChatGPTが天気を尋ねているユーザーの意図を汲んでget_current_weatherというFunctionを選択し、かつ、Bostonという地名を質問から抜き出してlocationに「Boston, MA」という値を埋めてくれているという点です。

{
  "id": "chatcmpl-7RMEfHarZvZ7DsTkhioDG6dPyJ4PE",
  ...
  "choices": [
    {
      "index": 0,
      "message": {
        "role": "assistant",
        "content": null,
        "function_call": {
          "name": "get_current_weather",
          "arguments": "{\n  \"location\": \"Boston, MA\"\n}"
        }
      },
      "finish_reason": "function_call"
    }
  ],
  ...
}

次に、開発者は天気を検索するシステムを持っていると仮定して、上で得られたパラメータを元に、こんなJSONデータが取得できたものとします。

{ "temperature": 22, "unit": "celsius", "description": "Sunny" }

再度、このデータ出力を取り込んでChat Completions APIを呼び出します。
Screenshot 2023-06-14 at 11.20.09 PM.png
リクエストのBodyに入力する内容は、一番最初のリクエストをベースにしていますが、messagesにChatGPTが返してきたFunctionの選択とパラメータ、そして外部機能を使って取得したデータ出力を追加しています。これは、あたかもこのような会話の経緯でデータを取得してきた、ということをChatGPT側に教えてあげているようなものですね。

{
  "model": "gpt-3.5-turbo-0613",
  "messages": [
    {"role": "user", "content": "What is the weather like in Boston?"},
    {"role": "assistant", "content": null, "function_call": {"name": "get_current_weather", "arguments": "{ \"location\": \"Boston, MA\"}"}},
    {"role": "function", "name": "get_current_weather", "content": "{\"temperature\": 22, \"unit\": \"celsius\", \"description\": \"Sunny\"}"}
  ],
  "functions": [
    {
      "name": "get_current_weather",
      "description": "Get the current weather in a given location",
      "parameters": {
        "type": "object",
        "properties": {
          "location": {
            "type": "string",
            "description": "The city and state, e.g. San Francisco, CA"
          },
          "unit": {
            "type": "string",
            "enum": ["celsius", "fahrenheit"]
          }
        },
        "required": ["location"]
      }
    }
  ]
}

「Send」ボタンを押して返ってくるレスポンスはこのような感じです。
Screenshot 2023-06-14 at 11.28.50 PM.png
messagesには、ユーザーに対する自然な回答の文が入っています。すごい・・。

{
  "id": "chatcmpl-7RMZdrjDXaDny6pE5FfadTvrXd8DC",
  ...
  "choices": [
    {
      "index": 0,
      "message": {
        "role": "assistant",
        "content": "The weather in Boston is currently sunny with a temperature of 22 degrees Celsius."
      },
      "finish_reason": "stop"
    }
  ],
  ...
}

OpenAIのサンプルのデータを日本語にしたら機能するのか?

じゃあ、これ日本語でも上手く動くの?と気になってきました。

そこで、入力としてこのようなデータをリクエストで送ってみました。質問だけでなく、Functionの定義も日本語です。ちなみにFunctionのnameは英数字しか受け付けませんでした。

{
  "model": "gpt-3.5-turbo-0613",
  "messages": [
    {"role": "user", "content": "横浜の天気はどんな感じ?"}
  ],
  "functions": [
    {
      "name": "get_current_weather",
      "description": "与えられた場所の現在の天気を取得",
      "parameters": {
        "type": "object",
        "properties": {
          "location": {
            "type": "string",
            "description": "県と市区町村。例: 愛知県名古屋市"
          },
          "unit": {
            "type": "string",
            "enum": ["摂氏", "華氏"]
          }
        },
        "required": ["location"]
      }
    }
  ]
}

すると、こんなレスポンスが返って来ます。横浜と聞いたのに対し、神奈川県横浜市、と県名まで埋めてきました。すごい・・。

{
  "id": "chatcmpl-7RMqnNiRPVVmoGI0K6EHxQ1BJq8yV",
  ...
  "choices": [
    {
      "index": 0,
      "message": {
        "role": "assistant",
        "content": null,
        "function_call": {
          "name": "get_current_weather",
          "arguments": "{\n  \"location\": \"神奈川県横浜市\"\n}"
        }
      },
      "finish_reason": "function_call"
    }
  ],
  ...
}

そしてデータも日本語で埋めたリクエストです。

{
  "model": "gpt-3.5-turbo-0613",
  "messages": [
    {"role": "user", "content": "横浜の天気はどんな感じ?"},
    {"role": "assistant", "content": null, "function_call": {"name": "get_current_weather", "arguments": "{ \"location\": \"神奈川県横浜市\"}"}},
    {"role": "function", "name": "get_current_weather", "content": "{\"temperature\": 22, \"unit\": \"摂氏\", \"description\": \"晴れ\"}"}
  ],
  "functions": [
    {
      "name": "get_current_weather",
      "description": "与えられた場所の現在の天気を取得",
      "parameters": {
        "type": "object",
        "properties": {
          "location": {
            "type": "string",
            "description": "県と市区町村。例: 愛知県名古屋市"
          },
          "unit": {
            "type": "string",
            "enum": ["摂氏", "華氏"]
          }
        },
        "required": ["location"]
      }
    }
  ]
}

それに対するレスポンスがこれです。完璧に返してきました。

{
  "id": "chatcmpl-7RMx7CDcxQnqkKHHND2lvUr9iAVaA",
  ...
  "choices": [
    {
      "index": 0,
      "message": {
        "role": "assistant",
        "content": "横浜の天気は晴れで、気温は22℃です。"
      },
      "finish_reason": "stop"
    }
  ],
  ...
}

終わりに

以上のような感じで、新機能「Function Calling」のすごさが伝わったかと思います。シェイン・グウさんは「大規模言語モデル(Software 2.0)自体は計算や知識には制限があり、現実世界での実行能力はゼロでした。これにより既存の全てのソフト(Software 1.0)と簡単に連携ができます」と表現していましたが、まさにレガシーなデータ資産が、この機能によりAIの世界と結びついて活用が進んでいくのでは、という期待を抱かせてくれます。

ところでツールとして紹介したPostman、このようにAPIを繰り返し呼び出したり、色々なパラメータを試してみるときに便利だなという感想を持たれたのではないでしょうか。おそらく、このAI連携のような機能をきっかけとして、APIの重要性が格段に大きくなる世界がくると予感しています。そのときに、PostmanのようなAPIツールも注目が集まってくるかと思います。

ちょうどそんなタイミングで、Postmanが東京オフィスをオープンします。2023年7月4日には東京オフィス・プレオープンイベントとして Postman Tokyo Meetup 2023.7 をリアル会場・オンラインのハイブリッドで開催予定ですので、ご興味ある方はぜひご参加ください!
postman-api-platform-social-preview-2.jpeg

40
38
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
40
38

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?