/v1 托管工具

在对话补全、Messages、Responses 请求中声明平台工具,由平台执行工具循环:三种格式的写法、执行规则、响应形状与计费。

更新于 2026-10-28阅读约 11 分钟

查看 .md

在 /v1 的请求中声明平台的工具后,模型请求这些工具时由平台执行,结果接入上下文后再次调用模型,直到模型作答,最后返回一个完整的响应。调用方无需实现工具循环。

接口声明写法响应中的工具调用
POST https://api.scirouter.cn/v1/chat/completionstools 中一项 type: "mcp"不出现在 tool_calls 中,记录在扩展字段 scirouter.tool_calls
POST https://api.scirouter.cn/v1/messagesmcp_servers + tools 中的 mcp_toolset,带 beta 请求头mcp_tool_use 与 mcp_tool_result 内容块
POST https://api.scirouter.cn/v1/responsestools 中一项 type: "mcp"mcp_list_tools 与 mcp_call 输出项

可用的工具、入参与出参、按用户计的限额与数据流向与 MCP 服务端相同,见 MCP 服务端与工具「工具」。任何支持函数调用的模型均可使用托管工具。

声明

#

对话补全

#
json
{
  "model": "YOUR_MODEL_ID",
  "messages": [{ "role": "user", "content": "近一年钙钛矿封装稳定性有哪些新进展?给出处。" }],
  "tools": [
    { "type": "mcp", "server_label": "scirouter", "allowed_tools": ["web_search", "fetch_page"], "require_approval": "never" }
  ],
  "scirouter": { "max_tool_rounds": 6 }
}

tools 中加入一项 type: "mcp"。该写法沿用 OpenAI Responses 的远程 MCP 工具,官方 SDK 不会拒绝。

字段说明
type固定为 "mcp"。tools 中只能有一项 type: "mcp";调用方自己的 function 工具可同时存在
server_label只接受 "scirouter",其他取值返回 400
allowed_tools可省略,省略时为本次部署开放的全部工具。写成字符串数组或 { "tool_names": [...] }。为空数组时返回 400;含不存在的工具名时返回 400,details.available 列出可用的工具
server_url不接受,写了返回 400。外部 MCP 服务器在调用方自己的客户端中连接
require_approval只能为 "never" 或不填

Messages

#
http
POST https://api.scirouter.cn/v1/messages
anthropic-beta: mcp-client-2025-11-20
json
{
  "model": "YOUR_MODEL_ID",
  "max_tokens": 4096,
  "messages": [{ "role": "user", "content": "近一年钙钛矿封装稳定性有哪些新进展?给出处。" }],
  "mcp_servers": [{ "type": "url", "url": "https://api.scirouter.cn/mcp", "name": "scirouter" }],
  "tools": [
    {
      "type": "mcp_toolset",
      "mcp_server_name": "scirouter",
      "default_config": { "enabled": false },
      "configs": { "web_search": { "enabled": true }, "fetch_page": { "enabled": true } }
    }
  ],
  "scirouter": { "max_tool_rounds": 6 }
}

写法沿用 Anthropic 的 MCP connector。

位置规则
请求头 anthropic-beta含 mcp-client-2025-11-20 或 mcp-client-2026-09-15。已弃用的 mcp-client-2025-04-04 也接受,此时工具选择写在 mcp_servers[].tool_configuration(enabled、allowed_tools)。都没有时返回 400
mcp_servers[]只接受一项 name: "scirouter",type 为 "url",url 为 https 且路径为 /mcp(写 https://api.scirouter.cn/mcp)。平台只按这些字段识别声明,不比对域名、不连接该地址。authorization_token 可省略,写了也不使用
tools[] 中的 mcp_toolset正好一项,mcp_server_name 为 "scirouter"。每个工具是否开启依次取 configs.<工具名>.enabled、default_config.enabled,都没写时开启;configs 中不存在的工具名不报错
不支持defer_loading 与 mcp_toolset.tools(固定的工具列表),写了返回 400
其他 MCP 服务器name 不是 scirouter 的服务器返回 400,details.reason 为 server_tool_unsupported

POST /messages/count_tokens 可携带同样的声明,见 Messages「统计 token 数」。

Responses

#
json
{
  "model": "YOUR_MODEL_ID",
  "input": "近一年钙钛矿封装稳定性有哪些新进展?给出处。",
  "tools": [
    { "type": "mcp", "server_label": "scirouter", "allowed_tools": ["web_search", "fetch_page"], "require_approval": "never" }
  ],
  "scirouter": { "max_tool_rounds": 6 }
}
  • tools 中的 mcp 项与对话补全的规则相同。server_label 不是 scirouter 时返回 400,details.reason 为 server_tool_unsupported。headers、authorization、server_description 不使用。
  • tool_choice 可写 { "type": "mcp", "server_label": "scirouter", "name": "web_search" }:带 name 时要求模型调用该工具,不带时要求模型调用一个工具。name 不是本次开启的托管工具时返回 400。响应中的 tool_choice 与请求原文相同。
  • max_tool_calls 对托管工具不起作用。

轮数上限

#

三种格式都接受顶层扩展字段 scirouter:

字段说明
scirouter.max_tool_rounds1–30 的整数,缺省 6。带工具调用模型的轮数上限,到达后的处理见执行流程
  • 顶层 scirouter 只接受 max_tool_rounds,写了其他键返回 400。未声明托管工具却写了 max_tool_rounds,同样返回 400。
  • 使用 OpenAI 官方 Python SDK 时,将 scirouter 放入 extra_body,SDK 会将其合并到请求体顶层。
  • 本次部署未开放托管工具时,声明返回 400。调用方自己的函数(Messages 的自定义工具)与开启的托管工具重名时返回 400,错误信息中写明名称。

执行流程

#
  1. 平台把开启的托管工具展开成函数定义,追加在调用方的工具之后,调用模型。工具描述按请求头 Accept-Language 选择语言:以 en 开头时为英文,其余为中文。
  2. 模型只请求托管工具时,平台执行这些工具,结果按模型给出的顺序接入上下文,再调用模型。同一轮最多 4 个工具同时执行。
  3. 模型请求调用方自己的函数时,循环结束,该轮返回调用方;调用方执行后发送下一轮,与不使用托管工具时相同。同一轮也请求了托管工具时,托管工具不执行(状态为 skipped),调用方回复后模型会重新请求。
  4. 执行过一轮托管工具后,要求必须调用工具或指名某个托管工具的 tool_choice 改为 auto。
  5. 达到 max_tool_rounds 后,平台再调用一次模型:工具定义照带,tool_choice 设为不调用工具,模型根据已有资料作答,因此请求总能得到回答。这一轮模型仍请求托管工具时不执行,状态为 skipped。
  6. 带托管工具的请求只发往支持工具调用的线路。模型没有支持工具调用的线路时返回 503 model_unavailable(同对话补全),不退回文本协议。

工具失败与限频

#

下列情况不报错,循环照常继续:原因作为该次工具调用的结果交回模型,状态为 failed,由模型决定重试或换用其他方法。

情况交回模型的结果
入参不符合工具的 schema、工具不存在哪个参数不合法、为什么;该次不执行
被限频(按用户计的核对、找先例次数,见 MCP 服务端与工具「限额与错误码」)「调用太频繁,这次没有执行:稍后再试或换个办法」
收费工具遇到余额不足或达到消费上限原因;该次不执行
工具已执行但未成功(网站无法打开、被策略拒绝、库中没有该记录)原因

MCP 服务端按 Key 计的两项限额不作用于托管工具。平台内部出错时,同一轮的其他工具调用被取消,整个请求返回错误。

响应

#

对话补全的响应

#

响应仍为 OpenAI 格式。托管工具的调用不出现在 choices[].message.tool_calls 中,顶层 scirouter 扩展字段(见可观测性)增加 tool_rounds 与 tool_calls。以下示例省略 choices 与 usage:

json
{
  "scirouter": {
    "request_id": "req_…",
    "cost_quota": 23180,
    "tool_rounds": 3,
    "tool_calls": [
      { "round": 0, "id": "call_…", "name": "web_search", "status": "done", "summary": "web 8 条", "ms": 1320 },
      { "round": 1, "id": "call_…", "name": "fetch_page", "status": "failed", "summary": "读网页失败:不允许的地址", "ms": 45 }
    ]
  }
}

数值为示例。

字段说明
tool_rounds调用模型的次数
tool_calls每项为一次托管工具调用。round 从 0 起,与请求日志的 v1_tool_round 标签口径相同;status 为 done / failed / skipped。不含入参与正文
cost_quota各轮模型调用之和,不含工具费,见计费
request_id每轮使用不同的 request_id,此处为最后一轮的

usage 为各轮之和,prompt_tokens_details 等嵌套字段逐项相加。

Messages 的响应

#

响应为一条 message:每个执行了托管工具的轮次依次给出模型的内容块(托管工具的 tool_use 换成 mcp_tool_use)与各次调用的 mcp_tool_result,最后是最后一轮的内容块。以下示例省略 usage:

json
{
  "id": "msg_…",
  "type": "message",
  "role": "assistant",
  "content": [
    { "type": "mcp_tool_use", "id": "toolu_…", "name": "web_search", "server_name": "scirouter", "input": { "query": "钙钛矿 封装 稳定性" } },
    { "type": "mcp_tool_result", "tool_use_id": "toolu_…", "is_error": false, "content": [{ "type": "text", "text": "网页搜索「钙钛矿 封装 稳定性」,8 条:…" }] },
    { "type": "text", "text": "近一年…" }
  ],
  "stop_reason": "end_turn",
  "scirouter": { "request_id": "req_…", "cost_quota": 23180, "tool_rounds": 2, "tool_calls": [{ "round": 0, "id": "toolu_…", "name": "web_search", "status": "done", "summary": "web 8 条", "ms": 1320 }] }
}

数值为示例。

字段说明
id第一轮的 id
mcp_tool_result.is_error为 true 时该次调用的状态为 failed,content[0].text 为原因
usage各轮之和;usage.iterations 逐轮列出每轮的用量
scirouter与对话补全的扩展字段相同
  • 状态为 skipped 的托管调用不出现在 content 中;去掉后不剩工具调用时,stop_reason 为 end_turn。
  • 继续对话时,将整条助手消息原样放回 messages。平台把其中 server_name 为 scirouter 的 mcp_tool_use 与对应的 mcp_tool_result 还原成普通的工具调用往返,再发给模型。

Responses 的响应

#

output 开头一项 mcp_list_tools,列出本次给模型的托管工具;每次执行一项 mcp_call;最后是最后一轮的输出项。以下示例省略 usage:

json
{
  "id": "resp_…",
  "object": "response",
  "output": [
    { "id": "mcpl_req_…", "type": "mcp_list_tools", "server_label": "scirouter", "tools": [{ "name": "web_search", "description": "…", "input_schema": { "type": "object" }, "annotations": { "readOnlyHint": true, "destructiveHint": false, "idempotentHint": true, "openWorldHint": true } }] },
    { "id": "call_…", "type": "mcp_call", "server_label": "scirouter", "name": "web_search", "arguments": "{\"query\":\"钙钛矿 封装 稳定性\"}", "approval_request_id": null, "status": "completed", "output": "网页搜索「钙钛矿 封装 稳定性」,8 条:…", "error": null },
    { "type": "message", "role": "assistant", "content": [{ "type": "output_text", "text": "近一年…" }] }
  ],
  "scirouter": { "request_id": "req_…", "cost_quota": 23180, "tool_rounds": 2, "tool_calls": [{ "round": 0, "id": "call_…", "name": "web_search", "status": "done", "summary": "web 8 条", "ms": 1320 }] }
}

数值为示例。

字段说明
id第一轮的 id
mcp_list_toolstools[] 含 name、description、input_schema 与 annotations。input 中已有 server_label 为 scirouter 的 mcp_list_tools 时不再列出
mcp_call.id模型给出的调用 id(call_…)
mcp_call.statuscompleted 或 failed。failed 时 output 为 null,error 见下表
usage各轮之和
tools / tool_choice与请求原文相同
scirouter与对话补全的扩展字段相同
error.type情况内容
mcp_tool_execution_error工具已执行但未成功、余额不足content[0].text 为原因
mcp_protocol_error入参不合法、工具不存在code 为 -32602,message 为原因
mcp_protocol_error被限频code 为 -32000,message 为原因
  • 状态为 skipped 的托管调用不出现在 output 中。
  • 继续对话时,将 output 原样放入下一次请求的 input。平台把 mcp_call 还原成 function_call 与 function_call_output,去掉 mcp_list_tools。

日志与缓存

#
  • 控制台中每轮记录一条请求日志,标签为 v1_tool_round;请求的 metadata 已有 8 个键时不添加该标签。
  • 带托管工具的请求不进入响应缓存(结果随网页内容变化),Idempotency-Key 照常生效。

流式响应

#

对话补全的流式响应

#
  • 中间轮的正文照常流出;托管工具的 tool_calls 增量不下发。
  • 每次工具开始与结束各发送一个 choices: [] 的分片,scirouter.tool 为该次工具调用:开始分片的 status 为空、ms 为 0,结束分片带 status / summary / ms。该机制与可观测性中的扩展分片相同,官方 SDK 会跳过这些分片。
  • [DONE] 之前的收尾分片带各轮合计;末尾的 usage 分片同样为各轮之和。
  • 扩展分片沿用该流第一个上游分片的 id / created / model。
text
data: {"id":"chatcmpl-…","object":"chat.completion.chunk","choices":[],"scirouter":{"tool":{"round":0,"id":"call_…","name":"web_search","status":"","ms":0}}}
data: {"id":"chatcmpl-…","object":"chat.completion.chunk","choices":[],"scirouter":{"tool":{"round":0,"id":"call_…","name":"web_search","status":"done","summary":"web 8 条","ms":1320}}}
data: {"id":"chatcmpl-…","object":"chat.completion.chunk","choices":[{"index":0,"delta":{"content":"近一年…"}}]}
data: {"id":"chatcmpl-…","object":"chat.completion.chunk","choices":[],"scirouter":{"request_id":"req_…","tool_rounds":3,"cost_quota":23180,"tool_calls":[…]}}
data: [DONE]

Messages 的流式响应

#
  • 整个循环是一条 message:message_start 只发送一次,内容块的 index 按下发顺序连续编号。
  • 托管工具调用以 mcp_tool_use 块下发:content_block_start(input 为 {})→ input_json_delta → content_block_stop。每次执行完发送一个 mcp_tool_result 块,content_block_start 带完整内容。一轮有多个托管调用时,先是各 mcp_tool_use,再是各 mcp_tool_result,顺序相同。
  • 只有最后一轮发送 message_delta 与 message_stop:message_delta 的 usage 为各轮之和并带 iterations,message_stop 带 scirouter 字段。

Responses 的流式响应

#
  • response.created 与 response.in_progress 只发送一次。随后是 mcp_list_tools 项:response.output_item.added → response.mcp_list_tools.in_progress → response.mcp_list_tools.completed → response.output_item.done。
  • 每次托管调用:response.output_item.added(mcp_call)→ response.mcp_call_arguments.delta → response.mcp_call_arguments.done → response.mcp_call.in_progress → response.mcp_call.completed 或 response.mcp_call.failed → response.output_item.done(带结果)。
  • output_index 按下发顺序编号,sequence_number 全程递增。
  • 只有最后一轮发送终态事件(response.completed / response.incomplete):response.output 为下发过的全部输出项,id 为第一轮的,usage 为各轮之和,事件顶层带 scirouter 字段。

计费

#
  • 每一轮按普通模型调用计费,cost_quota 为各轮之和。
  • web_search、fetch_page 读到的 PDF 与 run_code 另按平台服务计费,由调用所用 Key 的账户承担,计入该 Key 的月度上限,不计入 cost_quota。计费方式见 MCP 服务端与工具「计费」。
  • 控制花费:调小 max_tool_rounds;用 allowed_tools(Messages 用 configs)只开启需要的工具。

相关

#
  • 开始

  • 接入编程工具

  • 接口

  • 专题

  • 网页端指南

↑ ↓ 选择 · Enter 打开 · Esc 关闭

请验证你的身份

为了保护你的账户,这个操作需要再验证一次。

验证码已发送到你绑定的手机号。5 分钟内的其他敏感操作不会再问。

Cookie 偏好

您可以随时回到这里修改。页脚有常驻入口。

必要

维持登录状态、记住主题与语言偏好。没有它们本站无法正常工作,因此无法关闭。

统计

了解哪些功能有人用、用户在哪一步流失。只收集维度(页面、操作类型、计数),不收集您输入的任何内容。

本站不加载任何第三方统计脚本,也不做会话录屏。完整说明