# 工具调用

> 全部文档的索引见 [llms.txt](https://ark.volcengine.com/llms.txt)；在任一文档页面地址后追加 `.md` 可获取该页的 Markdown 版本。

Responses API 支持使用方舟大模型内置工具、函数调用 Function Calling 等工具来扩展模型的功能。这些功能使模型能够搜索网络资料、图片处理、私域知识库搜索或者调用自定义函数。
<span id="07456946"></span>
## 快速开始

以天气查询场景为例，介绍使用函数调用 Function Calling 的方法。

**选项：Curl**

**第一轮请求： 触发工具调用**

```Bash
curl https://ark.cn-beijing.volces.com/api/v3/responses \
  -H "Authorization: Bearer $ARK_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "doubao-seed-2-1-pro-260915",
    "store": true,
    "input": [
        {
            "type": "message",
            "role": "user",
            "content": "查询北京今天的天气"
        }
    ],
    "tools": [
        {
            "type": "function",
            "name": "get_weather",
            "description": "根据城市名称查询该城市当日天气（含温度、天气状况）",
            "parameters": {
                "type": "object",
                "properties": {
                    "location": {
                        "type": "string",
                        "description": "城市名称，如北京、上海（仅支持国内地级市）"
                    }
                },
                "required": ["location"]
            }
        }
    ]
  }'
```

**第一轮响应：返回 function_call 指令**
模型会返回工具调用指令，关键字段为`call_id`（关联后续结果）、`arguments`（调用参数）：

```
{
  "created_at": 1756980000,
  "id": "resp_02175698000123456789abcdef0123",
  "model": "doubao-seed-2-1-pro-260915",
  "object": "response",
  "output": [
    {
      "arguments": "{\"location\":\"北京\"}",
      "call_id": "call_abc123def456ghi789jkl0",
      "name": "get_weather",
      "type": "function_call",
      "id": "fc_02175698000abcdef0123456789gh",
      "status": "completed"
    }
  ],
  "status": "completed",
  "store": true,
  "expire_at": 1757239200
}
```

**执行工具：获取天气结果**
开发者根据 `arguments` 调用实际天气工具（如第三方天气 API），假设返回结果为：

```Python
{
    "city": "北京",
    "date": "2025-10-13",
    "temperature": "18~28℃",
    "condition": "晴转多云",
    "wind": "东北风2级"
}
```

**第二轮请求：回传结果并生成最终响应**
传入上一轮 `response_id`、工具结果，模型生成自然语言回答：

```Bash
curl https://ark.cn-beijing.volces.com/api/v3/responses \
  -H "Authorization: Bearer $ARK_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "doubao-seed-2-1-pro-260915",
    "previous_response_id": "resp_02175698000123456789abcdef0123",
    "input": [
      {
        "type": "function_call_output",
        "call_id": "call_abc123def456ghi789jkl0",
        "output": "{\"city\":\"北京\",\"date\":\"2025-10-13\",\"temperature\":\"18~28℃\",\"condition\":\"晴转多云\",\"wind\":\"东北风2级\"}"
      }
    ]
  }'
```

**第二轮响应：生成最终回答**
模型结合工具结果，返回自然语言响应：

```
{
    "created_at": 1756980100,
    "id": "resp_02175698010abcdef0123456789gh",
    "model": "doubao-seed-2-1-pro-260915",
    "object": "response",
    "output": [
        {
            "type": "message",
            "role": "assistant",
            "content": [
                {
                    "type": "output_text",
                    "text": "北京今天（2025-10-13）的天气为晴转多云，气温在18~28℃之间，东北风2级。"
                }
            ],
            "status": "completed",
            "id": "msg_02175698010abcdef0123456789ij"
        }
    ],
    "status": "completed",
    "store": true
}
```

**选项：Python**

```Python
import os
from arkruntime import Ark
import json

# Get API Key: https://ark.volcengine.com/region:cn-beijing/apikey
api_key = os.getenv('ARK_API_KEY')
client = Ark(
    base_url='https://ark.cn-beijing.volces.com/api/v3',
    api_key=api_key,
)

# Define the tool (weather query tool)
weather_tool = [
    {
        "type": "function",
        "name": "get_weather",
        "description": "根据城市名称查询该城市当日天气（含温度、天气状况）",
        "parameters": {
            "type": "object",
            "properties": {
                "location": {
                    "type": "string",
                    "description": "城市名称，如北京、上海（仅支持国内地级市）"
                }
            },
            "required": ["location"]
        }
    }
]

# ------------------- First Round Request: Trigger Tool Call -------------------
print("=== First Round Request: Trigger Tool Call ===")
first_response = client.responses.create(
    model="doubao-seed-2-1-pro-260915",
    store=True,
    input=[
        {
            "type": "message",
            "role": "user",
            "content": "查询北京今天的天气"
        }
    ],
    tools=weather_tool
)
# Extract key information（previous_response_id、call_id、arguments）
previous_response_id = first_response.id
function_call = next(
    item for item in first_response.output if item.type == "function_call"
)
call_id = function_call.call_id
call_arguments = function_call.arguments
print(f"First Round Response ID：{previous_response_id}")
print(f"Tool Call ID：{call_id}")
print(f"Call Parameters：{call_arguments}")

# ------------------- Simulate Tool Execution: Get Weather Results -------------------
print("=== Simulate Tool Execution: Get Weather Results ===")
# In real scenarios, call a third-party weather API here; we use mock data instead.
tool_output = {
    "city": "北京",
    "date": "2025-10-13",
    "temperature": "18~28℃",
    "condition": "晴转多云",
    "wind": "东北风2级"
}
print(f"Tool Return Result：{tool_output}")

# ------------------- Second Round Request: Return Result and Generate Final Response -------------------
print("=== Second Round Request: Return Result and Generate Final Response ===")
second_response = client.responses.create(
    model="doubao-seed-2-1-pro-260915",
    previous_response_id=previous_response_id,
    input=[
        {
            "type": "function_call_output",
            "call_id": call_id,
            "output": json.dumps(tool_output, ensure_ascii=False)
        }
    ]
)
# Extract and print the final answer
final_answer = next(
    item for item in second_response.output if item.type == "message"
)
print("=== Final Answer  ===")
print(final_answer.content[0].text)
```

**选项：Go**

```Go
package main

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

    "github.com/volcengine/ark-runtime-go/arkruntime"
    "github.com/volcengine/ark-runtime-go/arkruntime/model/responses"
)

func main() {
    client := arkruntime.NewClientWithApiKey(
        os.Getenv("ARK_API_KEY"),
        arkruntime.WithBaseUrl("https://ark.cn-beijing.volces.com/api/v3"),
    )
    tool := weatherTool()
    response, err := client.CreateResponses(context.Background(), &responses.ResponsesRequest{
        Model: "doubao-seed-2-1-pro-260915",
        Input: responses.NewStringResponsesInput("北京的天气怎么样？"),
        Store: responses.NewOptBool(true),
        Tools: []responses.Tool{tool},
    })
    if err != nil {
        fmt.Printf("response error: %v\n", err)
        return
    }

    call, ok := functionCall(response.Output)
    if !ok {
        fmt.Println(response)
        return
    }
    fmt.Printf(
        "response_id=%s call_id=%s arguments=%s\n",
        response.ID,
        call.CallID.Or(""),
        call.Arguments.Or(""),
    )

    toolOutput, err := json.Marshal(map[string]string{
        "city": "北京", "condition": "晴转多云", "temperature": "18-28 C",
    })
    if err != nil {
        panic(err)
    }
    second, err := client.CreateResponses(context.Background(), &responses.ResponsesRequest{
        Model:              "doubao-seed-2-1-pro-260915",
        PreviousResponseID: responses.NewOptString(response.ID),
        Input: responses.NewInputItemArrayResponsesInput([]responses.InputItem{
            {
                OneOf: responses.NewItemFunctionToolCallOutputInputItemSum(
                    responses.ItemFunctionToolCallOutput{
                        Type:   responses.ItemFunctionToolCallOutputTypeFunctionCallOutput,
                        CallID: responses.NewOptString(call.CallID.Or("")),
                        Output: responses.NewOptMessageContent(
                            responses.NewStringMessageContent(string(toolOutput)),
                        ),
                    },
                ),
            },
        }),
    })
    if err != nil {
        fmt.Printf("response error: %v\n", err)
        return
    }
    fmt.Println(second)
}

func weatherTool() responses.Tool {
    var parameters responses.FunctionToolParameters
    schema := `{"type":"object","properties":{"location":{"type":"string","description":"城市名称，如北京、上海"}},"required":["location"]}`
    if err := json.Unmarshal([]byte(schema), &parameters); err != nil {
        panic(err)
    }
    return responses.Tool{
        OneOf: responses.NewFunctionToolToolSum(responses.FunctionTool{
            Name: "get_weather",
            Type: responses.FunctionToolTypeFunction,
            Description: responses.NewOptString("根据城市名称查询该城市当日天气"),
            Parameters: responses.NewOptFunctionToolParameters(parameters),
        }),
    }
}

func functionCall(items []responses.OutputItem) (responses.ItemFunctionToolCall, bool) {
    for _, item := range items {
        if call, ok := item.OneOf.GetItemFunctionToolCall(); ok {
            return call, true
        }
    }
    return responses.ItemFunctionToolCall{}, false
}
```

**选项：Java**

```Java
package com.ark.example;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.volcengine.ark.runtime.models.responses.*;
import com.volcengine.ark.runtime.service.ArkService;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.JsonNode;
import java.util.*;

public class demo {
    public static ObjectMapper om = new ObjectMapper();
    public static List<Tool> buildTools() {
        JsonNode params = om.createObjectNode()
                .put("type", "object")
                .set("properties", om.createObjectNode()
                        .set("location", om.createObjectNode()
                                .put("type", "string")
                                .put("description", "城市名称，如北京、上海（仅支持国内地级市）")));


        FunctionTool t = FunctionTool.builder()
                .name("get_weather")
                .description("根据城市名称查询该城市当日天气（含温度、天气状况）")

                .parameters(om.convertValue(params, Map.class))
                .build();

        return Arrays.asList(t);
    }
    public static void main(String[] args) throws JsonProcessingException {
        String apiKey = System.getenv("ARK_API_KEY");

        ArkService arkService = ArkService.builder().apiKey(apiKey)
                .baseUrl("https://ark.cn-beijing.volces.com/api/v3")
                .build();
        System.out.println("=== First Round Request: Trigger Tool Call ===");
        ResponsesRequest req = ResponsesRequest.builder()
                .model("doubao-seed-2-1-pro-260915")
                .store(true)
                .input(ResponsesInput.ofList(java.util.Arrays.asList(ItemEasyMessage.builder().role(MessageRole.USER).content(
                                MessageContent.ofList(java.util.Arrays.asList(ContentItemText.builder().text("查询北京今天的天气").build()))
                        ).build())))
                .tools(buildTools())
                .build();
        Response resp = arkService.createResponse(req);
        System.out.println(resp);
        // Extract key information（previous_response_id、call_id、arguments）
        String previousId = resp.getId();
        OutputItem targetCall = null;
        for(OutputItem item : resp.getOutput()) {
            if (item.getType() == ItemType.FUNCTION_CALL) {
                targetCall = item;
                break;
            }
        }
        ObjectMapper objectMapper = new ObjectMapper();
        String jsonStr = objectMapper.writeValueAsString(targetCall);
        ItemFunctionToolCall functionCall = objectMapper.readValue(jsonStr, ItemFunctionToolCall.class);
        String callId = functionCall.getCallId();
        String callArguments = functionCall.getArguments();
        System.out.println("First Round Response ID:" + previousId);
        System.out.println("Tool Call ID:" + callId);
        System.out.println("Call Parameters:" + callArguments);

        System.out.println("=== Simulate Tool Execution: Get Weather Results  ===");
        Map<String, String> toolOutput = new HashMap<String, String>() {{
            put("city", "北京");

            put("date", "2025-10-13");
            put("temperature", "18~28℃");
            put("condition", "晴转多云");

            put("wind", "东北风2级");

        }};

        System.out.println(toolOutput);

        System.out.println("=== Second Round Request: Return Result and Generate Final Response ===");
        ResponsesRequest secondReq = ResponsesRequest.builder()
                .model("doubao-seed-2-1-pro-260915")
                .previousResponseId(previousId)
                .input(ResponsesInput.ofList(java.util.Arrays.asList(ItemFunctionToolCallOutput.builder().callId(callId).output(MessageContent.ofString(objectMapper.writeValueAsString(toolOutput))).build())))
                .tools(buildTools())
                .build();
        Response secondResp = arkService.createResponse(secondReq);
        System.out.println("=== Final Answer ===");
        System.out.println(secondResp);
        arkService.shutdownExecutor();
    }
}
```

**选项：OpenAI SDK**

```Python
import os
from openai import OpenAI
import json

# Get API Key: https://ark.volcengine.com/region:cn-beijing/apikey
api_key = os.getenv('ARK_API_KEY')
client = OpenAI(
    base_url='https://ark.cn-beijing.volces.com/api/v3',
    api_key=api_key,
)

# Define the tool (weather query tool)
weather_tool = [
    {
        "type": "function",
        "name": "get_weather",
        "description": "根据城市名称查询该城市当日天气（含温度、天气状况）",
        "parameters": {
            "type": "object",
            "properties": {
                "location": {
                    "type": "string",
                    "description": "城市名称，如北京、上海（仅支持国内地级市）"
                }
            },
            "required": ["location"]
        }
    }
]

# ------------------- First Round Request: Trigger Tool Call -------------------
print("=== First Round Request: Trigger Tool Call ===")
first_response = client.responses.create(
    model="doubao-seed-2-1-pro-260915",
    store=True,
    input=[
        {
            "type": "message",
            "role": "user",
            "content": "查询北京今天的天气"
        }
    ],
    tools=weather_tool
)
# Extract key information（previous_response_id、call_id、arguments）
previous_response_id = first_response.id
function_call = next(
    item for item in first_response.output if item.type == "function_call"
)
call_id = function_call.call_id
call_arguments = function_call.arguments
print(f"First Round Response ID：{previous_response_id}")
print(f"Tool Call ID：{call_id}")
print(f"Call Parameters：{call_arguments}")

# ------------------- Simulate Tool Execution: Get Weather Results -------------------
print("=== Simulate Tool Execution: Get Weather Results ===")
tool_output = {
    "city": "北京",
    "date": "2025-10-13",
    "temperature": "18~28℃",
    "condition": "晴转多云",
    "wind": "东北风2级"
}
print(f"Tool Return Result：{tool_output}")

# ------------------- Second Round Request: Return Result and Generate Final Response-------------------
print("=== Second Round Request: Return Result and Generate Final Response ===")
second_response = client.responses.create(
    model="doubao-seed-2-1-pro-260915",
    previous_response_id=previous_response_id,
    input=[
        {
            "type": "function_call_output",
            "call_id": call_id,
            "output": json.dumps(tool_output, ensure_ascii=False)
        }
    ]
)
# Extract and print the final answer
final_answer = next(
    item for item in second_response.output if item.type == "message"
)
print("=== Final Answer ===")
print(final_answer.content[0].text)
```

<span id="available-tools"></span>
## 支持的工具

<span id="built-in-tools"></span>
### 内置工具

当通过 Responses API 创建模型响应时，您可以通过在参数中配置 `tools` 字段来访问工具。每个工具中都有独特的配置要求，具体见如下教程：

* [豆包助手 API](/docs/doubao-assistant)

    为您的应用快速集成与豆包 App 同款的 AI 功能，例如日常沟通、深度沟通和联网搜索，快速获得安全、可靠且可控的优质 AI 体验。

* [联网搜索工具](/docs/web-search)

    支持豆包搜索 Custom 版和联网内容插件两种工具，可获取实时公开网络信息（如新闻、商品、天气等），解决数据时效性、知识盲区、信息同步等核心问题，并且无需自行开发搜索引擎或维护数据资源。

* [Image Process（图像处理工具）](/docs/image-process)

    支持通过 Responses API 调用对输入图片执行画点、画线、旋转、缩放、框选/裁剪关键区域等基础操作，适用于需模型通过视觉处理提升图片理解的场景（如图文内容分析、物体定位标注、多轮视觉推理等）。工具通过模型自动判断图像处理逻辑，支持与自定义函数混合使用，且可处理多轮视觉输入（上一轮输出图片作为下一轮输入）。

* [Knowledge Search（私域知识库搜索工具）](/docs/knowledge-search)

    支持通过 Responses API 调用直接获取企业私域知识库中的信息（如内部文档、产品手册、行业资料等），适用于需基于企业专属数据解答问题的场景（如内部培训问答、产品功能咨询、行业方案查询等）。工具通过模型自动判断是否需要调用私域知识库，支持与自定义函数、MCP 等工具混合使用，目前仅支持旗舰版知识库。

* [Apply Patch（代码补丁工具）](/docs/apply-patch)

    支持通过结构化补丁格式创建、更新或删除文件，适用于让模型直接生成文件修改方案的场景（如批量代码改写、机械化重构、测试文件生成等）。通过 Responses API 既可以将其作为内置工具直接启用，也可以按自定义工具方式接入，以兼容现有工具编排流程。

<span id="custom-function"></span>
### 自定义函数

您也可以在创建模型响应时，使用 `tools` 来定义自定义函数。模型通过调用自定义函数代码，来访问模型中无法直接使用的特定数据或功能。了解更多信息，请参见[Function Calling（函数调用）](/docs/function-calling)。

<span id="mcp"></span>
### 云部署 MCP 或 Remote MCP

Responses API 支持通过 Streamable HTTP 链接的 MCP 调用。适用于复杂任务（如多步数据查询 + 分析）场景，支持与自定义函数、Web Search 工具混合使用。详情请参见[云部署 MCP / Remote MCP](/docs/mcp-remote-mcp)。
