見出し画像

OpenAI API の Function Calling を試す

「OpenAI API」の新機能「Function Calling」を試したので、まとめました。


1. Function Calling

「Function Calling」は、開発者が事前に関数の定義を指定しておくことで、モデルが必要に応じて実行する関数とその引数を選択できるようにする機能です。

例えば、「東京の天気は?」という質問は、モデルだけでは現在の天気がわからないため正解を返すことができません。開発者が事前に天気情報の関数の定義を指定しておくことで、モデルは天気の質問があった際にその関数を呼ぶことを選択し、その関数の実行結果を使って正解を返すことができるようになります。

2. Function Callingの処理の流れ

「Function Calling」の基本的な処理の流れは、次のとおりです。

(1) ChatCompletionでユーザー入力と関数の定義を送る
必要に応じて、関数呼び出しのパラメータがJSONで返されます。
(2) レスポンスに関数呼び出しのパラメータがあるか確認
ある場合は関数を呼び出して関数の実行結果を取得します。
(3) ChatCompletionでユーザー入力と関数の実行結果を送る
ユーザー入力と関数の実行結果からモデルはレスポンスを作成します。

3. Colabでの実行

Colabでの実行例は、次のとおりです。

(1) パッケージのインストール。

# パッケージのインストール
!pip install openai

(2) 環境変数の準備。
以下のコードの <OpenAI_APIのAPIキー> にはOpenAI APIのAPIキーを指定します。(有料)

import openai

# OpenAI APIキーの準備
openai.api_key = "<OpenAI_APIのAPIキー>"

(3) 天気情報関数の定義。
今回は練習のためダミーデータを返しています。本番では外部APIから情報を取得します。

import json

# 天気情報の関数
def get_current_weather(location):
    # 本番では外部APIを利用
    weather_info = {
        "location": location,
        "forecast": "晴れ",
    }
    return json.dumps(weather_info)

(4) ChatCompletionでユーザー入力と関数の定義を送る。
openai.ChatCompletion.create()functionsに関数の定義を渡しています。

import openai

# ユーザー入力の準備
messages=[{"role": "user", "content": "東京都の天気は?"}]

# 関数の定義の準備
functions=[
    {
        "name": "get_current_weather",
        "description": "指定した場所の現在の天気を取得",
        "parameters": {
            "type": "object",
            "properties": {
                "location": {
                    "type": "string",
                    "description": "都道府県名(例:大阪府)",
                },
            },
            "required": ["location"],
        },
    }
]

# ChatCompletionでユーザー入力と関数の定義を送る
response = openai.ChatCompletion.create(
    model="gpt-3.5-turbo",
    messages=messages,
    functions=functions,
    function_call="auto",
)
response_message = response["choices"][0]["message"]
print(response_message)
{
  "role": "assistant",
  "content": null,
  "function_call": {
    "name": "get_current_weather",
    "arguments": "{\n  \"location\": \"\u6771\u4eac\u90fd\"\n}"
  }
}

今回はモデルが関数呼び出しを選択したため、contentにnull、function_callに関数呼び出しのパラメータ(JSON)が返されています。

引数は以下で確認できます。

# 引数の確認
print(response_message["function_call"]["arguments"])
{
"location": "東京都"
}

(5) レスポンスに関数呼び出しのパラメータがあるか確認し、ChatCompletionでユーザー入力と関数の実行結果を送る。

# レスポンスに関数呼び出しのパラメータがあるか確認
if response_message.get("function_call"):
    # 関数呼び出し
    available_functions = {
        "get_current_weather": get_current_weather,
    }
    function_name = response_message["function_call"]["name"]
    function_to_call = available_functions[function_name]
    function_args = json.loads(response_message["function_call"]["arguments"])
    function_response = function_to_call(
        location=function_args.get("location"),
    )

    # メッセージの準備
    messages.append(
        response_message
    ) # レスポンスメッセージ
    messages.append(
        {
            "role": "function",
            "name": function_name,
            "content": function_response,
        }
    ) # 関数の実行結果
    
    # ChatCompletionでユーザー入力と関数の実行結果を送る
    second_response = openai.ChatCompletion.create(
        model="gpt-3.5-turbo-0613",
        messages=messages,
    )
    print(second_response["choices"][0]["message"]["content"])
東京都の天気は晴れです。



いいなと思ったら応援しよう!