qwen-audio-3.0-realtime-plus
Model percakapan suara langsung yang menerima ucapan dan teks serta menjawab dengan suara atau teks. Dirancang untuk ritme percakapan yang alami dan interaksi dengan alat.
Tentang model
Deskripsi ini mencakup kemampuan model. Masukan, keluaran, dan opsi yang tersedia di Ailoot tercantum di bawah untuk metode yang dipilih.
Qwen-Audio-3.0-Realtime-Plus adalah model Alibaba untuk percakapan suara langsung. Model menerima ucapan dan teks, menjawab dengan audio dan teks, serta mendukung percakapan dua arah dengan pertukaran giliran yang alami. Audio dapat dikirim dan diterima secara bertahap, sehingga interaksi berkembang selama percakapan berlangsung.
Menentukan kapan lawan bicara selesai berbicara
Tersedia beberapa cara untuk menentukan batas giliran bicara: berdasarkan aktivitas suara, kelengkapan makna, dan kendali eksplisit. Pada layanan produsen, mode dipilih sebelum audio pertama dikirim; perubahan mode setelah percakapan dimulai memerlukan koneksi baru. Dukungan terhadap kendali ini ditentukan oleh metode yang dipilih. Mode semantik mempertimbangkan jeda dan kata pengisi: keraguan singkat tidak selalu berarti pengguna telah selesai menyampaikan pikirannya. Ucapan baru dari pengguna dapat menyela jawaban yang sedang dibuat, sehingga percakapan berlanjut dengan mempertimbangkan giliran berikutnya. Dalam mode semantik, pengenalan dapat diarahkan pada contoh ucapan lawan bicara yang dipilih agar tidak mudah terganggu oleh suara orang lain dan kebisingan latar.
Instruksi menentukan peran asisten dan gaya komunikasi. Penyampaian suara dapat mempertimbangkan nada, tempo, dan emosi; versi 3.0 menyediakan lima suara sistem dan suara berdasarkan contoh ucapan. Model mendukung 11 bahasa, termasuk bahasa Rusia, serta varian dialek Tionghoa yang disebutkan produsen. Pada layanan produsen, suara ditetapkan saat pengaturan sesi pertama kali diperbarui; pengiriman suara baru berikutnya dalam percakapan yang sama diabaikan. Pengaturan ini memerlukan dukungan dari metode akses yang dipilih.
Alat dan riwayat percakapan
Pemanggilan fungsi didukung. Model membentuk tindakan yang diperlukan, aplikasi yang terhubung menjalankannya dan mengembalikan hasil ke percakapan. Dengan demikian, percakapan dapat dibangun berdasarkan data faktual dan dilanjutkan setelah operasi selesai. Asisten suara dapat menggunakan hasil alat sambil mempertahankan konteks percakapan. Kemampuan produsen juga mencakup pencarian web bawaan jika metode yang dipilih menyediakannya. Pencarian web dan pemanggilan fungsi tidak dapat diaktifkan bersamaan dalam satu sesi.
Secara default, riwayat memuat 20 giliran percakapan, dengan rentang yang tersedia dari satu hingga 50. Audio yang terkumpul dibatasi hingga 300 detik; bagian riwayat yang lama dihapus jika batas terlampaui. Ini berbeda dari durasi satu giliran bicara: riwayat menentukan materi sebelumnya yang tetap tersedia saat percakapan dilanjutkan.
Konteks teks dan audio
Konteks formal berjumlah 40 960 token. Panjang masukan maksimum adalah 16 384 token, sedangkan keluaran 8192; batas masukan dan keluaran yang sama juga dinyatakan untuk mode penalaran, dengan batas rantai penalaran terpisah sebesar 1024 token.
Audio streaming menggunakan PCM satu kanal dengan representasi 16 bit: masukan pada 16 kHz dan keluaran pada 24 kHz. Data teks dan audio merupakan bagian dari percakapan yang sama. Masukan visual dan keluaran gambar tidak dinyatakan untuk model khusus ini; spesialisasinya adalah ucapan, teks, dan interaksi suara.
Ailoot · Suara waktu nyata GET /v1/realtime?model=qwen-audio-3.0-realtime-plus qwen-audio-3.0-realtime-plus
qwen-audio-3.0-realtime-plusMulai
Model percakapan suara langsung yang menerima ucapan dan teks serta menjawab dengan suara atau teks. Dirancang untuk ritme percakapan yang alami dan interaksi dengan alat.
- Masukan yang diterima
- Teks · Audio
- Hasil
- Teks · Audio
Tersedia di Ailoot · masukan & metode
Ailoot · Suara waktu nyata GET /v1/realtime?model=qwen-audio-3.0-realtime-plus
- Masukan
text,audio- Keluaran
text,audio- Format keluaran
- peristiwa sesi
| Kolom | Jenis | Persyaratan | Nilai & batasan | Bawaan |
|---|---|---|---|---|
Kolomquery.model | Jenisstring | PersyaratanWajib | Nilai & batasan qwen-audio-3.0-realtime-plus | Bawaan— |
Kolomsession.input_audio_format | Jenisstring | PersyaratanOpsional | Nilai & batasan pcm16, pcm | Bawaan— |
Kolomsession.output_audio_format | Jenisstring | PersyaratanOpsional | Nilai & batasan pcm16, pcm | Bawaan— |
Kolomsession.instructions | Jenisstring | PersyaratanOpsional | Nilai & batasan Batas berlaku untuk: kebijakan sesi yang dipilih | Bawaan— |
Kolomsession.max_history_turns | Jenisinteger | PersyaratanOpsional | Nilai & batasan Minimum: 1 Batas berlaku untuk: kebijakan sesi yang dipilih | Bawaan— |
Kolominput_audio_buffer.append.audio | Jenisbase64_string | PersyaratanWajib | Nilai & batasan Konten masukan: PCM16 mono; masukan 16 kHz, keluaran 24 kHz; panjang byte genap dan tidak kosong | Bawaan— |
Kombinasi bahan masukan
realtime_text_audio
Parameter metode dan siklus hidup
| Parameter | Kontrak |
|---|---|
Parametermaterial_types | Kontraktext, audio |
Parameterrequired | Kontraknull |
Parameteroptional_controls | Kontraknull |
Parametercontent_type | KontrakWebSocket |
Siklus hidup: exact retained published method
Struktur metode dan ID bersifat eksak; kemampuan pemasok terpisah dari penerimaan permintaan.
Paket
Tarif metode Ailoot
GET /v1/realtime?model=qwen-audio-3.0-realtime-plus- Masukan
- US$0,0008 / 1K
- Keluaran
- US$0,0064 / 1K
- Masukan
- US$0,0048 per menit audio
- Keluaran
- US$0,018 per menit audio keluaran
Ailoot mencadangkan perkiraan dana sebelum permintaan. Setelah hasil diterima, tagihan akhir diselesaikan berdasarkan penggunaan yang terukur. Penyelesaian tagihan streaming menggunakan catatan penggunaan akhir. Cara kerja cadangan dan penyelesaian tagihan →
Contoh permintaan
Ailoot · Suara waktu nyata
# Install the documented client once: python3 -m pip install websockets
import base64, json, os, time, wave
from pathlib import Path
from websockets.sync.client import connect
key = os.environ.get("AILOOT_API_KEY", "")
if not key.strip():
raise SystemExit("Set your AILOOT_API_KEY before connecting")
file = Path(os.environ.get("AILOOT_TEXT_FILE", ""))
if not file.is_file(): raise SystemExit("Set AILOOT_TEXT_FILE to your actual UTF-8 material")
material = file.read_text(encoding="utf-8")
if not material.strip(): raise SystemExit("Text material must not be empty")
out = Path("realtime-results")
out.mkdir(exist_ok=True)
audio, texts, complete = {}, {}, []
current_response = None
pending = False
deadline = time.monotonic() + 570 # Local client bound; lower server/session limits still apply.
def receive(ws, log):
global current_response, pending
left = deadline - time.monotonic()
if left <= 0:
raise TimeoutError("Client session limit; preserve IDs and partial results, do not replay")
event = json.loads(ws.recv(timeout=min(60, left)))
log.write(json.dumps(event, ensure_ascii=False) + "\n")
log.flush()
kind = event.get("type")
if kind == "error":
raise RuntimeError(json.dumps(event, ensure_ascii=False))
if kind == "response.created":
current_response = event["response"]["id"]
if kind in {"response.audio.delta", "response.output_audio.delta", "response.text.delta", "response.output_text.delta", "response.audio_transcript.delta", "response.output_audio_transcript.delta", "response.text.done", "response.audio_transcript.done"}:
identity = (event["response_id"], event["item_id"], event["output_index"], event["content_index"])
if kind in {"response.audio.delta", "response.output_audio.delta"}:
raw = base64.b64decode(event["delta"], validate=True)
if len(raw) % 2: raise ValueError("Output PCM16 chunk must have an even byte length")
audio.setdefault(identity, bytearray()).extend(raw)
elif kind.endswith(".done"):
texts[identity] = event.get("text", event.get("transcript", ""))
else:
texts[identity] = texts.get(identity, "") + event["delta"]
print(event["delta"], end="", flush=True)
if kind == "response.done":
response = event["response"]
complete.append(response)
if current_response is None: current_response = response["id"]
if response["id"] == current_response: pending = False
return event
def wait_for(ws, log, kind):
while True:
event = receive(ws, log)
if event.get("type") == kind: return event
def send(ws, event):
ws.send(json.dumps(event, ensure_ascii=False))
try:
# One exact model query; no reconnect/retry loop and no provider credentials.
with connect("wss://api.ailoot.ai/v1/realtime?model=qwen-audio-3.0-realtime-plus", additional_headers={"Authorization": "Bearer " + key}) as ws:
with (out / "events.jsonl").open("w", encoding="utf-8") as log:
wait_for(ws, log, "session.created")
send(ws, {"type":"session.update", "session":{"modalities":["audio","text"], "input_audio_format":"pcm", "output_audio_format":"pcm", "turn_detection":None}})
wait_for(ws, log, "session.updated")
send(ws, {"type":"conversation.item.create", "item":{"type":"message", "role":"user", "content":[{"type":"input_text", "text":material}]}})
send(ws, {"type":"response.create"})
pending = True
try:
while pending: receive(ws, log)
except KeyboardInterrupt:
# Cancel the actual current inference, then preserve its returned status.
send(ws, {"type":"response.cancel"})
while pending: receive(ws, log)
if not complete or complete[-1].get("status") != "completed":
raise RuntimeError("Response did not complete normally; inspect saved events and status")
finally:
manifest = {"responses":complete, "parts":[]}
for number, identity in enumerate(dict.fromkeys(list(audio) + list(texts))):
record = {"response_id":identity[0], "item_id":identity[1], "output_index":identity[2], "content_index":identity[3]}
if identity in audio:
raw = bytes(audio[identity])
pcm_file = out / ("audio-" + str(number) + ".pcm")
wav_file = out / ("audio-" + str(number) + ".wav")
pcm_file.write_bytes(raw)
with wave.open(str(wav_file), "wb") as wav:
wav.setnchannels(1); wav.setsampwidth(2); wav.setframerate(24000); wav.writeframes(raw)
record.update({"pcm":str(pcm_file), "wav":str(wav_file), "sample_rate_hz":24000})
if identity in texts:
text_file = out / ("text-" + str(number) + ".txt")
text_file.write_text(texts[identity], encoding="utf-8")
record["text"] = str(text_file)
manifest["parts"].append(record)
(out / "results.json").write_text(json.dumps(manifest, ensure_ascii=False, indent=2), encoding="utf-8")
print("\nSaved every received event and result in", out)
# Install the documented client once: python3 -m pip install websockets
import base64, json, os, time, wave
from pathlib import Path
from websockets.sync.client import connect
key = os.environ.get("AILOOT_API_KEY", "")
if not key.strip():
raise SystemExit("Set your AILOOT_API_KEY before connecting")
file = Path(os.environ.get("AILOOT_AUDIO_FILE", ""))
if not file.is_file(): raise SystemExit("Set AILOOT_AUDIO_FILE to your raw PCM16 mono 16-kHz recording")
material = file.read_bytes()
if not material or len(material) % 2 or material.startswith(b"RIFF"):
raise SystemExit("Use nonempty signed little-endian PCM16 mono 16-kHz bytes, not a WAV header")
out = Path("realtime-results")
out.mkdir(exist_ok=True)
audio, texts, complete = {}, {}, []
current_response = None
pending = False
deadline = time.monotonic() + 570 # Local client bound; lower server/session limits still apply.
def receive(ws, log):
global current_response, pending
left = deadline - time.monotonic()
if left <= 0:
raise TimeoutError("Client session limit; preserve IDs and partial results, do not replay")
event = json.loads(ws.recv(timeout=min(60, left)))
log.write(json.dumps(event, ensure_ascii=False) + "\n")
log.flush()
kind = event.get("type")
if kind == "error":
raise RuntimeError(json.dumps(event, ensure_ascii=False))
if kind == "response.created":
current_response = event["response"]["id"]
if kind in {"response.audio.delta", "response.output_audio.delta", "response.text.delta", "response.output_text.delta", "response.audio_transcript.delta", "response.output_audio_transcript.delta", "response.text.done", "response.audio_transcript.done"}:
identity = (event["response_id"], event["item_id"], event["output_index"], event["content_index"])
if kind in {"response.audio.delta", "response.output_audio.delta"}:
raw = base64.b64decode(event["delta"], validate=True)
if len(raw) % 2: raise ValueError("Output PCM16 chunk must have an even byte length")
audio.setdefault(identity, bytearray()).extend(raw)
elif kind.endswith(".done"):
texts[identity] = event.get("text", event.get("transcript", ""))
else:
texts[identity] = texts.get(identity, "") + event["delta"]
print(event["delta"], end="", flush=True)
if kind == "response.done":
response = event["response"]
complete.append(response)
if current_response is None: current_response = response["id"]
if response["id"] == current_response: pending = False
return event
def wait_for(ws, log, kind):
while True:
event = receive(ws, log)
if event.get("type") == kind: return event
def send(ws, event):
ws.send(json.dumps(event, ensure_ascii=False))
try:
# One exact model query; no reconnect/retry loop and no provider credentials.
with connect("wss://api.ailoot.ai/v1/realtime?model=qwen-audio-3.0-realtime-plus", additional_headers={"Authorization": "Bearer " + key}) as ws:
with (out / "events.jsonl").open("w", encoding="utf-8") as log:
wait_for(ws, log, "session.created")
send(ws, {"type":"session.update", "session":{"modalities":["audio","text"], "input_audio_format":"pcm", "output_audio_format":"pcm", "turn_detection":None}})
wait_for(ws, log, "session.updated")
for offset in range(0, len(material), 640):
send(ws, {"type":"input_audio_buffer.append", "audio":base64.b64encode(material[offset:offset+640]).decode("ascii")})
time.sleep(0.02)
send(ws, {"type":"input_audio_buffer.commit"})
wait_for(ws, log, "input_audio_buffer.committed")
send(ws, {"type":"response.create"})
pending = True
try:
while pending: receive(ws, log)
except KeyboardInterrupt:
# Cancel the actual current inference, then preserve its returned status.
send(ws, {"type":"response.cancel"})
while pending: receive(ws, log)
if not complete or complete[-1].get("status") != "completed":
raise RuntimeError("Response did not complete normally; inspect saved events and status")
finally:
manifest = {"responses":complete, "parts":[]}
for number, identity in enumerate(dict.fromkeys(list(audio) + list(texts))):
record = {"response_id":identity[0], "item_id":identity[1], "output_index":identity[2], "content_index":identity[3]}
if identity in audio:
raw = bytes(audio[identity])
pcm_file = out / ("audio-" + str(number) + ".pcm")
wav_file = out / ("audio-" + str(number) + ".wav")
pcm_file.write_bytes(raw)
with wave.open(str(wav_file), "wb") as wav:
wav.setnchannels(1); wav.setsampwidth(2); wav.setframerate(24000); wav.writeframes(raw)
record.update({"pcm":str(pcm_file), "wav":str(wav_file), "sample_rate_hz":24000})
if identity in texts:
text_file = out / ("text-" + str(number) + ".txt")
text_file.write_text(texts[identity], encoding="utf-8")
record["text"] = str(text_file)
manifest["parts"].append(record)
(out / "results.json").write_text(json.dumps(manifest, ensure_ascii=False, indent=2), encoding="utf-8")
print("\nSaved every received event and result in", out)
Terima dan simpan hasil
Ailoot · Suara waktu nyata
peristiwa sesi
Simpan semua hasil yang selesai
Simpan setiap respons lengkap, berkas, dan bagian konten yang dikembalikan.
Gabungkan setiap delta audio dan hasil teks/peristiwa yang dikembalikan untuk setiap ID respons aktual.
Jika respons asli perlu diperiksa
Simpan ID sesi/respons/peristiwa aktual beserta catatan buktinya.
Kesalahan dan langkah berikutnya
| Respons | Kondisi | Langkah berikutnya |
|---|---|---|
Respons426 · invalid_request_error | KondisiTidak ada peningkatan koneksi WebSocket | Langkah berikutnyaGunakan klien WebSocket dengan Upgrade: websocket. |
Alias
Alias model
Ailoot qwen-audio-3.0-realtime-plus
Alias jalur metode
Gunakan jalur metode yang ditampilkan di atas.
ID pemanggil terkait
FAQ · qwen-audio-3.0-realtime-plus
- Input dan hasil apa yang tersedia?
GET /v1/realtime?model=qwen-audio-3.0-realtime-plus·qwen-audio-3.0-realtime-plus:text,audio→text,audio- Batasan apa yang berlaku?
GET /v1/realtime?model=qwen-audio-3.0-realtime-plus·qwen-audio-3.0-realtime-plus:session.max_history_turns.minimum:1