qwen-audio-3.0-realtime-plus
En modell for direkte talesamtaler som tar imot tale og tekst og svarer med stemme eller tekst. Utviklet for et naturlig samtaletempo og samspill med verktøy.
Om modellen
Denne beskrivelsen dekker modellens funksjoner. Tilgjengelige inndata, utdata og alternativer i Ailoot er oppført nedenfor for den valgte metoden.
Qwen-Audio-3.0-Realtime-Plus er en modell fra Alibaba for direkte talesamtaler. Den tar imot tale og tekst, svarer med lyd og tekst og støtter en toveis samtale med naturlig utveksling av replikker. Lyd kan sendes og mottas i deler, slik at samspillet utvikler seg under samtalen.
Når samtalepartneren har snakket ferdig
Det finnes flere måter å avgjøre hvor en replikk slutter: lydaktivitet, innholdsmessig avslutning og eksplisitt styring. Hos produsenten velges modusen før den første lyden sendes; en endring etter at samtalen har startet, krever en ny tilkobling. Støtte for denne styringen avhenger av den valgte metoden. Den semantiske modusen tar hensyn til pauser og fyllord: en kort nøling betyr ikke nødvendigvis at brukeren har snakket ferdig. Ny tale fra brukeren kan avbryte svaret som genereres, slik at samtalen fortsetter med neste replikk tatt med i vurderingen. I semantisk modus kan gjenkjenningen rettes mot en stemmeprøve fra den valgte samtalepartneren for å bli mindre forstyrret av andre stemmer og bakgrunnsstøy.
Instruksjoner bestemmer assistentens rolle og samtalestil. Stemmebruken kan ta hensyn til tone, tempo og følelser; versjon 3.0 tilbyr fem systemstemmer og stemmer basert på taleprøver. Modellen støtter 11 språk, blant annet russisk, samt de kinesiske dialektvariantene produsenten oppgir. Hos produsenten angis stemmen ved første oppdatering av øktinnstillingene; en ny stemme som sendes senere i samme samtale, ignoreres. Disse innstillingene krever støtte i den valgte måten å bruke modellen på.
Verktøy og samtalehistorikk
Funksjonskall støttes. Modellen foreslår handlingen som trengs, det tilkoblede programmet utfører den og returnerer resultatet i samtalen. Dermed kan samtalen bygge på faktiske data og fortsette etter en utført operasjon. Taleassistenten kan bruke verktøyresultater og samtidig bevare samtalekonteksten. Produsentens muligheter omfatter også innebygd nettsøk dersom den valgte metoden tilbyr dette. Nettsøk og funksjonskall kan ikke aktiveres samtidig i én økt.
Historikken inneholder som standard 20 samtalerunder, med et tilgjengelig spenn fra én til 50. Samlet lyd har en grense på 300 sekunder; eldre deler av historikken slettes når grensene overskrides. Dette er noe annet enn lengden på en enkelt replikk: historikken bestemmer hvilket tidligere materiale som er tilgjengelig når samtalen fortsetter.
Tekstkontekst og lyd
Den formelle konteksten er 40 960 tokener. Maksimal inndatalengde er 16 384 tokener og maksimal utdatalengde 8192; de samme inn- og utdatagrensene oppgis for resonneringsmodus, med en egen grense på 1024 tokener for resonneringskjeden.
Strømmet lyd bruker PCM med én kanal og 16-bits representasjon: 16 kHz for inndata og 24 kHz for utdata. Tekst- og lyddata hører til samme samtale. Visuelle inndata og bilder som utdata er ikke oppgitt for denne bestemte modellen; den er spesialisert på tale, tekst og stemmebasert samspill.
Ailoot · Tale i sanntid GET /v1/realtime?model=qwen-audio-3.0-realtime-plus qwen-audio-3.0-realtime-plus
qwen-audio-3.0-realtime-plusStart
En modell for direkte talesamtaler som tar imot tale og tekst og svarer med stemme eller tekst. Utviklet for et naturlig samtaletempo og samspill med verktøy.
- Godkjente inndata
- Tekst · Lyd
- Resultater
- Tekst · Lyd
Tilgjengelig i Ailoot · inndata & metoder
Ailoot · Tale i sanntid GET /v1/realtime?model=qwen-audio-3.0-realtime-plus
- Inndatatyper
text,audio- Utdatatyper
text,audio- Utdataformat
- Økthendelser
| Felt | Type | Krav | Verdier & grenser | Standard |
|---|---|---|---|---|
Feltquery.model | Typestring | KravPåkrevd | Verdier & grenser qwen-audio-3.0-realtime-plus | Standard— |
Feltsession.input_audio_format | Typestring | KravValgfritt | Verdier & grenser pcm16, pcm | Standard— |
Feltsession.output_audio_format | Typestring | KravValgfritt | Verdier & grenser pcm16, pcm | Standard— |
Feltsession.instructions | Typestring | KravValgfritt | Verdier & grenser Grensen gjelder for: Valgt øktpolicy | Standard— |
Feltsession.max_history_turns | Typeinteger | KravValgfritt | Verdier & grenser Minimum: 1 Grensen gjelder for: Valgt øktpolicy | Standard— |
Feltinput_audio_buffer.append.audio | Typebase64_string | KravPåkrevd | Verdier & grenser Inngående innhold: PCM16 mono; 16 kHz inndata, 24 kHz utdata; bytelengden må være et partall og større enn null | Standard— |
Kombinasjoner av inngående materialer
realtime_text_audio
Metodeparametere og livssyklus
| Parameter | Avtale |
|---|---|
Parametermaterial_types | Avtaletext, audio |
Parameterrequired | Avtalenull |
Parameteroptional_controls | Avtalenull |
Parametercontent_type | AvtaleWebSocket |
Livssyklus: exact retained published method
Metodestrukturer og ID-er er eksakte; leverandørens evne er adskilt fra godkjenning av forespørselen.
Priser
Satser for Ailoot-metoder
GET /v1/realtime?model=qwen-audio-3.0-realtime-plus- Inndata
- 0,0008 USD / 1K
- Utdata
- 0,0064 USD / 1K
- Inndata
- 0,0048 USD per minutt lyd
- Utdata
- 0,018 USD per minutt utdatalyd
Ailoot reserverer et estimert beløp før en forespørsel. Etter resultatet gjøres det endelige beløpet opp basert på målt forbruk. Oppgjør for strømming bruker den endelige forbruksposten. Slik fungerer reservasjon og oppgjør →
Eksempelforespørsler
Ailoot · Tale i sanntid
# 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)
Motta og lagre resultater
Ailoot · Tale i sanntid
Økthendelser
Behold alle ferdige resultater
Behold alle fullstendige returnerte svar, filer og innholdsdeler.
Sett sammen hvert returnert lyddelta og hvert tekst- eller hendelsesresultat for hver faktiske svar-ID.
Hvis det opprinnelige svaret må kontrolleres
Behold faktiske økt-, svar- og hendelses-ID-er og kvitteringer.
Feil og neste trinn
| Svar | Vilkår | Neste trinn |
|---|---|---|
Svar426 · invalid_request_error | VilkårIngen oppgradering til WebSocket | Neste trinnBruk en WebSocket-klient med Upgrade: websocket. |
Aliaser
Modellaliaser
Ailoot qwen-audio-3.0-realtime-plus
Aliaser for metodestier
Bruk metodestiene som vises ovenfor.
Tilknyttede anroper-ID-er
FAQ · qwen-audio-3.0-realtime-plus
- Hvilke inndata og resultater er tilgjengelige?
GET /v1/realtime?model=qwen-audio-3.0-realtime-plus·qwen-audio-3.0-realtime-plus:text,audio→text,audio- Hvilke grenser gjelder?
GET /v1/realtime?model=qwen-audio-3.0-realtime-plus·qwen-audio-3.0-realtime-plus:session.max_history_turns.minimum:1