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 只能约束形状,不能证明库存、权限、金额、时间范围或业务状态正确。
工具失败后应该让模型无限重试吗?
不应该。设置总步数、单工具次数、截止时间和预算;确定性错误直接返回,临时错误才有限退避重试。
关联指南
官方来源
- OpenAI Function Calling Guide Official
- OpenAI Structured Outputs Guide Official
- OpenAI Responses API Reference Official
兔子API