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 返金照会 |
| ループ反復 | 条件を満たすまで繰り返し呼び出す | ページネーションで全データを取得 |