api

工具调用与结构化输出 API

直接答案tools 只让模型提出结构化调用,应用仍需鉴权、校验和执行;strict 结构化输出约束模型响应,但业务数据仍必须再次验证。

更新 · 审核信息

小白:模型提议,应用执行

工具调用不是把服务器权限交给模型。请求中的 tools 描述允许的函数和参数;模型返回工具调用后,应用先验证用户身份、租户权限、工具名和参数,再执行真实操作,并把工具结果送回下一轮。结构化输出则用 JSON Schema 约束最终答案形状,适合抽取、分类和表单生成;两者都不能替代业务规则。

调用前先在令牌管理创建本站 API Key,再打开模型广场,分别确认模型详情明确列出 /v1/responses/v1/chat/completions。模型名称相似不代表支持同一个端点:

export BASE_URL="https://api.tu-zi.com"
export API_KEY="你的本站 API Key"
export RESPONSES_MODEL_NAME="从模型广场复制、且支持 /v1/responses 的精确模型 ID"
export CHAT_MODEL_NAME="从模型广场复制、且支持 /v1/chat/completions 的精确模型 ID"

BASE_URL 不包含末尾的 /v1。下面的两个结构化输出示例分别对应两个端点,请不要把其中一套外层结构直接复制到另一套请求中。

最小工具调用请求

tool_response=$(curl -sS "$BASE_URL/v1/responses" \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d @- <<JSON
  {
    "model": "$RESPONSES_MODEL_NAME",
    "input": "查询订单 A123 的配送状态",
    "tools": [{
      "type": "function",
      "name": "get_order_status",
      "description": "读取当前用户有权查看的订单状态",
      "parameters": {
        "type": "object",
        "properties": {"order_id": {"type": "string"}},
        "required": ["order_id"],
        "additionalProperties": false
      },
      "strict": true
    }]
  }
JSON
)

response_id=$(printf '%s' "$tool_response" | jq -r '.id')
call_id=$(printf '%s' "$tool_response" | jq -r '.output[] | select(.type == "function_call") | .call_id' | head -n 1)
test -n "$response_id" && test "$response_id" != "null"
test -n "$call_id" && test "$call_id" != "null"

响应可能包含函数调用项、调用 ID 和 JSON 参数。应用只接受预注册工具,解析后再次按 schema 校验,并确认订单属于当前用户。示例使用 jq 取出响应 ID 和原 call_id。业务系统执行查询后,再把结果回传给同一轮 Responses:

curl -sS "$BASE_URL/v1/responses" \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d @- <<JSON
{
  "model": "$RESPONSES_MODEL_NAME",
  "previous_response_id": "$response_id",
  "input": [{
    "type": "function_call_output",
    "call_id": "$call_id",
    "output": "订单 A123 已发货"
  }]
}
JSON

第二次响应才会基于工具结果继续生成最终回答,也可能提出新的工具调用。应用应重复“验证、执行、回传”,直到出现最终答案或达到步数上限。不要把模型生成的 ID、URL、命令或金额直接视为可信输入。

结构化输出:Responses API

Responses API 的结构化输出定义必须放在 text.format 中。下面是一个可直接复制的最小请求:

curl "$BASE_URL/v1/responses" \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d @- <<JSON
{
  "model": "$RESPONSES_MODEL_NAME",
  "input": "用户反馈:我已经付款,但余额没有到账。请整理成工单。",
  "text": {
    "format": {
      "type": "json_schema",
      "name": "ticket",
      "strict": true,
      "schema": {
        "type": "object",
        "properties": {
          "category": {"type": "string", "enum": ["billing", "technical"]},
          "summary": {"type": "string"},
          "needs_human_review": {"type": "boolean"}
        },
        "required": ["category", "summary", "needs_human_review"],
        "additionalProperties": false
      }
    }
  }
}
JSON

结构化输出:Chat Completions

Chat Completions 使用 response_format.json_schema,外层结构与 Responses API 不同:

curl "$BASE_URL/v1/chat/completions" \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d @- <<JSON
{
  "model": "$CHAT_MODEL_NAME",
  "messages": [{"role": "user", "content": "用户反馈:我已经付款,但余额没有到账。请整理成工单。"}],
  "response_format": {
    "type": "json_schema",
    "json_schema": {
      "name": "ticket",
      "strict": true,
      "schema": {
        "type": "object",
        "properties": {
          "category": {"type": "string", "enum": ["billing", "technical"]},
          "summary": {"type": "string"},
          "needs_human_review": {"type": "boolean"}
        },
        "required": ["category", "summary", "needs_human_review"],
        "additionalProperties": false
      }
    }
  }
}
JSON

即使返回了合法 JSON,也要继续验证日期范围、金额精度、实体存在和授权。模型拒绝、内容策略拦截、输出截断、协议错误和有效 JSON 必须分开处理。

安全执行和幂等

每个工具独立配置权限、超时、输入大小、网络出口和速率限制。数据库操作使用参数化查询;HTTP 工具使用目标允许列表并防 SSRF;代码执行置于最小权限沙箱。写操作要求应用幂等键与人工确认策略,模型重复相同调用 ID 时返回已存在结果,不能再次扣款或下单。工具输出也可能含提示注入,回传模型前应结构化、裁剪并标记为不可信数据。

错误、循环和可观测性

工具错误以结构化 {code,message,retryable} 返回,避免把堆栈和密钥交给模型。限制总步数、每工具次数、总 token、总费用和墙钟时间;检测相同参数循环。日志记录 trace、response ID、调用 ID、工具名、参数哈希、授权决策、耗时、状态和副作用 ID,对敏感参数脱敏。流式响应中函数参数可能分片,必须等完成事件后再解析和执行。

专家:Schema 演进与代理治理

工具和输出 schema 需要版本号;新增可选字段可向后兼容,删除或改语义要发布新版本并灰度。用录制的请求、工具结果和最终答案做回放评测,覆盖越权、重复执行、部分失败、超时、拒绝和模型升级。对高风险写操作采用策略引擎与人审,将“模型决定调用什么”和“系统允许执行什么”彻底分离;故障恢复以持久化状态机为准,而不是依赖模型记住之前发生的副作用。

适用场景

  • 让模型安全调用业务函数
  • 生成符合 JSON Schema 的结构化数据
  • 构建可恢复、可审计的多步代理循环

API 协议

  • /v1/responses
  • /v1/chat/completions

FAQ

模型返回工具调用后,工具会自动执行吗?

不会。模型只生成工具名和参数;应用必须鉴权、按 schema 校验、执行并把结果回传。禁止直接拼接到 shell、SQL 或 URL。

strict=true 就不需要业务校验了吗?

仍然需要。Schema 只能约束形状,不能证明库存、权限、金额、时间范围或业务状态正确。

工具失败后应该让模型无限重试吗?

不应该。设置总步数、单工具次数、截止时间和预算;确定性错误直接返回,临时错误才有限退避重试。

官方来源

  1. OpenAI Function Calling Guide Official
  2. OpenAI Structured Outputs Guide Official
  3. OpenAI Responses API Reference Official