> ## Documentation Index
> Fetch the complete documentation index at: https://docs.arouter.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# 工具呼叫

> 讓 AI 能夠呼叫函式並在現實世界中執行操作。工具呼叫使模型能夠與外部 API、資料庫和服務互動。

工具呼叫（也稱為函式呼叫）允許模型請求執行您定義的特定函式。模型決定何時呼叫工具以及使用什麼參數——您的應用程式執行工具並回傳結果。

ARouter 支援所有主要供應商的工具呼叫。介面遵循 OpenAI 工具呼叫標準。

## 運作原理

工具呼叫遵循 3 步循環：

1. **帶工具的推理** — 您發送帶有工具定義的請求。模型決定呼叫工具並回傳 `tool_calls` 回應。
2. **工具執行（客戶端）** — 您的應用程式執行請求的函式並收集結果。
3. **帶工具結果的推理** — 您將工具結果回傳給模型，模型產生最終回應。

### 第 1 步：帶工具的推理

```json theme={null}
{
  "model": "openai/gpt-5.4",
  "messages": [
    { "role": "user", "content": "What is the weather in San Francisco?" }
  ],
  "tools": [
    {
      "type": "function",
      "function": {
        "name": "get_weather",
        "description": "Get the current weather for a location",
        "parameters": {
          "type": "object",
          "properties": {
            "location": {
              "type": "string",
              "description": "City name, e.g. 'San Francisco'"
            },
            "unit": {
              "type": "string",
              "enum": ["celsius", "fahrenheit"]
            }
          },
          "required": ["location"]
        }
      }
    }
  ],
  "tool_choice": "auto"
}
```

模型回傳 `tool_calls` 陣列：

```json theme={null}
{
  "id": "chatcmpl-xxx",
  "choices": [
    {
      "message": {
        "role": "assistant",
        "content": null,
        "tool_calls": [
          {
            "id": "call_abc123",
            "type": "function",
            "function": {
              "name": "get_weather",
              "arguments": "{\"location\": \"San Francisco\", \"unit\": \"fahrenheit\"}"
            }
          }
        ]
      },
      "finish_reason": "tool_calls"
    }
  ]
}
```

### 第 2 步：工具執行（客戶端）

您的應用程式使用模型的參數執行函式：

```python theme={null}
import json

tool_call = response.choices[0].message.tool_calls[0]
args = json.loads(tool_call.function.arguments)

# 執行您的函式
result = get_weather(
    location=args["location"],
    unit=args.get("unit", "fahrenheit")
)
# result = {"temperature": 72, "condition": "sunny", "unit": "fahrenheit"}
```

### 第 3 步：帶工具結果的推理

將工具結果作為 `tool` 角色訊息回傳：

```json theme={null}
{
  "model": "openai/gpt-5.4",
  "messages": [
    { "role": "user", "content": "What is the weather in San Francisco?" },
    {
      "role": "assistant",
      "content": null,
      "tool_calls": [
        {
          "id": "call_abc123",
          "type": "function",
          "function": {
            "name": "get_weather",
            "arguments": "{\"location\": \"San Francisco\", \"unit\": \"fahrenheit\"}"
          }
        }
      ]
    },
    {
      "role": "tool",
      "tool_call_id": "call_abc123",
      "content": "{\"temperature\": 72, \"condition\": \"sunny\", \"unit\": \"fahrenheit\"}"
    }
  ],
  "tools": [...]
}
```

## 完整範例

<Tabs>
  <Tab title="Python (OpenAI)">
    ```python theme={null}
    import json
    from openai import OpenAI

    client = OpenAI(
        base_url="https://api.arouter.ai/v1",
        api_key="lr_live_xxxx",
    )

    # 定義工具
    tools = [
        {
            "type": "function",
            "function": {
                "name": "get_weather",
                "description": "Get the current weather for a location",
                "parameters": {
                    "type": "object",
                    "properties": {
                        "location": {
                            "type": "string",
                            "description": "City name, e.g. 'San Francisco'",
                        },
                        "unit": {"type": "string", "enum": ["celsius", "fahrenheit"]},
                    },
                    "required": ["location"],
                },
            },
        }
    ]

    messages = [{"role": "user", "content": "What is the weather in San Francisco?"}]

    # 第 1 步：首次推理
    response = client.chat.completions.create(
        model="openai/gpt-5.4",
        messages=messages,
        tools=tools,
        tool_choice="auto",
    )

    assistant_message = response.choices[0].message
    messages.append(assistant_message)

    # 第 2 步：執行工具
    if assistant_message.tool_calls:
        for tool_call in assistant_message.tool_calls:
            if tool_call.function.name == "get_weather":
                args = json.loads(tool_call.function.arguments)
                # 模擬天氣 API
                result = {"temperature": 72, "condition": "sunny", "unit": args.get("unit", "fahrenheit")}

                messages.append({
                    "role": "tool",
                    "tool_call_id": tool_call.id,
                    "content": json.dumps(result),
                })

    # 第 3 步：最終推理
    final_response = client.chat.completions.create(
        model="openai/gpt-5.4",
        messages=messages,
        tools=tools,
    )

    print(final_response.choices[0].message.content)
    # "The current weather in San Francisco is 72°F and sunny."
    ```
  </Tab>

  <Tab title="Node.js (OpenAI)">
    ```typescript theme={null}
    import OpenAI from "openai";

    const client = new OpenAI({
      baseURL: "https://api.arouter.ai/v1",
      apiKey: "lr_live_xxxx",
    });

    // 定義工具
    const tools: OpenAI.Chat.ChatCompletionTool[] = [
      {
        type: "function",
        function: {
          name: "get_weather",
          description: "Get the current weather for a location",
          parameters: {
            type: "object",
            properties: {
              location: {
                type: "string",
                description: "City name, e.g. 'San Francisco'",
              },
              unit: { type: "string", enum: ["celsius", "fahrenheit"] },
            },
            required: ["location"],
          },
        },
      },
    ];

    const messages: OpenAI.Chat.ChatCompletionMessageParam[] = [
      { role: "user", content: "What is the weather in San Francisco?" },
    ];

    // 第 1 步：首次推理
    const response = await client.chat.completions.create({
      model: "openai/gpt-5.4",
      messages,
      tools,
      tool_choice: "auto",
    });

    const assistantMessage = response.choices[0].message;
    messages.push(assistantMessage);

    // 第 2 步：執行工具
    if (assistantMessage.tool_calls) {
      for (const toolCall of assistantMessage.tool_calls) {
        if (toolCall.function.name === "get_weather") {
          const args = JSON.parse(toolCall.function.arguments);
          const result = {
            temperature: 72,
            condition: "sunny",
            unit: args.unit ?? "fahrenheit",
          };

          messages.push({
            role: "tool",
            tool_call_id: toolCall.id,
            content: JSON.stringify(result),
          });
        }
      }
    }

    // 第 3 步：最終推理
    const finalResponse = await client.chat.completions.create({
      model: "openai/gpt-5.4",
      messages,
      tools,
    });

    console.log(finalResponse.choices[0].message.content);
    ```
  </Tab>

  <Tab title="Go">
    ```go theme={null}
    package main

    import (
        "context"
        "encoding/json"
        "fmt"
        "log"

        "github.com/arouter-ai/arouter-go"
    )

    func main() {
        client := arouter.NewClient("lr_live_xxxx",
            arouter.WithBaseURL("https://api.arouter.ai/v1"),
        )

        tools := []arouter.Tool{
            {
                Type: "function",
                Function: &arouter.FunctionDefinition{
                    Name:        "get_weather",
                    Description: "Get the current weather for a location",
                    Parameters: map[string]any{
                        "type": "object",
                        "properties": map[string]any{
                            "location": map[string]any{
                                "type":        "string",
                                "description": "City name",
                            },
                            "unit": map[string]any{
                                "type": "string",
                                "enum": []string{"celsius", "fahrenheit"},
                            },
                        },
                        "required": []string{"location"},
                    },
                },
            },
        }

        messages := []arouter.Message{
            {Role: "user", Content: "What is the weather in San Francisco?"},
        }

        // 第 1 步
        resp, err := client.CreateChatCompletion(context.Background(), arouter.ChatCompletionRequest{
            Model:    "openai/gpt-5.4",
            Messages: messages,
            Tools:    tools,
        })
        if err != nil {
            log.Fatal(err)
        }

        assistantMsg := resp.Choices[0].Message
        messages = append(messages, assistantMsg)

        // 第 2、3 步
        for _, tc := range assistantMsg.ToolCalls {
            var args map[string]string
            json.Unmarshal([]byte(tc.Function.Arguments), &args)
            result := fmt.Sprintf(`{"temperature":72,"condition":"sunny","unit":"%s"}`, args["unit"])
            messages = append(messages, arouter.Message{
                Role:       "tool",
                ToolCallID: tc.ID,
                Content:    result,
            })
        }

        finalResp, err := client.CreateChatCompletion(context.Background(), arouter.ChatCompletionRequest{
            Model:    "openai/gpt-5.4",
            Messages: messages,
            Tools:    tools,
        })
        if err != nil {
            log.Fatal(err)
        }

        fmt.Println(finalResp.Choices[0].Message.Content)
    }
    ```
  </Tab>

  <Tab title="cURL">
    ```bash theme={null}
    # 第 1 步：帶工具的推理
    curl https://api.arouter.ai/v1/chat/completions \
      -H "Authorization: Bearer lr_live_xxxx" \
      -H "Content-Type: application/json" \
      -d '{
        "model": "openai/gpt-5.4",
        "messages": [
          {"role": "user", "content": "What is the weather in San Francisco?"}
        ],
        "tools": [
          {
            "type": "function",
            "function": {
              "name": "get_weather",
              "description": "Get the current weather for a location",
              "parameters": {
                "type": "object",
                "properties": {
                  "location": {"type": "string"},
                  "unit": {"type": "string", "enum": ["celsius", "fahrenheit"]}
                },
                "required": ["location"]
              }
            }
          }
        ],
        "tool_choice": "auto"
      }'

    # 第 3 步：發送工具結果
    curl https://api.arouter.ai/v1/chat/completions \
      -H "Authorization: Bearer lr_live_xxxx" \
      -H "Content-Type: application/json" \
      -d '{
        "model": "openai/gpt-5.4",
        "messages": [
          {"role": "user", "content": "What is the weather in San Francisco?"},
          {
            "role": "assistant",
            "content": null,
            "tool_calls": [{"id": "call_abc123", "type": "function", "function": {"name": "get_weather", "arguments": "{\"location\": \"San Francisco\"}"}}]
          },
          {
            "role": "tool",
            "tool_call_id": "call_abc123",
            "content": "{\"temperature\": 72, \"condition\": \"sunny\"}"
          }
        ]
      }'
    ```
  </Tab>
</Tabs>

## 串流工具呼叫

啟用串流後，工具呼叫參數透過 `delta.tool_calls` 增量傳遞：

```typescript theme={null}
const stream = await client.chat.completions.create({
  model: "openai/gpt-5.4",
  messages: [{ role: "user", content: "What's the weather in NYC?" }],
  tools,
  stream: true,
});

let toolCallArgs = "";
let toolCallId = "";
let toolCallName = "";

for await (const chunk of stream) {
  const delta = chunk.choices[0]?.delta;

  if (delta?.tool_calls) {
    const tc = delta.tool_calls[0];
    if (tc.id) toolCallId = tc.id;
    if (tc.function?.name) toolCallName = tc.function.name;
    if (tc.function?.arguments) toolCallArgs += tc.function.arguments;
  }

  if (chunk.choices[0]?.finish_reason === "tool_calls") {
    // 所有參數已接收完畢
    const args = JSON.parse(toolCallArgs);
    console.log(`Calling ${toolCallName} with:`, args);
  }
}
```

## 支援的模型

使用 `GET /v1/models` 查找支援工具呼叫的模型。功能列表中包含 `tools` 的模型支援此功能。

```bash theme={null}
curl https://api.arouter.ai/v1/models \
  -H "Authorization: Bearer lr_live_xxxx"
```

大多數前沿模型都支援工具呼叫，包括：

* `openai/gpt-5.4`, `openai/gpt-5.4-pro`
* `anthropic/claude-sonnet-4.6`, `anthropic/claude-opus-4.5`
* `google/gemini-2.5-flash`, `google/gemini-2.5-pro`
* `deepseek/deepseek-v3.2`
