qwen-audio-3.0-realtime-plus
Modelo de conversación de voz en tiempo real que recibe voz y texto y responde con voz o texto. Está diseñado para mantener un ritmo de comunicación natural e interactuar con herramientas.
Sobre el modelo
Esta descripción cubre las capacidades del modelo. Las entradas, salidas y opciones disponibles en Ailoot se indican a continuación para el método seleccionado.
Qwen-Audio-3.0-Realtime-Plus es un modelo de Alibaba para conversaciones de voz en tiempo real. Recibe voz y texto, responde con audio y texto y admite una conversación bidireccional con un intercambio natural de intervenciones. El audio puede enviarse y recibirse por partes, de modo que la interacción avanza durante la conversación.
Cuándo ha terminado de hablar el interlocutor
Hay varias formas de detectar los límites de una intervención: actividad de audio, finalización semántica y control explícito. En el servicio del fabricante, el modo se elige antes de enviar el primer audio; cambiarlo una vez iniciada la conversación requiere una conexión nueva. La compatibilidad con este control depende del método elegido. El modo semántico tiene en cuenta pausas y muletillas: una breve vacilación no significa necesariamente que el usuario haya terminado de expresar su idea. Una nueva intervención del usuario puede interrumpir la respuesta que se está generando para continuar la conversación teniendo en cuenta lo que acaba de decir. En el modo semántico se puede orientar el reconocimiento con una muestra de voz del interlocutor elegido para prestar menos atención a otras voces y al ruido de fondo.
Las instrucciones definen el papel del asistente y su estilo de comunicación. La expresión de voz puede tener en cuenta el tono, el ritmo y la emoción; la versión 3.0 ofrece cinco voces del sistema y voces basadas en una muestra de habla. El modelo admite 11 idiomas, incluido el ruso, además de las variantes dialectales chinas indicadas por el fabricante. En el servicio del fabricante, la voz se fija en la primera actualización de los ajustes de sesión; enviar después otra voz dentro de la misma conversación se ignora. Estos ajustes requieren compatibilidad del método de acceso elegido.
Herramientas e historial de conversación
Se admite la llamada a funciones. El modelo propone la acción necesaria, la aplicación conectada la ejecuta y devuelve el resultado al diálogo. Así se puede organizar la conversación en torno a datos reales y continuarla después de la operación. El asistente de voz puede apoyarse en resultados de herramientas manteniendo el contexto de la conversación. Las capacidades del fabricante también incluyen búsqueda web integrada si el método elegido la ofrece. La búsqueda web y las llamadas a funciones no pueden activarse simultáneamente en una misma sesión.
Por defecto, el historial contiene 20 turnos de conversación y admite un rango de uno a 50. El audio acumulado tiene un límite de 300 segundos; se eliminan las partes antiguas del historial cuando se superan los límites. Esto difiere de la duración de una intervención: el historial determina qué material anterior sigue disponible al continuar el diálogo.
Contexto de texto y audio
El contexto formal es de 40 960 tokens. La longitud máxima de entrada es de 16 384 tokens y la de salida, 8192; se indican los mismos límites de entrada y salida para el modo de razonamiento, con un límite independiente de 1024 tokens para la cadena de razonamiento.
El audio en streaming utiliza PCM de un solo canal y representación de 16 bits: 16 kHz en la entrada y 24 kHz en la salida. Texto y audio pertenecen a una misma conversación. No se han anunciado entrada visual ni generación de imágenes para este modelo concreto; su especialidad es la voz, el texto y la interacción hablada.
Ailoot · Voz en tiempo real GET /v1/realtime?model=qwen-audio-3.0-realtime-plus qwen-audio-3.0-realtime-plus
qwen-audio-3.0-realtime-plusInicio
Modelo de conversación de voz en tiempo real que recibe voz y texto y responde con voz o texto. Está diseñado para mantener un ritmo de comunicación natural e interactuar con herramientas.
- Entradas aceptadas
- Texto · Audio
- Resultados
- Texto · Audio
Disponible en Ailoot · entradas y métodos
Ailoot · Voz en tiempo real GET /v1/realtime?model=qwen-audio-3.0-realtime-plus
- Entrada
text,audio- Salida
text,audio- Formato de salida
- eventos de sesión
| Campo | Tipo | Requisito | Valores y límites | Predeterminado |
|---|---|---|---|---|
Campoquery.model | Tipostring | RequisitoObligatorio | Valores y límites qwen-audio-3.0-realtime-plus | Predeterminado— |
Camposession.input_audio_format | Tipostring | RequisitoOpcional | Valores y límites pcm16, pcm | Predeterminado— |
Camposession.output_audio_format | Tipostring | RequisitoOpcional | Valores y límites pcm16, pcm | Predeterminado— |
Camposession.instructions | Tipostring | RequisitoOpcional | Valores y límites El límite se aplica a: política de sesión seleccionada | Predeterminado— |
Camposession.max_history_turns | Tipointeger | RequisitoOpcional | Valores y límites Mínimo: 1 El límite se aplica a: política de sesión seleccionada | Predeterminado— |
Campoinput_audio_buffer.append.audio | Tipobase64_string | RequisitoObligatorio | Valores y límites Contenido de entrada: PCM16 mono; entrada de 16 kHz, salida de 24 kHz; longitud en bytes no vacía y par | Predeterminado— |
Combinaciones de materiales de entrada
realtime_text_audio
Parámetros del método y ciclo de vida
| Parámetro | Contrato |
|---|---|
Parámetromaterial_types | Contratotext, audio |
Parámetrorequired | Contratonull |
Parámetrooptional_controls | Contratonull |
Parámetrocontent_type | ContratoWebSocket |
Ciclo de vida: exact retained published method
Las estructuras e ID de los métodos son exactos; la capacidad del proveedor y la admisión son conceptos distintos.
Tarifas
Tarifas de métodos Ailoot
GET /v1/realtime?model=qwen-audio-3.0-realtime-plus- Entrada
- USD 0.0008 / 1K
- Salida
- USD 0.0064 / 1K
- Entrada
- USD 0.0048 por minuto de audio
- Salida
- USD 0.018 por minuto de audio de salida
Ailoot reserva un monto estimado antes de la solicitud. Tras obtener el resultado, liquida el cargo definitivo según el uso medido. En las respuestas en flujo, la liquidación usa el registro de uso final. Cómo funcionan la reserva y la liquidación →
Solicitudes de ejemplo
Ailoot · Voz en tiempo real
# 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)
Recibir y guardar resultados
Ailoot · Voz en tiempo real
eventos de sesión
Conserva todos los resultados completados
Conserva todas las respuestas, archivos y partes de contenido completos recibidos.
Ensambla cada fragmento de audio devuelto y cada resultado de texto o evento para cada ID real de respuesta.
Si es necesario revisar la respuesta original
Conserva los ID reales de sesión, respuesta y evento, así como los comprobantes.
Errores y siguientes pasos
| Respuesta | Condición | Siguiente paso |
|---|---|---|
Respuesta426 · invalid_request_error | CondiciónSin actualización de conexión a WebSocket | Siguiente pasoUsa un cliente WebSocket con Upgrade: websocket. |
Alias
Alias del modelo
Ailoot qwen-audio-3.0-realtime-plus
Alias de rutas de métodos
Usa las rutas de método indicadas arriba.
ID de modelo relacionados
FAQ · qwen-audio-3.0-realtime-plus
- ¿Qué entradas y resultados están disponibles?
GET /v1/realtime?model=qwen-audio-3.0-realtime-plus·qwen-audio-3.0-realtime-plus:text,audio→text,audio- ¿Qué límites se aplican?
GET /v1/realtime?model=qwen-audio-3.0-realtime-plus·qwen-audio-3.0-realtime-plus:session.max_history_turns.minimum:1