Chat Completions(OpenAI 兼容)
POST /v1/chat/completions — OpenAI Chat Completions,按场景给出完整示例
兼容 OpenAI Chat Completions。把 base_url 指向 ModelSite,即可用同一套代码调用 DeepSeek、GLM、Qwen、MiniMax 等已上线模型,无需改业务代码。鉴权和计费平台已处理。
本页按「场景」组织:先看下面的场景总览,再到对应小节看请求、响应和注意事项。每个示例都标注了证据:已实测表示用线上测试账号真实调用过(2026-10-19),响应字段取自真实返回,id、时间戳、思考文本等取值替换为占位;依官方文档(未实测)表示按 OpenAI 官方文档写成,我们没有真实调用验证。
响应里的内容取决于所选模型。例如 glm-5.3-flash 强制思考,响应里总会带 reasoning_content。响应只包含标准字段:上游自带的非标准字段(如 stop_reason、metrics)不会返回;system_fingerprint 仅在上游给出标准的 fp_ 开头值时保留,否则省略。
场景总览
场景划分参照 OpenAI 官方的 Chat Completions、Streaming、Function calling、Structured outputs、Images and vision、Reasoning、Prompt caching 等指南。
| 场景 | 官方是否提供 | 我们的情况 | 示例入口 |
|---|---|---|---|
基础对话(单轮、system) | 是 | 支持 | 基础对话 |
| 多轮对话(自己带历史) | 是 | 支持 | 多轮对话 |
| 流式输出 | 是 | 支持 | 流式输出 |
工具调用(单个、并行、tool_choice、回填结果、流式) | 是 | 支持 | 工具调用 |
结构化输出:json_object | 是 | 支持 | JSON 模式 |
结构化输出:json_schema | 是 | 支持(是否严格遵守 schema 由上游决定) | JSON Schema |
思考 / 推理(reasoning_effort) | 是 | 支持 | 思考 |
| 图像输入(视觉) | 是 | 部分支持:需视觉模型;base64 已实测,公网 URL 未实测,不支持 file_id | 图像输入 |
| 提示缓存 | 是(自动缓存) | 支持:缓存由上游自动完成,命中量在 usage 里 | 提示缓存 |
n、stop、seed、logprobs 等采样参数 | 是 | 支持(是否生效看上游) | 常用参数 |
联网搜索(web_search_options) | 是(仅搜索专用模型) | 不支持:该参数转发给上游,实测对已上线模型没有联网效果;个别模型有私有开关,见各厂商页 | — |
音频输入输出(modalities、audio) | 是 | 未接入:没有已上线的音频对话模型 | — |
预测输出(prediction) | 是 | 未接入:没有已上线模型声明支持,未验证 | — |
存储与评测(store、metadata、Stored completions、Batch) | 是 | 不支持:平台不保存请求与响应,也没有 Batch 接口 | — |
基础对话
何时用:一问一答,或用 system 消息设定角色和语气。
证据:已实测(线上测试账号,2026-10-19)。
请求
curl https://api.modelsite.ai/v1/chat/completions \
-H "Authorization: Bearer $MODELSITE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "glm-5.3-flash",
"messages": [{"role": "user", "content": "用一句话解释量子纠缠"}],
"max_tokens": 1500
}'model 必填且区分大小写(计费与路由都依赖它)。思考模型的思考也算在 max_tokens 里,设得太小会在思考阶段就被截断(finish_reason 为 length,content 为空)。
响应
取回复文本:choices[0].message.content;结束原因看 finish_reason(stop / length / tool_calls / content_filter);用量看 usage。
{
"id": "chatcmpl-xxxx",
"object": "chat.completion",
"created": 1760000000,
"model": "glm-5.3-flash",
"choices": [
{
"finish_reason": "stop",
"index": 0,
"message": {
"role": "assistant",
"content": "量子纠缠是指两个粒子形成一种特殊的量子关联,使得无论它们相距多远,测量其中一个粒子的状态都会瞬间确定另一个粒子的对应状态。\n\n(注意:这种“瞬间关联”并不能用来超光速传递信息。)",
"refusal": null,
"reasoning_content": "The user is asking me to explain quantum entanglement in one sentence… (思考文本,已省略)"
}
}
],
"usage": {
"prompt_tokens": 17,
"completion_tokens": 642,
"total_tokens": 659,
"prompt_tokens_details": {
"cached_tokens": 0,
"created_cache_tokens": 0
},
"completion_tokens_details": {
"reasoning_tokens": 591,
"audio_tokens": 0,
"accepted_prediction_tokens": 0,
"rejected_prediction_tokens": 0
}
},
"system_fingerprint": "fp_xxxx"
}注意事项
usage里的*_details字段随上游而不同,没有对应用量时通常为 0。默认不返回费用字段(见下方「平台扩展」)。- 部分上游自有的用量字段(如 DeepSeek 的
prompt_cache_hit_tokens)会原样出现在usage中;名字含cost/price的上游字段会被平台隐去。 - 下面的接口卡片由 OpenAPI 规范自动渲染:HTTP 方法与路径、可交互的 Request body 参数表、Response schema。
Authorization
BearerAuth Authorization: Bearer $MODELSITE_API_KEY
In: header
Request Body
application/json
TypeScript Definitions
Use the request body type in TypeScript.
Response Body
application/json
application/json
application/json
application/json
application/json
curl -X POST "https://example.com/chat/completions" \ -H "Content-Type: application/json" \ -d '{ "model": "string", "messages": [ { "role": "system" } ] }'取回复:choices[0].message.content;思考在 reasoning_content;用量:usage。取自线上真实响应(glm-5.3-flash,2026-10-19),id、时间戳等为占位。
{ "id": "chatcmpl-xxxx", "object": "chat.completion", "created": 1760000000, "model": "glm-5.3-flash", "choices": [ { "finish_reason": "stop", "index": 0, "message": { "role": "assistant", "content": "量子纠缠是指两个粒子形成一种特殊的量子关联,使得无论它们相距多远,测量其中一个粒子的状态都会瞬间确定另一个粒子的对应状态。\n\n(注意:这种“瞬间关联”并不能用来超光速传递信息。)", "refusal": null, "reasoning_content": "The user is asking me to explain quantum entanglement in one sentence, in Chines…(已省略)" }, "stop_reason": 154827 } ], "usage": { "prompt_tokens": 17, "completion_tokens": 642, "total_tokens": 659, "prompt_tokens_details": { "cached_tokens": 0, "created_cache_tokens": 0 }, "completion_tokens_details": { "reasoning_tokens": 591, "audio_tokens": 0, "accepted_prediction_tokens": 0, "rejected_prediction_tokens": 0 } }, "system_fingerprint": "fp_xxxx"}多轮对话
何时用:需要上下文的连续对话。平台不保存对话,每次请求都要把完整历史放进 messages。
证据:依官方文档(未实测)。带工具的多轮(含 assistant 历史与 tool 消息)已实测,见工具调用。
请求
curl https://api.modelsite.ai/v1/chat/completions \
-H "Authorization: Bearer $MODELSITE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "glm-5.3-flash",
"messages": [
{"role": "system", "content": "用中文回答,简洁"},
{"role": "user", "content": "什么是量子纠缠?"},
{"role": "assistant", "content": "两个粒子的状态相互关联,与距离无关。"},
{"role": "user", "content": "它能用来超光速通信吗?"}
],
"max_tokens": 1500
}'响应:与基础对话相同的结构。
注意事项
messages[].role = "developer"会被改写成system。- 回传 assistant 历史时,部分思考模型还需要带上
reasoning_content,见思考。
流式输出
何时用:逐 token 展示、降低首字延迟。
证据:已实测(线上测试账号,2026-10-19)。
请求
curl -N https://api.modelsite.ai/v1/chat/completions \
-H "Authorization: Bearer $MODELSITE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "glm-5.3-flash",
"messages": [{"role": "user", "content": "只回复一个字:好"}],
"max_tokens": 600,
"reasoning_effort": "low",
"stream": true
}'响应
每个 data: 行是一个 JSON;增量文本拼接 choices[0].delta.content;以 data: [DONE] 结束。
data: {"id":"chatcmpl-stream-xxxx","object":"chat.completion.chunk","created":1760000000,"model":"glm-5.3-flash","choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning_content":""}}]}
data: {"id":"chatcmpl-stream-xxxx","object":"chat.completion.chunk","created":1760000000,"model":"glm-5.3-flash","choices":[{"index":0,"delta":{"content":"好"}}]}
data: {"id":"chatcmpl-stream-xxxx","object":"chat.completion.chunk","created":1760000000,"model":"glm-5.3-flash","choices":[{"delta":{},"finish_reason":"stop","index":0}]}
data: {"id":"chatcmpl-stream-xxxx","object":"chat.completion.chunk","created":1760000000,"model":"glm-5.3-flash","choices":[],"usage":{"prompt_tokens":18,"completion_tokens":3,"total_tokens":21,"prompt_tokens_details":{"cached_tokens":0,"created_cache_tokens":0},"completion_tokens_details":{"reasoning_tokens":0,"audio_tokens":0,"accepted_prediction_tokens":0,"rejected_prediction_tokens":0}},"system_fingerprint":"fp_xxxx"}
data: [DONE]注意事项
- 不传
stream_options时平台自动开启include_usage,用量在最后一个choices为空数组的块里;读取choices[0]前先判断长度。部分上游把usage放在最后一个内容块里,以usage非空为准。 - 思考模型在开启思考时,思考增量先到:
delta.reasoning_content,之后才是delta.content。 - 流已经开始输出后失败,HTTP 状态码已是 200,错误作为流内事件发出,见下方「错误」。
工具调用
何时用:让模型决定调用你定义的函数(查询天气、查库、调用内部接口)。流程是:声明 tools → 模型返回 tool_calls → 你执行函数 → 回填 tool 消息 → 模型给出最终回答。
证据:已实测(线上测试账号,2026-10-19):单个调用、回填结果、并行调用、指定函数、流式。tool_choice: "required" / "none"、parallel_tool_calls: false 依官方文档(未实测)。
请求(第一轮)
curl https://api.modelsite.ai/v1/chat/completions \
-H "Authorization: Bearer $MODELSITE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "glm-5.3-flash",
"messages": [{"role": "user", "content": "杭州明天天气怎么样?"}],
"tools": [{
"type": "function",
"function": {
"name": "get_weather",
"description": "Get the current weather for a city",
"parameters": {
"type": "object",
"properties": {"city": {"type": "string"}},
"required": ["city"]
}
}
}],
"max_tokens": 1500
}'响应(第一轮)
模型要调工具时 finish_reason 为 tool_calls;arguments 是 JSON 字符串,需自行解析。是否同时带 content 因模型而异(本例为 null,并行例子里带了一句文字)。
{
"id": "chatcmpl-xxxx",
"object": "chat.completion",
"created": 1760000000,
"model": "glm-5.3-flash",
"choices": [
{
"finish_reason": "tool_calls",
"index": 0,
"message": {
"role": "assistant",
"content": null,
"refusal": null,
"tool_calls": [
{
"id": "chatcmpl-tool-xxxxxxxx",
"type": "function",
"function": {
"name": "get_weather",
"arguments": "{\"city\": \"杭州\"}"
}
}
],
"reasoning_content": "The user is asking about the weather in Hangzhou tomorrow… (已省略)"
}
}
],
"usage": {
"prompt_tokens": 160,
"completion_tokens": 77,
"total_tokens": 237,
"prompt_tokens_details": {
"cached_tokens": 0,
"created_cache_tokens": 0
},
"completion_tokens_details": {
"reasoning_tokens": 65,
"audio_tokens": 0,
"accepted_prediction_tokens": 0,
"rejected_prediction_tokens": 0
}
},
"system_fingerprint": "fp_xxxx"
}回填工具结果(第二轮)
把 assistant 消息原样加回历史,再追加一条 tool 消息,用 tool_call_id 对应。思考模型的 assistant 消息里如果有 reasoning_content,也一起放回(见思考)。
curl https://api.modelsite.ai/v1/chat/completions \
-H "Authorization: Bearer $MODELSITE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "glm-5.3-flash",
"messages": [
{"role": "user", "content": "杭州明天天气怎么样?"},
{"role": "assistant", "content": null, "tool_calls": [
{"id": "chatcmpl-tool-xxxxxxxx", "type": "function",
"function": {"name": "get_weather", "arguments": "{\"city\": \"杭州\"}"}}
]},
{"role": "tool", "tool_call_id": "chatcmpl-tool-xxxxxxxx", "content": "多云 7~13°C"}
],
"tools": [ ... 同第一轮 ... ],
"max_tokens": 2000
}'第二轮响应是普通的成功响应(已实测,finish_reason 为 stop):
{
"id": "chatcmpl-xxxx",
"object": "chat.completion",
"created": 1760000000,
"model": "glm-5.3-flash",
"choices": [
{
"finish_reason": "stop",
"index": 0,
"message": {
"role": "assistant",
"content": "杭州明天天气多云,气温在 7~13°C 之间。早晚较凉,建议适当添衣保暖哦。",
"refusal": null
}
}
],
"usage": {
"prompt_tokens": 182,
"completion_tokens": 28,
"total_tokens": 210
},
"system_fingerprint": "fp_xxxx"
}并行调用:一次请求里问两个城市,模型在同一条 assistant 消息里返回两个 tool_calls(已实测)。每个调用都要回填一条对应 tool_call_id 的 tool 消息。
"message": {
"role": "assistant",
"content": "我来为您查询杭州和北京的当前天气。",
"tool_calls": [
{"id": "chatcmpl-tool-xxxxxxxx", "type": "function", "function": {"name": "get_weather", "arguments": "{\"city\": \"杭州\"}"}},
{"id": "chatcmpl-tool-yyyyyyyy", "type": "function", "function": {"name": "get_weather", "arguments": "{\"city\": \"北京\"}"}}
]
}指定函数:"tool_choice": {"type": "function", "function": {"name": "get_weather"}} 会强制模型调用该函数,即使用户只说了「你好」(已实测,返回了一个 get_weather 调用,content 为空字符串)。
流式工具调用:首块带 id 与 name,参数在后续块里按 index 拼接(已实测)。本例上游把整段参数放在一个块里,其他模型可能拆成多个片段。
data: {"id":"chatcmpl-stream-xxxx","object":"chat.completion.chunk","created":1760000000,"model":"glm-5.3-flash","choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"id":"chatcmpl-tool-xxxxxxxx","type":"function","function":{"name":"get_weather"}}]}}]}
data: {"id":"chatcmpl-stream-xxxx","object":"chat.completion.chunk","created":1760000000,"model":"glm-5.3-flash","choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"{\"city\": \"杭州\"}"}}]}}]}
data: {"id":"chatcmpl-stream-xxxx","object":"chat.completion.chunk","created":1760000000,"model":"glm-5.3-flash","choices":[{"delta":{},"finish_reason":"tool_calls","index":0}]}
... (usage 块与 [DONE] 同基础流式)注意事项
parallel_tool_calls只有同时传了tools才会转发给上游。functions/function_call(官方已废弃的旧字段)不会被转成tools/tool_choice,请直接用tools。strict: true等 schema 约束原样转给上游,是否严格遵守由上游决定。
JSON 模式(json_object)
何时用:只要求输出是合法 JSON,不约束字段。
证据:已实测(线上测试账号,2026-10-19)。
请求
curl https://api.modelsite.ai/v1/chat/completions \
-H "Authorization: Bearer $MODELSITE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "glm-5.3-flash",
"messages": [{"role": "user", "content": "以 JSON 返回北京的名称和人口(万),键为 city 和 population"}],
"response_format": {"type": "json_object"},
"max_tokens": 2000
}'响应(message.content 即 JSON 文本,其余字段同基础对话)
"message": {
"role": "assistant",
"content": "{\n \"city\": \"北京\",\n \"population\": 2189\n}",
"refusal": null,
"reasoning_content": "… (已省略)"
}注意事项:官方要求提示词里出现「JSON」字样,建议照做。json_object 只保证语法合法,不保证字段;需要字段约束用下一节。
结构化输出(json_schema)
何时用:要求输出严格符合你给定的 JSON Schema。
证据:已实测(线上测试账号,2026-10-19)。
请求
curl https://api.modelsite.ai/v1/chat/completions \
-H "Authorization: Bearer $MODELSITE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "glm-5.3-flash",
"messages": [{"role": "user", "content": "提取:张三,28岁,住在上海"}],
"response_format": {
"type": "json_schema",
"json_schema": {
"name": "person",
"strict": true,
"schema": {
"type": "object",
"properties": {
"name": {"type": "string"},
"age": {"type": "integer"},
"city": {"type": "string"}
},
"required": ["name", "age", "city"],
"additionalProperties": false
}
}
},
"max_tokens": 2000
}'响应
"message": {
"role": "assistant",
"content": "{\n \"age\": 28,\n \"city\": \"上海\",\n \"name\": \"张三\"\n}",
"refusal": null,
"reasoning_content": "… (已省略)"
}注意事项
- 本例输出符合 schema,字段顺序不保证(本例按字母序)。
- 平台把
response_format原样转给上游,不在平台侧校验输出;strict是否由上游强制,因上游而异。收到结果后仍建议自己校验。 finish_reason为length时输出可能被截断,解析前先检查。
思考(thinking / reasoning)
何时用:需要模型先推理再回答,或需要控制推理强度。
证据:已实测(线上测试账号,2026-10-19):glm-5.3-flash 默认返回思考,reasoning_effort: "low" 时思考几乎为空。reasoning 对象、thinking 的其他取值依官方或厂商文档(未实测)。
请求
curl https://api.modelsite.ai/v1/chat/completions \
-H "Authorization: Bearer $MODELSITE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "glm-5.3-flash",
"messages": [{"role": "user", "content": "只回复一个字:好"}],
"reasoning_effort": "low",
"max_tokens": 600
}'响应
默认情况下思考在 message.reasoning_content(流式在 delta.reasoning_content,先于正文到达),思考的 token 数见 usage.completion_tokens_details.reasoning_tokens,完整真实响应见基础对话(reasoning_tokens 为 591)。reasoning_effort: "low" 时实测 reasoning_tokens 为 0,响应里没有思考文本(见流式输出的响应)。
注意事项
- 平台不会默认开启或关闭思考,也不会替你补
reasoning_effort:你传什么转发什么;不传则由上游模型默认行为决定。唯一例外:GPT / o 系列模型收到thinking时,会换算成reasoning_effort(low/medium/high)。 thinking、enable_thinking等不是 OpenAI 标准字段,Python SDK 里放extra_body。各厂商的取值见 DeepSeek、GLM、Qwen、MiniMax。- 请求里的 OpenRouter 风格
reasoning对象会被归一化:reasoning.effort→reasoning_effort,reasoning.max_tokens→thinking.budget_tokens,reasoning.effort = "none"→thinking: disabled,reasoning.enabled = true且无其他字段 →reasoning_effort: medium。对 GLM-5.3 等不接受medium的模型,请直接传上游支持的reasoning_effort,不要用reasoning.enabled。 - 多轮回传:DeepSeek(带
tools时必须)、GLM、Qwen、MiniMax 的模型会读取历史 assistant 消息里的reasoning_content,平台原样转发,你的客户端需要把上一轮返回的值放回历史;其他模型会丢弃该字段。(此行为依赖尚未发布的代码。)
图像输入(视觉)
何时用:让视觉模型看图回答。需要选支持图像输入的模型(如 qwen3-vl-plus);纯文本模型传图会被上游拒绝或忽略。
证据:base64 图片已实测(线上测试账号,2026-10-19,qwen3-vl-plus);公网 URL 形式依官方文档(未实测)。
请求
curl https://api.modelsite.ai/v1/chat/completions \
-H "Authorization: Bearer $MODELSITE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "qwen3-vl-plus",
"messages": [{
"role": "user",
"content": [
{"type": "text", "text": "这张图里有什么?一句话回答。"},
{"type": "image_url", "image_url": {"url": "data:image/png;base64,iVBORw0KGgo..."}}
]
}],
"max_tokens": 300
}'响应
{
"id": "chatcmpl-xxxx",
"object": "chat.completion",
"created": 1760000000,
"model": "qwen3-vl-plus",
"choices": [
{
"index": 0,
"message": {
"role": "assistant",
"content": "图中是一个红色的实心圆。",
"refusal": null,
"reasoning_content": ""
},
"finish_reason": "stop"
}
],
"usage": {
"prompt_tokens": 82,
"completion_tokens": 10,
"total_tokens": 92,
"prompt_tokens_details": { "cached_tokens": 0, "text_tokens": 16, "image_tokens": 66 },
"completion_tokens_details": {
"reasoning_tokens": 0,
"audio_tokens": 0,
"accepted_prediction_tokens": 0,
"rejected_prediction_tokens": 0,
"text_tokens": 10
}
}
}注意事项
- 图像按输入 token 计费,分模态用量见
usage.prompt_tokens_details(image_tokens)。 - 公网 URL 要求上游能访问到;不确定时用 base64。各模型对图片尺寸、数量、视频输入的限制见各厂商页。
image_url.detail保留并转发;image_url.format、file.format是非标准子字段,转发前会被删除。- 不支持 OpenAI 的
file_id(Files API)。
提示缓存
何时用:多次请求共享很长的前缀(系统提示、文档、工具定义)时降低成本和延迟。
证据:已实测(线上测试账号,2026-10-19,deepseek-v4.1-flash):同一个约 2900 token 的前缀连续请求两次,第二次命中 2816 token。
OpenAI 的缓存是自动的,没有请求参数。我们同样不需要你做任何事:缓存由上游自动完成,平台只把命中量放进 usage.prompt_tokens_details.cached_tokens。
请求:把稳定内容放在 messages 开头,变化的内容放最后,连续发两次相同前缀的请求。
curl https://api.modelsite.ai/v1/chat/completions \
-H "Authorization: Bearer $MODELSITE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "deepseek-v4.1-flash",
"messages": [
{"role": "system", "content": "你是客服助手。参考以下条款回答问题:\n(此处是约 2900 token 的长文本)"},
{"role": "user", "content": "第3条说了什么?一句话。"}
],
"max_tokens": 300,
"reasoning_effort": "low"
}'响应(只列 usage;第一次请求)
"usage": {
"prompt_tokens": 2903,
"completion_tokens": 82,
"total_tokens": 2985,
"prompt_tokens_details": { "cached_tokens": 0 },
"completion_tokens_details": { "reasoning_tokens": 57 }
}第二次请求(命中):
"usage": {
"prompt_tokens": 2903,
"completion_tokens": 123,
"total_tokens": 3026,
"prompt_tokens_details": { "cached_tokens": 2816 },
"completion_tokens_details": { "reasoning_tokens": 98 }
}注意事项
- 命中与否、最小可缓存长度、保留时间都由上游决定,
cached_tokens是上游报告的数;命中部分按缓存价计费。 - 显式缓存标记:在
content块或消息上加cache_control: {"type": "ephemeral"},仅对 claude / gemini 前缀的模型和 Qwen 模型保留(Qwen 会规整成{"type":"ephemeral"},去掉ttl),其他模型的cache_control会被删除。Qwen 的显式缓存依赖尚未发布的代码。 - 有缓存写入的上游,用量里还可能出现
prompt_tokens_details.cache_write_tokens与cache_write_token_details(按 5 分钟 / 1 小时 TTL 拆分)。
常用参数:n、stop、logprobs
何时用:一次生成多个候选、遇到指定字符串停止、取 token 概率。
证据:已实测(线上测试账号,2026-10-19,glm-5.3-flash):n: 2 与 stop 同时使用、logprobs 单独使用。seed、temperature、top_p 等依官方文档(未实测),是否生效看上游。
请求
curl https://api.modelsite.ai/v1/chat/completions \
-H "Authorization: Bearer $MODELSITE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "glm-5.3-flash",
"messages": [{"role": "user", "content": "从1数到十,用逗号分隔,数到5就停止输出"}],
"max_tokens": 200,
"reasoning_effort": "low",
"n": 2,
"stop": ["6"]
}'响应(n: 2、stop: ["6"];choices 有两项)
"choices": [
{
"finish_reason": "stop",
"index": 0,
"message": { "role": "assistant", "content": "1, 2, 3, 4, 5\n\n已数到5,停止输出。", "refusal": null, "reasoning_content": "Simple." }
},
{
"finish_reason": "stop",
"index": 1,
"message": { "role": "assistant", "content": "1, 2, 3, 4, 5", "refusal": null, "reasoning_content": "Simple." }
}
]logprobs: true 时每个 choice 多一个 logprobs.content[],每项含 token、logprob、bytes 和 top_logprobs(本例 top_logprobs: 2)。
注意事项
- 平台不限制
n > 1,费用按所有候选的真实用量计。 - 思考模型的
logprobs会包含思考阶段的 token(实测首个 token 是上游的思考结束标记),不要把它当作只覆盖正文。 stop传字符串时会转成单元素数组再转发。top_logprobs官方范围是 0 到 20。logprobs: false等同于不传。
错误
401 密钥无效或缺失
{"error":{"type":"authentication_error","message":"invalid API key"}}缺少 Authorization 头时 message 为 missing or invalid authorization header。
402 余额不足
{"error":{"type":"insufficient_quota","message":"insufficient balance"}}429 触发限流
{"error":{"type":"rate_limit_error","message":"too many requests"}}响应头带 Retry-After(秒),按它退避重试。
403 无权调用该模型
{"error":{"type":"model_access_error","message":"model 'glm-5.3-flash' is not allowed for this API key"}}503 网关容量已满
{"error":{"type":"overloaded_error","message":"gateway at capacity, retry later"}}同样带 Retry-After: 5。
502 上游暂不可用(已实测遇到)
{"error":{"type":"server_error","message":"upstream service unavailable"}}503 当前没有可用上游(已实测遇到)
{"error":{"code":"no_upstream_available","message":"<说明文本>","type":"service_unavailable"}}某个模型的上游都处于临时冷却时出现,稍后重试。这两类错误的 message 文本可能变化,请按 HTTP 状态码和 error.type / error.code 判断。
400 模型不存在
{"error":{"type":"invalid_request_error","message":"unknown model: not-a-model"}}model 填错或未上线时是 400(不是 404)。
400 参数错误
{"error":{"message":"messages: messages is required and must not be empty","type":"invalid_request_error","code":"invalid_request_error"}}请求通过网关后由路由层校验,错误体多一个 code 字段。
流式请求在已经开始输出后失败,HTTP 状态码已是 200,错误会作为流内事件发出:data: {"error":{"message":"The upstream stream ended unexpectedly before completion.","type":"server_error"}},随后是 data: [DONE];遇到 error 块就当作失败处理,不要把已收到的内容当作完整回复。完整错误码与处理建议见 错误码。
上游超时、连接失败、限流(429)、5xx、上游鉴权类错误,且发生在你收到任何响应内容之前时,平台会自动换另一个可用上游重试,这类临时问题通常不会以报错形式出现在你这边。参数错误(400)和内容安全拦截不会重试,直接返回给你。流已经开始输出后失败不会重试。
不支持或有差异的参数
平台不会按「参数清单」丢弃参数,也不会钳制取值:除下表列出的、代码里写死的改写外,请求体原样转给上游,参数是否生效、被忽略还是报错(返回 4xx)由上游决定。不同模型对同一个参数的支持不同,某个参数是否真正生效请以实测为准。thinking、enable_thinking、enable_search 等平台没有识别的顶层字段也原样透传,Python SDK 里放 extra_body。
| 参数 | 行为 | 说明 |
|---|---|---|
model | 必填,区分大小写 | 缺失返回 400 missing model field;未知或未上线返回 400 unknown model: <id>;当前 Key 无权调用该模型返回 403 model_access_error |
max_tokens / max_completion_tokens | 改写 | 两个同时传时只用 max_completion_tokens,向上游只发一个。设得过大时,余额不足可能被 402 拒绝 |
stop | 改写 | 字符串形式会转成单元素数组再转发 |
stream_options | 部分支持 | 平台只识别 include_usage,其他子字段(如 include_obfuscation)会被丢弃。stream: true 且没传 stream_options 时,网关自动补 {"include_usage": true} |
n | 透传 | 平台不限制 n > 1;费用按所有候选的真实用量计 |
logprobs top_logprobs | 部分透传 | logprobs: false 不会转发(等同于不传);其余透传 |
parallel_tool_calls | 条件转发 | 只有同时传了 tools 才转发,否则丢弃 |
thinking reasoning_effort reasoning | 改写 | 见上方「思考」:GPT / o 系列把 thinking 换算成 reasoning_effort,reasoning 对象被归一化,thinking.type = "adaptive" 对非 MiniMax 模型会被丢弃(后两条依赖尚未发布的代码) |
functions function_call | 不转换 | 官方已废弃的旧字段,不会转成 tools / tool_choice,只作为未知字段原样转发;请直接用 tools |
messages[].role = "developer" | 改写 | 转成 system |
image_url.format、file.format | 去除 | 非标准子字段,转发前删除;image_url.detail 保留 |
cache_control | 去除或改写 | content 块与消息上的 cache_control:claude / gemini 前缀的模型保留;Qwen 保留但规整为 {"type":"ephemeral"}(ttl 被去掉);其他模型全部删除(Qwen 一条依赖尚未发布的代码) |
历史消息里的 reasoning_content | 按模型保留 | DeepSeek、GLM、Qwen、MiniMax 保留,其他模型删除(依赖尚未发布的代码) |
响应里的 prompt_text prompt_token_ids kv_transfer_params prompt_logprobs token_ids | 删除 | 上游推理引擎可能带出的内部字段,网关在出口统一删除 |
平台扩展
下面是平台自己定义、OpenAI 官方没有的内容。
请求参数
| 参数 | 说明 |
|---|---|
thinking | 各厂商的思考开关,原样透传;取值见各厂商页。GPT / o 系列例外,会换算成 reasoning_effort |
reasoning | OpenRouter 风格的思考配置:effort、max_tokens、enabled、exclude。归一化规则见上方「思考」 |
reasoning.exclude: true,或 include_reasoning: false | 模型照常思考并计费,但响应(含流式)里不返回思考内容。只对本端点有效 |
top_k | 非 OpenAI 标准的采样参数,已识别,转发给上游,是否生效由上游决定 |
| 其他厂商私有字段 | 原样透传,见各厂商页 |
请求头
网关只放行下面这些请求头,其余一律丢弃:Authorization、Content-Type、Accept、Accept-Encoding、Origin、User-Agent、Anthropic-Beta、OpenAI-Beta。X-Request-ID 你自己带的值会被沿用并在响应头回显;没带则由平台生成。平台没有其他自定义请求头,身份、组织、价格等内部头无法由调用方伪造。
响应头
| 响应头 | 说明 |
|---|---|
X-Request-ID | 请求 ID,排查问题时提供给我们 |
Retry-After | 429(触发限流)时给出建议退避秒数;网关容量满时返回 503 overloaded_error,同样带 Retry-After: 5 |
Content-Type: text/event-stream、Cache-Control: no-cache、X-Accel-Buffering: no | 流式响应;流空闲时网关每 15 秒发一个 : heartbeat 注释帧保活,SSE 客户端会自动忽略 |
平台不返回 X-RateLimit-* 一类的限流额度头,限流信息只有 429 状态码和 Retry-After。
响应字段
| 字段 | 说明 |
|---|---|
usage.cost、usage.cost_details | 本次请求的费用。默认不返回,仅当你所在组织被设置为 total(只返回 cost)或 detailed(再加 cost_details 分项)时出现,设置由平台管理员在后台完成,调用方不能通过请求参数开启。金额是精确小数字符串,例如 "0.00002618";无法计价的请求这两个字段都不出现。cost_details 只含大于 0 的分项,如 prompt_cost、completion_cost、reasoning_cost、prompt_cache_read_cost |
message.reasoning_content(流式 delta.reasoning_content) | 思考过程;部分上游同时返回内容相同的 reasoning |
usage.prompt_tokens_details.cache_write_tokens 及 cache_write_token_details | 有缓存写入的上游会出现 |
上游自有的 usage 字段 | 如 DeepSeek 的 prompt_cache_hit_tokens,原样保留;名字含 cost / price 的字段会被隐去 |
自动行为
- 流式请求没传
stream_options时自动开启include_usage。 - 余额在流式输出途中耗尽时,流会被切断,并收到
data: {"error":{"type":"insufficient_quota","message":"balance exhausted"}},随后是data: [DONE]。 - 请求体超过大小上限返回 413
request body too large。 - 上游失败时的自动重试与换上游规则见上方「错误」。