Chat Completions
通过 OpenAI 兼容协议调用文本、多模态、工具调用与结构化输出能力。
最后更新: 2026-08-06POST
/v1/chat/completions创建一次非流式或 SSE 流式对话补全。
请求字段
| 参数 | 类型 | 要求 | 说明 |
|---|---|---|---|
model | string | 必填 | 已启用的对话模型编码;从 /api/v1/model/list 查询实际可用值。 |
messages | array | 必填 | 有序消息数组,支持 developer、system、user、assistant、tool,以及兼容旧客户端的 function 角色。 |
stream | boolean | 可选 | true 使用 SSE 增量返回;默认 false。 |
stream_options | object | 可选 | 流式选项;include_usage=true 时最终分片可包含 usage。 |
tools | array | 可选 | OpenAI 兼容函数工具声明。模型可能在 message.tool_calls 或增量 tool_calls 中返回调用。 |
tool_choice | string | object | 可选 | 控制是否以及如何选择工具。 |
response_format | object | 可选 | 请求 JSON Object 或模型支持的 JSON Schema 结构化输出。 |
temperature | number | 可选 | 采样温度;可用范围取决于所选模型。 |
max_tokens | integer | 可选 | 最大输出 Token 数;是否支持及上限取决于所选模型。 |
| messages[].content 形式 | 内容项 | 说明 |
|---|---|---|
| string | - | 普通文本消息。 |
| array | text | 文本内容项,字段为 text。 |
| array | image_url | 远程 HTTP(S) 图片或模型支持的 data URL,字段为 image_url.url。 |
| array | input_audio | Base64 音频,字段为 input_audio.data 和 input_audio.format;当前页面支持 mp3、wav。 |
| array | file | 文件内容项;file 中传 file_id,或传 file_data,并可附 filename。 |
cURL 示例
curl --request POST 'https://api.easerouter.com/v1/chat/completions' --header 'Authorization: Bearer YOUR_API_KEY' --header 'Content-Type: application/json' --data-raw '{
"model": "YOUR_CHAT_MODEL",
"messages": [
{"role": "system", "content": "You are a precise assistant."},
{"role": "user", "content": "用三句话解释什么是向量数据库。"}
],
"stream": false
}'curl --no-buffer --request POST 'https://api.easerouter.com/v1/chat/completions' --header 'Authorization: Bearer YOUR_API_KEY' --header 'Content-Type: application/json' --header 'Accept: text/event-stream' --data-raw '{
"model": "YOUR_CHAT_MODEL",
"messages": [{"role": "user", "content": "写一句产品标语。"}],
"stream": true,
"stream_options": {"include_usage": true}
}'Python SDK 示例
import os
from openai import OpenAI
client = OpenAI(
api_key=os.environ["EASEROUTER_API_KEY"],
base_url="https://api.easerouter.com/v1",
)
response = client.chat.completions.create(
model="YOUR_CHAT_MODEL",
messages=[{"role": "user", "content": "用一句话介绍递归。"}],
)
print(response.choices[0].message.content)
print(response.usage)import os
from openai import OpenAI
client = OpenAI(
api_key=os.environ["EASEROUTER_API_KEY"],
base_url="https://api.easerouter.com/v1",
)
stream = client.chat.completions.create(
model="YOUR_CHAT_MODEL",
messages=[{"role": "user", "content": "列出三个代码审查要点。"}],
stream=True,
stream_options={"include_usage": True},
)
for chunk in stream:
if chunk.choices and chunk.choices[0].delta.content:
print(chunk.choices[0].delta.content, end="", flush=True)
if chunk.usage:
print("
usage:", chunk.usage)Node.js SDK 示例
import OpenAI from 'openai'
const client = new OpenAI({
apiKey: process.env.EASEROUTER_API_KEY,
baseURL: 'https://api.easerouter.com/v1'
})
const response = await client.chat.completions.create({
model: 'YOUR_CHAT_MODEL',
messages: [{ role: 'user', content: '用一句话介绍递归。' }]
})
console.log(response.choices[0].message.content)
console.log(response.usage)import OpenAI from 'openai'
const client = new OpenAI({
apiKey: process.env.EASEROUTER_API_KEY,
baseURL: 'https://api.easerouter.com/v1'
})
const stream = await client.chat.completions.create({
model: 'YOUR_CHAT_MODEL',
messages: [{ role: 'user', content: '列出三个代码审查要点。' }],
stream: true,
stream_options: { include_usage: true }
})
for await (const chunk of stream) {
const text = chunk.choices[0]?.delta?.content
if (text) process.stdout.write(text)
if (chunk.usage) console.log('
usage:', chunk.usage)
}图片和音频输入
{
"role": "user",
"content": [
{"type": "text", "text": "描述图片,再概括音频内容。"},
{"type": "image_url", "image_url": {"url": "https://example.com/image.png"}},
{"type": "input_audio", "input_audio": {"data": "BASE64_AUDIO", "format": "mp3"}},
{"type": "file", "file": {"file_data": "data:application/pdf;base64,BASE64_FILE", "filename": "brief.pdf"}}
]
}浏览器在线对话页只允许选择一个本地原始附件,可使用常见图片、MP3/WAV 或文件,大小不超过 10 MiB;远程图片 URL 是单独的可选输入。该限制属于在线页面的浏览器保护,不代表所有模型具有相同输入上限。
工具调用与结构化输出
{
"tools": [{
"type": "function",
"function": {
"name": "get_weather",
"description": "查询指定城市天气",
"parameters": {
"type": "object",
"properties": {"city": {"type": "string"}},
"required": ["city"],
"additionalProperties": false
}
}
}],
"response_format": {"type": "json_object"}
}- 非流式工具调用读取 choices[0].message.tool_calls;流式调用必须按 index 合并 delta.tool_calls 中分片的 id、function.name 和 function.arguments。
- function.arguments 是 JSON 字符串,执行工具前必须完成解析、参数校验和权限检查。不要直接执行模型生成的命令。
- JSON Object 模式通常还需要在提示词中明确要求输出 JSON;JSON Schema 的可用性取决于模型。
非流式响应
{
"id": "chatcmpl-abc123",
"object": "chat.completion",
"created": 1785984000,
"model": "YOUR_CHAT_MODEL",
"choices": [{
"index": 0,
"message": {"role": "assistant", "content": "向量数据库用于存储和检索向量表示。"},
"finish_reason": "stop"
}],
"usage": {"prompt_tokens": 18, "completion_tokens": 14, "total_tokens": 32}
}SSE 流式响应
data: {"id":"chatcmpl-abc123","object":"chat.completion.chunk","choices":[{"index":0,"delta":{"role":"assistant","content":"向量"},"finish_reason":null}]}
data: {"id":"chatcmpl-abc123","object":"chat.completion.chunk","choices":[{"index":0,"delta":{"content":"数据库"},"finish_reason":null}]}
data: {"id":"chatcmpl-abc123","object":"chat.completion.chunk","choices":[],"usage":{"prompt_tokens":18,"completion_tokens":14,"total_tokens":32}}
data: [DONE]- 按空行分隔 SSE 事件,只拼接 data: 行;网络分片可能落在任意 UTF-8 字节位置。
- 收到 data: [DONE] 才表示流完整结束;连接提前关闭应按中断处理。
- 开启 include_usage 后,最终用量分片可以没有 choices。业务代码不能假定每个分片都有 choices[0]。
- 用户取消请求后应停止读取并保留已接收文本,不要把部分文本误认为完整答案。
错误响应
该接口使用 OpenAI 兼容 HTTP 错误语义。参数、鉴权、限流或处理失败时可能返回非 2xx 状态及 error 对象;不要按视频接口的顶层 code 字段判断。
{
"error": {
"message": "model is required",
"type": "invalid_request_error",
"param": "model",
"code": "invalid_request"
}
}兼容边界
- SDK 的 base URL 必须设置为 https://api.easerouter.com/v1;SDK 会在其后追加 /chat/completions。
- 当前只承诺 Chat Completions 所需协议,不承诺 OpenAI 平台的全部接口、参数或 Beta 功能。
- 可用模型仍通过平台自有 GET /api/v1/model/list 查询;当前不承诺 GET /v1/models。
- 除 model 映射、平台注入 Authorization 和内部强制采集 usage 外,请求扩展字段原样透传;响应只把 model 改写回客户端请求的模型编码。
- 当前不支持 Idempotency-Key。超时后直接重试可能产生重复调用与重复费用;调用方应先核对自身请求记录并谨慎决定是否重试。
- 最终支持情况、上下文窗口和多模态限制以所选模型实际能力为准。
- 非流式响应是单个 JSON;流式响应是 text/event-stream。客户端必须按 Content-Type 选择解析方式。