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

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

こんな経験ありませんか?AIに天気を調べてもらったり、ファイルを読み込んだり、APIを呼び出したりしたいのに、「外部データにアクセスできません」と返ってくるだけ。

かなりイライラしますよね。

実は、AIが賢くないからではなく、ツール呼び出しという核となる機能が欠けているのです。今日は、AIを「ただおしゃべりするだけ」から「実際に仕事をする」に変える技術についてお話ししましょう。


AIツール呼び出しとは?

一言で言えば、ツール呼び出しはAIに手を与えることです。

従来の大規模言語モデルは、学習データに基づいてしか質問に答えられません。「北京の今日の天気は?」と聞いても、「リアルタイムデータにアクセスできません」と言うだけ。しかしツール呼び出しがあれば、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,  # この行を追加
        # ... 他のフィールド
    }
}]

有効にすると、AIが返すパラメータは定義したSchemaに100%一致することが保証されます。本番環境では強く推奨します—そうしないと、奇妙な解析エラーに遭遇する可能性があります。


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

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

並列呼び出し

Claudeは一度に複数のツール呼び出しを返すことをサポートしています。例えば、ユーザーが「北京と上海の天気を比較して」と聞くと、Claudeは2つのget_weather呼び出しを一度にリクエストします:

response = client.messages.create(
    model="claude-sonnet-4-20250514",
    messages=[{"role": "user", "content": "北京と上海の天気を比較して"}],
    tools=tools
)

# response.contentには2つのtool_useブロックが含まれる可能性
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クライアント(Claude Code/Claude Desktop)

    MCPサーバー(ツールプロバイダー)

   外部ツール/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に「このプロジェクトのオープンなissueは何ですか?」と聞くと、ツールを直接呼び出して結果を整理してくれました。

プロセス全体で、ツールの存在を全く感じさせません—これこそツール呼び出しの理想的な状態です。


本番環境の落とし穴

ツール呼び出しはシンプルに聞こえますが、本番環境に入ると、かなり落とし穴があります。

セキュリティ:AIを野放しにしない

AIがあなたが呼び出してほしくないAPIを呼び出す可能性があります。解決策:

  1. ツール権限レベル:AIには必要なツールのみを与える;機密操作には人間の確認が必要
  2. 入力検証:AIが生成したパラメータは必ずAPIに渡す前に検証する
  3. 呼び出し監査:各ツール呼び出しのパラメータと結果をログに記録し、トレース可能に

ある失敗例を見ました:AIがユーザーの適当な入力をデータベースクエリインターフェースに直接渡し、結果として…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秒待ってリトライ

トークンコスト

ツール定義と返された結果は両方ともトークンを消費します。特に大量のデータを返す場合、コストが高くなる可能性があります。いくつかの提案:

  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`フラグを提供してグレースフルデグラデーションを実現します。OpenAIはよりシンプルで、単純なシナリオに適しています。
MCPを直接のFunction Callingの代わりに使うべきタイミングは?
ツールエコシステムを構築し、同じツールセットで複数の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%一致することを保証します。本番環境では強く推奨—各種解析エラーを回避できます。関数定義に`"strict": true`を追加して有効化します。

5 min read · 公開日: 2026年3月21日 · 更新日: 2026年3月22日

コメント

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

関連記事