qwen-audio-3.0-realtime-plus
Model za glasovni pogovor v živo, ki sprejema govor in besedilo ter odgovarja z glasom ali besedilom. Zasnovan je za naraven tempo pogovora in uporabo orodij.
O modelu
Ta opis zajema zmožnosti modela. Vhodi, izhodi in možnosti, ki so na voljo v Ailoot, so spodaj navedeni za izbrano metodo.
Qwen-Audio-3.0-Realtime-Plus je model družbe Alibaba za glasovni pogovor v živo. Sprejema govor in besedilo, odgovarja z zvokom in besedilom ter podpira dvosmeren pogovor z naravnim izmenjavanjem replik. Zvok je mogoče pošiljati in prejemati po delih, zato interakcija poteka med samim pogovorom.
Kdaj sogovornik konča misel
Na voljo je več načinov določanja meja replike: glede na zvočno aktivnost, pomensko zaključenost in z izrecnim upravljanjem. Pri proizvajalcu se način izbere pred pošiljanjem prvega zvoka; za spremembo po začetku pogovora je potrebna nova povezava. Podpora za to upravljanje je odvisna od izbranega načina dostopa. Pomenski način upošteva premore in govorna mašila: kratko oklevanje še ne pomeni nujno, da je uporabnik končal misel. Nov uporabnikov govor lahko prekine nastajajoči odgovor, da se pogovor nadaljuje ob upoštevanju naslednje replike. V pomenskem načinu lahko prepoznavanje usmerite na govorni vzorec izbranega sogovornika, da se manj odziva na druge glasove in hrup v ozadju.
Navodila določajo vlogo pomočnika in slog pogovora. Glasovna izvedba lahko upošteva ton, tempo in čustvo; za različico 3.0 je predvidenih pet sistemskih glasov in glasovi na podlagi govornega vzorca. Model podpira 11 jezikov, vključno z ruščino, ter različice kitajskih narečij, ki jih navaja proizvajalec. Pri proizvajalcu se glas določi ob prvi posodobitvi nastavitev seje; poznejše pošiljanje novega glasu v istem pogovoru se prezre. Te nastavitve zahtevajo podporo izbranega načina dostopa.
Orodja in zgodovina pogovora
Podprto je klicanje funkcij. Model oblikuje potrebno dejanje, povezana aplikacija pa ga izvede in rezultat vrne v pogovor. Tako lahko pogovor temelji na dejanskih podatkih in se nadaljuje po izvedeni operaciji. Glasovni pomočnik lahko uporablja rezultate orodij, pri tem pa ohranja kontekst pogovora. Zmožnosti proizvajalca vključujejo tudi vgrajeno spletno iskanje, če ga omogoča izbrani način dostopa. Spletnega iskanja in klicev funkcij ni mogoče hkrati vključiti v eni seji.
Zgodovina privzeto vsebuje 20 korakov pogovora, predviden pa je razpon od enega do 50. Za nakopičeni zvok velja omejitev 300 sekund; ob prekoračitvi omejitev se starejši deli zgodovine odstranijo. To se razlikuje od trajanja posamezne replike: zgodovina določa, katero prejšnje gradivo ostane na voljo pri nadaljevanju pogovora.
Besedilni kontekst in zvok
Formalni kontekst obsega 40 960 tokenov. Največja dolžina vhoda je 16 384 tokenov, izhoda pa 8192; enaki vhodni in izhodni omejitvi sta navedeni za način sklepanja, z ločeno omejitvijo verige sklepanja na 1024 tokenov.
Za pretočni zvok je predviden enokanalni PCM s 16-bitnim zapisom: na vhodu 16 kHz, na izhodu pa 24 kHz. Besedilni in zvočni podatki pripadajo istemu pogovoru. Za ta konkretni model vizualni vhod in izhod v obliki slik nista navedena; specializiran je za govor, besedilo in glasovno interakcijo.
Ailoot · Glas v realnem času GET /v1/realtime?model=qwen-audio-3.0-realtime-plus qwen-audio-3.0-realtime-plus
qwen-audio-3.0-realtime-plusZačetek
Model za glasovni pogovor v živo, ki sprejema govor in besedilo ter odgovarja z glasom ali besedilom. Zasnovan je za naraven tempo pogovora in uporabo orodij.
- Dovoljeni vhodi
- Besedilo · Zvok
- Rezultati
- Besedilo · Zvok
Na voljo v Ailoot · vhodi in metode
Ailoot · Glas v realnem času GET /v1/realtime?model=qwen-audio-3.0-realtime-plus
- Vhod
text,audio- Izhod
text,audio- Izhodni format
- dogodki seje
| Polje | Vrsta | Zahteva | Vrednosti in omejitve | Privzeto |
|---|---|---|---|---|
Poljequery.model | Vrstastring | ZahtevaObvezno | Vrednosti in omejitve qwen-audio-3.0-realtime-plus | Privzeto— |
Poljesession.input_audio_format | Vrstastring | ZahtevaIzbirno | Vrednosti in omejitve pcm16, pcm | Privzeto— |
Poljesession.output_audio_format | Vrstastring | ZahtevaIzbirno | Vrednosti in omejitve pcm16, pcm | Privzeto— |
Poljesession.instructions | Vrstastring | ZahtevaIzbirno | Vrednosti in omejitve Omejitev velja za: izbrani pravilnik seje | Privzeto— |
Poljesession.max_history_turns | Vrstainteger | ZahtevaIzbirno | Vrednosti in omejitve Najmanj: 1 Omejitev velja za: izbrani pravilnik seje | Privzeto— |
Poljeinput_audio_buffer.append.audio | Vrstabase64_string | ZahtevaObvezno | Vrednosti in omejitve Vhodna vsebina: PCM16 mono; vhod 16 kHz, izhod 24 kHz; neprazna soda dolžina v bajtih | Privzeto— |
Kombinacije vhodnih gradiv
realtime_text_audio
Parametri in življenjski cikel metode
| Parameter | Specifikacija |
|---|---|
Parametermaterial_types | Specifikacijatext, audio |
Parameterrequired | Specifikacijanull |
Parameteroptional_controls | Specifikacijanull |
Parametercontent_type | SpecifikacijaWebSocket |
Življenjski cikel: exact retained published method
Strukture metod in ID so natančno določeni; zmožnost ponudnika je ločena od sprejema zahteve.
Cenik
Cene metod Ailoot
GET /v1/realtime?model=qwen-audio-3.0-realtime-plus- Vhod
- 0,0008 $ / 1K
- Izhod
- 0,0064 $ / 1K
- Vhod
- 0,0048 $ na minuto zvoka
- Izhod
- 0,018 $ na minuto izhodnega zvoka
Ailoot pred zahtevo rezervira ocenjeni znesek. Po rezultatu obračuna končni strošek na podlagi izmerjene porabe. Obračun pretakanja uporablja končni zapis porabe. Kako delujeta rezervacija in obračun →
Primeri zahtev
Ailoot · Glas v realnem času
# 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)
Prejmi in shrani rezultate
Ailoot · Glas v realnem času
dogodki seje
Ohrani vse dokončane rezultate
Shranite vsak v celoti vrnjen odgovor, datoteko in del vsebine.
Za vsak dejanski ID odgovora združite vse vrnjene zvočne prirastke ter besedilne rezultate in rezultate dogodkov.
Če je treba preveriti izvirni odgovor
Ohranite dejanske ID-je seje/odgovora/dogodkov in dokazila.
Napake in naslednji koraki
| Odgovor | Pogoj | Naslednji korak |
|---|---|---|
Odgovor426 · invalid_request_error | PogojBrez nadgradnje WebSocket | Naslednji korakUporabite odjemalca WebSocket z Upgrade: websocket. |
Druga imena
Druga imena modelov
Ailoot qwen-audio-3.0-realtime-plus
Druga imena poti metod
Uporabite zgoraj navedene poti metod.
Povezani ID-ji za klic
FAQ · qwen-audio-3.0-realtime-plus
- Kateri vhodi in rezultati so na voljo?
GET /v1/realtime?model=qwen-audio-3.0-realtime-plus·qwen-audio-3.0-realtime-plus:text,audio→text,audio- Katere omejitve veljajo?
GET /v1/realtime?model=qwen-audio-3.0-realtime-plus·qwen-audio-3.0-realtime-plus:session.max_history_turns.minimum:1