qwen-audio-3.0-realtime-plus
Tiesioginio balso dialogo modelis, priimantis kalbą bei tekstą ir atsakantis balsu arba tekstu. Sukurtas natūraliam bendravimo tempui ir sąveikai su įrankiais.
Apie modelį
Šis aprašas apima modelio galimybes. Pasirinktam metodui Ailoot prieinamos įvestys, išvestys ir parinktys nurodytos toliau.
Qwen-Audio-3.0-Realtime-Plus — Alibaba modelis tiesioginiam balso dialogui. Jis priima kalbą ir tekstą, atsako garsu bei tekstu ir palaiko abipusį pokalbį su natūraliu pasikeitimu replikomis. Garsą galima siųsti ir gauti dalimis, todėl sąveika vyksta pokalbio metu.
Kada pašnekovas baigė mintį
Numatyti keli būdai replikos riboms nustatyti: pagal garso aktyvumą, minties užbaigtumą ir tiesioginiu valdymu. Gamintojo sistemoje režimas pasirenkamas prieš siunčiant pirmąjį garsą; norint jį pakeisti prasidėjus pokalbiui, reikia naujo ryšio. Šio valdymo palaikymas priklauso nuo pasirinkto metodo. Prasminis režimas atsižvelgia į pauzes ir kalbos užpildus: trumpas sutrikimas nebūtinai reiškia, kad naudotojas baigė mintį. Nauja naudotojo kalba gali nutraukti kuriamą atsakymą, kad pokalbis tęstųsi atsižvelgiant į kitą repliką. Prasminiame režime atpažinimą galima nukreipti pagal pasirinkto pašnekovo kalbos pavyzdį, kad svetimi balsai ir foninis triukšmas mažiau blaškytų.
Instrukcijos nustato pagalbininko vaidmenį ir bendravimo stilių. Kalbant balsu galima atsižvelgti į toną, tempą ir emociją; 3.0 versijoje numatyti penki sisteminiai balsai ir balsai pagal kalbos pavyzdį. Modelis palaiko 11 kalbų, įskaitant rusų, bei gamintojo nurodytus kinų dialektų variantus. Gamintojo sistemoje balsas nustatomas pirmą kartą atnaujinant sesijos nuostatas; vėliau tame pačiame pokalbyje pateiktas naujas balsas ignoruojamas. Šioms nuostatoms reikia pasirinkto kreipimosi būdo palaikymo.
Įrankiai ir pokalbio istorija
Palaikomi funkcijų iškvietimai. Modelis suformuoja reikiamą veiksmą, prijungta programa jį atlieka ir grąžina rezultatą į dialogą. Tai leidžia pokalbį grįsti faktiniais duomenimis ir tęsti jį po atliktos operacijos. Balso pagalbininkas gali remtis įrankių rezultatais, išlaikydamas pokalbio kontekstą. Gamintojo galimybės taip pat apima integruotą žiniatinklio paiešką, jei ją teikia pasirinktas metodas. Žiniatinklio paieškos ir funkcijų iškvietimų negalima vienu metu įjungti vienoje sesijoje.
Pagal numatytąsias nuostatas istorijoje yra 20 pokalbio ėjimų, numatytas diapazonas — nuo vieno iki 50. Sukaupto garso riba — 300 sekundžių; viršijus apribojimus, senos istorijos dalys pašalinamos. Tai skiriasi nuo atskiros replikos trukmės: istorija nustato, kuri ankstesnė medžiaga lieka prieinama tęsiant dialogą.
Teksto kontekstas ir garsas
Formalus kontekstas — 40 960 tokenų. Didžiausia įvesties apimtis — 16 384 tokenai, išvesties — 8192; tokios pačios įvesties ir išvesties ribos nurodytos samprotavimo režimui, o atskira samprotavimo grandinės riba — 1024 tokenai.
Srautiniam garsui numatytas vienkanalis PCM su 16 bitų duomenimis: įvestyje — 16 kHz, išvestyje — 24 kHz. Teksto ir garso duomenys priklauso vienam pokalbiui. Vaizdinė įvestis ir vaizdų išvestis šiam konkrečiam modeliui nėra deklaruotos; jo specializacija — kalba, tekstas ir bendravimas balsu.
Ailoot · Balsas realiuoju laiku GET /v1/realtime?model=qwen-audio-3.0-realtime-plus qwen-audio-3.0-realtime-plus
qwen-audio-3.0-realtime-plusPradžia
Tiesioginio balso dialogo modelis, priimantis kalbą bei tekstą ir atsakantis balsu arba tekstu. Sukurtas natūraliam bendravimo tempui ir sąveikai su įrankiais.
- Leidžiamos įvestys
- Tekstas · Garsas
- Rezultatai
- Tekstas · Garsas
Prieinama Ailoot · įvestys ir metodai
Ailoot · Balsas realiuoju laiku GET /v1/realtime?model=qwen-audio-3.0-realtime-plus
- Įvestis
text,audio- Išvestis
text,audio- Išvesties formatas
- seanso įvykiai
| Laukas | Tipas | Reikalavimas | Reikšmės ir ribos | Numatyta |
|---|---|---|---|---|
Laukasquery.model | Tipasstring | ReikalavimasPrivaloma | Reikšmės ir ribos qwen-audio-3.0-realtime-plus | Numatyta— |
Laukassession.input_audio_format | Tipasstring | ReikalavimasNeprivaloma | Reikšmės ir ribos pcm16, pcm | Numatyta— |
Laukassession.output_audio_format | Tipasstring | ReikalavimasNeprivaloma | Reikšmės ir ribos pcm16, pcm | Numatyta— |
Laukassession.instructions | Tipasstring | ReikalavimasNeprivaloma | Reikšmės ir ribos Riba taikoma: pasirinkta seanso politika | Numatyta— |
Laukassession.max_history_turns | Tipasinteger | ReikalavimasNeprivaloma | Reikšmės ir ribos Mažiausia reikšmė: 1 Riba taikoma: pasirinkta seanso politika | Numatyta— |
Laukasinput_audio_buffer.append.audio | Tipasbase64_string | ReikalavimasPrivaloma | Reikšmės ir ribos Įvesties turinys: PCM16 mono; 16 kHz įvestis, 24 kHz išvestis; netuščias lyginis baitų skaičius | Numatyta— |
Įvesties medžiagos deriniai
realtime_text_audio
Metodo parametrai ir gyvavimo ciklas
| Parametras | Specifikacija |
|---|---|
Parametrasmaterial_types | Specifikacijatext, audio |
Parametrasrequired | Specifikacijanull |
Parametrasoptional_controls | Specifikacijanull |
Parametrascontent_type | SpecifikacijaWebSocket |
Gyvavimo ciklas: exact retained published method
Metodų struktūros ir ID yra tikslūs; tiekėjo galimybės yra atskirtos nuo užklausos priėmimo.
Planai
Ailoot metodų įkainiai
GET /v1/realtime?model=qwen-audio-3.0-realtime-plus- Įvestis
- 0,0008 USD / 1K
- Išvestis
- 0,0064 USD / 1K
- Įvestis
- 0,0048 USD už garso minutę
- Išvestis
- 0,018 USD už išvesties garso minutę
Ailoot prieš užklausą rezervuoja numatomą sumą. Gavus rezultatą, galutinis mokestis nuskaitomas pagal išmatuotą naudojimą. Srautinio atsakymo atsiskaitymui naudojamas galutinis naudojimo įrašas. Kaip veikia rezervavimas ir atsiskaitymas →
Užklausų pavyzdžiai
Ailoot · Balsas realiuoju laiku
# 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)
Gauti ir išsaugoti rezultatus
Ailoot · Balsas realiuoju laiku
seanso įvykiai
Išsaugoti visus baigtus rezultatus
Išsaugokite kiekvieną visą grąžintą atsakymą, failą ir turinio dalį.
Kiekvienam tikram atsakymo ID sujunkite visas grąžintas garso dalis ir teksto bei įvykių rezultatus.
Jei reikia patikrinti pradinį atsakymą
Išsaugokite tikruosius seanso, atsakymo ir įvykių ID bei patvirtinimo įrašus.
Klaidos ir tolesni veiksmai
| Atsakymas | Sąlyga | Kitas žingsnis |
|---|---|---|
Atsakymas426 · invalid_request_error | SąlygaNėra protokolo perjungimo į WebSocket | Kitas žingsnisNaudokite WebSocket klientą su Upgrade: websocket. |
Pseudonimai
Modelių pseudonimai
Ailoot qwen-audio-3.0-realtime-plus
Metodų kelių pseudonimai
Naudokite aukščiau nurodytus metodų kelius.
Susiję ID iškvietimui
FAQ · qwen-audio-3.0-realtime-plus
- Kokios įvestys ir rezultatai prieinami?
GET /v1/realtime?model=qwen-audio-3.0-realtime-plus·qwen-audio-3.0-realtime-plus:text,audio→text,audio- Kokie apribojimai taikomi?
GET /v1/realtime?model=qwen-audio-3.0-realtime-plus·qwen-audio-3.0-realtime-plus:session.max_history_turns.minimum:1