跳到主要内容

Quincy Qwen3.5 Omni Plus Realtime

GET 

/v1/realtime

通过 OpenAI Realtime 风格的 WebSocket 调用 qwen3.5-omni-plus-realtime。画面以抽帧 JPEG 发送,不是整段视频流。

快照名 qwen3.5-omni-plus-realtime-2026-03-15 与别名能力相同。

使用本系统签发的 API Token。不要带 OpenAI 的 Sec-WebSocket-Protocolopenai-insecure-api-key.*)。本网关与上游均使用 Bearer。

建立连接

这是 WebSocket 接口(wss://),不是 HTTP GET。不要用普通 HTTPS curl 去调。

wss://open-api.fancyai.com/v1/realtime?model=qwen3.5-omni-plus-realtime
Authorization: Bearer YOUR_API_KEY

curl(需要 curl 8+ 且支持 WebSocket):

curl --no-buffer \
-H "Authorization: Bearer $API_KEY" \
"wss://open-api.fancyai.com/v1/realtime?model=qwen3.5-omni-plus-realtime"

连接成功后,服务端会下发 session.created

Python:

import os
import json
import websocket

WS_URL = "wss://open-api.fancyai.com/v1/realtime?model=qwen3.5-omni-plus-realtime"
API_KEY = os.environ["API_KEY"]

def on_open(ws):
print("connected")

def on_message(ws, message):
print(json.dumps(json.loads(message), ensure_ascii=False, indent=2))

ws = websocket.WebSocketApp(
WS_URL,
header=["Authorization: Bearer " + API_KEY],
on_open=on_open,
on_message=on_message,
)
ws.run_forever()

Request

Responses

Switching Protocols — WebSocket established

配置会话

连接后发送 session.update

{
"event_id": "event_001",
"type": "session.update",
"session": {
"modalities": ["text", "audio"],
"voice": "Tina",
"instructions": "你是语音助手,用简洁口语回答。",
"audio": {
"input": { "format": { "type": "pcm", "sample_rate": 16000 } },
"output": { "format": { "type": "pcm", "sample_rate": 24000 } }
},
"turn_detection": {
"type": "semantic_vad",
"threshold": 0.5,
"silence_duration_ms": 800
}
}
}
字段说明
modalities["text"] 只出文本;["text","audio"] 出文本+语音
voice输出音色,默认 Tina
audio.input/output.format仅 3.5 Realtime 支持。输入默认 pcm/16000,输出默认 pcm/24000。采样率可选 8000/16000/24000/48000
input_audio_format / output_audio_format旧字段,仍可用
turn_detectionsemantic_vad(推荐)或 server_vad。设为 null 为手动模式
enable_search联网搜索,默认关闭。不可与 tools 同时开启
tools函数工具。不可与 enable_search 同时开启

配置成功后服务端返回 session.updated

会话结束发送 session.finish,或直接断开 WebSocket。不关闭会导致上下文一直累积并持续计费。

发送音频

PCM/WAV 音频做 Base64 后发送:

{
"type": "input_audio_buffer.append",
"audio": "<base64>"
}

建议约 100ms 一包。

VAD 模式semantic_vad / server_vad):服务端检测到说完后自动提交并生成回复。

手动模式turn_detectionnull):发完音频后自行提交并触发回复:

{ "type": "input_audio_buffer.commit" }
{ "type": "response.create" }

打断当前回复:

{ "type": "response.cancel" }

发送图片(视频抽帧)

模型不接收整段视频。从摄像头或视频里抽帧,按 JPEG 做 Base64 发送:

{
"type": "input_image_buffer.append",
"image": "<base64 jpeg>"
}

约束:

  • 必须先至少发送过一次 input_audio_buffer.append
  • 格式 JPG/JPEG;建议 480P 或 720P,最高 1080P
  • Base64 后单张不超过 256KB,编码前建议不超过 190KB
  • 实时看画面建议 1 帧/秒(最多 2 帧/秒)
  • VAD 模式下,在 input_audio_buffer.speech_stopped 之前把当前帧发完

音频是时间轴,图片按发送时刻插入。可以随时打开或关闭画面。

纯文本输入

{
"type": "conversation.item.create",
"item": {
"type": "message",
"role": "user",
"content": [{ "type": "input_text", "text": "现在外面天气怎么样?" }]
}
}

手动模式随后再发 response.create

接收回复

只出文本:

事件含义
response.text.delta增量文本
response.text.done完整文本

出文本+音频:

事件含义
response.audio_transcript.delta语音对应的增量文本
response.audio_transcript.done完整转写
response.audio.deltaBase64 增量音频,解码后播放
response.audio.done本段音频结束
response.done本轮结束,带 usage

其它常用事件:

事件含义
session.created连接就绪
session.updated会话配置已生效
input_audio_buffer.speech_started检测到用户开始说话(可在此取消当前回复)
input_audio_buffer.speech_stopped检测到用户说完
conversation.item.input_audio_transcription.completed用户语音转写完成(需开启输入转录)
error错误

计费

按每轮 response.done 里的 Token 计费,不按连接时长。多轮对话时,窗口内的历史音频/图片/文本会再次计入本轮输入。

出语音时,输出文本不再另计(与网关结算一致)。

单价按新加坡地域原价、人民币兑美元 6.8 折算:

计费项plus-realtime
输入:文本 / 图片 / 视频帧$2.315 / M
输入:音频$18.184 / M
输出:仅文本$13.666 / M
输出:文本 + 音频(输出文本不计费)$68.329 / M

音频折算(不足 1 秒按 1 秒):

  • 输入:秒数 × 7
  • 输出:秒数 × 12.5

图片 / 视频帧:每 32×32 像素约 1 Token,单张最少 4、最多 1280。

联网搜索另计,默认关闭。toolsenable_search 不能同时开。

限制

plus-realtime
音频最大轮次100
视频(帧)最大轮次50
音频最大时长600 s
视频(帧)最大时长240 s
单次会话最长 120 分钟

超时后服务端会断开。更早的历史会被丢掉。

选型

更强理解、更长上下文请用 plus。低延迟场景请用 qwen3.5-omni-flash-realtime。本接口不提供 WebRTC / AOQ。

官方能力说明见 Qwen-Omni 实时模型。客户端只连本系统 /v1/realtime