0. 入る前に
最近のAIモデルは、単に文章を生成するだけではなく、
「自らの判断で関数を実行する」=Tool(ツール)呼び出し ができるようになりました。
この仕組みを使えば、
AIが「天気を調べる」「データベースを操作する」「翻訳を呼び出す」といった
外部のロジックを自動で扱えるようになります。
この記事では、実際にPythonでOpenAIのFunction Calling(Tool呼び出し)を利用し、
AIが天気関数を自分で選び実行するエージェントを構築してみます。
1. なぜ「Tool」が必要なのか?
通常のAIチャットは、テキストで答えるだけの「言葉の世界」に閉じています。
しかし現実のアプリケーションでは、AIがただ説明するだけでなく、
実際に何かを実行できることが求められます。
たとえば:
- 「東京の天気を教えて」と言われたら → 実際にAPIを叩いて天気を取得する
- 「今日の予定を登録して」と言われたら → カレンダーに書き込む
- 「円ドルレートを教えて」と言われたら → 為替データを取得する
これを可能にするのが、OpenAIの「Function Calling(Tool呼び出し)」です。
2. コード全体の流れ
import openai, json
client = openai.OpenAI()
messages = []
# --- 呼び出される関数(Tool)を定義 ---
def get_weather(city):
return "33 degrees celcius."
FUNCTION_MAP = {
"get_weather": get_weather,
}
TOOLS = [
{
"type": "function",
"function": {
"name": "get_weather",
"description": "A function to get the weather of a city.",
"parameters": {
"type": "object",
"properties": {
"city": {
"type": "string",
"description": "The name of the city to get the weather of.",
}
},
"required": ["city"],
},
},
}
]
AIに「呼び出せる関数の一覧」を教える部分がこの TOOLS です。
これによりAIは、ユーザーの質問を見て「この関数を使えばいい」と判断できます。
from openai.types.chat import ChatCompletionMessage
def process_ai_response(message: ChatCompletionMessage):
if message.tool_calls:
# AIが関数呼び出しを提案した場合
messages.append({
"role": "assistant",
"content": message.content or "",
"tool_calls": [
{
"id": tool_call.id,
"type": "function",
"function": {
"name": tool_call.function.name,
"arguments": tool_call.function.arguments,
},
}
for tool_call in message.tool_calls
],
])
# 実際に関数を実行
for tool_call in message.tool_calls:
function_name = tool_call.function.name
arguments = tool_call.function.arguments
print(f"Calling function: {function_name} with {arguments}")
try:
arguments = json.loads(arguments)
except json.JSONDecodeError:
arguments = {}
function_to_run = FUNCTION_MAP.get(function_name)
result = function_to_run(**arguments)
print(f"Ran {function_name} with args {arguments} for a result of {result}")
messages.append({
"role": "tool",
"tool_call_id": tool_call.id,
"name": function_name,
"content": result,
})
call_ai()
else:
messages.append({"role": "assistant", "content": message.content})
print(f"AI: {message.content}")
AIが「関数を使うべき」と判断したときだけ、
message.tool_calls が返ってきます。
ここで実際にPythonの関数を動かしています。
def call_ai():
response = client.chat.completions.create(
model="gpt-4o-mini",
messages=messages,
tools=TOOLS,
)
process_ai_response(response.choices[0].message)
while True:
message = input("Send a message to the LLM...")
if message in ["quit", "q"]:
break
messages.append({"role": "user", "content": message})
print(f"User: {message}")
call_ai()
User: hi
AI: Hello! How can I assist you today?
User: my name is jung
AI: Nice to meet you, Jung! How can I help you today?
User: what is the weather in spain
Calling function: get_weather with {"city":"Spain"}
Ran get_weather with args {'city': 'Spain'} for a result of 33 degrees celcius.
AI: The weather in Spain is currently 33 degrees Celsius.
AIが「スペインの天気」を聞かれた時、自ら get_weather() 関数を呼び出しています。
この一連の動作は、完全にAIの判断に基づいています。
3. Toolの意義
| 役割 | 説明 |
|---|---|
| AI | どのツールを使うかを判断する「脳」 |
| Tool(Function) | 実際に動作する「手足」 |
| Messages | 記憶(コンテキスト)を保持する「メモリ」 |
4. 最後に、AIエージェントの基本構造について
今回の記事で紹介した仕組みの背景には、AIエージェントの基本構造があります。
def process_ai_response(message: ChatCompletionMessage):
if message.tool_calls:
# AIが関数呼び出しを提案した場合
for tool_call in message.tool_calls:
function_name = tool_call.function.name
arguments = json.loads(tool_call.function.arguments)
result = FUNCTION_MAP[function_name](**arguments)
# 実行結果をAIに返す
messages.append({
"role": "tool",
"tool_call_id": tool_call.id,
"name": function_name,
"content": result,
})
call_ai()
else:
print(f"AI: {message.content}")
このように、
AI → 関数を提案(tool call) → 関数実行 → 結果を再入力して再推論
というサイクルを回すことで、AIは「思考」+「行動」を組み合わせたエージェント的動作を実現します。