OpenAI APIというよりPythonがわからない話。
function callingは、「こんな関数を用意したけど『???』という質問に回答するためには、どの関数を呼び出せばよい?」という問いに、「関数名と引数で答えてくれる」機能である。
この、「こんな関数を用意した」という部分、用意した関数についての説明をOpenAI APIに渡すためのリストfunctionsパラメータについて。
私はPython素人なので、functions = [{...}]の部分について調べた。
以下のようなプログラムで見る。
import openai # OpenAI API への送信と、その結果の受信は、json形式で行われる import json ############################################################### import os import re
############################### # 処理に必要な関数を用意 ############################### # @brief Google検索する # @param keyword 検索キーワード # @param datefrom 記事の更新日時範囲 # @param dateto 記事の更新日時範囲 def getGoogleSearch(keyword,datefrom,dateto): # 本当はここに関数の処理を書くのだが、今回はOpenAI APIの返答のためのサンプルなので実装しない # function callingを呼び出すだけなら別に定義の必要もないわけだが格好がつかないので一応。 pass # @brief 決められたサイトからニュースを取得する # @param newssite サイトのURL # @param count 取得する結果の件数 def getNews(newssite,count): # こちらも同じ pass # @brief 自分のハードディスクからキーワードを持つファイルを検索する # @param keyword 検索ワード # @param extension 拡張子 def searchDocument(keyword,extention): # こちらも同じ pass
############################### # どんな関数を用意したかをOpenAI APIに教えるためのリスト。今回知らせる関数は三つ。 ############################### functions = [ { # 用意した関数の名前 "name": "getGoogleSearch", # 関数の説明 "description": "Google検索する", # パラメータ一覧 "parameters": { "type": "object", "properties": { "keyword" : { "type": "string", "description": "検索キーワード。スペース区切りで複数可" }, "datefrom" : { "type": "string", "description": "記事の更新日の範囲の古いほう。yyyy/mm/ddで指定" }, "dateto": { "type": "string", "description": "記事の更新日の範囲の新しいほう。yyyy/mm/ddで指定" }, }, # 必須パラメータ "required": ["keyword"], }, }, ############################################### { # 用意した関数の名前 "name": "getNews", # 関数の説明 "description": "決められたサイトからニュースを取得する", # パラメータ一覧 "parameters": { "type": "object", "properties": { "newssite" : { "type": "string", "description": "サイトのURL" }, "count" : { "type": "integer", "description": "取得する結果の件数" }, }, # 必須パラメータ "required": ["newssite","count"], }, }, ############################################### { # 用意した関数の名前 "name": "searchDocument", # 関数の説明 "description": "自分のハードディスクからキーワードを持つファイルを検索する", # パラメータ一覧 "parameters": { "type": "object", "properties": { "keyword" : { "type": "string", "description": "検索するキーワード" }, "extention" : { "type": "string", "description": "拡張子" }, }, # 必須パラメータ "required": ["keyword","extention"], }, } ]
############################### # OpenAIに何かしら問いかける ############################### # APIキー openai.api_key = "sk-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" # 問いかけの内容 ask_get_allitem = [ { "role": "user", "content": "飲み会の時の画像を探してください。田中さんが写っています。" } ] # OpenAIに送信 response = openai.ChatCompletion.create( model="gpt-3.5-turbo", messages=ask_get_allitem, functions=functions, ) # 結果を取得 res_message = response['choices'][0]['message']
############################### # OpenAIからの返答を確認する ############################### # もし、OpenAIが、この応答には関数呼び出しが必要と判断したら、 # res_message['function_call'] に、関数呼び出しに必要な情報が入っている if res_message.get('function_call'): # OpenAIが処理にふさわしいと判断した関数の名前 function_name = res_message['function_call']['name'] # OpenAIが処理にふさわしいと判断した関数の引数 arguments = json.loads(res_message['function_call']['arguments']) # 何を呼び出すべきと判断したか、確認のために表示 print("function_name: ", function_name) print("arguments: ", arguments) else: # OpenAIが関数呼び出しをしないと判断した場合、messageの中身をそのまま表示する print(response.choices[0]["message"]["content"].strip())
functionsは辞書のリストで表す。リストは [項目1, 項目2 , 項目3]の形をしている。つまり
functions=[ 関数1について , 関数2について , 関数3について }
という形をしている。で、関数1について、これは辞書になっている。辞書はkeyとvalueのペアを一つの項目とし、ペアを複数持つ。
keyとvalueのペアは、key : valueの形で持ち、それらを{}でまとめて一つの辞書にする。つまり
dic = { key1 : value1 , # アイテム1 key2 : value2 , # アイテム2 key3 : value3 , # アイテム3 }
という形をしている。
結果、各関数に関する情報を辞書としてまとめ、それをリストとしたものをfunctionsに渡すということになる。
functions = [ # 関数1に関する情報を辞書で指定 { "name" : "function1", # keyは"name" , valueは"function1" "description" : "関数1の説明", # keyは"description" , valueは"関数1の説明" }, # 関数2に関する情報を辞書で指定 { # 略 }, # 関数3に関する情報を辞書で指定 { # 略 } ] # こんな風にアクセス print( functions[0]['name'] )