qwen-audio-3.0-realtime-plus
Model dialog suara langsung yang menerima pertuturan dan teks, lalu menjawab melalui suara atau teks. Direka untuk tempo perbualan yang semula jadi dan interaksi dengan alat.
Tentang model
Huraian ini merangkumi keupayaan model. Input, output dan pilihan yang tersedia di Ailoot disenaraikan di bawah untuk kaedah yang dipilih.
Qwen-Audio-3.0-Realtime-Plus ialah model Alibaba untuk dialog suara langsung. Model menerima pertuturan dan teks, menjawab melalui audio dan teks serta menyokong perbualan dua hala dengan pertukaran ujaran yang semula jadi. Audio boleh dihantar dan diterima secara berbahagi, jadi interaksi berkembang sepanjang perbualan.
Menentukan bila pengguna selesai bercakap
Beberapa cara disediakan untuk menentukan sempadan ujaran: berdasarkan aktiviti bunyi, kelengkapan makna dan kawalan yang dinyatakan secara jelas. Dalam sistem pengeluar, mod dipilih sebelum audio pertama dihantar; sambungan baharu diperlukan untuk menukarnya selepas perbualan bermula. Sokongan kawalan ini bergantung pada kaedah yang dipilih. Mod semantik mengambil kira jeda dan kata pengisi: keraguan seketika tidak semestinya bermaksud pengguna sudah selesai menyampaikan fikirannya. Pertuturan baharu daripada pengguna boleh mengganggu respons yang sedang dijana supaya perbualan diteruskan dengan mengambil kira ujaran seterusnya. Dalam mod semantik, pengecaman boleh dipandu oleh sampel pertuturan individu yang dipilih untuk mengurangkan gangguan daripada suara orang lain dan bunyi latar.
Arahan menentukan peranan pembantu dan gaya perbualan. Penyampaian suara boleh mengambil kira nada, tempo dan emosi; versi 3.0 menyediakan lima suara sistem dan suara berdasarkan sampel pertuturan. Model menyokong 11 bahasa, termasuk bahasa Rusia, serta variasi dialek Cina yang dinyatakan oleh pengeluar. Dalam sistem pengeluar, suara ditetapkan semasa kemas kini tetapan sesi yang pertama; suara baharu yang dihantar kemudian dalam perbualan yang sama diabaikan. Tetapan ini memerlukan sokongan daripada kaedah akses yang dipilih.
Alat dan sejarah perbualan
Panggilan fungsi disokong. Model menentukan tindakan yang diperlukan, aplikasi yang disambungkan melaksanakannya dan mengembalikan hasil ke dalam dialog. Ini membolehkan perbualan dibina berdasarkan data sebenar dan diteruskan selepas operasi selesai. Pembantu suara boleh menggunakan hasil alat sambil mengekalkan konteks perbualan. Keupayaan pengeluar turut merangkumi carian web terbina dalam jika disediakan oleh kaedah yang dipilih. Carian web dan panggilan fungsi tidak boleh diaktifkan serentak dalam satu sesi.
Secara lalai, sejarah mengandungi 20 giliran perbualan, dengan julat yang disediakan daripada satu hingga 50. Had 300 saat ditetapkan bagi audio terkumpul; bahagian sejarah yang lama dibuang apabila had dilampaui. Ini berbeza daripada tempoh satu ujaran: sejarah menentukan bahan terdahulu yang masih tersedia apabila dialog diteruskan.
Konteks teks dan audio
Konteks formal ialah 40 960 token. Panjang input maksimum ialah 16 384 token, manakala output maksimum ialah 8192; had input dan output yang sama dinyatakan bagi mod penaakulan, dengan had rantaian penaakulan berasingan sebanyak 1024 token.
Audio penstriman menggunakan PCM satu saluran dengan perwakilan 16 bit: input pada 16 kHz dan output pada 24 kHz. Data teks dan audio tergolong dalam perbualan yang sama. Input visual dan penghasilan imej tidak dinyatakan bagi model khusus ini; pengkhususannya ialah pertuturan, teks dan interaksi suara.
Ailoot · Suara masa nyata GET /v1/realtime?model=qwen-audio-3.0-realtime-plus qwen-audio-3.0-realtime-plus
qwen-audio-3.0-realtime-plusPengenalan
Model dialog suara langsung yang menerima pertuturan dan teks, lalu menjawab melalui suara atau teks. Direka untuk tempo perbualan yang semula jadi dan interaksi dengan alat.
- Input yang diterima
- Teks · Audio
- Hasil
- Teks · Audio
Tersedia di Ailoot · input & kaedah
Ailoot · Suara masa nyata GET /v1/realtime?model=qwen-audio-3.0-realtime-plus
- Input
text,audio- Output
text,audio- Format output
- peristiwa sesi
| Medan | Jenis | Keperluan | Nilai & had | Lalai |
|---|---|---|---|---|
Medanquery.model | Jenisstring | KeperluanDiperlukan | Nilai & had qwen-audio-3.0-realtime-plus | Lalai— |
Medansession.input_audio_format | Jenisstring | KeperluanPilihan | Nilai & had pcm16, pcm | Lalai— |
Medansession.output_audio_format | Jenisstring | KeperluanPilihan | Nilai & had pcm16, pcm | Lalai— |
Medansession.instructions | Jenisstring | KeperluanPilihan | Nilai & had Had terpakai pada: dasar sesi yang dipilih | Lalai— |
Medansession.max_history_turns | Jenisinteger | KeperluanPilihan | Nilai & had Minimum: 1 Had terpakai pada: dasar sesi yang dipilih | Lalai— |
Medaninput_audio_buffer.append.audio | Jenisbase64_string | KeperluanDiperlukan | Nilai & had Kandungan input: PCM16 mono; input 16 kHz, output 24 kHz; panjang bait genap yang tidak kosong | Lalai— |
Gabungan bahan input
realtime_text_audio
Parameter kaedah dan kitar hayat
| Parameter | Kontrak |
|---|---|
Parametermaterial_types | Kontraktext, audio |
Parameterrequired | Kontraknull |
Parameteroptional_controls | Kontraknull |
Parametercontent_type | KontrakWebSocket |
Kitar hayat: exact retained published method
Struktur kaedah dan ID adalah tepat; keupayaan pembekal berasingan daripada penerimaan permintaan.
Pelan harga
Kadar kaedah Ailoot
GET /v1/realtime?model=qwen-audio-3.0-realtime-plus- Input
- USD 0.0008 / 1K
- Output
- USD 0.0064 / 1K
- Input
- USD 0.0048 bagi setiap minit audio
- Output
- USD 0.018 bagi setiap minit audio keluaran
Ailoot merizabkan anggaran amaun sebelum permintaan. Selepas hasil diterima, caj akhir diselesaikan berdasarkan penggunaan terukur. Penyelesaian caj penstriman menggunakan rekod penggunaan akhir. Cara rizab dan penyelesaian caj berfungsi →
Contoh permintaan
Ailoot · Suara masa 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 masa nyata
peristiwa sesi
Simpan semua hasil yang selesai
Simpan setiap respons lengkap, fail dan bahagian kandungan yang dikembalikan.
Gabungkan setiap delta audio dan hasil teks/peristiwa yang dikembalikan bagi setiap ID respons sebenar.
Jika respons asal perlu disemak
Simpan ID sesi/respons/peristiwa sebenar dan resit.
Ralat dan langkah seterusnya
| Respons | Syarat | Langkah seterusnya |
|---|---|---|
Respons426 · invalid_request_error | SyaratTiada naik taraf WebSocket | Langkah seterusnyaGunakan klien WebSocket dengan Upgrade: websocket. |
Alias
Alias model
Ailoot qwen-audio-3.0-realtime-plus
Alias laluan kaedah
Gunakan laluan kaedah yang dipaparkan di atas.
ID pemanggil berkaitan
FAQ · qwen-audio-3.0-realtime-plus
- Apakah input dan hasil yang tersedia?
GET /v1/realtime?model=qwen-audio-3.0-realtime-plus·qwen-audio-3.0-realtime-plus:text,audio→text,audio- Apakah had yang terpakai?
GET /v1/realtime?model=qwen-audio-3.0-realtime-plus·qwen-audio-3.0-realtime-plus:session.max_history_turns.minimum:1