スクリプトをAPI判断でより柔軟に実行するFunction Callingがあります。Function CallingはAIモデルが適切な関数と引数を起動する仕組みです。自然言語で指示することで関数を起動させられます。
動作としてはリフレクションが近いのですが、AIが何を呼び出すか判定する点が特徴です。
Sample
import json import os from openai import OpenAI CHATGPT_MODEL = "gpt-4o" def save(file_path: str, content: str) -> None: with open(file_path, "w") as f: f.write(content) # OpenAI APIキー設定 client = OpenAI( api_key=os.environ.get("OPENAI_API_KEY"), ) # 関数定義 def greet_tanaka() -> str: return "いらっしゃい, 田中さん!" def greet_unknown(name: str) -> str: return f"待って、あなた誰?(あなたの名前: {name})" # Function Callingで登録する関数リスト functions = [ { "name": "greet_tanaka", "description": "田中さんに対して特別な挨拶をする", "parameters": {"type": "object", "properties": {}}, }, { "name": "greet_unknown", "description": "田中さん以外の人物に対して、誰かを確認する挨拶をする", "parameters": { "type": "object", "properties": {"name": {"type": "string", "description": "挨拶する相手の名前"}}, "required": ["name"], }, }, ] def hello(name: str): # ユーザーからの指示を送る response = client.chat.completions.create( model=CHATGPT_MODEL, messages=[{"role": "user", "content": f"{name}さんに挨拶して"}], functions=functions, function_call="auto", ) # モデルの返答を取り出し message = response.choices[0].message if message.function_call: func_name = message.function_call.name arguments = json.loads(message.function_call.arguments or "{}") # argumentsがない場合は空dict print("関数が呼び出されました:", func_name) # 関数マッピング function_map = { "greet_tanaka": greet_tanaka, "greet_unknown": greet_unknown, } if func_name in function_map: func = function_map[func_name] if arguments: result = func(**arguments) else: result = func() print("実行結果:", result) else: print("未知の関数が呼び出されました:", func_name) else: print("関数呼び出しは提案されませんでした。") hello("田中") hello("吉田")
実行結果
> python .\test.py 関数が呼び出されました: greet_tanaka 実行結果: いらっしゃい, 田中さん! 関数が呼び出されました: greet_unknown 実行結果: 待って、あなた誰?(あなたの名前: 吉田さん)
注意点
柔軟性をとても引き上げる仕組みなのですが危険もあります。もし重大な結果(外部送金、ユーザー削除、課金処理など)を持つ関数を登録してしまうとモデルの提案次第でそれらが実行されうるのです。重大な結果を持つ関数を登録しないか、あるいは必ず実施前に人間の承認を別途必要とするプロセスを追加しておくなどの対策が必須です。