models

qwen-audio-3.0-realtime-plus

Markdown · JSON

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-plus

Alibaba /qwen-audio-3.0-realtime-plus

Inicio

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
CampoTipoRequisitoValores y límitesPredeterminado
Campoquery.modelTipostringRequisitoObligatorioValores y límites
qwen-audio-3.0-realtime-plus
Predeterminado—
Camposession.input_audio_formatTipostringRequisitoOpcionalValores y límites
pcm16, pcm
Predeterminado—
Camposession.output_audio_formatTipostringRequisitoOpcionalValores y límites
pcm16, pcm
Predeterminado—
Camposession.instructionsTipostringRequisitoOpcionalValores y límites
El límite se aplica a: política de sesión seleccionada
Predeterminado—
Camposession.max_history_turnsTipointegerRequisitoOpcionalValores y límites
Mínimo: 1
El límite se aplica a: política de sesión seleccionada
Predeterminado—
Campoinput_audio_buffer.append.audioTipobase64_stringRequisitoObligatorioValores 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ámetroContrato
Parámetromaterial_typesContratotext, audio
ParámetrorequiredContratonull
Parámetrooptional_controlsContratonull
Parámetrocontent_typeContratoWebSocket

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

Ailoot Voz en tiempo realGET /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

Python WebSocket · textoPython WebSocket · audio
# 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
RespuestaCondiciónSiguiente paso
Respuesta426 · invalid_request_errorCondiciónSin actualización de conexión a WebSocketSiguiente 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

qwen-audio-3.0-realtime-plus

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

Más detalles

Conecta Ailoot a Claude Code, OpenCode, Hermes o tu aplicación.

La empresa y su cartera de proyectos

La empresa y su cartera de proyectos: millones de clientes; ventas por miles de millones al mes.

Compra tokens con descuento.

Ahorro por suscripción para trabajo habitual. Códigos promocionales: hasta el 50% al comprar tokens.

Suscripción
Elige un plan con descuento para tus peticiones habituales.
Código de hasta el 50%
Introduce el código al comprar. El precio se recalcula según la promoción vigente.
Gasto en el historial
Modelo, tokens e importe quedan guardados por cada petición.

Elegir suscripción · Consultar precios de modelos

Conecta la API al producto que vendes.

SaaS, aplicaciones y bots bajo la oferta y el acuerdo de licencia Ailoot. Solicita una licencia de reventa para redistribuir el acceso.

Aplicación comercial
Integra generación de texto, imágenes, vídeo y sonido en funciones de pago de tu servicio.
Licencia para revendedores
Envía descripción del proyecto y esquema de acceso. Solicita condiciones escritas de uso y reventa.
Documentos en la web
La oferta, el acuerdo de licencia y la política de datos están disponibles antes de conectar.

Solicitar licencia de reventa · Oferta y acuerdo de licencia