Function callingとは?
自前で作成した関数一覧をLLMに渡し、LLMがプロンプトを受け取った際、その中から使いたい関数があった場合に選ばせる機能。
LLMは関数を実行できないので、LLMが使いたいと応答した関数の実行はアプリケーション側で実行し、結果を再度LLMに返却する。
サンプルコードと具体的な処理の流れ
地域を指定して天気情報を返却するモック関数を定義
import json
def get_current_weather(location, unit="celsius"):
weather_info = {
"location": location,
"temperature": "27",
"unit": "celsius",
"forecast": ["sunny", "cloudy"],
}
return json.dumps(weather_info)
LLMに渡す関数一覧を定義
get_current_weatherを定義する
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. Tokyo",
},
"unit": {
"type": "string",
"enum": ["celsius", "fahrenheit"]
},
},
"required": ["location"],
},
}
]
ライブラリインストール
pip install openai
関数情報をfunctionsパラメータで渡し、LLMへAPIリクエスト
import openai
messages = [
{"role": "system", "content": "You are a helpful assistant."},
{"role": "user", "content": "What's the weather like in Fukuoka?"},
]
response = openai.ChatCompletion.create(
model="gpt-3.5-turbo",
messages=messages,
functions=functions
)
print(response)
レスポンス(大事なところだけ抜粋)
"model": "gpt-3.5-turbo-0613",
"choices": [
{
"index": 0,
"message": {
"role": "assistant",
"content": null,
"function_call": {
"name": "get_current_weather",
"arguments": "{\n \"location\": \"Fukuoka\"\n}"
}
},
"finish_reason": "function_call"
}
],
レスポンス値のfunction_callに使いたい関数と、使用する際の引数が返却される。
LLMに言われた引数を指定し関数を実行
response_message = response["choices"][0]["message"]
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"),
unit=function_args.get("unit"),
)
print(function_response)
レスポンス(モック)
{"location": "Fukuoka", "temperature": "27", "unit": "celsius", "forecast": ["sunny", "cloudy"]}
会話履歴に追加
messages.append(response_message)
messages.append({
"role": "function",
"name": function_name,
"content": function_response
})
print(messages)
messagesの中身
[{'role': 'system', 'content': 'You are a helpful assistant.'}, {'role': 'user', 'content': "What's the weather like in Fukuoka?"}, <OpenAIObject at 0x796a07cca750> JSON: {
"role": "assistant",
"content": null,
"function_call": {
"name": "get_current_weather",
"arguments": "{\n \"location\": \"Fukuoka\"\n}"
}
}, {'role': 'function', 'name': 'get_current_weather', 'content': '{"location": "Fukuoka", "temperature": "27", "unit": "celsius", "forecast": ["sunny", "cloudy"]}'}]
実行した関数の結果をAPIへリクエスト
second_response = openai.ChatCompletion.create(
model="gpt-3.5-turbo",
messages=messages,
functions=functions
)
print(second_response)
関数の実行結果を踏まえてレスポンスが返却された
contentの部分
"model": "gpt-3.5-turbo-0613",
"choices": [
{
"index": 0,
"message": {
"role": "assistant",
"content": "The current weather in Fukuoka is 27 degrees Celsius. It is currently sunny with some clouds."
},
"finish_reason": "stop"
}