言語を切り替える
テーマを切り替える

エージェントのツール呼び出し実践:AI に外部 API とサービスを呼び出させる

AI に天気を調べてもらう、ファイルを読んでもらう、API を叩いてもらおうとしたのに、返ってくるのは「私は外部データにアクセスできません」の一言だけ——そんな経験はありませんか。

なかなか厄介ですよね。

実はこれは、AI が賢くないわけではなく、ある中核的な能力——ツール呼び出し——を欠いているからです。今日は、AI を「会話するだけ」から「実際に仕事ができる」存在へと変えるこの技術について話していきます。


AI のツール呼び出しとは?

ありていに言えば、ツール呼び出しとは AI に一双の手を持たせることです。

従来の大規模言語モデル(LLM)は、学習データに基づいてしか答えられません。「東京の今日の天気は?」と聞いても、「リアルタイムデータは取得できません」としか返せませんでした。しかしツール呼び出しがあれば、AI は自ら特定の関数の実行をリクエストできます。たとえば天気 API を呼び出し、その結果をあなたに返してくれます。

この能力はどれほど重要でしょうか。おおよそ「机上で論じるだけの軍師」から「自ら兵を率いて戦える将軍」への飛躍に近いものです。

主流の 3 つの方式

現在、市場には主に 3 つのツール呼び出し方式があります。

方式代表的な製品適したシーン
Function CallingOpenAI GPT構造化出力、シンプルな API 呼び出し
Tool UseClaude複雑なツールチェーン、多段階タスク
MCPClaude Code標準化されたツールエコシステム

どれを選ぶか?ニーズ次第です。シンプルなシーンなら OpenAI の Function Calling で十分。複雑なエージェントシステムには Claude の Tool Use が向いています。ツールのエコシステムを築きたいなら、MCP がトレンドです。


OpenAI Function Calling:入門から実践まで

まずは OpenAI の方式を見てみましょう。Function Calling はとてもシンプルに設計されていて、流れは 3 ステップだけです。

  1. ツールを定義する(どんなツールが使えるかを AI に伝える)
  2. AI がどのツールを呼び出すか決める(関数名とパラメータを返す)
  3. あなたがツールを実行し、結果を返す

完全な例

天気を調べるツールを作るとしましょう。まずはツールの Schema を定義します。

tools = [{
    "type": "function",
    "function": {
        "name": "get_weather",
        "description": "指定した都市の現在の天気情報を取得する",
        "parameters": {
            "type": "object",
            "properties": {
                "city": {
                    "type": "string",
                    "description": "都市名(例:'東京'、'大阪')"
                },
                "unit": {
                    "type": "string",
                    "enum": ["celsius", "fahrenheit"],
                    "description": "温度単位。デフォルトは摂氏"
                }
            },
            "required": ["city"]
        }
    }
}]

あの description フィールドには要注意です——決して手を抜かないでください。AI はこれを頼りに、いつこのツールを呼ぶべきかを判断します。以前、「天気を取得」とだけ書いた人を見ましたが、AI はどんな場面で使えばいいのか全く分かりませんでした。「指定した都市の現在の天気情報を取得する」に変えたところ、呼び出しの正確率が 60% から一気に 95% まで上がりました。

次にリクエストを送ります。

response = client.chat.completions.create(
    model="gpt-4o",
    messages=[
        {"role": "user", "content": "東京は今日暑い?"}
    ],
    tools=tools
)

AI はツール呼び出しのリクエストを返します。

tool_call = response.choices[0].message.tool_calls[0]
# tool_call.function.name = "get_weather"
# tool_call.function.arguments = '{"city": "東京"}'

そして、あなたが本物の関数呼び出しを実行し、結果を返します。

# 天気 API を呼び出す
weather_result = get_weather_from_api("東京")

# 結果を会話に戻す
final_response = client.chat.completions.create(
    model="gpt-4o",
    messages=[
        {"role": "user", "content": "東京は今日暑い?"},
        response.choices[0].message,  # AI のツール呼び出しリクエスト
        {
            "role": "tool",
            "tool_call_id": tool_call.id,
            "content": json.dumps(weather_result)
        }
    ]
)

すると AI は天気データをもとに自然な返答をしてくれます。「東京は今日 28 度で、かなり暑いですね。外出時は日焼け対策をお忘れなく。」

Strict Mode:出力の安定性を保証する

2024 年、OpenAI は Strict Mode を導入しました。JSON Schema のマッチングが不安定になる問題を解決します。有効化はとても簡単です。

tools = [{
    "type": "function",
    "function": {
        "name": "get_weather",
        "strict": True,  # この 1 行を追加
        # ... その他のフィールド
    }
}]

有効にすると、AI が返すパラメータは定義した Schema に 100% 適合することが保証されます。本番環境では必ず有効にしましょう。さもないと、さまざまな奇妙な解析エラーに遭遇するかもしれません。


Claude Tool Use:より強力なツールチェーン

Claude の Tool Use は、設計思想の面で OpenAI といくつか重要な違いがあります。

並列呼び出し

Claude は一度に複数のツール呼び出しを返すことに対応しています。たとえば「東京と大阪の天気を比べて」とユーザーが尋ねると、Claude は一度に get_weather を 2 回呼び出すようリクエストします。

response = client.messages.create(
    model="claude-sonnet-4-20250514",
    messages=[{"role": "user", "content": "東京と大阪の天気を比べて"}],
    tools=tools
)

# response.content には tool_use ブロックが 2 つ含まれる場合がある
for block in response.content:
    if block.type == "tool_use":
        print(f"呼び出し: {block.name}、パラメータ: {block.input}")

これは複雑なタスクを処理するときに特に役立ちます。OpenAI も並列呼び出しに対応していますが、Claude の実装はより洗練されています——どの呼び出しを並列にできて、どれを直列にすべきかを賢く判断します。

Tool Choice 戦略

Claude はより細かい粒度でツール選択を制御できます。

# 自動選択(デフォルト)
tool_choice = {"type": "auto"}

# ツール使用を強制(ツールなしでは回答しない)
tool_choice = {"type": "any"}

# 特定のツールを指定
tool_choice = {"type": "tool", "name": "get_weather"}

いつ any を使うか?ユーザーの質問が、ツールを通さなければ答えられないと確信できるときです。たとえば注文状況の照会は、データベースを叩かなければ答えようがないので、AI に必ずツールを使わせます。

エラー処理

ツール呼び出しの失敗は日常茶飯事です。API のタイムアウト、ネットワークの揺らぎ、パラメータエラー……Claude は優雅なエラー処理の仕組みを用意しています。

tool_result = {
    "type": "tool_result",
    "tool_use_id": tool_use.id,
    "content": "API 呼び出し失敗:接続タイムアウト",  # 失敗理由を AI に伝える
    "is_error": True  # エラーとしてマーク
}

AI はエラーを見ると、別の方法を試したり、ユーザーに丁寧な案内をしたりします。例外をそのまま投げるよりずっと優れています——ユーザーは技術的なエラーの羅列ではなく、「申し訳ありません。天気サービスは一時的に利用できません。しばらくしてからお試しください」といったメッセージを目にします。


MCP:ツール標準化の未来

ツール呼び出しを語るうえで、MCP(Model Context Protocol)は避けて通れません。

なぜ MCP が必要なのか?

現在のツールエコシステムは断片化しすぎています。Claude に GitHub ツールをつなぎ、ChatGPT に Slack ツールをつなぐ——そのどれもが個別の開発を必要とします。MCP の目標は、統一された標準を打ち立てること。一度書いたツールを、どこでも使えるようにすることです。

アーキテクチャはとてもシンプルです。

MCP Client(Claude Code / Claude Desktop)

    MCP Server(ツール提供者)

   External Tool / API

Claude Code での MCP 実践

Claude Code は現時点で MCP サポートが最も優れた製品です。/mcp コマンドでツールを設定できます。

# リモート MCP サーバーを追加
claude mcp add my-server --transport sse --url https://api.example.com/mcp

# ローカルツールを追加
claude mcp add local-tool --command node ./my-tool.js

設定が済むと、Claude Code はサーバーが提供するツールを自動的に発見します。会話の中で関連する内容に触れると、自動で呼び出してくれます。

例を挙げましょう。私は get-github-issues というツールを設定し、Claude Code に「このプロジェクトの open issues は何がある?」と尋ねました。すると、そのままツールを呼び出して、結果を整理して返してくれました。

このプロセスの間、私はツールの存在をまったく意識しませんでした——これこそツール呼び出しの理想の姿です。


本番環境のいくつかの落とし穴

ツール呼び出しは簡単そうに聞こえますが、いざ本番に乗せると、落とし穴は少なくありません。

セキュリティ:AI に勝手をさせない

AI は、あなたが呼んでほしくない API を呼び出すかもしれません。解決策はこうです。

  1. ツール権限の段階分け:AI には必要なツールだけを与え、機密操作は人の確認を必須にする
  2. 入力検証:AI が生成したパラメータは再検証し、そのまま API に渡さない
  3. 呼び出し監査:毎回のツール呼び出しのパラメータと結果を記録し、追跡しやすくする

私はある反面教師の事例を見ました。AI がユーザーの無造作な入力をそのままデータベースのクエリ API に渡し、結果は……SQL インジェクションでした。AI が直接注入したわけではありませんが、悪意ある入力を素通しさせてしまったのです。だからこそ、AI が生成したパラメータを決して信用してはいけません。

タイムアウトとリトライ

ツール呼び出しは失敗し得ます。妥当なタイムアウト時間を設定し、リトライの仕組みと組み合わせましょう。

async def call_tool_with_retry(tool_func, args, max_retries=3):
    for attempt in range(max_retries):
        try:
            return await asyncio.wait_for(
                tool_func(**args),
                timeout=10.0  # 10 秒でタイムアウト
            )
        except asyncio.TimeoutError:
            if attempt == max_retries - 1:
                return {"error": "ツール呼び出しがタイムアウトしました"}
            await asyncio.sleep(1)  # 1 秒待ってリトライ

Token コスト

ツールの定義も返却結果も、Token を消費します。特に大量のデータを返すときはコストが高くなりがちです。いくつかの提案です。

  1. ツール説明を簡潔に:description は短くできるなら短く、ただし要点は明確に
  2. 返却データを制限する:API が返すデータはまずフィルタし、必要なフィールドだけ残す
  3. キャッシュを使う:同じクエリの結果は数分間キャッシュできる

最後に

ツール呼び出しは、AI エージェントの中核的な能力です。これがなければ AI は机上の空論しかできません。これがあって初めて、AI は本当にあなたの仕事を助けられます。

OpenAI の Function Calling はシンプルで使いやすく、入門やシンプルなシーンに向いています。Claude の Tool Use はより強力で、複雑なエージェントシステムに適しています。MCP はツール標準化のトレンドであり、長く注目する価値があります。

どれを選ぶか?あなたのニーズ次第です。ただし、どれを選ぶにしても、セキュリティ、エラー処理、性能チューニングという 3 つの落とし穴だけは、必ず前もって考え抜いておきましょう。


参考資料

FAQ

OpenAI の Function Calling と Claude の Tool Use にはどんな違いがありますか?
主な違いは並列呼び出しとエラー処理です。Claude は一度に複数のツール呼び出しを返すことをネイティブにサポートし、どれを並列実行できるかを賢く判断します。エラー処理では、Claude は `is_error` マークを用意しており、AI が優雅にフォールバックできます。OpenAI はよりシンプルで扱いやすく、単純なシーンに向いています。
Function Calling ではなく、いつ MCP を使うべきですか?
ツールのエコシステムを構築し、同じツール群を複数の AI プラットフォームで使いたいときは MCP を選びます。MCP は標準化されたツールプロトコルを提供しており、一度書いたツールを Claude や ChatGPT など複数のクライアントから利用でき、重複開発を避けられます。
ツール呼び出しが失敗したらどう処理しますか?
3 つの提案があります。1)タイムアウトとリトライの仕組みを設定する(例:10 秒タイムアウト、最大 3 回リトライ)。2)Claude の `is_error: true` マークを使って失敗理由を AI に伝える。3)キャッシュデータの返却や丁寧な案内など、フォールバック案を用意する。
AI が機密性の高い API を呼び出すのをどう防ぎますか?
権限の段階分けが鍵です。AI には必要なツールだけを与え、機密操作(支払いや削除など)は人の確認を必須にします。さらに、AI が生成したパラメータを決してそのまま信用せず、必ず再検証してから API に渡します。
Strict Mode とは何ですか?有効にする必要がありますか?
Strict Mode は OpenAI が 2024 年に導入した機能で、AI が返すパラメータが、定義した JSON Schema に 100% 適合することを保証します。本番環境では有効化を強くおすすめします。さまざまな解析エラーを防げます。有効化の方法:function 定義に `"strict": true` を加えます。

4分で読めます · 公開日: 2026年3月21日 · 更新日: 2026年6月8日

関連記事

コメント

GitHubアカウントでログインしてコメントできます