Skip to main content

Qwen-Omni-Realtime

Qwen-Omni-Realtime 是千问推出的实时音视频聊天模型。能同时理解流式的音频与图像输入(例如从视频流中实时抽取的连续图像帧),并实时输出高质量的文本与音频。

支持的地域:北京、新加坡,需使用各地域的API Key。 在线体验:请参见如何在线体验 Qwen-Omni-Realtime 模型?

如何使用

1. 建立连接

通用 WebSocket 和 WebRTC 建连示例使用 qwen3.8-omni-flash-realtime;型号专属配置示例使用各自标注的模型。 Qwen-Omni-Realtime 模型支持 WebSocket、WebRTC 和 AOQ 三种协议接入。WebSocket 适合服务端集成和快速接入;WebRTC 适合浏览器端、低延迟语音场景,音频通过 UDP 直接传输,内置回声消除和降噪。如果是客户端对接,且更看重稳定的延迟、弱网下的交互能力、实时双工的降噪与回声消除,可优先考虑 AOQ。协议对比与选型请参见Realtime API 概述。
  • WebSocket
  • WebRTC
  • AOQ
qwen3.8-omni-flash-realtime 必须使用下方绑定业务空间的调用地址。调用前请获取对应地域、对应业务空间的 API Key 和业务空间 ID。
  • WebSocket 原生连接
  • DashScope Python SDK
  • DashScope Java SDK
连接时需要以下配置项:
配置项说明
调用地址华北2(北京)地域:wss://{WorkspaceId}.cn-beijing.maas.aliyuncs.com/api-ws/v1/realtime新加坡地域:wss://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/api-ws/v1/realtime调用时请将{WorkspaceId}替换为真实的业务空间ID。
查询参数查询参数为model,需指定为访问的模型名。示例:?model=qwen3.8-omni-flash-realtime
请求头使用 Bearer Token 鉴权:Authorization: Bearer DASHSCOPE_API_KEY
DASHSCOPE_API_KEY 是您在百炼上申请的API Key。
# pip install websocket-client
import json
import websocket
import os

API_KEY=os.getenv("DASHSCOPE_API_KEY")
# 以下为华北2(北京)地域的URL。请将 {WorkspaceId} 替换为您的百炼业务空间ID,各地域的URL不同。
API_URL = "wss://{WorkspaceId}.cn-beijing.maas.aliyuncs.com/api-ws/v1/realtime?model=qwen3.8-omni-flash-realtime"

headers = [
    "Authorization: Bearer " + API_KEY
]

def on_open(ws):
    print(f"Connected to server: {API_URL}")
def on_message(ws, message):
    data = json.loads(message)
    print("Received event:", json.dumps(data, indent=2))
def on_error(ws, error):
    print("Error:", error)

ws = websocket.WebSocketApp(
    API_URL,
    header=headers,
    on_open=on_open,
    on_message=on_message,
    on_error=on_error
)

ws.run_forever()

2. 配置会话

发送客户端事件session.update: 通过 session.update 配置输出模态、音色、音频格式和 VAD。下面是 Qwen3.8-Omni-Flash-Realtime 的 WebSocket Manual 模式配置,与最小音频问答示例一致。本例使用“龙安灵心”音色(longanlingxin):
{
  "type": "session.update",
  "session": {
    "modalities": [
      "text",
      "audio"
    ],
    "turn_detection": null,
    "audio": {
      "input": {
        "format": {
          "type": "pcm",
          "sample_rate": 16000,
          "sample_format": "s16le",
          "channels": 1,
          "packing": "interleaved",
          "channel_layout": "mono"
        }
      },
      "output": {
        "voice": "longanlingxin",
        "format": {
          "type": "pcm",
          "sample_rate": 24000
        }
      }
    }
  }
}
以下示例使用 Qwen3.5-Omni-Realtime 的 Ethan 音色和 semantic_vad 配置。
{
    // 该事件的id,由客户端生成
    "event_id": "event_ToPZqeobitzUJnt3QqtWg",
    // 事件类型,固定为session.update
    "type": "session.update",
    // 会话配置
    "session": {
        // 输出模态,支持设置为["text"](仅输出文本)或["text","audio"](输出文本与音频)。
        "modalities": [
            "text",
            "audio"
        ],
        // 输出音频的音色
        "voice": "Ethan",
        // 推荐写法:同时配置音频格式和采样率(仅 qwen3.5-omni-plus-realtime / qwen3.5-omni-flash-realtime 支持)
        // 输入格式:pcm / wav,默认 pcm;采样率:8000/16000/24000/48000,默认 16000
        // 输出格式:pcm / wav,默认 pcm;采样率:8000/16000/24000/48000,默认 24000
        "audio": {
            "input": {
                "format": {
                    "type": "pcm",
                    "sample_rate": 16000
                }
            },
            "output": {
                "format": {
                    "type": "pcm",
                    "sample_rate": 24000
                }
            }
        },
        // 系统消息,用于设定模型的目标或角色。
        "instructions": "你是某五星级酒店的AI客服专员,请准确且友好地解答客户关于房型、设施、价格、预订政策的咨询。请始终以专业和乐于助人的态度回应,杜绝提供未经证实或超出酒店服务范围的信息。",
        // 是否开启语音活动检测。若需启用,需传入一个配置对象,服务端将据此自动检测语音起止。
        // 设置为null表示由客户端决定何时发起模型响应。
        "turn_detection": {
            // VAD类型,取值为server_vad或semantic_vad。使用qwen3.5-omni-realtime系列模型时推荐设为semantic_vad。
            "type": "semantic_vad",
            // VAD检测阈值。建议在嘈杂的环境中增加,在安静的环境中降低。
            "threshold": 0.5,
            // 检测语音停止的静音持续时间,超过此值后会触发模型响应。取值范围 200-6000,默认 800。金融核实等短回答场景建议 500-600。
            "silence_duration_ms": 800
        }
    }
}
本段列举的音频格式与采样率选项适用于 qwen3.5-omni-plus-realtime 和 qwen3.5-omni-flash-realtime 模型,历史兼容字段 input_audio_format / output_audio_format 仍有效,建议采用 audio.input.format / audio.output.format 字段。
每通会话结束后,发送 session.finish 事件关闭会话,或直接断开 WebSocket 连接。同一会话不关闭会导致上下文持续累积。 多通道音频、视频聚合和 MCP 的配置及 SDK 示例见扩展会话配置。

3. 输入音频与图片

音频输入是推荐的主要输入方式;图片输入可选。模型也支持纯文本输入:通过 conversation.item.create 发送 input_text 类型内容,无需音频,适用于非实时对话场景。模型目录标注的“支持文本输入”包括用户纯文本对话、system instructions 和 function_call_output。输入方式取决于接入协议。
  • WebSocket
  • WebRTC
客户端通过input_audio_buffer.append和 input_image_buffer.append 事件发送 Base64 编码的音频和图片数据到服务端缓冲区。
图片可以来自本地文件,或从视频流中实时采集。
启用服务端VAD时,服务端会在检测到语音结束时自动提交数据并触发响应。禁用VAD时(手动模式),客户端必须在发送完数据后,主动调用input_audio_buffer.commit事件来提交。

4. 接收模型响应

模型的响应格式取决于配置的输出模态。
  • WebSocket
  • WebRTC

模型选型

实时音视频对话优先使用 Qwen3.8-Omni-Flash-Realtime。模型支持音视频双工交互,接收文本、图片、流式音频和视频输入,返回文本与音频。支持 WebSocket、WebRTC 和 AOQ 接入,接入方式见建立连接。
模型的名称、上下文、价格、快照版本等信息请参见百炼控制台;并发限流条件请参考限流。

使用限制

qwen3.8-omni-flash-realtime 的全部输入 Token 总数上限为 196608,输入长度计算规则与 Qwen3.5-Omni-Realtime 一致。
  • 联网搜索和工具调用不兼容,不可同时开启。
  • 单次会话最长可持续 120 分钟,达到此上限后服务将主动关闭连接。
  • 模型会维护对话历史上下文,当对话轮次或累计时长超过以下限制时,将自动丢弃更早的历史信息。最大时长指模型上下文中能保留的音频或视频(图像帧)累计时长上限。该时长不是整个会话的持续时间。
    由于视频以抽帧方式输入(建议 1 帧/秒),视频最大时长即模型能保留的图像帧累计时长。例如 240 秒表示模型最多保留最近 240 秒内收到的帧,超过后更早的帧将被丢弃。

    模型

    音频最大轮次

    视频最大轮次

    音频最大时长

    视频最大时长

    qwen3.8-omni-flash-realtime

    100轮

    50轮

    600秒

    240秒

    qwen3.5-omni-plus-realtime

    100轮

    50轮

    600秒

    240秒

    qwen3.5-omni-flash-realtime

    80轮

    50轮

    480秒

    120秒

  • 调用 close() 关闭 WebSocket 连接时,若连接刚建立即关闭(无会话交互),关闭耗时约 5-10 秒,此为正常现象。服务端需完成音频流处理、上下文缓存及推理资源初始化后才能响应关闭请求。建议异步执行 close() 操作,避免阻塞主流程。

快速开始

您需要获取与配置 API Key并配置API Key到环境变量。 请选择您熟悉的编程语言,通过以下步骤快速体验与 Realtime 模型实时对话的功能。
  • WebSocket
  • WebRTC

最小音频问答

先配置 API Key,安装 websocket-client。将 REALTIME_WS_URL 设为建立连接中对应地域的完整 WebSocket 地址并替换业务空间 ID;示例自动添加模型查询参数。将 PCM_FILE 设为一段短的 16 kHz、16-bit little-endian、单声道、无文件头 PCM 语音文件路径。示例使用 Manual 模式:等待会话配置生效后发送音频、提交缓冲区,再请求回复。文本打印到终端,音频写入 reply.pcm(24 kHz PCM,非 WAV 文件)。在 macOS 或 Linux 终端中执行以下命令。将 WebSocket 地址替换为所选地域、业务空间的服务地址,无需手动添加模型查询参数。
python3 -m pip install websocket-client
export REALTIME_WS_URL="<workspace-websocket-url>"
export PCM_FILE="./input.pcm"
如果已有单声道、16 kHz、16-bit PCM 编码的 input.wav,可用 Python 提取 PCM 音频。此步骤检查格式,不进行重采样。
import wave
from pathlib import Path

with wave.open("input.wav", "rb") as source:
    if (source.getnchannels(), source.getframerate(), source.getsampwidth(),
            source.getcomptype()) != (1, 16000, 2, "NONE"):
        raise ValueError("Expected mono 16 kHz, 16-bit PCM WAV audio.")
    Path("input.pcm").write_bytes(source.readframes(source.getnframes()))
准备好输入后,运行以下客户端。示例使用“龙安灵心”音色(longanlingxin):
import base64
import json
import os
from pathlib import Path
from urllib.parse import parse_qsl, urlencode, urlsplit, urlunsplit
import websocket

parts = urlsplit(os.environ["REALTIME_WS_URL"])
query = dict(parse_qsl(parts.query))
query["model"] = "qwen3.8-omni-flash-realtime"
url = urlunsplit((parts.scheme, parts.netloc, parts.path, urlencode(query), ""))
audio = Path(os.environ["PCM_FILE"]).read_bytes()
if not audio or len(audio) % 2:
    raise ValueError("Provide non-empty 16-bit mono PCM audio.")

ws = websocket.create_connection(
    url,
    header=["Authorization: Bearer " + os.environ["DASHSCOPE_API_KEY"]],
    timeout=30,
)

def receive():
    event = json.loads(ws.recv())
    if event["type"] == "error":
        raise RuntimeError(event.get("error"))
    return event

try:
    while receive()["type"] != "session.created":
        pass
    ws.send(json.dumps({
        "type": "session.update",
        "session": {
            "modalities": ["text", "audio"],
            "turn_detection": None,
            "audio": {
                "input": {"format": {
                    "type": "pcm", "sample_rate": 16000,
                    "sample_format": "s16le", "channels": 1,
                    "packing": "interleaved", "channel_layout": "mono",
                }},
                "output": {
                    "voice": "longanlingxin",
                    "format": {"type": "pcm", "sample_rate": 24000},
                },
            },
        },
    }))
    while receive()["type"] != "session.updated":
        pass
    for offset in range(0, len(audio), 3200):
        ws.send(json.dumps({
            "type": "input_audio_buffer.append",
            "audio": base64.b64encode(audio[offset:offset + 3200]).decode("ascii"),
        }))
    ws.send(json.dumps({"type": "input_audio_buffer.commit"}))
    while receive()["type"] != "input_audio_buffer.committed":
        pass
    ws.send(json.dumps({"type": "response.create"}))
    with open("reply.pcm", "wb") as output:
        while True:
            event = receive()
            if event["type"] == "response.audio.delta":
                output.write(base64.b64decode(event["delta"]))
            elif event["type"] in ("response.audio_transcript.delta", "response.text.delta"):
                print(event["delta"], end="", flush=True)
            elif event["type"] == "response.done":
                print("\nResponse status:", event["response"]["status"])
                break
finally:
    ws.close()
成功收到回复后,将 reply.pcm 包装为 WAV 文件,再使用音频播放器播放:
import wave
from pathlib import Path

with wave.open("reply.wav", "wb") as target:
    target.setnchannels(1)
    target.setsampwidth(2)
    target.setframerate(24000)
    target.writeframes(Path("reply.pcm").read_bytes())

实时录音示例

  • DashScope Python SDK
  • DashScope Java SDK
  • WebSocket(Python)
  • 准备运行环境
您的 Python 版本需要不低于 3.10。首先根据您的操作系统安装 pyaudio。
  • macOS
  • Debian/Ubuntu
  • CentOS
  • Windows
brew install portaudio && pip install pyaudio
安装完成后,通过 pip 安装依赖:
pip install websocket-client dashscope
  • 选择交互模式
    • VAD 模式(Voice Activity Detection,自动检测语音起止) 服务端自动判断用户何时开始与停止说话并作出回应。
    • Manual 模式(按下即说,松开即发送) 客户端控制语音起止。用户说话结束后,客户端需主动发送消息至服务端。
    • VAD 模式
    • Manual 模式
    新建一个 python 文件,命名为vad_dash.py,并将以下代码复制到文件中:
    # 依赖:dashscope >= 1.26.5,pyaudio
    import os
    import base64
    import time
    import pyaudio
    from dashscope.audio.qwen_omni import MultiModality, AudioFormat,OmniRealtimeCallback,OmniRealtimeConversation
    import dashscope
    
    # 配置参数:地址、API Key、音色、模型、模型角色
    # 指定地域,设为cn表示华北2(北京)地域,设为intl表示新加坡地域。请将 {WorkspaceId} 替换为您的百炼业务空间ID。
    region = 'cn'
    base_domain = '{WorkspaceId}.cn-beijing.maas.aliyuncs.com' if region == 'cn' else '{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com'
    url = f'wss://{base_domain}/api-ws/v1/realtime'
    # 配置 API Key,若没有设置环境变量,请用 API Key 将下行替换为 dashscope.api_key = "sk-xxx"
    dashscope.api_key = os.getenv('DASHSCOPE_API_KEY')
    # 指定音色
    voice = 'Tina'
    # 指定模型
    model = 'qwen3.8-omni-flash-realtime'
    # 指定模型角色
    instructions = "你是个人助理小云,请用幽默风趣的方式回答用户的问题"
    class SimpleCallback(OmniRealtimeCallback):
        def __init__(self, pya):
            self.pya = pya
            self.out = None
        def on_open(self):
            # 初始化音频输出流
            self.out = self.pya.open(
                format=pyaudio.paInt16,
                channels=1,
                rate=24000,
                output=True
            )
        def on_event(self, response):
            if response['type'] == 'response.audio.delta':
                # 播放音频
                self.out.write(base64.b64decode(response['delta']))
            elif response['type'] == 'conversation.item.input_audio_transcription.delta':
                # 流式预览:text为已确认前缀,stash为待确认后缀
                preview = response.get('text', '') + response.get('stash', '')
                print(f"\r[User] {preview}", end='', flush=True)
            elif response['type'] == 'conversation.item.input_audio_transcription.completed':
                # 转录完成,打印最终文本并换行
                print(f"\r[User] {response['transcript']}")
            elif response['type'] == 'response.audio_transcript.done':
                # 打印助手回复文本
                print(f"[LLM] {response['transcript']}")
    
    # 1. 初始化音频设备
    pya = pyaudio.PyAudio()
    # 2. 创建回调函数和会话
    callback = SimpleCallback(pya)
    conv = OmniRealtimeConversation(model=model, callback=callback, url=url)
    # 3. 建立连接并配置会话
    conv.connect()
    conv.update_session(output_modalities=[MultiModality.AUDIO, MultiModality.TEXT], voice=voice, instructions=instructions)
    # 4. 初始化音频输入流
    mic = pya.open(format=pyaudio.paInt16, channels=1, rate=16000, input=True)
    # 5. 主循环处理音频输入
    print("对话已开始,对着麦克风说话 (Ctrl+C 退出)...")
    try:
        while True:
            audio_data = mic.read(3200, exception_on_overflow=False)
            conv.append_audio(base64.b64encode(audio_data).decode())
            time.sleep(0.01)
    except KeyboardInterrupt:
        # 清理资源
        conv.close()
        mic.close()
        callback.out.close()
        pya.terminate()
        print("\n对话结束")
    
    运行vad_dash.py,通过麦克风即可与 Qwen-Omni-Realtime 模型实时对话,系统会检测您的音频起始位置并自动发送到服务器,无需您手动发送。

交互流程

  • VAD 模式
  • Manual 模式
将session.update事件的session.turn_detection.type 设为"server_vad"或"semantic_vad"以启用 VAD 模式。适用于语音通话场景。WebSocket 和 WebRTC 均支持 VAD 模式,两者的服务端事件一致,区别在于音频和图片的传输方式不同。
WebRTC 仅支持 VAD 模式,不支持 Manual 模式。WebRTC 的音频通过 RTP 直接传输,无需发送 input_audio_buffer.append 事件;图片通过视频轨道传输,不支持 input_image_buffer.append 事件。控制指令和服务端事件通过 DataChannel 传输,事件类型与 WebSocket 一致。
交互流程如下:
  1. 客户端发送音频数据。WebSocket 通过 input_audio_buffer.append 事件发送;WebRTC 通过音频轨道(RTP)自动传输,无需手动发送事件。
  2. 服务端检测到语音开始,通过 DataChannel(WebRTC)或 WebSocket 发送 input_audio_buffer.speech_started 事件。
  3. 服务端检测到语音结束,发送input_audio_buffer.speech_stopped 事件。
  4. 服务端自动提交音频缓冲区,发送input_audio_buffer.committed 事件。
  5. 服务端开始生成响应,依次发送 response.created、conversation.item.created 等事件。模型的音频回复通过 WebSocket 的 response.audio.delta 事件增量返回,或通过 WebRTC 的音频轨道(RTP)直接传输。
  6. 响应过程中,服务端通过 response.audio_transcript.delta 事件增量返回文字转录,最终发送 response.done 事件标志响应完成。
生命周期客户端事件服务端事件
会话初始化session.update
会话配置
session.created
会话已创建
session.updated
会话配置已更新
用户音频输入input_audio_buffer.append
WebSocket:通过此事件添加音频到缓冲区
input_image_buffer.append
WebSocket:通过此事件添加图片到缓冲区
WebRTC:音频通过 RTP 音频轨道自动传输,图片通过视频轨道传输,无需发送上述事件。
input_audio_buffer.speech_started
检测到语音开始
input_audio_buffer.speech_stopped
检测到语音结束
input_audio_buffer.committed
服务器收到提交的音频
服务器音频输出无response.created
服务端开始生成响应
response.output_item.added
响应时有新的输出内容
conversation.item.created
对话项被创建
response.content_part.added
新的输出内容添加到assistant message
response.audio_transcript.delta
增量生成的转录文字
response.audio.delta
WebSocket:模型增量生成的音频通过此事件返回。WebRTC:音频通过 RTP 音频轨道直接传输,不返回此事件。
response.audio_transcript.done
文本转录完成
response.audio.done
音频生成完成
response.content_part.done
Assistant message 的文本或音频内容流式输出完成
response.output_item.done
Assistant message 的整个输出项流式传输完成
response.done
响应完成
conversation.item.input_audio_transcription.delta
用户语音输入的文字流式转录(需在 session.update 中启用 input_audio_transcription)
conversation.item.input_audio_transcription.completed
用户语音输入的文字转录完成(需在 session.update 中启用 input_audio_transcription)

多通道音频、视频聚合与 MCP

以下配置适用于 Qwen3.8-Omni-Flash-Realtime。
  • 多通道音频(WebSocket 接入):在首段音频前设置 session.audio.input.format。支持 1、2、4 声道;多通道必须为 PCM、16000 Hz、s16le、interleaved。2 声道使用 raw_mic_array,4 声道使用 foa_ambix。字段约束和 JSON 片段见客户端事件。
  • 视频聚合:session.video.input.representation_compact 默认为 none;设为 normal 可聚合视频表征,降低计算开销,适用于不依赖细粒度视觉信息的场景。也必须在首段音频前配置,开始输入后不得修改。
  • 音色:默认音色为 Tina。新接入使用 session.audio.output.voice;如果同时设置了它和兼容字段 session.voice,输出音频使用 session.audio.output.voice 指定的音色。可选音色及声音复刻入口见音色列表。
  • MCP:在 session.tools 中配置公网 HTTPS MCP Streamable HTTP 服务;仅在没有活动 Response 时更新 MCP 配置。默认需要审批。先确认工具发现完成,再发起需要该工具的 Response。执行结果、拒绝和失败处理以及续答步骤见MCP 交互流程。

SDK 配置视频聚合

Qwen3.8-Omni-Flash-Realtime 使用 DashScope Python SDK 1.26.5 及以上版本,或 Java SDK 2.22.15 及以上版本。视频聚合参数通过 SDK 透传:Python 在 update_session 中传入 video,Java 通过 OmniRealtimeConfig.builder().parameters(...) 传入。 以下示例配置一个 Manual 模式会话:文本与音频输出、Tina 音色、关闭输入转写,并启用视频聚合。先按下方 SDK 示例建立连接,将模型设为 qwen3.8-omni-flash-realtime,用本例替换该示例的会话配置调用,在首段音频输入前调用一次。conversation 为已连接的 SDK 会话。SDK 会同时发送音色、VAD 等配置;如需其他音色、VAD 或转写设置,在同一次调用中完整设置。Java 需导入 java.util.Arrays、java.util.Map、java.util.HashMap、com.alibaba.dashscope.audio.omni.OmniRealtimeConfig 和 com.alibaba.dashscope.audio.omni.OmniRealtimeModality。
from dashscope.audio.qwen_omni import MultiModality

conversation.update_session(
    output_modalities=[MultiModality.AUDIO, MultiModality.TEXT],
    voice="Tina",
    enable_turn_detection=False,
    enable_input_audio_transcription=False,
    video={
        "input": {
            "representation_compact": "normal",
        },
    },
)

联网搜索

联网搜索功能使模型能够基于实时检索数据进行回复,适用于股票价格、天气预报等需要即时信息的场景。模型可自主判断是否需要搜索来回应用户的即时问题。
Qwen3.8-Omni-Flash-Realtime 和 Qwen3.5-Omni-Realtime 系列模型支持联网搜索,且默认关闭,需通过 session.update 事件启用。
计费请参考计费说明中的agent策略。

启用方式

在 session.update 事件中添加以下参数:
  • enable_search:设置为 true 启用联网搜索功能。
  • search_options.enable_source:设置为 true 返回搜索结果来源列表。
参数详情请参见session.update。

响应格式

启用联网搜索后,response.done 事件中的 usage 会新增 plugins 字段,用于记录搜索计量信息:
{
    "usage": {
        "total_tokens": 2937,
        "input_tokens": 2554,
        "output_tokens": 383,
        "input_tokens_details": {
            "text_tokens": 2512,
            "audio_tokens": 42
        },
        "output_tokens_details": {
            "text_tokens": 90,
            "audio_tokens": 293
        },
        "plugins": {
            "search": {
                "count": 1,
                "strategy": "agent"
            }
        }
    }
}

代码示例

以下示例展示如何在实时对话中启用联网搜索功能。
  • DashScope Python SDK
  • DashScope Java SDK
  • WebSocket(Python)
在 update_session 调用中传入 enable_search 和 search_options 参数:
import os
import base64
import time
import json
import pyaudio
from dashscope.audio.qwen_omni import MultiModality, AudioFormat, OmniRealtimeCallback, OmniRealtimeConversation
import dashscope

dashscope.api_key = os.getenv('DASHSCOPE_API_KEY')
# 以下为华北2(北京)地域的URL。请将 {WorkspaceId} 替换为您的百炼业务空间ID,各地域的URL不同。
url = 'wss://{WorkspaceId}.cn-beijing.maas.aliyuncs.com/api-ws/v1/realtime'
model = 'qwen3.8-omni-flash-realtime'
voice = 'Tina'

class SearchCallback(OmniRealtimeCallback):
    def __init__(self, pya):
        self.pya = pya
        self.out = None
    def on_open(self):
        self.out = self.pya.open(format=pyaudio.paInt16, channels=1, rate=24000, output=True)
    def on_event(self, response):
        if response['type'] == 'response.audio.delta':
            self.out.write(base64.b64decode(response['delta']))
        elif response['type'] == 'conversation.item.input_audio_transcription.delta':
            preview = response.get('text', '') + response.get('stash', '')
            print(f"\r[User] {preview}", end='', flush=True)
        elif response['type'] == 'conversation.item.input_audio_transcription.completed':
            print(f"\r[User] {response['transcript']}")
        elif response['type'] == 'response.audio_transcript.done':
            print(f"[LLM] {response['transcript']}")
        elif response['type'] == 'response.done':
            usage = response.get('response', {}).get('usage', {})
            plugins = usage.get('plugins', {})
            if plugins.get('search'):
                print(f"[Search] count={plugins['search']['count']}, strategy={plugins['search']['strategy']}")

pya = pyaudio.PyAudio()
callback = SearchCallback(pya)
conv = OmniRealtimeConversation(model=model, callback=callback, url=url)
conv.connect()
conv.update_session(
    output_modalities=[MultiModality.AUDIO, MultiModality.TEXT],
    voice=voice,
    instructions="你是个人助理小云",
    enable_search=True,
    search_options={'enable_source': True}
)
mic = pya.open(format=pyaudio.paInt16, channels=1, rate=16000, input=True)
print("联网搜索已启用,对着麦克风说话 (Ctrl+C 退出)...")
try:
    while True:
        audio_data = mic.read(3200, exception_on_overflow=False)
        conv.append_audio(base64.b64encode(audio_data).decode())
        time.sleep(0.01)
except KeyboardInterrupt:
    conv.close()
    mic.close()
    callback.out.close()
    pya.terminate()
    print("\n对话结束")

API 参考

通过 AOQ 接入的流程和示例,请参见AOQ 接入。支持的模型及版本请参见模型与协议支持范围。

计费与限流

计费规则

Qwen-Omni-Realtime 模型根据不同模态(音频、图像)对应的Token数计费。计费详情请参见百炼控制台。 输出语音时,qwen3.8-omni-flash-realtime 的音频及对应文本分别按音频输出和文本输出单价计费;Qwen3.5-Omni-Realtime 系列仅对音频计费,对应文本不计费。 MCP 工具调用不额外收费,模型推理仍按模型价格计费。MCP 的调用流程与使用限制见MCP 交互流程。
在多轮实时对话中,模型每次生成响应时,需要将上下文窗口内的所有历史对话内容(包括之前各轮的音频、图片和文本)与本轮新增输入一并作为输入 Token 进行处理。因此,输入 Token 会随对话轮次的增加而逐轮累积,而非仅计算当前轮次的新增输入。例如,假设一段 10 秒的音频输入转换为 70 个 Token(Qwen3.5-Omni-Realtime 系列模型),在第 3 轮对话时,该音频仍在上下文窗口内,则它依然会被计入第 3 轮的输入 Token。实际计费的输入 Token 数 = 上下文窗口内所有历史轮次的内容 Token 数 + 本轮新增输入的 Token 数。
  • 音频
  • 图片
  • 视频
  • Qwen3.8-Omni-Flash-Realtime、Qwen3.5-Omni-Realtime 系列模型:
    • 输入音频计算公式:总 Token 数 = 音频时长(单位:秒)* 7
    • 输出音频计算公式:总 Tokens 数 = 音频时长(单位:秒)* 12.5
  • qwen3-omni-flash-realtime-2025-09-15:输入与输出音频的计算公式均为总 Token 数 = 音频时长(单位:秒)* 12.5 若音频时长不足1秒,则按 1 秒计算。
qwen3.8-omni-flash-realtime 开启空间音频输入时,音频输入 Token 数为普通音频的 2 倍,2 通道和 4 通道的倍数相同。

限流

模型限流规则请参见限流。

常见问题

如何在线体验 Qwen-Omni-Realtime 模型?

A:您可以通过以下方式一键部署:
  1. 访问函数计算模板,部署类型选择直接部署,百炼 API-KEY 填入您的 API Key;单击创建并部署默认环境。
  2. 等待约一分钟,在环境详情的环境信息中获取访问域名,将访问域名的http改成https(示例:https://omni-realtime.fcv3.xxxx.cn-hangzhou.fc.devsapp.net),修改后的 HTTPS 链接指向一个可在线体验的 Web 应用,可通过它与模型进行实时视频或语音通话。
此链接使用自签名证书,仅用于临时测试。首次访问时,浏览器会显示安全警告,这是预期行为,请勿在生产环境使用。如需继续,请按浏览器提示操作(如点击“高级” → “继续前往(不安全)”)。
通过资源信息-函数资源查看项目源代码。
函数计算与阿里云百炼均为新用户提供免费额度,可以覆盖简单调试所需成本,额度耗尽后按量计费。只有在访问的情况下会产生费用。

怎么向模型输入图片?

A:输入方式取决于接入协议。 WebSocket:通过客户端发送input_image_buffer.append事件。
  • VAD 模式 该模式会根据语音检测情况自动提交音频与图片,请在服务端响应input_audio_buffer.speech_stopped前发送input_image_buffer.append事件。
  • Manual 模式 参见实时录音示例,依次选择“WebSocket(Python)”和“Manual 模式”,展开 manual_mode.py,取消注释图片输入与提交的两部分代码,即可传入本地图片。
WebRTC:通过视频轨道(RTP)发送画面帧,无需发送 input_image_buffer.append 事件。 若用于视频通话场景,可以对视频抽帧,建议以 1张/秒 的频率向服务端发送图像。input_image_buffer.append 事件。 DashScope SDK 代码请参见Omni-Realtime 示例代码。

收不到 ASR 转录文本(transcript)怎么办?

A:如果没有收到 conversation.item.input_audio_transcription.completed 事件,或事件中的 transcript 为空,请依次检查:
  1. 输入转录配置。DashScope Python SDK 的 update_session 参数 enable_input_audio_transcription 默认为 True;设为 False 时,SDK 会将会话中的 input_audio_transcription 置为 null。直接使用 WebSocket,或通过 WebRTC DataChannel 发送会话配置时,按输入音频转录配置检查发送的 session.update.session.input_audio_transcription。enable_input_audio_transcription 是 SDK 参数,不是 session.update 的顶层字段。
  2. 转录失败事件。同时监听 conversation.item.input_audio_transcription.failed。失败时可从事件的 error.code、error.message 和 error.param 查看错误信息。
  3. 音频是否完成提交。VAD 模式下检查服务端是否检测到语音起止;Manual 模式下确认已发送 input_audio_buffer.commit。没有提交本轮音频时,不要只等待转录完成事件。
  4. 连接和 SDK 版本。确认本轮音频输入期间连接未中断;WebRTC 接入还需检查 DataChannel 状态。使用 DashScope Python SDK 时,核对版本符合本文的最低要求(1.26.5)。

错误码

如果模型调用失败并返回报错信息,请参见错误码进行解决。

音色列表

Qwen-Omni-Realtime模型的音色列表可参见音色列表。
Token Plan
模型体验
模型调优
模型压缩
用量统计与性能监控
资产中心
服务支持