LLMのToolコーリングの動作原理
LLMがツールを呼び出す仕組みをシンプルに理解する


サムネはUnsplashのSarah Dorweilerが撮影した写真
はじめに
大規模言語モデル(LLM)は、計算やAPI呼び出しなど、モデル単体では対応できない処理を外部ツールに委ねることで、より複雑なタスクに対応できる。
この仕組みは「Toolコーリング」または「Functionコーリング」と呼ばれる。
たとえば「東京の現在の天気を教えて」という指示に対し、LLMは自分で天気を知るのではなく、天気APIを呼び出すツールを指定し、そのツールの実行結果をもとに回答を生成する。
本記事では、Toolコーリングの基本的な動作原理を解説する。
動作原理
Toolコーリングの仕組みは驚くほどシンプルである。以下にその基本フローを示す。
1. ツールの一覧を定義して渡す
まず、LLMに使用可能なツールの一覧を渡す。各ツールには次の情報を含める:
- 名前:ツールの識別名(例:
get_weather
) - 説明:ツールの用途や役割(例:「天気情報を取得する」)
- 引数:必要な入力(例:
{"city": "Tokyo"}
)
これにより、LLMはどのタスクにどのツールを使えばよいか判断できる。
2. 「ツールを使ってよい」と伝える
プロンプト内で、ツールの使用を許可する旨を明示する。
たとえば次のように指示する:
必要に応じて定義されたツールを使用し、その際はツール名と引数をJSON形式で返すこと。
3. ツール名が返ってきたら実行する
LLMがツールの使用を選んだ場合、以下のような形式で出力する。
{
"tool": "get_weather",
"args": {
"city": "Tokyo"
}
}
この出力をもとに、プログラム側で該当ツールを実行し、その結果を再びLLMに渡して最終回答を生成する。
サンプルコード(Python)
以下のコードでは、「札幌の天気を教えて」という質問に対し、LLMが必要であればget_weather
というツールを呼び出すようになっている。
import os
import json
import requests
# APIキーとエンドポイント
API_KEY = os.getenv("LLM_API_KEY")
API_URL = "https://your-llm-endpoint.example.com/v1/chat/completions"
headers = {
"Content-Type": "application/json",
"Authorization": f"Bearer {API_KEY}"
}
# 1. ツール定義
system_prompt = """
あなたは天気案内アシスタントです。以下のツールが使えます。
[TOOL] get_weather
説明: 指定都市の現在の天気を取得する
引数: {"city": "<都市名>", "unit": "<celsius|fahrenheit>"}
出力:
- ツールを呼び出す必要がある場合は、必ず JSON 文字列だけを返してください。
例: {"tool":"get_weather","args":{"city":"大阪","unit":"celsius"}}
- 直接回答できる場合は、平文の自然言語で答えてください。
"""
# 2. ユーザーからの質問
user_prompt = "札幌の現在の天気を教えてください。"
# 3. 初回リクエスト
payload = {
"model": "your-model-name",
"messages": [
{"role": "system", "content": system_prompt},
{"role": "user", "content": user_prompt}
]
}
resp = requests.post(API_URL, headers=headers, data=json.dumps(payload))
resp.raise_for_status()
assistant_msg = resp.json()["choices"][0]["message"]["content"]
# 4. 応答が JSON 形式かチェック
try:
cmd = json.loads(assistant_msg)
tool_name = cmd["tool"]
args = cmd["args"]
except (json.JSONDecodeError, KeyError):
# JSON でなければそのまま出力
print("Assistant:", assistant_msg)
exit()
# 5. ツールを実行
def get_weather(city: str, unit: str = "celsius"):
# 実際には外部API呼び出しを想定
return {"city": city, "temp": 15, "unit": unit, "desc": "くもり"}
if tool_name == "get_weather":
result = get_weather(**args)
else:
result = {"error": f"Unknown tool: {tool_name}"}
# 6. 実行結果をLLMにフィードバック
feedback = {
"role": "tool",
"name": tool_name,
"content": json.dumps(result)
}
followup_payload = {
"model": "your-model-name",
"messages": [
{"role": "system", "content": system_prompt},
{"role": "user", "content": user_prompt},
{"role": "assistant", "content": assistant_msg},
feedback
]
}
followup_resp = requests.post(API_URL, headers=headers, data=json.dumps(followup_payload))
followup_resp.raise_for_status()
final_answer = followup_resp.json()["choices"][0]["message"]["content"]
print("Assistant:", final_answer)
このコードは、Toolコーリングの動作を最小構成で実装している。LLMの出力がJSON形式であればツールを呼び出し、そうでなければそのまま出力するというシンプルな設計である。
処理の流れ
- 使用可能なツールの一覧をLLMに渡す(名前、用途、引数など)
- ツールを使ってよいことをプロンプトで明示する
- LLMが必要に応じてツール名と引数を返す
- プログラムがそのツールを実行する
- 実行結果をLLMにフィードバックする
- LLMが最終回答を生成する
Toolコーリングが可能なモデルの特徴
Toolコーリングに対応しているモデルは、以下の特徴を備えている:
-
ツール定義(名前・説明・引数)を理解できる
ツールの仕様を文脈として把握し、適切に使い分ける能力がある。 -
タスクに応じてツールの必要性を判断できる
ユーザーの入力内容をもとに、ツールを使うべきかどうかを判断できる。 -
適切なツール名と入力値を返すよう訓練されている
実行すべきツール名とその引数を、決められた形式で出力する能力がある。
対応しているモデル
Toolコーリング(Function Calling)は、以下のようなモデルで利用可能である。
モデル名 | 対応状況 | 備考 |
---|---|---|
GPT-4(OpenAI) | ✅ | functions またはtools オプションで利用 |
Claude 3(Anthropic) | ✅ | MCP準拠、Tool Use対応 |
Mistral(OpenRouter経由) | ✅ | Tool Use対応プロンプトで動作 |
Gemini 1.5 Pro(Google) | ✅ | Enterprise向けMCP対応 |
おわりに
Toolコーリングは、LLMが外部のツールと連携して複雑な処理を行うための基本技術である。
仕組み自体は「ツールを定義し、ツール名が返ってきたら実行する」というシンプルなものだ。
フレームワークやSDKで包まれると分かりづらくなるが、内部の流れを把握すると親しみやすくなるように思う。

通りすがりのラマ🦙
このブログでは個人開発で得た知見や興味のあるテクノロジーに関する記事を執筆します。 日々公開されている情報に助けられているので、自分が得た知見も世の中に還元していければと思います。 解決できないバグに出会うと、草を食べます。🦙🌿 経歴: 情報工学部→日系SIer→外資系IT企業 興味: Webアプリケーション開発、Webデザイン、AI 趣味: 個人開発、テニス