Skip to main content
全模態

Qwen-Omni-Realtime

Qwen-Omni-Realtime 是千問推出的即時音視訊交談模型。能同時理解流式的音頻與映像輸入(例如從視頻流中即時抽取的連續映像幀),並即時輸出高品質的文本與音頻。

支援的地區:新加坡、北京,需使用各地區的API Key

如何使用

1. 建立串連

Qwen-Omni-Realtime 模型支援 WebSocket、WebRTC 和 AOQ 三種協議接入。WebSocket 適合服務端整合和快速接入;WebRTC 適合瀏覽器端、低延遲語音情境,音頻通過 UDP 直接傳輸,內建回聲消除和降噪。如果是用戶端對接,且更看重穩定的延遲、弱網下的互動能力、即時雙工的降噪與回聲消除,可優先考慮 AOQ。協議對比與選型請參見Realtime API 概述
  • WebSocket
  • WebRTC
  • 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.5-omni-plus-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")
# 以下為新加坡地區URL,調用時請將{WorkspaceId}替換為真實的業務空間ID,各地區的URL不同。
API_URL = "wss://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/api-ws/v1/realtime?model=qwen3.5-omni-plus-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
{
    // 該事件的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-realtimeqwen3.5-omni-flash-realtime 模型,歷史相容欄位 input_audio_format / output_audio_format 仍有效,建議採用 audio.input.format / audio.output.format 欄位。
每通會話結束後,發送 session.finish 事件關閉會話,或直接斷開 WebSocket 串連。同一會話不關閉會導致上下文持續累積。

3. 輸入音頻與圖片

音頻輸入是推薦的主要輸入方式;圖片輸入可選。模型也支援純文字輸入:通過 conversation.item.create 發送 input_text 類型內容,無需音頻,適用於非即時對話情境。模型目錄標註的“支援文本輸入”包括使用者純文字對話、system instructions 和 function_call_output。輸入方式取決於接入協議。
  • WebSocket
  • WebRTC
用戶端通過input_audio_buffer.append和 input_image_buffer.append 事件發送 Base 64 編碼的音頻和圖片資料到服務端緩衝區。
圖片可以來自本地檔案,或從視頻流中即時採集。
啟用服務端VAD時,服務端會在檢測到語音結束時自動認可資料並觸發響應。禁用VAD時(手動模式),用戶端必須在發送完資料後,主動調用input_audio_buffer.commit事件來提交。

4. 接收模型響應

模型的響應格式取決於配置的輸出模態。
  • WebSocket
  • WebRTC

模型選型

Qwen3.5-Omni-Realtime 系列模型是千問最新推出的即時多模態模型,相比於上一代的 Qwen3-Omni-Flash-Realtime:
  • 智能水平 模型智力大幅提升,與 Qwen3.5-Plus 智能水平相當。
  • 連網搜尋 原生支援連網搜尋(WebSearch),模型可自主判斷是否需要搜尋來回應即時問題。詳見連網搜尋
  • 工具調用 支援 Function Calling,模型可自主判斷是否需要調用外部工具,實現與外部系統的互動。詳見Qwen-Omni-Realtime 系列
  • 語義打斷 自動識別對話意圖,避免附和聲和無意義背景音觸發打斷。
  • 語音控制 通過語音指令控制聲音大小、語速和情緒,如“語速快一些”、“聲音大一些”、“用開心的語氣”等。
  • 支援的語言 支援 113 種語種和方言的語音辨識,以及 36 種語種和方言的語音產生。
  • 支援的音色 支援 55 種音色(47 種多語言 + 8 種方言),具體可查看音色列表
  • 聲音複刻 qwen3.5-omni-plus-realtime 和 qwen3.5-omni-flash-realtime 支援聲音複刻功能,可使用自訂音色進行即時對話。詳見聲音複刻
模型的名稱、上下文、價格、快照版本等資訊請參見百鍊控制台;並發限流條件請參考限流

響應延遲與最佳化

Qwen3.5-Omni-Realtime 系列這類端到端即時多模態模型,在單個模型內同時完成語音辨識、語義理解與語音產生,各環節無法像 ASR+LLM+TTS 拼接方案那樣獨立並行、單獨最佳化,因此端到端方案的總回應時間通常高於拼接方案中單獨的 LLM 環節。以 DashScope WebSocket API 為例,文本輸入、voice=Tinasilence_duration_ms=800 情境下的實測參考值:qwen3.5-omni-flash-realtime 總響應約 5.1 秒,拼接方案中 LLM 環節單獨調用約 3.1 秒,端到端比該 LLM 環節慢約 2.0 秒。以上為特定參數下的單次實測參考值,實際耗時會隨輸入長度、網路狀況和語音活動檢測(VAD)配置變化。

最佳化建議

  1. 優先使用 Flash 版本:實測 qwen3.5-omni-flash-realtime 總響應約 5.1 秒,qwen3.5-omni-plus-realtime 約 5.8 秒,flash 比 plus 快約 0.7 秒(714 毫秒)。對響應時效性敏感的情境建議優先選用 flash 版本。
  2. 降低網路延遲:WebSocket 串連的往返時延會直接疊加到端到端回應時間上,建議將商務服務部署在靠近所調用地區服務端的地區(該模型支援華北 2(北京)和新加坡地區),並按“1. 建立串連”中的地區說明選擇對應的調用地址。

使用限制

  • 連網搜尋和工具調用不相容,不可同時開啟。
  • 單次會話最長可持續 120 分鐘,達到此上限後服務將主動關閉串連。
  • 模型會維護對話歷史上下文,當對話輪次或累計時間長度超過以下限制時,將自動丟棄更早的歷史資訊。最大時間長度指模型上下文中能保留的音頻或視頻(映像幀)累計時間長度上限。
    由於視頻以抽幀方式輸入(建議 1 幀/秒),視頻最大時間長度即模型能保留的映像幀累計時間長度。例如 240 秒錶示模型最多保留最近 240 秒內收到的幀,超過後更早的幀將被丟棄。
    qwen3-omni-flash-realtime 最大輪次為 8 輪,一般會先觸及輪次限制,時間長度限制為模型的上下文長度限制,不再單獨列出。

    模型

    音頻最大輪次

    視頻最大輪次

    音頻最大時間長度

    視頻最大時間長度

    qwen3.5-omni-plus-realtime

    100輪

    50輪

    600秒

    240秒

    qwen3.5-omni-flash-realtime

    80輪

    50輪

    480秒

    120秒

    qwen3-omni-flash-realtime

    8輪

    8輪

  • 調用 close() 關閉 WebSocket 串連時,若串連剛建立即關閉(無會話互動),關閉耗時約 5-10 秒,此為正常現象。服務端需完成音頻流處理、上下文緩衝及推理資源初始化後才能響應關閉請求。建議非同步執行 close() 操作,避免阻塞主流程。

快速開始

您需要擷取與配置 API Key配置API Key到環境變數 請選擇您熟悉的程式設計語言,通過以下步驟快速體驗與 Realtime 模型即時對話的功能。
  • WebSocket
  • WebRTC
  • 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.23.9,pyaudio
    import os
    import base64
    import time
    import pyaudio
    from dashscope.audio.qwen_omni import MultiModality, AudioFormat,OmniRealtimeCallback,OmniRealtimeConversation
    import dashscope
    
    # 配置參數:地址、API Key、音色、模型、模型角色
    # 指定地區,設為intl表示新加坡地區,設為cn表示華北2(北京)地區。請將 {WorkspaceId} 替換為您的百鍊業務空間ID。
    region = 'intl'
    base_domain = '{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com' if region == 'intl' else '{WorkspaceId}.cn-beijing.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 = 'Ethan'
    # 指定模型
    model = 'qwen3.5-omni-plus-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.createdconversation.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)

連網搜尋

連網搜尋功能使模型能夠基於即時檢索資料進行回複,適用於股票價格、天氣預報等需要即時資訊的情境。模型可自主判斷是否需要搜尋來回應使用者的即時問題。
連網搜尋僅 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_searchsearch_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')
# 以下為新加坡地區URL,調用時請將{WorkspaceId}替換為真實的業務空間ID,各地區的URL不同。
url = 'wss://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/api-ws/v1/realtime'
model = 'qwen3.5-omni-plus-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 參考

計費與限流

計費規則

Qwen-Omni-Realtime 模型根據不同模態(音頻、映像)對應的Token數計費。計費詳情請參見百鍊控制台。
在多輪即時對話中,模型每次產生響應時,需要將上下文視窗內的所有歷史對話內容(包括之前各輪的音頻、圖片和文本)與本輪新增輸入一併作為輸入 Token 進行處理。因此,輸入 Token 會隨對話輪次的增加而逐輪累積,而非僅計算當前輪次的新增輸入。例如,假設一段 10 秒的音頻輸入轉換為 70 個 Token(Qwen3.5-Omni-Realtime 系列模型),在第 3 輪對話時,該音頻仍在上下文視窗內,則它依然會被計入第 3 輪的輸入 Token。實際計費的輸入 Token 數 = 上下文視窗內所有歷史輪次的內容 Token 數 + 本輪新增輸入的 Token 數。
  • 音頻
  • 圖片
  • Qwen3.5-Omni-Realtime 系列模型:
    • 輸入音頻計算公式:總 Token 數 = 音頻時間長度(單位:秒)* 7
    • 輸出音頻計算公式:總 Tokens 數 = 音頻時間長度(單位:秒)* 12.5
  • Qwen3-Omni-Flash-Realtime系列模型:輸入與輸出音訊計算公式均為總 Token 數 = 音頻時間長度(單位:秒)* 12.5
  • Qwen-Omni-Turbo-Realtime系列模型:輸入與輸出音訊計算公式均為總 Token 數 = 音頻時間長度(單位:秒)* 25 若音頻時間長度不足1秒,則按 1 秒計算。

限流

模型限流規則請參見限流

錯誤碼

如果模型調用失敗並返回報錯資訊,請參見錯誤碼進行解決。

音色列表

Qwen-Omni-Realtime模型的音色列表可參見音色列表
Token Plan
模型體驗
用量統計與效能監控
資產中心
服務支援