Chat Completions 格式

根据对话历史生成模型回答,支持流式和非流式响应、图片输入和工具调用。兼容 OpenAI Chat Completions API:OpenAI 官方 SDK 和大多数兼容 OpenAI 的应用把 Base URL 改成 https://api.lyrouter.com/v1 即可使用。同一个模型可能由 OpenAI 兼容或 Anthropic 协议的通道服务,网关会自动转换请求和响应,本页同时说明转换时哪些参数会变化。

POST/v1/chat/completions

鉴权

在请求头中携带 API Key:

Authorization: Bearer <API Key>

Bearer 区分大小写。也可以改用 x-api-key: <API Key>,两者同时存在时只读 Authorization。API Key 在工作空间的 API 密钥 页面创建,只用于 LYRouter 鉴权,不会转发给上游服务商。完整说明见接入地址与鉴权。

请求头

请求头 必填 说明
Content-Type 否 建议携带 application/json。不带时网关按 JSON 解析请求体;写成其他值(如 application/x-www-form-urlencoded)时返回 400

请求体

参数 类型 必填 说明
model string 否 模型 ID,例如模型广场中复制的系统模型标识;也可以写虚拟模型 @vmodel/<名称> 或 lyrouter/auto。不写、写成 "" 或 null 时使用工作空间的默认模型,没有默认模型时返回 400。见模型命名与查询
messages array 是 对话消息,结构见下文
stream boolean 否 true 时以 SSE 流式返回,默认 false
stream_options object 否 流式时网关总是设为 {"include_usage": true},最后一个 chunk 带 usage,你传的值会被覆盖
max_tokens integer 否 本次最多生成的 Token 数。Anthropic 协议通道要求必填,请求中没有 max_tokens 和 max_completion_tokens 时网关补 4096
max_completion_tokens integer 否 OpenAI 新版的输出上限字段,透传给 OpenAI 兼容通道;发往 Anthropic 协议通道时在没有 max_tokens 的情况下作为 max_tokens 使用
temperature number 否 采样温度,取值范围以模型为准(Anthropic 协议通道为 0~1),网关不做换算
top_p number 否 核采样
stop string | array 否 停止序列;发往 Anthropic 协议通道时转换为 stop_sequences
tools array 否 可调用的函数列表,见工具调用
tool_choice string | object 否 "auto"、"none"、"required" 或 {"type":"function","function":{"name":"..."}},各协议的对应关系见工具调用
parallel_tool_calls boolean 否 是否允许一次返回多个工具调用;发往 Anthropic 协议通道时会被去掉
response_format object 否 {"type":"json_object"} 或 {"type":"json_schema",...};只对 OpenAI 兼容通道生效,发往 Anthropic 协议通道时会被去掉
reasoning_effort string 否 推理强度,网关按服务商处理,见下文「推理参数」
enable_thinking / thinking_budget boolean / integer 否 思考开关与思考预算,网关按服务商处理,见下文「推理参数」
seed integer 否 随机种子;透传给 OpenAI 兼容通道,是否生效取决于模型;发往 Anthropic 协议通道时会被去掉
user string 否 终端用户标识,透传给上游,是否生效取决于模型
frequency_penalty / presence_penalty / logprobs / n — 否 透传给 OpenAI 兼容通道,是否生效取决于模型;发往 Anthropic 协议通道时会被去掉

表中没有列出的其他参数,网关原样转发给 OpenAI 兼容通道,是否生效取决于模型。

messages 的结构

每条消息包含 role 和 content:

role 用途 说明
system 系统提示词 放在最前面。发往 Anthropic 协议通道时,所有 system 和 developer 消息合并为 Anthropic 的 system,content 请写成字符串
developer 新版 OpenAI 的系统提示词 透传给 OpenAI 兼容通道,是否支持取决于模型;Anthropic 协议通道按 system 处理
user 用户输入 content 可以是字符串或内容块数组
assistant 模型之前的回答 多轮对话时原样放回;包含工具调用时带 tool_calls
tool 工具执行结果 必须带 tool_call_id,对应上一条 assistant 消息中的调用 ID

content 有两种写法。纯文本直接写字符串;需要图片时写成内容块数组:

{
  "role": "user",
  "content": [
    { "type": "text", "text": "这张图里有什么?" },
    { "type": "image_url", "image_url": { "url": "https://example.com/cat.jpg" } }
  ]
}
  • image_url.url 可以是公网可访问的 https:// 地址,也可以是 data:image/png;base64,<数据> 形式的 Base64 数据。
  • 模型必须支持图像输入,只接受文本的模型返回 400 This model accepts text input only。在模型广场用「输入模态」筛选可用模型,详见多模态能力。
  • Anthropic 协议通道只转换文本块和图片块;input_audio、file 等其他内容块只对 OpenAI 兼容通道有效。

推理参数

三个推理参数分属不同服务商的写法,网关按实际服务这次请求的服务商保留或去掉,不会把其中一个换算成另一个(发往 Anthropic 协议通道时转换成 thinking,见表中说明):

实际服务的上游 reasoning_effort enable_thinking thinking_budget
OpenAI 官方接口 转发 去掉 去掉
阿里云百炼(DashScope 兼容接口) 去掉 转发 转发
DeepSeek 官方接口 去掉 去掉 去掉(是否思考由所选模型决定)
Anthropic 协议通道 去掉 true 且没有预算时转为 thinking: {"type": "adaptive"},false 时不开启思考 大于 0 时转为 thinking: {"type": "enabled", "budget_tokens": N}
其他 OpenAI 兼容服务商 原样转发 原样转发 原样转发
  • 实际服务的服务商在请求日志详情的「服务商」中查看。同一模型有多个来源时,请对每个来源验证推理参数是否生效。
  • Anthropic 协议通道开启思考时,上游要求 max_tokens 大于 budget_tokens,网关不调整这些参数,不满足时由上游返回 400。
  • 强制工具调用(tool_choice 为 "required" 或指定函数)且没有写 enable_thinking / thinking_budget 时,阿里云百炼通道会被自动加上 enable_thinking: false,因为这类上游在思考模式下不接受强制工具调用。
  • OpenAI Python SDK 没有定义 enable_thinking、thinking_budget,请放在 extra_body 中传递,例如 extra_body={"enable_thinking": False};Node.js SDK 直接写在请求参数里即可。

请求示例

curl https://api.lyrouter.com/v1/chat/completions \
  -H "Authorization: Bearer $LYROUTER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "MODEL_ID",
    "messages": [
      {"role": "system", "content": "你是一个简洁的助手。"},
      {"role": "user", "content": "用一句话介绍 LYRouter。"}
    ],
    "temperature": 0.7,
    "max_tokens": 512
  }'

响应

非流式请求返回一个 chat.completion 对象;出错时返回 error 对象。下面的 200 是 OpenAI 兼容通道的典型响应,400 是没有写 model 且工作空间没有默认模型,429 是 API Key 当天的 Token 配额已用完(见429:限流与配额)。

{
  "id": "chatcmpl-9f1c2a7e4b",
  "object": "chat.completion",
  "created": 1791950400,
  "model": "MODEL_ID",
  "choices": [
    {
      "index": 0,
      "message": {
        "role": "assistant",
        "content": "LYRouter 是可信模型服务与 Token 治理平台,用一个 API Key 统一调用多家模型服务商。"
      },
      "finish_reason": "stop"
    }
  ],
  "usage": {
    "prompt_tokens": 1250,
    "completion_tokens": 32,
    "total_tokens": 1282,
    "prompt_tokens_details": { "cached_tokens": 1024 },
    "completion_tokens_details": { "reasoning_tokens": 0 }
  }
}
字段 说明
id 上游生成的响应 ID,不是 LYRouter 的 Request ID。网关不在响应中返回 Request ID,排查时在日志详情顶部复制
model 上游返回的模型名,可能与请求中的模型 ID 写法不同;实际使用的模型以日志的「模型(实际)」为准
choices[0].message.content 回答正文;只返回工具调用时可能为 null 或空字符串
choices[0].message.tool_calls 模型请求调用的工具,见工具调用
choices[0].message.reasoning_content 部分模型返回的思考过程;由 Anthropic 协议通道服务且开启思考时同样出现在这里
choices[0].message.reasoning_blocks LYRouter 扩展字段,只在 Anthropic 协议通道开启思考时出现,保存带签名的原始思考块。多轮工具调用时把 assistant 消息原样放回,网关才能把思考块交还上游
choices[0].finish_reason stop(正常结束)、length(达到输出上限)、tool_calls(等待工具结果)、content_filter(被上游过滤)等。Anthropic 协议通道的 end_turn、stop_sequence 映射为 stop,max_tokens 映射为 length,tool_use 映射为 tool_calls
usage 本次的 Token 用量,由上游上报,见下表

usage 与日志中的四项 Token

usage 的字段取决于实际服务的上游。它与请求日志「Token 消耗」四项的对应关系如下:

日志中的名称 OpenAI 兼容通道 Anthropic 协议通道
「输入(缓存命中)」 prompt_tokens_details.cached_tokens(DeepSeek 等上游为 prompt_cache_hit_tokens) cache_read_input_tokens
「输入(缓存未命中)」 prompt_tokens 减去缓存命中 prompt_tokens
「输出」 completion_tokens,包含思考 Token(completion_tokens_details.reasoning_tokens) completion_tokens
「显式缓存创建」 不出现 cache_creation_input_tokens

由 Anthropic 协议通道服务时,响应中的 usage 是这样的,prompt_tokens 不包含缓存命中和缓存写入:

"usage": {
  "prompt_tokens": 226,
  "completion_tokens": 32,
  "total_tokens": 258,
  "cache_read_input_tokens": 1024,
  "cache_creation_input_tokens": 0
}

自己按 usage 估算费用时,先确认是哪种上游,再按四项分别计价,方法见调用费用与缓存计费。核对时以日志为准。

流式响应

设置 "stream": true 后,响应的 Content-Type 为 text/event-stream,每个事件是一行 data: <JSON> 加一个空行:

data: {"id":"chatcmpl-9f1c2a7e4b","object":"chat.completion.chunk","created":1791950400,"model":"MODEL_ID","choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":null}]}

data: {"id":"chatcmpl-9f1c2a7e4b","object":"chat.completion.chunk","created":1791950400,"model":"MODEL_ID","choices":[{"index":0,"delta":{"content":"LYRouter 是"},"finish_reason":null}]}

data: {"id":"chatcmpl-9f1c2a7e4b","object":"chat.completion.chunk","created":1791950400,"model":"MODEL_ID","choices":[{"index":0,"delta":{"content":"可信模型服务与 Token 治理平台。"},"finish_reason":null}]}

data: {"id":"chatcmpl-9f1c2a7e4b","object":"chat.completion.chunk","created":1791950400,"model":"MODEL_ID","choices":[{"index":0,"delta":{},"finish_reason":"stop"}]}

data: {"id":"chatcmpl-9f1c2a7e4b","object":"chat.completion.chunk","created":1791950400,"model":"MODEL_ID","choices":[],"usage":{"prompt_tokens":1250,"completion_tokens":32,"total_tokens":1282,"prompt_tokens_details":{"cached_tokens":1024}}}

data: [DONE]
  • 正文在 choices[0].delta.content 中逐段到达,思考过程在 delta.reasoning_content(个别上游为 delta.reasoning)。
  • 网关总会开启 include_usage,所以结束前有一个 choices 为空数组、带 usage 的 chunk。读取 choices[0] 之前先判断数组非空。
  • data: [DONE] 是正常结束的标记。没有收到它就断开,或收到了 "code": "stream_interrupted" 的错误事件,说明输出不完整,见超时与流式中断。
  • 由 Anthropic 协议通道服务时,chunk 由网关转换生成,带 usage 的 chunk 只有 prompt_tokens、completion_tokens、total_tokens 三个字段,缓存数量请在日志中查看。
curl -N https://api.lyrouter.com/v1/chat/completions \
  -H "Authorization: Bearer $LYROUTER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"model":"MODEL_ID","stream":true,"messages":[{"role":"user","content":"写两行关于秋天的诗"}]}'

三种对话接口的事件格式对比和客户端实现要点见流式响应。

网关行为

与直接调用上游相比,经 LYRouter 调用有以下差别:

  • 选择通道与回退:网关按工作空间的路由策略为模型选择通道,失败时换下一个通道,最后可能改用工作空间的默认模型,见失败重试与备用模型和通道选择与路由策略。流式输出开始后不再换通道。
  • 协议转换:通道是 Anthropic 协议时,网关把请求转换成 Anthropic Messages 格式,响应再转换回 Chat Completions 格式。response_format、seed、n、logprobs、top_logprobs、frequency_penalty、presence_penalty、logit_bias、parallel_tool_calls、reasoning_effort 会被去掉,metadata 只保留 user_id;这些去掉不会写进响应头。对比见模型能力与兼容性。
  • 推理参数:按上文「推理参数」的表格保留、去掉或转换。
  • 提示词缓存标记:cache_control 只在 Anthropic 协议通道上生效,保留文本内容块和工具定义上的标记,"ttl": "1h" 时网关把 anthropic-beta 请求头设为 1 小时缓存所需的值(覆盖客户端自带的值);发往 OpenAI 兼容通道时全部删除,由上游的隐式缓存工作。
  • 历史消息中的扩展字段:发往 OpenAI 兼容通道前,网关删除消息上的 reasoning_content、reasoning_blocks 和 cache_control。
  • 固定 JSON 键序:网关把发往上游的请求体中所有 JSON 对象的键按固定顺序重新排列,包括工具调用参数字符串里的 JSON,使相同内容每次产生相同的字节,提高上游前缀缓存的命中率,见降低成本与优化缓存。
  • 数字精度:网关会解析并重新编码请求体,数字最多保留 14 位有效数字。超过的长整数(如 19 位 ID)会变成科学计数法,请以字符串传递。
  • 用量:流式请求总会返回 usage;usage 的字段随上游变化,见上文对照表。

常见错误

错误响应为 {"error":{"message":"...","type":"...","code":"..."}},code 只有部分错误才有。

状态码 error.message error.code 原因与处理
400 you must provide a model parameter missing_model 没有写 model,工作空间也没有默认模型。写上模型 ID。请求体不是合法的 JSON 对象时,部分版本也返回这个错误,见下一行
400 request body must be a JSON object invalid_json 请求体不是合法的 JSON 对象,例如 JSON 被截断或顶层是数组。部分版本返回的是 400 you must provide a model parameter(missing_model)。工作空间设置了默认模型时,返回的是 {"message":"could not get parse JSON request body: <解析错误>"},外层没有 error
400 This model accepts text input only unsupported_model_input 给只接受文本的模型发了图片等非文本内容,换用支持图像输入的模型
400 This model does not support the chat_completions API unsupported_model_api 模型不支持对话接口,例如图像生成模型
403 Model is not available in the model plaza model_not_available 工作空间没有开通这个模型,请管理员在模型广场开通,或换用已开通的模型
503 all routed candidates exhausted no_route_candidate 找不到可服务这次请求的通道,常见于 @vmodel/<名称> 写错或模型没有可用来源,见模型不可用
  • 401 / 403 鉴权问题见401 / 403:鉴权与权限,429 见429:限流与配额。
  • 500 / 504 是连接上游失败或等待上游超时,响应体是 HTML 页面而不是 JSON,见超时与流式中断。
  • 网关自己生成的部分 400 是一行纯文本而不是 JSON,例如 Content-Type 不是 application/json 时的 unsupported content-type: …。这类响应的响应头目前仍是 Content-Type: application/json,解析错误体前请先判断正文是否为 JSON。
  • 上游服务商返回的错误会原样转发,状态码和报错原文由上游决定。完整列表见错误码与请求标识。