はじめに
ChatGPTをはじめとする生成AI(LLM)は、驚くほど自然な文章を生成できますが、その知識は学習データに基づいたものであり、リアルタイムの情報や外部のデータベースにアクセスすることはできません。例えば、「今日の東京の天気は?」と質問しても、正確な答えを得ることは困難です。
この課題を解決する強力な技術がFunction Callingです。Function Callingを利用することで、LLMは外部のAPIや独自の関数といった「ツール」を利用できるようになります。本記事では、Function Callingの基本的な仕組みから、Pythonを使った具体的な実装方法までを、初中級者向けに分かりやすく解説します。
Function Callingとは?
Function Callingとは、LLMがユーザーの質問や指示に応じて、あらかじめ定義された関数(Function)を呼び出すべきだと判断し、どの関数を、どのような引数で呼び出すべきかをJSON形式で提案する機能です。重要なのは、LLM自身が関数を直接実行するわけではないという点です。あくまで「この関数を使ってください」というリクエストを返すだけで、実際の実行は私たちのアプリケーション側で行います。
この仕組みにより、LLMは以下のようなタスクを実現できます。
- 天気予報APIを呼び出して最新の天気を答える
- 社内データベースに接続して顧客情報を検索する
- 外部の計算ライブラリを使って複雑な数学問題を解く
- EコマースサイトのAPIを叩いて商品を注文する
開発者はLLMに「使えるツール」のリストを提示し、LLMはその中から最適なツールを選択します。これにより、LLMの応答能力を安全かつ柔軟に拡張することが可能になります。
Function Callingの実装フロー
Function Callingを実装する際の基本的な処理フローは、以下の4つのステップで構成されます。ここではOpenAI APIを例に説明します。
- 関数の定義とツール情報の準備: まず、PythonなどでLLMに使わせたい関数を定義します。次に、その関数の名前、目的、引数(パラメータ)の情報をJSONスキーマ形式で記述し、APIリクエストの
toolsパラメータに含めます。 - LLMへのリクエスト: ユーザーからの入力と、ステップ1で準備したツール情報を含めてLLMにリクエストを送信します。
- LLMからの応答(Tool Call)の解釈: LLMが関数の使用が適切だと判断すると、通常の文章の代わりに、呼び出すべき関数の名前と引数を含む
tool_callsオブジェクトを返します。 - 関数の実行と結果の返却: アプリケーション側で
tool_callsオブジェクトを解釈し、指定された関数を実際に実行します。そして、その実行結果を再度LLMに送信することで、LLMは結果に基づいた最終的な回答を生成します。
この一連の対話を通じて、LLMはあたかも外部ツールを自ら使いこなしているかのように振る舞うことができるのです。
実装例:Pythonで天気予報ボットを作る
それでは、実際にPythonとOpenAI APIを使って、特定の場所の天気を答える簡単なチャットボットを実装してみましょう。ここでは、実際のAPIを叩く代わりにダミーの関数を使用します。
まず、天気を取得するための関数を定義し、その情報をtoolsとしてまとめます。
import openai
import json
# 1. 外部ツールのダミー関数を定義
def get_current_weather(location, unit="celsius"):
"""指定された場所の現在の天気を取得する"""
if "tokyo" in location.lower():
return json.dumps({"location": "Tokyo", "temperature": "15", "unit": unit})
elif "san francisco" in location.lower():
return json.dumps({"location": "San Francisco", "temperature": "22", "unit": unit})
else:
return json.dumps({"location": location, "temperature": "unknown"})
# 2. LLMに渡すツール情報を定義
tools = [
{
"type": "function",
"function": {
"name": "get_current_weather",
"description": "指定された場所の現在の天気を取得する",
"parameters": {
"type": "object",
"properties": {
"location": {
"type": "string",
"description": "天気予報を知りたい都市名。例: Tokyo",
},
"unit": {"type": "string", "enum": ["celsius", "fahrenheit"]},
},
"required": ["location"],
},
},
}
]
# 3. ユーザーの質問でAPIを呼び出す
client = openai.OpenAI()
messages = [{"role": "user", "content": "東京の今の天気は何度ですか?"}]
response = client.chat.completions.create(
model="gpt-4o",
messages=messages,
tools=tools,
tool_choice="auto",
)
response_message = response.choices[0].message
# 4. LLMがツールの使用を要求した場合の処理
if response_message.tool_calls:
tool_call = response_message.tool_calls[0]
function_name = tool_call.function.name
function_args = json.loads(tool_call.function.arguments)
# 5. 関数を実行し、結果を取得
function_response = get_current_weather(
location=function_args.get("location"),
unit=function_args.get("unit")
)
# 6. 関数の結果をLLMに渡して最終回答を得る
messages.append(response_message) # アシスタントの応答を追加
messages.append(
{
"tool_call_id": tool_call.id,
"role": "tool",
"name": function_name,
"content": function_response,
}
)
second_response = client.chat.completions.create(
model="gpt-4o",
messages=messages
)
print(second_response.choices[0].message.content)
# 出力例: 東京の現在の気温は15度です。
このコードは、「東京の天気」という質問からget_current_weather関数を引数{"location": "Tokyo"}で呼び出すべきだとLLMが判断し、その結果を元に最終的な回答を生成する流れを示しています。
まとめ
本記事では、生成AIの能力を拡張するFunction Callingの概念と、その具体的な実装方法について解説しました。Function Callingは、LLMに外部のAPIやデータベースといったツールを使わせるための強力な仕組みです。これにより、リアルタイム情報の取得や、専門的な計算、外部サービスとの連携など、LLM単体では実現不可能なタスクを実行できるようになります。
今回紹介したのは基本的な実装例ですが、複数の関数を扱ったり、より複雑な引数を渡したり、エラーハンドリングを組み込んだりと、応用範囲は非常に広いです。ぜひこの技術を活用して、より高度で実用的なAIアプリケーションの開発に挑戦してみてください。Function Callingを使いこなすことが、これからのAI開発者にとって重要なスキルとなるでしょう。