Google Colab で OpenAI API の Function Calling を試す
「Google Colab」で「OpenAI API」の「Assistant API」の「Function Calling」を試したので、まとめました。
前回
1. Function Calling
「Assistant API」は、さまざまなタスクを実行できる強力な「AIアシスタント」を作成するためのAPIです。
「Assistant API」は現在、次の3つのツールをサポートしています。
今回は、「Function Calling」を使います。「Chat Completions API」と同様に、「Assistant API」は「Function Calling」をサポートしています。「Function Calling」は、アシスタントに関数定義を指定することで、呼び出す必要がある場合に、関数呼び出しの要求を返すことができます。関数呼び出しの要求時には「Run」は一時停止され、関数呼び出し結果を提供することで「Run」は続行されます。
2. セットアップ
Colabでのセットアップ手順は、次のとおりです。
(1) パッケージのインストール。
# パッケージのインストール
!pip install openai
(2) 環境変数の準備。
以下のコードの <OpenAI_APIキー> にはOpenAIのサイトで取得できるAPIキーを指定します。(有料)
import os
os.environ["OPENAI_API_KEY"] = "<OpenAI_APIキー>"
(3) クライアントの準備。
「クライアント」は「OpenAI API」にアクセスするインタフェースになります。
from openai import OpenAI
# クライアントの準備
client = OpenAI()
4. アシスタントの実行
アシスタントの実行手順は、次のとおりです。
(1) アシスタントの作成。
toolsに「function」と関数の定義を指定します。
# アシスタントの作成
assistant = client.beta.assistants.create(
instructions="あなたはお天気ボットです。 提供されている関数を使用して質問に答えます。",
model="gpt-4-1106-preview",
tools=[{
"type": "function",
"function": {
"name": "getCurrentTemperature",
"description": "特定の場所の気温を取得",
"parameters": {
"type": "object",
"properties": {
"location": {"type": "string", "description": "場所 (例:東京)"},
"unit": {"type": "string", "enum": ["c", "f"]}
},
"required": ["location"]
}
}
}]
)
(2) スレッドの作成。
会話するためスレッドを作成します。
# スレッドの準備
thread = client.beta.threads.create()
(3) ユーザーメッセージの追加。
# ユーザーメッセージの追加
message = client.beta.threads.messages.create(
thread_id=thread.id,
role="user",
content="群馬県の気温を教えてください。"
)
(4) スレッドのメッセージリストの確認。
ユーザーメッセージが1つ追加されています。
# スレッドのメッセージリストの確認
messages = client.beta.threads.messages.list(
thread_id=thread.id,
order="asc"
)
for message in messages:
print(message.role, ":", message.content[0].text.value)
user : 群馬県の気温を教えてください。
(5) アシスタントにリクエスト。
# アシスタントにリクエスト
run = client.beta.threads.runs.create(
thread_id=thread.id,
assistant_id=assistant.id,
)
(6) アシスタントへのリクエストの実行状況の確認。
アシスタントは、関数をトリガーするユーザーメッセージを受け取ると、ステータス「require_action」に移行します。
# 実行状況の確認
run = client.beta.threads.runs.retrieve(
thread_id=thread.id,
run_id=run.id
)
print(run.status)
requires_action
「require_action」になったら、10分以内に関数の出力を提出しないと期限切れ状態「expired」になります。
(7) require_actionのパラメータの取得。
今回は、ツールID、関数名、引数を取得します。
import json
# require_actionのパラメータの取得
tool_id = run.required_action.submit_tool_outputs.tool_calls[0].id
tool_function_name = run.required_action.submit_tool_outputs.tool_calls[0].function.name
tool_function_arguments = json.loads(run.required_action.submit_tool_outputs.tool_calls[0].function.arguments)
print("id:", tool_id)
print("name:", tool_function_name)
print("arguments:", tool_function_arguments)
id: call_6avyFMrvuLtLTr1BzYmVL8p7
name: getCurrentTemperature
arguments: {'location': '群馬県', 'unit': 'c'}
(8) パラメータをもとに関数を実行。
今回は簡易化のため、実処理を行わないダミー関数を使ってます。
# 特定の場所の気温を取得する関数 (ダミー)
def getCurrentTemperature(location, unit):
print("location:", location)
print("unit:", unit)
return "22度"
# 特定の場所の気温を取得
tool_function_output = getCurrentTemperature(
tool_function_arguments["location"],
tool_function_arguments["unit"]
)
(9) 関数の出力を提出。
# 関数の出力を提出
run = client.beta.threads.runs.submit_tool_outputs(
thread_id=thread.id,
run_id=run.id,
tool_outputs=[
{
"tool_call_id": tool_id,
"output": tool_function_output,
}
]
)
(10) スレッドのメッセージリストの確認。
ステータス「completed」の場合は、メッセージリストにアシスタントメッセージが追加されています。
# スレッドのメッセージリストの確認
messages = client.beta.threads.messages.list(
thread_id=thread.id,
order="asc"
)
for message in messages:
print(message.role, ":", message.content[0].text.value)
user : 群馬県の気温を教えてください。
assistant : 群馬県の気温は22度です。
5. Assistant Playground
作成した「アシスタント」は、「Assistant Playground」でも動作確認できます。関数のコールバックを入力するUIも提供しています。
【おまけ】 JSONモード と Function Calling の違い
「JSONモード」と「Function Calling」の違いは、「JSONモード」が JSON形式のみ検証しているのに対し、「Function Calling」のJSON形式を検証かつスキーマの準拠 (関数定義にあわせる) を強制しています。
次回
この記事が気に入ったらサポートをしてみませんか?