Pular para o conteúdo

Otimização de latência em agentes de voz: guia passo a passo

Publicado
Última atualização

OuvirOuça este artigo

A resposta de um agente de voz depende do tempo total entre o momento em que o usuário termina de falar e o início da resposta do agente. Esse atraso raramente é causado por um único componente lento. Ele se acumula em várias etapas independentes, cada uma contribuindo com dezenas ou centenas de milissegundos, e para reduzir é preciso saber quanto tempo cada etapa consome.

Otimizar a latência de um agente de voz é identificar onde esse tempo está escondido e recuperá-lo etapa por etapa.

Este artigo complementa o guia conceitual sobre latência. Enquanto aquela página explica o que é latência, aqui você encontra detalhes sobre arquitetura e medições, para que você saia com um orçamento de latência mensurável e ações práticas para aplicar.

Resumo

  • O tempo até o primeiro áudio representa todo o pipeline, não apenas o tempo de inferência de um modelo.
  • O tempo até o primeiro token do LLM e o endpointing são os maiores responsáveis pela latência.
  • Sobrepor etapas, em vez de executá-las em série, recupera a maior parte do tempo.
  • Streaming, escolha do codec e ajuste do buffer do player ajudam a economizar milissegundos.
  • Você deve medir por região no seu próprio ambiente, reportando P50 e P95.

Definindo o orçamento de latência do agente de voz

O orçamento de latência é o tempo total até o primeiro áudio, distribuído entre as etapas do pipeline, com cada etapa recebendo uma cota que deve somar menos que o seu objetivo. Definir esse orçamento é o primeiro passo e também onde muitos erram, pois engenheiros podem confundir dois números parecidos, mas com significados diferentes.

O primeiro é a latência de inferência do modelo: o tempo que o modelo leva para gerar uma resposta. Para nossos modelos Flashisso é aproximadamente 75 ms para entradas curtas típicas, sem contar a latência de rede e do aplicativo. É um valor interno, útil para comparar um modelo com outro. Não é o tempo que o usuário realmente percebe.

Do ponto de vista do usuário, o foco é o tempo até o primeiro áudio (TTFA): o tempo entre o usuário parar de falar e ouvir a primeira resposta do agente. O TTFA sempre é maior que a latência de inferência de qualquer modelo, pois soma todas as etapas do pipeline.

Um agente de voz em cascata passa por cinco etapas:

  • captura (microfone) -> STT -> LLM -> TTS -> reprodução

O áudio é capturado do microfone, transcrito em texto, enviado para o modelo de linguagem, o texto é sintetizado em voz e essa voz é armazenada em buffer e reproduzida. Cada etapa adiciona latência, e em várias delas o maior custo não é o que você imagina.

Veja um exemplo para um agente em inglês com servidores próximos do usuário. Os números são faixas ilustrativas, não garantias.

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, os dois maiores responsáveis pela latência são o tempo até o primeiro token do LLM e o atraso do endpointing no início da cadeia.

A tabela ajuda a visualizar o pipeline, mas sugere que as etapas rodam em série, o que não acontece. Muitas otimizações de latência vêm da sobreposição dessas etapas, e é aí que a maior parte do tempo é recuperada.

Speech to Text: otimização da latência de transcrição e endpointing

A transcrição é a segunda etapa do pipeline, e seu maior custo não é a transcrição em si, mas decidir quando o usuário terminou de falar. Esta seção cobre ambos os pontos para ajudar você a otimizar a latência.

A transcrição ocorre antes de chegar ao LLM.Scribe v2 em Tempo Real(scribe_v2_realtime) retorna transcrições parciais em cerca de 150 ms e transmite em blocos de áudio, então a transcrição é gerada enquanto o usuário ainda está falando. Suporta PCM de 8kHz a 48kHz e codificação mu-law, o que é importante para a seção de codec abaixo. As transcrições parciais de 150 ms têm baixo custo.

O maior custo de latência é o endpointing: o momento em que o sistema decide que o usuário realmente terminou sua vez.

A Detecção de Atividade de Voz (VAD) segmenta o áudio com base no silêncio, e é aí que o tempo se acumula. Se você esperar, por exemplo, 700 ms de silêncio antes de considerar que a vez terminou, estará adicionando 700 ms a cada interação, além do tempo da transcrição em si. Esse atraso não aparece em testes de precisão de transcrição, mas faz diferença em uma conversa real. Geralmente, é a maior fonte de latência controlável em todo o processo e, justamente por ser controlável, é um bom ponto de partida.

O endpointing é um equilíbrio entre rapidez e interrupção. Um limite curto de silêncio faz o agente responder rápido, mas pode cortar o usuário no meio de uma frase durante uma pausa natural. Um limite longo é mais seguro, mas deixa tudo mais lento. Na prática, as três mudanças que otimizam a latência em

  1. Ajuste fino do limiar de silêncio:Reduza o limiar ao menor valor que não corte as pausas naturais dos usuários e meça a taxa de interrupção em produção, em vez de adivinhar.
  2. Inclua um evento de controle físico: Use controle manual quando sua aplicação souber que a vez terminou por outro sinal (soltar push-to-talk, evento de interface), em vez de esperar o temporizador do VAD.
  3. Sobreponha com o processamento do LLM:Envie parciais estáveis para o LLM antes do final. Se o texto final mudar, revise. Isso esconde o atraso do endpointing atrás do processamento do prompt do LLM.

Para mais detalhes, o Scribe v2 Realtime está explicado na página de recursos de speech to text e na página do produto de transcrição de voz em tempo real.

A contribuição do LLM para a latência

O modelo de linguagem geralmente é o maior responsável pelo TTFA, então é onde a sobreposição traz mais ganhos. O ponto principal é que o agente não precisa da resposta completa para começar a falar.

A melhor estratégia é transmitir tokens do LLM para o TTS assim que chegam, em blocos por frase ou oração. O ideal é armazenar tokens até o fim de uma frase, sintetizar essa frase enquanto a próxima ainda está sendo gerada:

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 conversas longas, prefira o WebSocket de Transformar Texto em Áudio, assim a conexão aberta recebe texto incrementalmente sem precisar reabrir a cada frase. Só o tempo em que o modelo está gerando áudio conta para o limite de concorrência, então um WebSocket aberto e ocioso praticamente não tem custo.

Transformar Texto em Áudio: streaming e escolha de voz

A etapa de transformar texto em áudio é onde você pode controlar a latência com mais precisão. Os dois principais fatores são: como transmitir o áudio e qual voz escolher.

Flash v2.5 (eleven_flash_v2_5) é o modelo recomendado para uso em agentes. Ele oferece cerca de 75 ms de inferência para entradas curtas, suporta 32 idiomas e aceita até 40.000 caracteres por solicitação.

O valor de 75 ms refere-se apenas à inferência. O tempo total de TTFA do TTS mostrado acima é maior porque inclui o tempo de ida e volta da rede e o agendamento do servidor, além da inferência.

O maior fator aqui é o streaming. Se você pedir o áudio completo e esperar, o usuário só ouve depois que tudo é sintetizado. Se usar streaming, o usuário ouve o primeiro trecho assim que ele é gerado, e o resto chega enquanto ele já está ouvindo. O streaming não deixa o modelo mais rápido, mas começa a entregar o áudio enquanto ainda está sendo gerado.

O guia de streaming explica o streaming HTTP, e o guia de WebSocket em tempo real mostra como usar WebSocket para receber tokens do LLM.

Inicialize o cliente uma vez e reutilize em todas as chamadas:

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

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

Depois, configure o stream e encaminhe conforme os dados chegam:

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
}

O outro fator é a escolha da voz, que também impacta a latência. Vozes padrão, vozes sintéticas e Clones Instantâneos (IVC) sintetizam mais rápido que Clones Profissionais (PVC), pois PVCs têm mais complexidade e aumentam o tempo de geração. Para agentes com requisitos rígidos de latência, a combinação de Flash com IVC ou voz padrão é a opção mais rápida.

Escolha do tamanho dos blocos de streaming

Com tokens indo para o TTS e áudio voltando, a próxima decisão é o tamanho dos blocos e quanto o player armazena antes de começar.

Blocos menores chegam ao player mais rápido, reduzindo a latência inicial, mas geram mais mensagens e um pequeno custo extra por bloco. Blocos maiores são mais eficientes para transporte, mas fazem o usuário esperar mais pelo primeiro. Para agentes interativos, prefira blocos menores no início da fala, pois o primeiro bloco é o mais esperado; os seguintes chegam enquanto o áudio já está tocando e seu tamanho importa menos.

O player representa uma parte significativa da latência restante. A maioria dos players de áudio não começa a tocar no primeiro byte recebido. Eles fazem um pequeno buffer para evitar travamentos caso o fluxo fique mais lento por um momento. Um buffer padrão de 500 ms é comum e é adicionado diretamente à latência percebida. Reduzir esse valor diminui a TTFA, mas pode aumentar um pouco o risco de travamentos. O valor ideal depende da variação de rede entre seu servidor e o cliente:

  • Em uma conexão estável (reprodução no servidor, cliente no mesmo local), um buffer de 50 a 150 ms costuma ser seguro e já reduz bastante a TTFA.
  • Em conexões móveis ou entre regiões, um buffer maior evita falhas audíveis que são piores que a latência extra.

A configuração ideal depende do seu caso de uso e das prioridades.

Escolha de codec

O destino do áudio deve definir o codec solicitado. Retornamos formatos como mp3_44100_128, mp3_22050_32, pcm_16000, pcm_24000 e ulaw_8000. Usar o formato nativo do transporte elimina uma etapa de transcodificação e ajuda na otimização da latência.

Para telefonia, como Twilio e similares, use ulaw_8000. A rede telefônica é 8kHz mu-law de ponta a ponta, então pedir esse formato evita transcodificação e corresponde ao esperado pela operadora. Não há vantagem em sintetizar áudio de alta fidelidade que será reduzido pela rede; isso só adiciona latência sem ganho audível.

Para WebRTC e reprodução em navegador, use PCM (pcm_24000 ou pcm_16000) ou MP3. PCM é sem compressão, então não há etapa de decodificação no cliente, o que reduz um pouco a latência por bloco e é útil ao alimentar pipelines de áudio direto. MP3 é mais compacto, o que ajuda em conexões limitadas, com o custo de uma decodificação leve no cliente.

Geografia e distância de rede

Todas as otimizações acima assumem que os dados percorrem distâncias curtas. A geografia define o limite mínimo do seu orçamento de latência, então vale a pena analisar antes de ajustar qualquer outra coisa.

Atendemos solicitações a partir de clusters na América do Norte, Europa e Sudeste Asiático, e cada solicitação é direcionada automaticamente para o cluster mais próximo. O tempo de ida e volta pela internet pública normalmente varia de 20 a 200 ms, dependendo da proximidade geográfica, e não pode ser reduzido sem mudar a localização da sua infraestrutura.

Um agente que parece instantâneo em San Francisco, perto de um cluster norte-americano, pode parecer lento para um usuário no Sul da Ásia, cujo tráfego cruza o oceano duas vezes por interação.

A solução é colocar seus servidores próximos dos usuários, não só de nós. Se seus usuários estão na Europa, rode o backend do agente na Europa para encurtar o caminho usuário-servidor; nosso roteamento cuida do caminho servidor-modelo a partir de um cluster próximo.

Medindo a latência do agente de voz por conta própria

Os números da tabela de orçamento de latência acima são faixas ilustrativas para planejamento. Os números reais devem vir de um script como este, rodando no seu próprio ambiente.

A instrumentação abaixo mede o TTFA da etapa de TTS isoladamente, do pedido ao primeiro bloco de áudio, em vários testes, e mostra os percentis. Rode a partir da mesma região dos seus servidores, não do seu computador de desenvolvimento. Assume o cliente elevenlabs já inicializado:

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`);

Alguns pontos importantes:

  • Reporte P50 e P95:Foque nesses valores, não na média. A média esconde os piores casos, e são eles que fazem o agente parecer instável. P95 é a experiência de uma a cada vinte interações.
  • Teste por localização: Rode o mesmo script em cada região atendida e mantenha os resultados separados.
  • Espaçamento para precisão:Espaçe as requisições (como no setTimeout acima). Se disparar todas de uma vez, você mede sua própria fila, não o serviço. Ao exceder o limite de concorrência, as requisições entram em fila por prioridade, o que normalmente adiciona cerca de 50ms, e acima da capacidade você recebe HTTP 429.
  • Meça toda a cadeia de latência:Aplique o mesmo padrão de tempo para as outras etapas. Envolva seu

Seguindo essas dicas, você conseguirá medir a latência do agente de voz por conta própria. A partir daí, terá um caminho claro de prioridades para atacar.

O que mais reduz a latência do agente de voz?

Se você quer ações rápidas, estas são as mudanças com maior impacto.

Em ordem de impacto, use os métodos abaixo para reduzir a latência do agente:

  • Inicie o processamento do LLM com parciais estáveis do STT para esconder o atraso do endpointing.
  • Transmita tokens do LLM para o TTS em limites de frases, assim a síntese da primeira frase ocorre enquanto a segunda ainda está sendo gerada.
  • Transmita o áudio do TTS para o player e ajuste o buffer para o menor valor que sua rede suporta.
  • Use Flash com voz padrão ou IVC para o TTS mais rápido e combine o codec com o transporte (ulaw_8000 para telefonia, PCM ou MP3 para navegador/WebRTC).
  • Coloque seus servidores próximos dos usuários e meça por região, pois os caminhos de rede são reais e diferentes.

Para técnicas mais avançadas, veja o guia de otimização de latência para desenvolvedores. Para um ponto de partida completo, o API quickstart e o guia de streaming trazem exemplos práticos.

Quer acesso mais rápido a agentes otimizados?ElevenAgents já implementa esse pipeline com otimizações de sobreposição.

Crie agentes de voz com baixa latência usando ElevenAgents

Otimizar a latência de agentes de voz exige medir cada etapa e sobrepor as etapas para que as mais lentas rodem enquanto outras já estão em andamento. Você pode construir e ajustar esse pipeline manualmente, usando os padrões acima, ou começar com um pipeline já otimizado.

O ElevenAgents implementa toda essa cadeia, do streaming de STT ao envio token a token para o LLM e TTS Flash, com técnicas de sobreposição já integradas. Em vez de começar do zero, você só ajusta os limites para a performance que mais importa para você.

Comece usando o ElevenAgents para criar um agente hoje ou fale com vendas para saber mais.

Perguntas frequentes sobre otimização de latência em agentes de voz

Artigos relacionados

Crie com o áudio de IA da mais alta qualidade