qwen-audio-3.0-realtime-plus
Modello per il dialogo vocale in tempo reale: riceve parlato e testo e risponde con voce o testo. È progettato per un ritmo di conversazione naturale e per l'interazione con strumenti.
Informazioni sul modello
Questa descrizione illustra le funzionalità del modello. Gli input, gli output e le opzioni disponibili in Ailoot per il metodo selezionato sono elencati di seguito.
Qwen-Audio-3.0-Realtime-Plus è un modello di Alibaba per il dialogo vocale in tempo reale. Riceve parlato e testo, risponde con audio e testo e supporta una conversazione bidirezionale con scambi naturali di battute. L'audio può essere inviato e ricevuto a segmenti, così l'interazione si sviluppa durante il dialogo.
Quando l'interlocutore ha concluso il pensiero
Sono previsti diversi modi per determinare i confini di una battuta: in base all'attività vocale, alla completezza del significato o tramite un controllo esplicito. Presso il produttore, la modalità si sceglie prima di inviare il primo audio; per cambiarla dopo l'inizio della conversazione è necessaria una nuova connessione. Il supporto di questo controllo dipende dal metodo scelto. La modalità semantica tiene conto delle pause e dei riempitivi del parlato: una breve esitazione non indica necessariamente che l'utente abbia concluso il pensiero. Una nuova battuta dell'utente può interrompere la risposta in corso di generazione, per proseguire la conversazione tenendo conto del nuovo intervento. Nella modalità semantica si può orientare il riconoscimento su un campione vocale dell'interlocutore scelto, per ridurre l'influenza di altre voci e del rumore di fondo.
Le istruzioni definiscono il ruolo dell'assistente e lo stile di conversazione. La resa vocale può tenere conto di tono, ritmo ed emozione; per la versione 3.0 sono previste cinque voci di sistema e voci basate su un campione vocale. Il modello supporta 11 lingue, tra cui il russo, oltre alle varianti dialettali cinesi indicate dal produttore. Presso il produttore, la voce si imposta al primo aggiornamento delle impostazioni della sessione; l'invio successivo di una nuova voce nella stessa conversazione viene ignorato. Queste impostazioni richiedono il supporto della modalità di accesso scelta.
Strumenti e cronologia della conversazione
È supportata la chiamata di funzioni. Il modello formula l'azione necessaria, l'applicazione collegata la esegue e restituisce il risultato al dialogo. Questo permette di costruire la conversazione attorno a dati effettivi e di proseguirla dopo l'operazione eseguita. L'assistente vocale può basarsi sui risultati degli strumenti, conservando il contesto della conversazione. Le capacità del produttore comprendono anche la ricerca web integrata, se offerta dal metodo scelto. La ricerca web e le chiamate di funzioni non possono essere attivate contemporaneamente nella stessa sessione.
Per impostazione predefinita, la cronologia contiene 20 turni di conversazione; l'intervallo previsto va da uno a 50. Per l'audio accumulato è stabilito un limite di 300 secondi; le parti più vecchie della cronologia vengono eliminate quando i limiti sono superati. È diverso dalla durata di una singola battuta: la cronologia determina quale materiale precedente resta disponibile quando il dialogo prosegue.
Contesto testuale e audio
Il contesto formale è di 40 960 token. La lunghezza massima dell'input è di 16 384 token, quella dell'output di 8192; gli stessi limiti di input e output sono indicati per la modalità di ragionamento, con un limite separato di 1024 token per la catena di ragionamento.
Per l'audio in streaming è previsto PCM mono a 16 bit: in ingresso a 16 kHz, in uscita a 24 kHz. Testo e audio appartengono alla stessa conversazione. Per questo specifico modello non sono dichiarati input visivo né output di immagini; la sua specializzazione è il parlato, il testo e l'interazione vocale.
Ailoot · Voce in tempo reale GET /v1/realtime?model=qwen-audio-3.0-realtime-plus qwen-audio-3.0-realtime-plus
qwen-audio-3.0-realtime-plusIntroduzione
Modello per il dialogo vocale in tempo reale: riceve parlato e testo e risponde con voce o testo. È progettato per un ritmo di conversazione naturale e per l'interazione con strumenti.
- Input accettati
- Testo · Audio
- Risultati
- Testo · Audio
Disponibile in Ailoot · input e metodi
Ailoot · Voce in tempo reale GET /v1/realtime?model=qwen-audio-3.0-realtime-plus
- Tipi di input
text,audio- Tipi di output
text,audio- Formato di output
- eventi della sessione
| Campo | Tipo | Requisito | Valori e limiti | Predefinito |
|---|---|---|---|---|
Campoquery.model | Tipostring | RequisitoObbligatorio | Valori e limiti qwen-audio-3.0-realtime-plus | Predefinito— |
Camposession.input_audio_format | Tipostring | RequisitoFacoltativo | Valori e limiti pcm16, pcm | Predefinito— |
Camposession.output_audio_format | Tipostring | RequisitoFacoltativo | Valori e limiti pcm16, pcm | Predefinito— |
Camposession.instructions | Tipostring | RequisitoFacoltativo | Valori e limiti Il limite si applica a: regole selezionate per la sessione | Predefinito— |
Camposession.max_history_turns | Tipointeger | RequisitoFacoltativo | Valori e limiti Minimo: 1 Il limite si applica a: regole selezionate per la sessione | Predefinito— |
Campoinput_audio_buffer.append.audio | Tipobase64_string | RequisitoObbligatorio | Valori e limiti Contenuto in input: PCM16 mono; ingresso a 16 kHz, uscita a 24 kHz; lunghezza in byte non vuota e pari | Predefinito— |
Combinazioni di materiali in input
realtime_text_audio
Parametri e ciclo di vita del metodo
| Parametro | Contratto |
|---|---|
Parametromaterial_types | Contrattotext, audio |
Parametrorequired | Contrattonull |
Parametrooptional_controls | Contrattonull |
Parametrocontent_type | ContrattoWebSocket |
Ciclo di vita: exact retained published method
Le strutture dei metodi e gli ID sono esatti; la capacità del fornitore è distinta dall’ammissione delle richieste.
Tariffe
Tariffe dei metodi Ailoot
GET /v1/realtime?model=qwen-audio-3.0-realtime-plus- Input
- 0,0008 USD / 1K
- Output
- 0,0064 USD / 1K
- Input
- 0,0048 USD per minuto di audio
- Output
- 0,018 USD per minuto di audio in output
Ailoot prenota un importo stimato prima di una richiesta. Dopo il risultato, addebita il costo finale in base all’utilizzo misurato. Per lo streaming, l’addebito usa il record finale di utilizzo. Come funzionano la prenotazione e l’addebito finale →
Esempi di richieste
Ailoot · Voce in tempo reale
# 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)
Ricevi e salva i risultati
Ailoot · Voce in tempo reale
eventi della sessione
Conserva tutti i risultati completati
Conserva ogni risposta, file e parte di contenuto restituiti per intero.
Assembla ogni frammento audio incrementale restituito e ogni risultato di testo o evento per ciascun ID effettivo di risposta.
Se occorre verificare la risposta originale
Conserva gli ID effettivi di sessione, risposta ed evento e le ricevute.
Errori e passaggi successivi
| Risposta | Condizione | Passaggio successivo |
|---|---|---|
Risposta426 · invalid_request_error | CondizioneNessun passaggio al protocollo WebSocket | Passaggio successivoUsa un client WebSocket con Upgrade: websocket. |
Alias
Alias del modello
Ailoot qwen-audio-3.0-realtime-plus
Alias dei percorsi dei metodi
Usa i percorsi dei metodi indicati sopra.
ID di chiamata correlati
FAQ · qwen-audio-3.0-realtime-plus
- Quali input e risultati sono disponibili?
GET /v1/realtime?model=qwen-audio-3.0-realtime-plus·qwen-audio-3.0-realtime-plus:text,audio→text,audio- Quali limiti si applicano?
GET /v1/realtime?model=qwen-audio-3.0-realtime-plus·qwen-audio-3.0-realtime-plus:session.max_history_turns.minimum:1