多模态对话(OpenAI Chat Completions 协议)
接口概述
支持图片、音频、文件的视觉理解模型,兼容 OpenAI Chat Completions 格式:可对图片做描述、分析、对比,支持音频转写与理解,支持文件内容提取与问答。多模态与纯文本共用同一个接口,区别只在 messages[].content 的写法。
纯文本对话的完整参数表见「OpenAI 兼容-Chat」页,本页只讲多模态部分。
接口地址
POST https://ai.jw-info.com/v1/chat/completions
请求头
| 请求头 | 值 | 是否必填 | 说明 |
|---|---|---|---|
| Content-Type | application/json | 是 | 请求体格式 |
| Authorization | Bearer {API_KEY} | 是 | 认证信息;也可以用 x-api-key: {API_KEY},两种写法用同一把 Key |
| Accept | application/json | 否 | 响应格式 |
与纯文本的区别
多模态场景下 messages[].content 是一个内容块数组,每个元素代表一种内容类型;纯文本场景中 content 是字符串。
// 多模态:content 为数组
"content": [
{ "type": "text", "text": "描述这张图片" },
{ "type": "image_url", "image_url": { "url": "https://example.com/photo.jpg" } }
]
// 纯文本:content 为字符串(仍支持)
"content": "你好,请帮我解答这个问题"
内容块类型
| type | 字段 | 说明 |
|---|---|---|
text | text(string) | 文本内容 |
image_url | image_url.url(string) | 图片 URL,或 data:image/...;base64, 编码 |
image_url | image_url.detail(string,可选) | 图片解析精度:low / high / auto(默认 auto) |
input_audio | input_audio.data(string) | 音频的 Base64 编码数据 |
input_audio | input_audio.format(string) | 音频格式:wav / mp3 等 |
file | file.file_id(string) | 已上传文件的 ID(与 file_data 二选一) |
file | file.file_data(string) | 文件的 Base64 编码数据 |
file | file.file_name(string,可选) | 文件名 |
其余请求参数(model、temperature、max_tokens、stream、tools 等)与纯文本一致,见「OpenAI 兼容-Chat」页。
请求示例
1. 图片 URL 方式
curl https://ai.jw-info.com/v1/chat/completions \
-H "Content-Type: application/json" \
-H "Authorization: Bearer sk-你的密钥" \
-d '{
"model": "qwen3.7-plus",
"messages": [
{
"role": "user",
"content": [
{ "type": "text", "text": "这张图片里有什么?请详细描述。" },
{
"type": "image_url",
"image_url": {
"url": "https://example.com/sample.jpg",
"detail": "high"
}
}
]
}
]
}'
from openai import OpenAI
client = OpenAI(api_key="sk-你的密钥", base_url="https://ai.jw-info.com/v1")
resp = client.chat.completions.create(
model="qwen3.7-plus",
messages=[
{
"role": "user",
"content": [
{"type": "text", "text": "这张图片里有什么?请详细描述。"},
{
"type": "image_url",
"image_url": {"url": "https://example.com/sample.jpg",
"detail": "high"},
},
],
}
],
)
print(resp.choices[0].message.content)
2. 图片 Base64 方式
图片不便于放到公网时,直接传 data: URL:
curl https://ai.jw-info.com/v1/chat/completions \
-H "Content-Type: application/json" \
-H "Authorization: Bearer sk-你的密钥" \
-d '{
"model": "qwen3.7-plus",
"messages": [
{
"role": "user",
"content": [
{ "type": "text", "text": "请分析这张图片中的文字内容。" },
{
"type": "image_url",
"image_url": { "url": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg==" }
}
]
}
]
}'
import base64
def encode_image(image_path: str) -> str:
"""本地图片 -> data URL(MIME 类型按扩展名给出)"""
with open(image_path, "rb") as f:
data = base64.b64encode(f.read()).decode("utf-8")
return f"data:image/{image_path.rsplit('.', 1)[-1]};base64,{data}"
def describe_image(image_path: str, prompt: str = "描述这张图片",
model: str = "qwen3.7-plus") -> str:
resp = client.chat.completions.create(
model=model,
messages=[{
"role": "user",
"content": [
{"type": "text", "text": prompt},
{"type": "image_url", "image_url": {"url": encode_image(image_path)}},
],
}],
)
return resp.choices[0].message.content
Base64 会显著放大请求体,建议只在图片不可公网访问时使用;接口的请求体上限为 64MB。
3. 多图对比
同一条消息里放多个 image_url 内容块即可:
curl https://ai.jw-info.com/v1/chat/completions \
-H "Content-Type: application/json" \
-H "Authorization: Bearer sk-你的密钥" \
-d '{
"model": "qwen3.7-plus",
"messages": [
{
"role": "user",
"content": [
{ "type": "text", "text": "这两张图片有什么相同和不同之处?" },
{ "type": "image_url", "image_url": { "url": "https://example.com/image1.jpg" } },
{ "type": "image_url", "image_url": { "url": "https://example.com/image2.jpg" } }
]
}
]
}'
4. 音频输入
音频以 Base64 传入,并声明格式:
curl https://ai.jw-info.com/v1/chat/completions \
-H "Content-Type: application/json" \
-H "Authorization: Bearer sk-你的密钥" \
-d '{
"model": "qwen3.7-plus",
"messages": [
{
"role": "user",
"content": [
{ "type": "text", "text": "请将这段录音转写成文字。" },
{
"type": "input_audio",
"input_audio": {
"data": "UklGRiQAAABXQVZFZm10IBAAAAABAAEARKwAAIhYAQACABAAZGF0YQAAAAA=",
"format": "wav"
}
}
]
}
]
}'
import base64
def transcribe_audio(audio_path: str, prompt: str = "请转写这段音频",
model: str = "qwen3.7-plus") -> str:
with open(audio_path, "rb") as f:
audio_b64 = base64.b64encode(f.read()).decode("utf-8")
resp = client.chat.completions.create(
model=model,
messages=[{
"role": "user",
"content": [
{"type": "text", "text": prompt},
{"type": "input_audio",
"input_audio": {"data": audio_b64,
"format": audio_path.rsplit(".", 1)[-1]}},
],
}],
)
return resp.choices[0].message.content
5. 文件输入
curl https://ai.jw-info.com/v1/chat/completions \
-H "Content-Type: application/json" \
-H "Authorization: Bearer sk-你的密钥" \
-d '{
"model": "qwen3.7-plus",
"messages": [
{
"role": "user",
"content": [
{ "type": "text", "text": "请总结这份文件的主要内容。" },
{
"type": "file",
"file": {
"file_data": "VGhpcyBpcyBhIHNhbXBsZSBmaWxlIGNvbnRlbnQu",
"file_name": "report.pdf"
}
}
]
}
]
}'
import base64
def analyze_file(file_path: str, prompt: str = "请总结这个文件",
model: str = "qwen3.7-plus") -> str:
with open(file_path, "rb") as f:
file_b64 = base64.b64encode(f.read()).decode("utf-8")
resp = client.chat.completions.create(
model=model,
messages=[{
"role": "user",
"content": [
{"type": "text", "text": prompt},
{"type": "file",
"file": {"file_data": file_b64,
"file_name": file_path.replace("\\", "/").split("/")[-1]}},
],
}],
)
return resp.choices[0].message.content
音频与文件输入的支持度随模型而异,模型不支持时会返回参数错误;遇到就换支持该能力的模型,或改用图片输入。
6. 纯文本(兼容模式)
content 直接写成字符串即可,无需数组形式:
{
"model": "qwen3.7-plus",
"messages": [
{ "role": "user", "content": "你好,请介绍一下你自己" }
]
}
响应格式
响应结构与纯文本 Chat Completions 相同:
| 字段 | 类型 | 说明 |
|---|---|---|
| id | string | 请求唯一标识 |
| object | string | 固定 chat.completion |
| created | integer | 创建时间戳(Unix 秒) |
| model | string | 实际使用的模型 |
| choices[].index | integer | 候选回复索引(从 0 开始) |
| choices[].message.role | string | 固定 assistant |
| choices[].message.content | string | 识别 / 回答的文本内容 |
| choices[].finish_reason | string | 停止原因:stop / length / content_filter |
| usage.prompt_tokens | integer | 输入 token 数(图片、音频、文件都折算在内) |
| usage.completion_tokens | integer | 输出 token 数 |
| usage.total_tokens | integer | 总 token 数 |
{
"id": "chatcmpl-xxxxxxxxxxxxx",
"object": "chat.completion",
"created": 1710000000,
"model": "qwen3.7-plus",
"choices": [
{
"index": 0,
"message": {
"role": "assistant",
"content": "这张图片展示了一座位于海边的灯塔,天空晴朗……"
},
"finish_reason": "stop"
}
],
"usage": { "prompt_tokens": 150, "completion_tokens": 80, "total_tokens": 230 }
}
流式响应
请求体带 stream: true 时按 SSE 返回增量帧,最后以 data: [DONE] 结束:
data: {"id":"chatcmpl-xxx","object":"chat.completion.chunk","choices":[{"index":0,"delta":{"role":"assistant","content":"这是"},"finish_reason":null}]}
data: {"id":"chatcmpl-xxx","object":"chat.completion.chunk","choices":[{"index":0,"delta":{"content":"一张"},"finish_reason":null}]}
data: {"id":"chatcmpl-xxx","object":"chat.completion.chunk","choices":[{"index":0,"delta":{"content":"图片"},"finish_reason":null}]}
data: [DONE]
流式响应末尾会返回一帧只带 usage 的统计,无需调用方设置;中途断开时按已产生的用量计费。
错误格式
{
"error": {
"message": "Invalid image URL: connection timeout",
"type": "invalid_request_error",
"code": "invalid_image_url"
}
}
| 错误码 | 说明 |
|---|---|
invalid_request_error | 请求参数错误 |
invalid_image_url | 图片 URL 无法访问或格式不支持 |
invalid_audio_format | 音频格式不支持 |
rate_limit_exceeded | 请求频率超限 |
context_length_exceeded | Token 数量超出模型限制 |
authentication_error | API Key 无效 |
状态码与错误处理约定见「错误码」页。
可用模型
以下模型支持多模态(图片 + 音频 + 文件)能力,也都支持纯文本对话:
| 模型 | 供应商 | 最大 Token | 说明 |
|---|---|---|---|
| qwen3.7-plus | 通义千问 | 128K | 旗舰多模态模型 |
| qwen3.6-plus | 通义千问 | 128K | 高性能多模态 |
| qwen3.6-flash | 通义千问 | 128K | 轻量快速多模态 |
| qwen3.5-plus | 通义千问 | 128K | 上一代旗舰 |
| qwen3.5-flash | 通义千问 | 128K | 上一代轻量版 |
| qwen3.5-122b-a10b | 通义千问 | 128K | 大参数 MoE 模型 |
| qwen3.5-397b-a17b | 通义千问 | 128K | 超大参数 MoE 模型 |
| qwen3.5-35b-a3b | 通义千问 | 128K | 轻量 MoE 模型 |
| minimax-m3 | MiniMax | 128K | MiniMax 多模态模型 |
| doubao-seed-2.0-pro | 豆包 | 128K | 豆包旗舰多模态 |
| doubao-seed-2.0-lite | 豆包 | 128K | 豆包轻量多模态 |
| doubao-seed-2.0-mini | 豆包 | 128K | 豆包极速多模态 |
| kimi-k3 | 月之暗面 | 128K | Kimi 旗舰多模态 |
| kimi-k2.7-code | 月之暗面 | 128K | Kimi 代码多模态 |
| kimi-k2.6 | 月之暗面 | 128K | Kimi 多模态 |
| kimi-k2.5 | 月之暗面 | 128K | Kimi 多模态 |
模型广场上带「视觉理解」标签的模型都支持图片输入;音频与文件输入只有部分模型支持,以实际调用结果为准。模型名与单价以模型广场为准。
计费说明
- 图片、音频、文件都会被折算成输入 token,与文本一起按模型单价计费;输出按输出单价计费。
- 每次调用的费用记入控制台「费用中心」,接口响应本身不返回费用。
- 余额不足会返回 402,需要管理员在控制台手工授信。