Presentamos Eleven v4Conoce Eleven v4, nuestro modelo más expresivo hasta la fecha.

Ir al contenido

Optimización de latencia en agentes de voz: guía paso a paso

Publicado
Última actualización

EscucharEscucha este artículo

La capacidad de respuesta de un agente de voz viene determinada por el retraso total entre el momento en que un usuario termina de hablar y aquel en que el agente empieza a responder. Rara vez ese retraso se debe a un único componente lento. Se acumula en varias etapas independientes, cada una de las cuales aporta unas decenas o cientos de milisegundos, y reducirlo requiere saber cuánto tiempo consume cada etapa.

Optimizar la latencia de un agente de voz consiste en encontrar dónde se oculta ese tiempo y recuperarlo etapa a etapa.

Este artículo complementa la visión general conceptual de la latencia. Mientras que esa página explica qué es la latencia, esta trata la arquitectura y la medición, para que acabes con un presupuesto de latencia que puedas medir y un conjunto de acciones concretas que aplicar.

Resumen

  • El tiempo hasta el primer audio representa todo el flujo de procesamiento, no el tiempo de inferencia de un único modelo.
  • El tiempo hasta el primer token del LLM y la detección de final de turno son las dos partidas más importantes.
  • Superponer etapas, en lugar de ejecutarlas en serie, recupera gran parte del presupuesto.
  • El streaming, la elección del códec y el ajuste del búfer del reproductor reducen milisegundos de forma medible.
  • Debes medir por región en tu propio despliegue e informar de P50 y P95.

Definir el presupuesto de latencia de un agente de voz

Un presupuesto de latencia es un objetivo total de tiempo hasta el primer audio, distribuido entre las etapas del flujo de procesamiento, con un margen asignado a cada etapa cuya suma debe quedar por debajo de tu objetivo. Definirlo es el primer paso y también donde el trabajo de latencia suele fallar, ya que se pueden confundir dos cifras que parecen similares pero significan cosas distintas.

La primera es la latencia de inferencia del modelo: el tiempo que un modelo dedica a generar una salida. Para nuestros modelos Flash es de aproximadamente 75 ms para entradas cortas habituales, sin incluir la sobrecarga de red y de la aplicación. Es una cifra interna y resulta útil para comparar modelos entre sí. No es la cifra que experimenta tu usuario.

Desde la perspectiva del usuario, debes centrarte en el tiempo hasta el primer audio (TTFA): el tiempo transcurrido desde que el usuario deja de hablar hasta que oye la primera muestra de la respuesta del agente. El TTFA siempre es mayor que la latencia de inferencia de cualquier modelo individual, porque suma todo el flujo de procesamiento.

Un agente de voz en cascada es una cadena de cinco etapas:

  • captura (micrófono) -> STT -> LLM -> TTS -> reproducción

El audio se captura desde el micrófono, se transcribe a texto, se envía a un modelo de lenguaje, el texto del modelo se sintetiza de nuevo en voz y esa voz se almacena en búfer y se reproduce. Cada etapa añade latencia y, en varias de ellas, el mayor coste no es el que esperarías.

Este es un ejemplo práctico para un agente en inglés con servidores razonablemente cerca del usuario. Las cifras son rangos ilustrativos, no garantías.

What it covers
Capture + endpointing
Mic capture, VAD/turn-detection delay before the turn is considered finished
STT finalization
Last partial to committed transcript after end-of-speech
Network (client to your server to our API)
Round-trips across the pipeline
LLM time-to-first-token
Prompt processing until the first usable token
TTS time-to-first-audio
First TTS request until first audio chunk leaves the model
Player buffering
Client-side buffer before playback begins
End-to-end TTFA
The total latency of the end-to-end pipeline
P50
Capture + endpointing
120 ms
STT finalization
60 ms
Network (client to your server to our API)
60 ms
LLM time-to-first-token
250 ms
TTS time-to-first-audio
110 ms
Player buffering
80 ms
End-to-end TTFA
~680 ms
P95
Capture + endpointing
280 ms
STT finalization
150 ms
Network (client to your server to our API)
160 ms
LLM time-to-first-token
600 ms
TTS time-to-first-audio
220 ms
Player buffering
150 ms
End-to-end TTFA
~1560 ms

Normalmente, las dos partidas de latencia más importantes son el tiempo hasta el primer token del LLM y el retraso de detección de final de turno al inicio de la cadena. 

La tabla es una forma útil de visualizar el flujo de procesamiento, pero implica que las etapas se ejecutan estrictamente en serie, y no es así. Varias de las optimizaciones más importantes de la latencia de agentes de voz consisten en superponerlas, y es con esa superposición como se recupera la mayor parte del presupuesto indicado abajo.

Voz a Texto: optimización de la latencia de transcripción y detección de final de turno

La transcripción es la segunda etapa del flujo de procesamiento, y su coste real no es la transcripción en sí, sino decidir cuándo el usuario ha dejado de hablar. Esta sección aborda ambos aspectos para ayudarte a optimizar la latencia de tu agente de voz.

La transcripción ocurre antes de llegar al LLM. Scribe v2 Realtime (scribe_v2_realtime) devuelve transcripciones parciales en aproximadamente 150 ms y transmite fragmentos de audio, por lo que la transcripción se genera mientras el usuario sigue hablando. Admite PCM de 8 kHz a 48 kHz y codificación mu-law, algo relevante para la sección sobre códecs más adelante. Los parciales de 150 ms tienen un coste reducido.

El mayor coste de latencia es la detección de final de turno: el momento en que tu sistema decide que el usuario realmente ha terminado su turno.

Detección de Actividad de Voz (VAD) segmenta la voz según los silencios, y ahí es donde se acumula el tiempo. Si esperas, por ejemplo, 700 ms de silencio antes de declarar que el turno ha terminado, habrás añadido 700 ms a cada turno, además de la propia transcripción. Ese retraso es invisible en una prueba de precisión de transcripción, pero muy perceptible en una conversación real. Con frecuencia es la mayor latencia controlable de todo el flujo de procesamiento y, precisamente porque es controlable, es un buen punto de partida.

La detección de final de turno supone un equilibrio entre capacidad de respuesta e interrupciones. Un umbral de silencio corto hace que el agente responda rápido, pero puede cortar al usuario a mitad de frase durante una pausa natural. Un umbral largo es seguro, pero lento. En la práctica, los tres cambios que optimizan la latencia en Voz a Texto son:

  1. Ajusta el umbral de silencio: Reduce el umbral de silencio hasta el valor más bajo que no recorte las pausas naturales de tus usuarios y mide después la tasa de interrupciones en producción, en lugar de hacer suposiciones.
  2. Incorpora un evento de control físico: Usa control de confirmación manual cuando tu aplicación sepa que el turno ha terminado a partir de otra señal (soltar el botón de pulsar para hablar, un evento de la interfaz), en vez de esperar al temporizador de VAD.
  3. Superpónlo con los procesos del LLM: Envía los parciales antes al procesamiento posterior. Introduce parciales estables en el LLM y revísalos si la transcripción final difiere; es una forma de ejecución especulativa que oculta el retraso de detección de final de turno tras el procesamiento del prompt del LLM.

Para más información, Scribe v2 Realtime se describe con más detalle en la página de capacidades de Voz a Texto y en la página del producto Voz a Texto en Tiempo Real.

La contribución del LLM a la latencia

El modelo de lenguaje suele ser el mayor contribuyente individual al TTFA, por lo que también es donde más compensa la superposición al optimizar la latencia de un agente de voz. La idea clave es que el agente no necesita tener toda la respuesta antes de empezar a hablar.

El patrón que recupera la mayor parte del presupuesto de latencia consiste en transmitir tokens desde el LLM e introducirlos en TTS a medida que llegan, agrupados en los límites de frases u oraciones. La lógica es almacenar tokens en búfer hasta un límite de oración y sintetizar entonces esa oración mientras la siguiente aún se está generando:

const SENTENCE_END = /(?<=[.!?])\s+/;

async function* speakLlmStream(tokens: AsyncIterable<string>) {
  let buffer = "";
  for await (const token of tokens) {
    buffer += token;
    const parts = buffer.split(SENTENCE_END);
    buffer = parts.pop() ?? ""; // keep the incomplete fragment
    for (const sentence of parts) {
      if (sentence.trim()) yield* synthesize(sentence.trim());
    }
  }
  if (buffer.trim()) yield* synthesize(buffer.trim());
}

async function* synthesize(text: string) {
  const stream = await elevenlabs.textToSpeech.stream("JBFqnCBsd6RMkjVDRZzb", {
    text,
    modelId: "eleven_flash_v2_5",
    outputFormat: "mp3_44100_128",
  });
  yield* stream;
}

Para conversaciones largas, prioriza el WebSocket de TTS para que una conexión abierta pueda recibir texto de forma incremental sin volver a pagar el establecimiento de conexión con cada oración. Solo cuenta para tu límite de concurrencia el tiempo durante el que el modelo genera audio activamente, por lo que un WebSocket abierto e inactivo es prácticamente gratuito.

Texto a Voz: streaming y elección de voz

Texto a Voz es la etapa en la que puedes concretar la latencia con mayor precisión. Tiene dos palancas principales: cómo transmites el audio y qué voz eliges.

Flash v2.5 (eleven_flash_v2_5) es el modelo que debes usar en un agente. Ofrece aproximadamente 75 ms de inferencia del modelo para entradas cortas, admite 32 idiomas y acepta hasta 40.000 caracteres por solicitud.

La cifra de 75 ms corresponde únicamente a la inferencia. La línea de TTFA de TTS del presupuesto anterior es mayor porque añade el viaje de ida y vuelta por la red y la planificación del servidor a la inferencia.

La principal palanca aquí es el streaming. Si solicitas el audio completo y esperas, el usuario espera a que se sintetice todo el clip antes de oír nada. Si transmites en streaming, el usuario oye el primer fragmento en cuanto se genera y el resto llega mientras ya está escuchando. El streaming no acelera el modelo; simplemente empieza a enviar la salida al usuario mientras el modelo sigue generando.

La guía práctica de streaming trata el streaming mediante HTTP, y la guía de WebSocket en tiempo real explica la vía de WebSocket que necesitarás para introducir tokens desde un LLM.

Inicializa el cliente una vez y reutilízalo para cada llamada siguiente:

import { ElevenLabsClient } from "@elevenlabs/elevenlabs-js";

const elevenlabs = new ElevenLabsClient({ apiKey: process.env.ELEVENLABS_API_KEY });

Después, configura un stream y reenvíalo a medida que llegue:

const stream = await elevenlabs.textToSpeech.stream("JBFqnCBsd6RMkjVDRZzb", {
  text: "Your call is connected. How can I help today?",
  modelId: "eleven_flash_v2_5",
  outputFormat: "mp3_44100_128",
});

for await (const chunk of stream) {
  // forward each chunk to your audio sink as it arrives
}

La otra palanca es la elección de voz, que también tiene un coste de latencia. Las voces predeterminadas, las voces sintéticas y los Clones de Voz Instantáneos (IVC) sintetizan más rápido que los Clones de Voz Profesionales (PVC), ya que los PVC incorporan una complejidad adicional del modelo que añade sobrecarga en cada generación. Para un agente con requisitos estrictos de latencia, la combinación de Flash con un IVC o una voz predeterminada es la opción con menor latencia.

Opciones de tamaño de fragmentos de streaming

Con tokens que entran en TTS y audio que vuelve, la siguiente decisión es qué tamaño dar a los fragmentos y cuánto debe almacenar el reproductor en búfer antes de empezar.

Los fragmentos más pequeños llegan antes al reproductor y reducen la latencia hasta el primer byte, a costa de más mensajes y una sobrecarga por fragmento ligeramente mayor. Los fragmentos grandes son más eficientes de transportar, pero hacen que el usuario espere más por el primero. Para agentes interactivos, da prioridad a fragmentos pequeños al principio de la intervención, porque el usuario está esperando ese primer fragmento; los posteriores llegan mientras el audio ya se está reproduciendo y su tamaño importa menos.

El reproductor representa una parte importante de la latencia restante. La mayoría de reproductores de audio no empiezan a reproducir con el primer byte. Almacenan una pequeña cantidad en búfer para evitar cortes si el stream se ralentiza brevemente. Es habitual usar un búfer predeterminado de 500 ms, que se añade directamente a la latencia percibida. Reducirlo intercambia un pequeño aumento del riesgo de cortes por un TTFA menor, y el valor adecuado depende de la fluctuación de red entre tu servidor y el cliente:

  • En una conexión estable (reproducción en el servidor o cliente ubicado en la misma ubicación), un búfer de 50 a 150 ms suele ser seguro y reduce notablemente el TTFA.
  • En una conexión móvil inestable o entre regiones, un búfer mayor evita huecos audibles que son peores que la latencia que cuestan.

La configuración exacta que elijas aquí depende de tu caso de uso activo y de tus prioridades.

Opciones de códec

El destino del audio debe determinar el códec que solicites. Devolvemos formatos como mp3_44100_128, mp3_22050_32, pcm_16000, pcm_24000 y ulaw_8000. Hacer coincidir el formato nativo del transporte elimina un paso de transcodificación y ayuda a optimizar la latencia de los agentes de voz.

Para telefonía, como Twilio y proveedores similares, usa ulaw_8000. La red telefónica utiliza mu-law de 8 kHz de extremo a extremo, por lo que solicitarlo directamente evita un paso de transcodificación en tu flujo de procesamiento y se ajusta a lo que espera el operador. No aporta ningún beneficio sintetizar audio de mayor fidelidad que la red telefónica reducirá inmediatamente; solo añadirías latencia sin perder nada audible.

Para WebRTC y la reproducción en navegador, usa PCM (pcm_24000 o pcm_16000) o un formato MP3. PCM no está comprimido, por lo que no hay ningún paso de decodificación en el cliente, lo que elimina una pequeña cantidad de latencia por fragmento y resulta práctico cuando alimentas directamente un flujo de Web Audio. MP3 es más compacto en la red, lo que ayuda en conexiones limitadas, a costa de una decodificación ligera en el cliente.

Geografía y distancias de red

Todas las optimizaciones anteriores dan por hecho que los bytes recorren una distancia corta. La geografía establece el límite inferior de tu presupuesto de latencia, así que conviene analizarla antes de ajustar cualquier otra cosa.

Atendemos solicitudes desde clústeres de Norteamérica, Europa y el Sudeste Asiático, y enrutamos automáticamente cada solicitud al clúster más cercano. El viaje de ida y vuelta por la red pública de internet suele ser de 20 a 200 ms según la proximidad geográfica, y no puede reducirse sin cambiar dónde se ejecuta tu infraestructura.

Un agente que parece instantáneo en San Francisco, a poca distancia de un clúster norteamericano, puede resultar lento para un usuario del sur de Asia cuyo tráfico cruza un océano dos veces por turno.

La solución es ubicar conjuntamente los servidores de tu aplicación con tus usuarios, no solo con nosotros. Si tus usuarios están en Europa, ejecuta el backend de tu agente en Europa para que el tramo entre el usuario y tu servidor sea corto; nuestro enrutamiento se encargará después del tramo entre tu servidor y el modelo desde un clúster cercano.

Cómo medir tú mismo la latencia de un agente de voz

Las cifras de la tabla de presupuesto de latencia anterior son rangos ilustrativos para planificar. Las cifras con las que trabajes en producción deben proceder de un script como este, ejecutado en tu propio despliegue.

La instrumentación siguiente mide el TTFA de la etapa de TTS de forma aislada, es decir, el tiempo desde la solicitud hasta el primer fragmento de audio, en muchas pruebas e informa de los percentiles. Ejecútala desde la misma región donde se ejecutan tus servidores, no desde tu equipo de desarrollo. Da por hecho que usas el cliente de elevenlabs de antes:

const VOICE_ID = "JBFqnCBsd6RMkjVDRZzb";
const TEXT = "Thanks for waiting. I have pulled up your account and I can help with that now.";
const TRIALS = 50;

async function measureTtfa(): Promise<number | null> {
  const start = performance.now();
  const stream = await elevenlabs.textToSpeech.stream(VOICE_ID, {
    text: TEXT,
    modelId: "eleven_flash_v2_5",
    outputFormat: "mp3_44100_128",
  });
  for await (const _chunk of stream) {
    return performance.now() - start; // first chunk -> stop the clock
  }
  return null;
}

function percentile(values: number[], p: number): number {
  const v = [...values].sort((a, b) => a - b);
  const k = (v.length - 1) * (p / 100);
  const lo = Math.floor(k);
  const hi = Math.min(lo + 1, v.length - 1);
  return v[lo] + (v[hi] - v[lo]) * (k - lo);
}

const samples: number[] = [];
for (let i = 0; i < TRIALS; i++) {
  const ttfa = await measureTtfa();
  if (ttfa !== null) samples.push(ttfa);
  await new Promise((r) => setTimeout(r, 300)); // space requests, don't measure your own queueing
}

console.log(`trials: ${samples.length}`);
console.log(`P50:    ${percentile(samples, 50).toFixed(0)} ms`);
console.log(`P95:    ${percentile(samples, 95).toFixed(0)} ms`);

Algunas cosas que debes recordar:

  • Informa de P50 y P95: Céntrate en estos, en lugar de en la media. La media oculta la cola, y la cola es lo que hace que un agente parezca poco fiable. P95 representa la experiencia de uno de cada veinte turnos. 
  • Experimentación basada en la ubicación: Ejecuta el mismo script desde cada región a la que prestes servicio y conserva los resultados por separado.
  • Espacia las solicitudes para lograr precisión: Espacia tus solicitudes (el setTimeout anterior). Si las lanzas todas a la vez, medirás tu propia cola en lugar del servicio. Cuando se supera el límite de concurrencia, las solicitudes se encolan por prioridad, lo que normalmente añade unos 50 ms, y al superar la capacidad recibirás HTTP 429.
  • Mide toda la cadena de latencia: Amplía el mismo patrón de medición a las demás etapas. Incluye la finalización de STT, el primer token de tu LLM y el inicio de tu reproductor entre los mismos paréntesis de performance.now(), y podrás completar toda la tabla de presupuesto con tus propias cifras y ver qué etapa abordar primero.

Siguiendo estos consejos, podrás medir tú mismo la latencia de un agente de voz. A partir de ahí, tendrás una ruta clara de prioridades que abordar primero.

¿Qué reduce más la latencia de un agente de voz?

Si quieres algunas acciones rápidas en las que centrarte, estos son los cambios de mayor impacto.

A grandes rasgos y por orden de impacto, puedes usar los siguientes métodos para reducir la latencia de un agente:

  • Inicia el trabajo del LLM con parciales estables de STT para ocultar el retraso de detección de final de turno.
  • Transmite los tokens del LLM a TTS en los límites de las oraciones para que la síntesis de la primera se superponga a la generación de la segunda.
  • Transmite el audio de TTS al reproductor y reduce su búfer al valor mínimo que tolere la fluctuación de tu red.
  • Usa Flash junto con una voz predeterminada o un IVC para obtener TTS con la menor latencia, y adapta el códec al transporte (ulaw_8000 para telefonía; PCM o MP3 para navegador/WebRTC).
  • Ubica conjuntamente tus servidores con tus usuarios y mide por región, porque los tramos de red son reales y desiguales.

Para consultar técnicas específicas más avanzadas, consulta la guía práctica para desarrolladores sobre optimización de latencia. Para disponer de un punto de partida completo y ejecutable, la guía de inicio rápido de la API y la guía práctica de streaming incluyen ejemplos completos. 

¿Quieres acceder más rápido a cascadas de agentes optimizadas? ElevenAgents implementa este flujo de procesamiento con optimizaciones de superposición ya incorporadas.

Crea agentes de voz de baja latencia con ElevenAgents

Optimizar la latencia de un agente de voz requiere medir cada etapa y después superponerlas para que las más lentas se ejecuten mientras ya se está realizando otro trabajo. Puedes crear y ajustar esa cascada manualmente a lo largo de varias iteraciones, aprovechando los patrones anteriores, o empezar con un flujo de procesamiento que ya incluya optimizaciones de latencia.

ElevenAgents implementa esta cascada completa, desde STT en streaming hasta la transferencia de tokens uno a uno desde el LLM a Flash TTS, con técnicas de superposición ya incorporadas. En lugar de empezar desde cero, ajustarás los umbrales según el rendimiento que más te importe.

Empieza usando ElevenAgents para crear un agente hoy o contactar con ventas para obtener más información.

Preguntas frecuentes sobre la optimización de latencia de agentes de voz 

Escrito por

Tadas Petra es Developer Relations Engineer y ayuda a desarrolladores a crear con la suite de productos de ElevenLabs. Además, es fundador de Hungrimind, una plataforma de formación para desarrolladores. Antes fue Lead Developer Advocate en Agora e instructor en Zero To Mastery.

Artículos relacionados

Crea con el audio IA de la más alta calidad