Tool Calls の概要

DeepSeek V4 は OpenAI 互換の Function Calling(現在は Tool Calls と呼ばれる)を完全にサポートしており、AI がユーザーのリクエストを満たすために外部ツールを呼び出すかどうかを自律的に決定できます。モデル自体はツールを実行せず、構造化された呼び出しリクエストを生成し、開発者のコードが実際に実行して結果を返します。

基本的な Tool Call の例

from openai import OpenAI
import json
import os

client = OpenAI(
    api_key=os.environ.get('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": "都市名"},
                "unit": {"type": "string", "enum": ["celsius", "fahrenheit"]}
            },
            "required": ["city"]
        }
    }
}, {
    "type": "function",
    "function": {
        "name": "get_stock_price",
        "description": "株価のリアルタイム価格を取得",
        "parameters": {
            "type": "object",
            "properties": {
                "symbol": {"type": "string", "description": "株式コード"}
            },
            "required": ["symbol"]
        }
    }
}]

# リクエストを送信
response = client.chat.completions.create(
    model='deepseek-v4-flash',
    messages=[{"role": "user", "content": "今日の北京の天気は?ついでに AAPL の株価も調べて"}],
    tools=tools,
    tool_choice="auto"
)

# tool calls を処理
msg = response.choices[0].message
if msg.tool_calls:
    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})")

並列 Tool Calls

ユーザーのリクエストが複数の独立したツールに関連する場合、DeepSeek V4 はすべてのツールを自動的に並列呼び出しし、往復遅延を大幅に削減します。上記の例では、天気クエリと株価クエリが同時に実行されます。並列呼び出しの利点:

  • 複数のツールをリクエストする場合、API 呼び出しは1回で済む
  • 合計遅延 = max(単一ツールの遅延) であり、合計ではない
  • 依存関係は自動的に処理される—依存関係のあるツールは直列のまま

厳格モード(Strict Mode)

DeepSeek V4 は tool_choice パラメータをサポートし、ツール呼び出しの動作を正確に制御します:

tool_choice 値動作
"auto"(デフォルト)モデルがツールを呼び出すかどうかを自律的に決定
"required"ツール呼び出しを強制
"none"ツール呼び出しを禁止し、テキストのみで応答
{"type":"function","function":{"name":"xxx"}}指定された関数の呼び出しを強制

Node.js 完全な例

import OpenAI from 'openai';

const openai = new OpenAI({
  baseURL: 'https://api.deepseek.com',
  apiKey: process.env.DEEPSEEK_API_KEY,
});

async function runWithTools(prompt) {
  const messages = [{ role: 'user', content: prompt }];

  const response = await openai.chat.completions.create({
    model: 'deepseek-v4-pro',
    messages,
    tools: [/* ツール定義 */],
    tool_choice: 'auto',
  });

  const msg = response.choices[0].message;

  if (msg.tool_calls) {
    // すべてのツール呼び出しを実行
    for (const tc of msg.tool_calls) {
      const result = await executeTool(tc.function.name, JSON.parse(tc.function.arguments));
      messages.push({ role: 'tool', tool_call_id: tc.id, content: JSON.stringify(result) });
    }

    // 結果をモデルに返して最終応答を生成
    const final = await openai.chat.completions.create({
      model: 'deepseek-v4-pro',
      messages,
    });
    return final.choices[0].message.content;
  }

  return msg.content;
}

エラーハンドリングのベストプラクティス

  • ツール実行の失敗:明確なエラーメッセージ(空でない文字列)を返し、モデルが失敗理由を認識し、代替案を試みられるようにする
  • タイムアウト制御:各ツールにタイムアウトを設定(推奨30秒)、タイムアウト後はタイムアウトエラーを返す
  • 結果の簡素化:モデルに返す結果は簡潔にし、必要な情報のみを含めてコンテキスト超過を避ける
  • リトライ機構:ツール実行が失敗した場合、自動的に1回リトライする

マルチツールオーケストレーションパターン

パターン説明適用シナリオ
並列呼び出し複数の独立したツールを同時に呼び出す天気+株価+ニュースを調べる
直列依存ツールBがツールAの結果に依存まずドキュメントを検索し、その結果を分析する
条件分岐ユーザーの入力に応じて異なるツールを選択カスタマーサービス:注文照会 or 返金照会
ループ反復条件を満たすまで繰り返し呼び出すページネーションで全データを取得