qwen-audio-3.0-realtime-plus
Model til direkte stemmedialog, der modtager tale og tekst og svarer med stemme eller tekst. Beregnet til en naturlig samtalerytme og samspil med værktøjer.
Om modellen
Denne beskrivelse dækker modellens funktioner. Tilgængelige input, output og indstillinger i Ailoot står nedenfor for den valgte metode.
Qwen-Audio-3.0-Realtime-Plus er en model fra Alibaba til direkte stemmedialog. Den modtager tale og tekst, svarer med lyd og tekst og understøtter en tovejssamtale med naturlig udveksling af replikker. Lyd kan sendes og modtages i dele, så samspillet udvikler sig under samtalen.
Når samtalepartneren har afsluttet sin tanke
Der er flere måder at bestemme replikkens grænser på: lydaktivitet, semantisk afslutning og eksplicit styring. Hos producenten vælges tilstanden før det første lydinput; ændring efter samtalens start kræver en ny forbindelse. Understøttelsen af denne styring afhænger af den valgte metode. Den semantiske tilstand tager højde for pauser og fyldord: en kort tøven betyder ikke nødvendigvis, at brugeren har afsluttet sin tanke. Ny tale fra brugeren kan afbryde det igangværende svar, så samtalen fortsætter med den næste replik. I den semantiske tilstand kan genkendelsen rettes mod en taleprøve fra den valgte samtalepartner for at blive mindre påvirket af andre stemmer og baggrundsstøj.
Instruktioner fastlægger assistentens rolle og samtalestil. Stemmeføringen kan tage højde for tone, tempo og følelse; version 3.0 har fem systemstemmer og stemmer baseret på en taleprøve. Modellen understøtter 11 sprog, herunder russisk, samt de kinesiske dialektvarianter, producenten angiver. Hos producenten vælges stemmen ved den første opdatering af sessionens indstillinger; efterfølgende angivelse af en ny stemme i samme samtale ignoreres. Disse indstillinger kræver understøttelse af den valgte adgangsmetode.
Værktøjer og samtalehistorik
Funktionskald understøttes. Modellen formulerer den nødvendige handling, og den tilsluttede applikation udfører den og returnerer resultatet til dialogen. Dermed kan samtalen bygges omkring faktiske data og fortsætte efter den udførte operation. Stemmeassistenten kan bruge værktøjsresultater og bevare samtalens kontekst. Producentens muligheder omfatter også indbygget websøgning, hvis den valgte metode stiller den til rådighed. Websøgning og funktionskald kan ikke være aktiveret samtidig i samme session.
Som standard indeholder historikken 20 samtaleture, og et interval fra én til 50 er muligt. Den samlede lyd i historikken har en grænse på 300 sekunder; gamle dele slettes, når grænserne overskrides. Dette adskiller sig fra varigheden af en enkelt replik: historikken bestemmer, hvilket tidligere materiale der fortsat er tilgængeligt, når dialogen fortsætter.
Tekstkontekst og lyd
Den formelle kontekst er 40 960 tokens. Den maksimale inputlængde er 16 384 tokens og outputlængden 8192; de samme input- og outputgrænser er angivet for ræsonnementstilstanden, med en særskilt grænse på 1024 tokens for ræsonnementskæden.
Til streaming af lyd bruges enkeltkanals PCM med 16-bit-repræsentation: 16 kHz i input og 24 kHz i output. Tekst- og lyddata hører til samme samtale. Visuelt input og billedoutput er ikke beskrevet for denne model; dens speciale er tale, tekst og stemmeinteraktion.
Ailoot · Stemme i realtid GET /v1/realtime?model=qwen-audio-3.0-realtime-plus qwen-audio-3.0-realtime-plus
qwen-audio-3.0-realtime-plusStart
Model til direkte stemmedialog, der modtager tale og tekst og svarer med stemme eller tekst. Beregnet til en naturlig samtalerytme og samspil med værktøjer.
- Accepterede input
- Tekst · Lyd
- Resultater
- Tekst · Lyd
Tilgængelig i Ailoot · input og metoder
Ailoot · Stemme i realtid GET /v1/realtime?model=qwen-audio-3.0-realtime-plus
- Inputtyper
text,audio- Outputtyper
text,audio- Outputformat
- sessionshændelser
| Felt | Type | Krav | Værdier og grænser | Standard |
|---|---|---|---|---|
Feltquery.model | Typestring | KravPåkrævet | Værdier og grænser qwen-audio-3.0-realtime-plus | Standard— |
Feltsession.input_audio_format | Typestring | KravValgfrit | Værdier og grænser pcm16, pcm | Standard— |
Feltsession.output_audio_format | Typestring | KravValgfrit | Værdier og grænser pcm16, pcm | Standard— |
Feltsession.instructions | Typestring | KravValgfrit | Værdier og grænser Grænsen gælder for: den valgte sessionspolitik | Standard— |
Feltsession.max_history_turns | Typeinteger | KravValgfrit | Værdier og grænser Minimum: 1 Grænsen gælder for: den valgte sessionspolitik | Standard— |
Feltinput_audio_buffer.append.audio | Typebase64_string | KravPåkrævet | Værdier og grænser Inputindhold: PCM16 mono; 16 kHz input, 24 kHz output; ikke-tom, lige bytelængde | Standard— |
Kombinationer af inputmaterialer
realtime_text_audio
Metodeparametre og livscyklus
| Parameter | Kontrakt |
|---|---|
Parametermaterial_types | Kontrakttext, audio |
Parameterrequired | Kontraktnull |
Parameteroptional_controls | Kontraktnull |
Parametercontent_type | KontraktWebSocket |
Livscyklus: exact retained published method
Metodernes strukturer og ID’er er præcise; leverandørens muligheder er adskilt fra adgangstilladelse.
Priser
Ailoot-metodetakster
GET /v1/realtime?model=qwen-audio-3.0-realtime-plus- Input
- 0,0008 US$ / 1K
- Output
- 0,0064 US$ / 1K
- Input
- 0,0048 US$ pr. minut lyd
- Output
- 0,018 US$ pr. minut lydoutput
Ailoot reserverer et estimeret beløb før en anmodning. Efter resultatet afregnes det endelige beløb ud fra det målte forbrug. Ved streaming bruges den endelige forbrugsregistrering til afregningen. Sådan fungerer reservation og afregning →
Eksempelanmodninger
Ailoot · Stemme i realtid
# 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)
Hent og gem resultater
Ailoot · Stemme i realtid
sessionshændelser
Behold alle færdige resultater
Gem hvert fuldstændigt returneret svar, hver fil og hver indholdsdel.
Saml hvert returneret lyddelta og hvert tekst- eller hændelsesresultat for hvert faktisk svar-ID.
Hvis det oprindelige svar skal kontrolleres
Behold de faktiske sessions-, svar- og hændelses-ID’er samt dokumentationen.
Fejl og næste trin
| Svar | Betingelse | Næste trin |
|---|---|---|
Svar426 · invalid_request_error | BetingelseIngen opgradering til WebSocket | Næste trinBrug en WebSocket-klient med Upgrade: websocket. |
Aliaser
Modelaliaser
Ailoot qwen-audio-3.0-realtime-plus
Aliaser for metodestier
Brug metodestierne vist ovenfor.
Relaterede kalder-ID’er
FAQ · qwen-audio-3.0-realtime-plus
- Hvilke input og resultater er tilgængelige?
GET /v1/realtime?model=qwen-audio-3.0-realtime-plus·qwen-audio-3.0-realtime-plus:text,audio→text,audio- Hvilke grænser gælder?
GET /v1/realtime?model=qwen-audio-3.0-realtime-plus·qwen-audio-3.0-realtime-plus:session.max_history_turns.minimum:1