SIMPLE

LLMのToolコーリングの動作原理

LLMがツールを呼び出す仕組みをシンプルに理解する

通りすがりのラマ🦙
10 May, 2025

サムネは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形式であればツールを呼び出し、そうでなければそのまま出力するというシンプルな設計である。

処理の流れ

  1. 使用可能なツールの一覧をLLMに渡す(名前、用途、引数など)
  2. ツールを使ってよいことをプロンプトで明示する
  3. LLMが必要に応じてツール名と引数を返す
  4. プログラムがそのツールを実行する
  5. 実行結果をLLMにフィードバックする
  6. 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 趣味: 個人開発、テニス