AI にツール呼び出し機能が必要な理由
大規模言語モデルは強力ですが、本質的な限界があります。リアルタイム情報を取得できず、コードを実行できず、外部システムを操作できません。Function Calling(関数呼び出し)は、まさにこれらの問題を解決するために生まれました。AI が人間がツールを使うように、外部 API や関数を自律的に選択して呼び出し、モデルの境界を突破できるようにします。
次のシナリオを想像してください。ユーザーが「今日の北京の天気は?」と尋ねます。純粋なテキストモデルは、トレーニングデータが特定の日付で終了しているため、答えることができません。しかし、Function Calling を備えた AI は次のように行動します。天気 API を呼び出す必要があると認識 → 正しい API リクエストを構築 → 返された JSON データを解析 → 自然言語でユーザーに返答します。これがツール呼び出しループの魅力です。
Function Calling の仕組み
Function Calling は、AI が実際に関数を呼び出すのではなく、巧妙に設計されたプロトコルです。
- ツールの定義:開発者はモデルに利用可能な関数(名前、パラメータ、目的)を記述します。
- モデルの決定:AI はユーザー入力を分析し、ツールを呼び出すかどうか、どのツールを呼び出すか、どのパラメータを渡すかを決定します。
- 開発者の実行:開発者のコードが実際の関数呼び出しを実行します。
- 結果のフィードバック:実行結果がモデルに返され、モデルはそれに基づいて最終応答を生成します。
このプロトコルの巧妙さは、AI が「何をするかを決定」する一方で、実際の実行権限は常に開発者にあるため、安全性と制御性が保証される点です。
スキルチェーン分解:ツールオーケストレーションチェーン
「ツールオーケストレーションチェーン」スキルチェーンを例に、各ノードがツール呼び出しフローで果たす役割を分解します。
ノード 1:要件理解(sp-188)—AI はまずユーザーの意図を正確に理解する必要があります。ユーザーが「最近のフライトを調べて」と言った場合、AI はこれが外部ツールの呼び出しを必要とするタスクであり、単純なテキストの Q&A ではないと認識する必要があります。
ノード 2:ツール選択(sp-179)—利用可能なツールセットから最も適切なツールを選択します。ユーザーがフライトを調べたい場合、天気 API ではなくフライト検索 API を呼び出す必要があります。このノードでは、AI に「ツールマッチング」能力が求められます。
ノード 3:ツール呼び出し(sp-181)—正しいパラメータを構築して呼び出しを実行します。AI はユーザーの曖昧な要求(例:「最近のフライト」)を正確な API パラメータ(例:date=2026-07-13, from=北京, to=上海)に変換する必要があります。
ノード 4:結果解析(sp-187)—API が返した構造化データを、ユーザーにわかりやすい自然言語の応答に変換します。フライト検索では数十件の JSON データが返されるかもしれませんが、ユーザーが必要とするのは最も関連性の高い 2〜3 件だけです。
実践:マルチツール Agent の構築
以下のコードは、複数のツールを備えた Agent Loop の実装を示しています。
import json from openai import OpenAI import requests client = OpenAI( api_key="your-deepseek-api-key", base_url="https://api.deepseek.com" ) # 利用可能なツールを定義 tools = [ { "type": "function", "function": { "name": "get_weather", "description": "指定された都市のリアルタイムの天気情報を取得します", "parameters": { "type": "object", "properties": { "city": {"type": "string", "description": "都市名、例:北京"} }, "required": ["city"] } } }, { "type": "function", "function": { "name": "search_web", "description": "インターネットで最新情報を検索します", "parameters": { "type": "object", "properties": { "query": {"type": "string", "description": "検索キーワード"}, "num_results": {"type": "integer", "description": "返す結果の数"} }, "required": ["query"] } } }, { "type": "function", "function": { "name": "calculate", "description": "数学計算を実行します", "parameters": { "type": "object", "properties": { "expression": {"type": "string", "description": "数式"} }, "required": ["expression"] } } } ] # ツール実装関数 def execute_tool(tool_name, arguments): if tool_name == "get_weather": city = arguments.get("city") # 実際のプロジェクトでは天気 API を呼び出します return f"{city} は今日晴れ、気温 25°C、湿度 60%" elif tool_name == "search_web": query = arguments.get("query") return f"'{query}' の検索結果:関連情報が 3 件見つかりました..." elif tool_name == "calculate": expression = arguments.get("expression") try: result = eval(expression) return f"計算結果:{expression} = {result}"except: return "計算式が無効です" return "不明なツール" class ToolCallingAgent: def __init__(self, max_iterations=5): self.max_iterations = max_iterations self.messages = [] def run(self, user_input): self.messages = [{ "role": "system", "content": "あなたはタスクを完了するためにツールを使用できるインテリジェントアシスタントです。段階的に考え、適切にツールを使用してください。" }, { "role": "user", "content": user_input }] for i in range(self.max_iterations): print(f"=== 第 {i+1} ラウンド ===") response = client.chat.completions.create( model="deepseek-chat", messages=self.messages, tools=tools ) msg = response.choices[0].message # モデルが直接返答する場合 if msg.content and not msg.tool_calls: return msg.content # モデルがツールを呼び出す場合 if msg.tool_calls: self.messages.append(msg) for tool_call in msg.tool_calls: func_name = tool_call.function.name func_args = json.loads(tool_call.function.arguments) print(f"ツール呼び出し: {func_name}({func_args})") result = execute_tool(func_name, func_args) self.messages.append({ "role": "tool", "tool_call_id": tool_call.id, "content": result }) return "最大反復回数に達しました" # 使用例 agent = ToolCallingAgent(max_iterations=5) result = agent.run("今日の北京の天気は?また、156 * 23 + 89 を計算して。") print(f"最終返答: {result}") re> ツール呼び出しのベストプラクティス
ツールの説明を正確に:モデルのツール選択は、ツールの説明に完全に依存します。説明が明確であればあるほど、選択は正確になります。各ツールの説明には、機能説明、適用シナリオ、パラメータの詳細、戻り値の形式を含めることをお勧めします。
パラメータ検証は必須:モデルが不合理なパラメータを生成する可能性があります。execute_tool では常にパラメータ検証を行い、パラメータエラーによるツール呼び出しの失敗を防ぎます。
エラーをモデルにフィードバック:ツール呼び出しが失敗した場合、単にエラーメッセージを返すのではなく、構造化されたエラー説明をモデルに返し、戦略を調整する機会を与えます。例:「天気 API の呼び出しに失敗:都市名「北惊」は存在しません。「北京」を使用することをお勧めします」。
ツールの数を制御:利用可能なツールが多すぎると、モデルの選択が難しくなります。ツールの数を10個以内に抑えるか、ツールをグループ化し、コンテキストに応じて動的に提供することをお勧めします。
ツール呼び出しとエージェントループの深い統合
ツール呼び出しは一度きりの操作ではなく、エージェントループに組み込まれた継続的なプロセスです。1回のツール呼び出しの結果が次のツール呼び出しを引き起こす可能性があります。例えば、まず「AI分野の最新論文」を検索し、検索結果の論文タイトルに基づいて、PDF解析ツールを呼び出して論文の詳細を取得します。このようなチェーン型ツール呼び出しは、エージェントループの強力な能力の表れです。
このスキルチェーンを自分で編成してみませんか?
スキルチェーンで開く →