Skip to main content
Omni-modal

Qwen-Omni-Realtime

Qwen-Omni-Realtime memproses input audio dan gambar streaming (termasuk frame video) serta menghasilkan respons teks dan audio secara real-time.

Wilayah yang didukung: Singapura, China (Beijing). Setiap wilayah memerlukan API key sendiri.

Cara menggunakan

1. Membuat koneksi

Qwen-Omni-Realtime mendukung WebSocket dan WebRTC. WebSocket cocok untuk integrasi sisi server dengan pengaturan cepat. WebRTC ditujukan untuk skenario suara berlatensi rendah berbasis browser, mentransmisikan audio melalui UDP dengan pembatalan gema dan reduksi kebisingan bawaan.
  • WebSocket
  • WebRTC
  • WebSocket Native
  • DashScope Python SDK
  • DashScope Java SDK
Parameter koneksi:
ParameterDeskripsi
EndpointWilayah China (Beijing): wss://{WorkspaceId}.cn-beijing.maas.aliyuncs.com/api-ws/v1/realtimeWilayah Singapura: wss://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/api-ws/v1/realtimeGanti {WorkspaceId} dengan workspace ID Anda yang sebenarnya.
Parameter kueriGunakan parameter kueri model untuk menentukan model. Contoh: ?model=qwen3.5-omni-plus-realtime
Header permintaanGunakan token Bearer untuk autentikasi: Authorization: Bearer DASHSCOPE_API_KEY
DASHSCOPE_API_KEY adalah API key dari Model Studio.
# pip install websocket-client
import json
import websocket
import os

API_KEY=os.getenv("DASHSCOPE_API_KEY")
# Wilayah Singapura. Ganti {WorkspaceId} dengan workspace ID Bailian Anda. URL berbeda-beda tergantung wilayah.
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. Mengonfigurasi sesi

Kirim event klien session.update:
{
    // ID event yang dihasilkan klien.
    "event_id": "event_ToPZqeobitzUJnt3QqtWg",
    // Jenis event. Harus "session.update".
    "type": "session.update",
    // Konfigurasi sesi.
    "session": {
        // Modalitas output. Atur ke ["text"] untuk output teks saja, atau ["text", "audio"] untuk output teks dan audio.
        "modalities": [
            "text",
            "audio"
        ],
        // Suara untuk output audio.
        "voice": "Ethan",
        // Format audio input. Hanya "pcm" yang didukung. Input audio harus berupa aliran audio PCM dengan laju sampel 16 kHz.
        "input_audio_format": "pcm",
        // Format audio output. Hanya "pcm" yang didukung. Output audio adalah aliran audio PCM dengan laju sampel 24 kHz.
        "output_audio_format": "pcm",
        // Instruksi sistem untuk menentukan tujuan atau peran model.
        "instructions": "Anda adalah agen layanan pelanggan AI untuk hotel bintang lima. Jawab pertanyaan pelanggan tentang jenis kamar, fasilitas, harga, dan kebijakan pemesanan secara akurat dan ramah. Selalu tanggapi dengan sikap profesional dan membantu. Jangan memberikan informasi yang belum dikonfirmasi atau informasi di luar cakupan layanan hotel.",
        // Mengaktifkan deteksi aktivitas suara (VAD) di sisi server. Jika diaktifkan, server secara otomatis mendeteksi awal dan akhir ucapan.
        // Jika null, klien mengontrol kapan memicu respons model.
        "turn_detection": {
            // Jenis VAD. Nilai valid: "server_vad" dan "semantic_vad". Kami merekomendasikan "semantic_vad" untuk model seri qwen3.5-omni-realtime.
            "type": "semantic_vad",
            // Ambang batas deteksi VAD. Kami merekomendasikan menaikkan nilai ini di lingkungan berisik dan menurunkannya di lingkungan tenang.
            "threshold": 0.5,
            // Durasi diam dalam milidetik (ms) yang menandakan akhir ucapan. Model memicu respons jika durasi ini terlampaui.
            "silence_duration_ms": 800
        }
    }
}

3. Input audio dan gambar

Input audio wajib; input gambar opsional. Metode input tergantung pada protokol.
  • WebSocket
  • WebRTC
Kirim data audio dan gambar yang diencode Base64 ke buffer server menggunakan event input_audio_buffer.append dan input_image_buffer.append.
Gambar dapat berasal dari file lokal atau tangkapan aliran video real-time.
Dengan VAD sisi server diaktifkan, server secara otomatis mengirimkan data dan memicu respons saat akhir ucapan. Dengan VAD dinonaktifkan (mode manual), panggil event input_audio_buffer.commit untuk mengirimkan data setelah pengiriman.

4. Menerima respons model

Format respons tergantung pada modalitas output yang dikonfigurasi.
  • WebSocket
  • WebRTC

Pemilihan model

Qwen3.5-Omni-Realtime meningkatkan Qwen3-Omni-Flash-Realtime di bidang-bidang berikut:
  • Tingkat kecerdasan Setara dengan Qwen3.5-Plus.
  • Pencarian web Pencarian web bawaan — model secara otonom mencari untuk menjawab pertanyaan real-time. Untuk detailnya, lihat Pencarian web.
  • Pemanggilan alat Pemanggilan fungsi — model secara otonom memanggil alat eksternal. Untuk detailnya, lihat Seri Qwen-Omni-Realtime.
  • Interrupsi semantik Mengidentifikasi maksud percakapan untuk mencegah interupsi dari backchanneling dan kebisingan latar belakang.
  • Kontrol suara Kontrol volume, laju berbicara, dan emosi melalui perintah suara (misalnya, "berbicara lebih cepat", "lebih keras", "dengan nada bahagia").
  • Bahasa yang didukung Mendukung pengenalan suara untuk 113 bahasa dan dialek serta generasi suara untuk 36 bahasa dan dialek.
  • Suara yang didukung Mendukung 55 suara, termasuk 47 suara multibahasa dan 8 suara dialek. Untuk daftar lengkap, lihat Daftar suara.
  • Kloning suara Gunakan suara kloning kustom untuk percakapan real-time (Qwen3.5-omni-plus-realtime dan Qwen3.5-omni-flash-realtime). Untuk detailnya, lihat Kloning suara.
Periksa konsol Model Studio untuk nama model, konteks, harga, dan versi snapshot. Untuk batas laju konkurensi, lihat Pembatasan laju.

Batasan

  • Pencarian web dan pemanggilan alat saling eksklusif.
  • Sesi WebSocket tunggal dapat berlangsung hingga 120 menit. Koneksi ditutup secara otomatis pada batas ini.
  • Model menyimpan riwayat percakapan hingga batas putaran dan durasi berikut. Ketika terlampaui, riwayat terlama dibuang. Durasi maksimum adalah durasi kumulatif audio atau video (frame gambar) yang disimpan dalam konteks.
    Video dimasukkan sebagai frame yang diekstraksi (direkomendasikan: 1 fps). Durasi maksimum video adalah durasi kumulatif frame yang disimpan — misalnya, 240 detik berarti hanya frame dari 240 detik terakhir yang disimpan.
    Model qwen3-omni-flash-realtime memiliki batas 8 putaran dialog (biasanya tercapai lebih dulu). Batas durasinya tergantung pada panjang konteks model dan tidak tercantum secara terpisah.

    Model

    Putaran audio maksimum

    Putaran video maksimum

    Durasi audio maksimum

    Durasi video maksimum

    qwen3.5-omni-plus-realtime

    100 putaran

    50 putaran

    600 detik

    240 detik

    qwen3.5-omni-flash-realtime

    80 putaran

    50 putaran

    480 detik

    120 detik

    qwen3-omni-flash-realtime

    8 putaran

    8 putaran

    —

    —

Memulai

Dapatkan API key dan tetapkan sebagai variabel lingkungan. Pilih bahasa pemrograman dan ikuti langkah-langkah untuk memulai obrolan real-time.
  • WebSocket
  • WebRTC
  • DashScope Python SDK
  • DashScope Java SDK
  • WebSocket (Python)
  • Lingkungan runtime
Pastikan Python 3.10 atau lebih baru telah terinstal.Instal PyAudio untuk sistem operasi Anda.
  • macOS
  • Debian/Ubuntu
  • CentOS
  • Windows
brew install portaudio && pip install pyaudio
Instal dependensi lainnya:
pip install websocket-client dashscope
  • Mode interaksi
    • Mode VAD (Deteksi Aktivitas Suara, secara otomatis mendeteksi awal dan akhir ucapan) Server merespons setelah mendeteksi akhir ucapan pengguna.
    • Mode manual (tekan untuk berbicara, lepas untuk mengirim) Klien mengontrol awal dan akhir ucapan. Setelah berbicara, aplikasi Anda harus memberi tahu server.
    • Mode VAD
    • Mode manual
    Buat file Python bernama vad_dash.py dan salin kode berikut ke dalam file tersebut:
    # Dependensi: 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
    
    # Konfigurasi: URL, API key, suara, model, peran model
    # Tentukan wilayah. 'intl' untuk wilayah Singapura, 'cn' untuk wilayah China (Beijing). Ganti {WorkspaceId} dengan workspace ID Bailian Anda.
    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'
    # Konfigurasi API key. Jika variabel lingkungan tidak diatur, ganti baris berikut dengan API key Anda: dashscope.api_key = "sk-xxx"
    dashscope.api_key = os.getenv('DASHSCOPE_API_KEY')
    # Tentukan suara.
    voice = 'Ethan'
    # Tentukan model.
    model = 'qwen3.5-omni-plus-realtime'
    # Tentukan peran model.
    instructions = "Anda adalah Xiaoyun, asisten pribadi. Jawab pertanyaan pengguna dengan cara yang lucu dan cerdas."
    class SimpleCallback(OmniRealtimeCallback):
        def __init__(self, pya):
            self.pya = pya
            self.out = None
        def on_open(self):
            # Inisialisasi aliran output audio.
            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':
                # Putar audio.
                self.out.write(base64.b64decode(response['delta']))
            elif response['type'] == 'conversation.item.input_audio_transcription.delta':
                # Pratinjau streaming: teks adalah awalan yang dikonfirmasi, stash adalah akhiran yang belum dikonfirmasi.
                preview = response.get('text', '') + response.get('stash', '')
                print(f"\r[User] {preview}", end='', flush=True)
            elif response['type'] == 'conversation.item.input_audio_transcription.completed':
                # Transkripsi selesai. Cetak teks akhir dan pindah ke baris baru.
                print(f"\r[User] {response['transcript']}")
            elif response['type'] == 'response.audio_transcript.done':
                # Cetak teks respons asisten.
                print(f"[LLM] {response['transcript']}")
    
    # 1. Inisialisasi perangkat audio.
    pya = pyaudio.PyAudio()
    # 2. Buat fungsi callback dan percakapan.
    callback = SimpleCallback(pya)
    conv = OmniRealtimeConversation(model=model, callback=callback, url=url)
    # 3. Hubungkan dan konfigurasikan sesi.
    conv.connect()
    conv.update_session(output_modalities=[MultiModality.AUDIO, MultiModality.TEXT], voice=voice, instructions=instructions)
    # 4. Inisialisasi aliran input audio.
    mic = pya.open(format=pyaudio.paInt16, channels=1, rate=16000, input=True)
    # 5. Loop utama untuk memproses input audio.
    print("Conversation started. Speak into the microphone (Ctrl+C to exit)...")
    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:
        # Bersihkan sumber daya.
        conv.close()
        mic.close()
        callback.out.close()
        pya.terminate()
        print("\nConversation ended")
    
    Jalankan vad_dash.py untuk memulai percakapan real-time melalui mikrofon Anda. Sistem mendeteksi ucapan dan mengalirkan audio ke server.

Alur interaksi

  • Mode VAD
  • Mode manual
Atur session.turn_detection.type dalam session.update ke "server_vad" atau "semantic_vad" untuk mengaktifkan mode VAD. Cocok untuk skenario panggilan suara. Baik WebSocket maupun WebRTC mendukung mode VAD dengan event server yang sama; perbedaannya hanya pada cara transmisi audio dan gambar.
WebRTC hanya mendukung mode VAD dan tidak mendukung Mode Manual. Dengan WebRTC, audio ditransmisikan langsung melalui RTP tanpa mengirim event input_audio_buffer.append; gambar ditransmisikan melalui track video tanpa dukungan untuk event input_image_buffer.append. Perintah kontrol dan event server ditransmisikan melalui DataChannel dengan jenis event yang sama seperti WebSocket.
Alur interaksinya sebagai berikut:
  1. Klien mengirim data audio. WebSocket mengirimnya melalui event input_audio_buffer.append; WebRTC mentransmisikannya secara otomatis melalui track audio (RTP) tanpa mengirim event secara manual.
  2. Server mendeteksi awal ucapan dan mengirim event input_audio_buffer.speech_started melalui DataChannel (WebRTC) atau WebSocket.
  3. Server mendeteksi akhir ucapan dan mengirim event input_audio_buffer.speech_stopped.
  4. Server mengirimkan buffer audio dan mengirim event input_audio_buffer.committed.
  5. Server mulai menghasilkan respons, mengirim event conversation.item.created dan event lainnya. Respons audio dikembalikan secara bertahap melalui event WebSocket response.audio.delta, atau ditransmisikan langsung melalui track audio WebRTC (RTP).
  6. Selama respons, server mengembalikan transkripsi teks bertahap melalui event response.audio_transcript.delta, dan mengirim event response.done saat respons selesai.
Siklus hidupEvent klienEvent server
Inisialisasi sesisession.update
Konfigurasi sesi
session.created
Sesi dibuat.
session.updated
Konfigurasi sesi diperbarui.
Input audio penggunainput_audio_buffer.append
WebSocket: Menambahkan audio ke buffer melalui event ini.
input_image_buffer.append
WebSocket: Menambahkan gambar ke buffer melalui event ini.
WebRTC: Audio ditransmisikan secara otomatis melalui track RTP audio, dan gambar ditransmisikan melalui track video. Event ini tidak diperlukan.
input_audio_buffer.speech_started
Deteksi awal ucapan.
input_audio_buffer.speech_stopped
Deteksi akhir ucapan.
input_audio_buffer.committed
Buffer audio telah dikomit.
Keluaran Audio ServerTidak adaresponse.created
Generasi respons dimulai.
response.output_item.added
Item output baru ditambahkan ke respons.
conversation.item.created
Item percakapan dibuat.
response.content_part.added
Bagian konten baru ditambahkan ke pesan asisten.
response.audio_transcript.delta
Teks transkripsi yang dihasilkan secara bertahap.
response.audio.delta
WebSocket: Audio yang dihasilkan secara bertahap dari model dikembalikan melalui event ini. WebRTC: Audio ditransmisikan langsung melalui track audio RTP; event ini tidak dikembalikan.
response.audio_transcript.done
Transkripsi teks selesai.
response.audio.done
Generasi audio selesai.
response.content_part.done
Streaming konten teks atau audio asisten selesai.
response.output_item.done
Seluruh item output asisten telah selesai distreaming.
response.done
Respons selesai.
conversation.item.input_audio_transcription.completed
Transkripsi input audio pengguna selesai (memerlukan pengaktifan input_audio_transcription dalam session.update).

Pencarian web

Pencarian web memungkinkan model menggunakan data real-time untuk menjawab pertanyaan tentang informasi terkini seperti harga saham dan cuaca. Model secara otomatis menentukan apakah pencarian diperlukan.
Hanya qwen3.5-omni-plus-realtime yang mendukung pencarian web. Dinonaktifkan secara default; aktifkan dengan session.update.
Untuk penagihan, lihat kebijakan agent dalam aturan penagihan.

Aktifkan pencarian web

Tambahkan parameter berikut ke event session.update:
  • enable_search: Atur ke true untuk mengaktifkan fitur pencarian web.
  • search_options.enable_source: Atur ke true untuk menyertakan sumber hasil pencarian dalam respons.
Untuk parameter lainnya, lihat session.update.

Format respons

Saat pencarian web diaktifkan, objek usage dalam response.done menyertakan field plugins dengan informasi metering pencarian:
{
    "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"
            }
        }
    }
}

Contoh kode

Aktifkan pencarian web dalam percakapan real-time:
  • DashScope Python SDK
  • DashScope Java SDK
  • WebSocket (Python)
Teruskan parameter enable_search dan search_options dalam pemanggilan update_session:
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')
# Wilayah Singapura. Ganti {WorkspaceId} dengan workspace ID Bailian Anda. URL berbeda-beda tergantung wilayah.
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="You are Xiaoyun, a personal assistant.",
    enable_search=True,
    search_options={'enable_source': True}
)
mic = pya.open(format=pyaudio.paInt16, channels=1, rate=16000, input=True)
print("Web search is enabled. Speak into the microphone (Ctrl+C to exit)...")
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("\nConversation ended.")

Referensi API

Penagihan dan pembatasan laju

Penagihan

Penagihan berbasis token, diukur berdasarkan modalitas (audio, gambar, teks). Periksa konsol Model Studio untuk harga.
Dalam percakapan real-time multi-putaran, setiap kali model menghasilkan respons, ia memproses semua konten percakapan historis dalam jendela konteks — termasuk audio, gambar, dan teks dari putaran sebelumnya — bersama dengan input baru putaran saat ini sebagai token input. Akibatnya, token input terakumulasi setiap putaran alih-alih hanya dihitung untuk input baru putaran saat ini.Sebagai contoh, jika input audio 10 detik dikonversi menjadi 70 token (Qwen3.5-Omni-Realtime), dan audio tersebut masih berada dalam jendela konteks pada putaran 3, audio tersebut tetap dihitung terhadap token input untuk putaran 3. Token input yang ditagih sebenarnya = token dari semua putaran historis dalam jendela konteks + token dari input baru putaran saat ini.
  • Audio
  • Gambar
  • Qwen3.5-Omni-Realtime:
    • Audio input: total token = Durasi audio (detik) * 7
    • Audio output: total token = Durasi audio (detik) * 12,5
  • Qwen3-Omni-Flash-Realtime: Audio input dan output menggunakan rumus yang sama: total token = Durasi audio (detik) * 12,5
  • Qwen-Omni-Turbo-Realtime: Audio input dan output menggunakan rumus yang sama: total token = Durasi audio (detik) * 25 Durasi audio kurang dari 1 detik ditagih sebagai 1 detik.

Pembatasan laju

Untuk batas laju model, lihat Pembatasan laju.

Kode kesalahan

Jika pemanggilan model gagal dan mengembalikan pesan kesalahan, lihat Kode kesalahan untuk resolusi.

Daftar suara

Untuk daftar suara yang tersedia untuk model Qwen-Omni-Realtime, lihat Suara.
Rencana Token (Team Edition)
Model playground
Statistik dan Pemantauan
Asset Center
Dukungan layanan