Para fazer um agente de voz começar a falar antes de terminar a resposta, envie cada frase completa para o Kokoro-82M assim que ela estiver pronta. No exemplo da AWS, o modelo de síntese de fala (TTS, na sigla em inglês) roda em um endpoint em tempo real do Amazon SageMaker AI, enquanto um agente no Amazon Bedrock AgentCore continua gerando texto. O endpoint sintetiza as mensagens em sequência: o ganho vem de começar pela primeira frase mais cedo, não de processar várias frases ao mesmo tempo.

Como o exemplo distribui as tarefas

O Kokoro-82M, com 82 milhões de parâmetros, roda em um contêiner personalizado num endpoint do SageMaker AI configurado com uma instância ml.g5.xlarge. O agente usa Strands e roda no Amazon Bedrock AgentCore. No caminho até o navegador, o exemplo usa Server-Sent Events (SSE), um mecanismo para enviar eventos do servidor ao cliente; entre o agente e o endpoint de voz, usa uma sessão WebSocket bidirecional.

O contêiner expõe GET /ping para verificação de saúde, POST /invocations para streaming de resposta e WS /invocations-bidirectional-stream para a sessão bidirecional. Essa separação permite que o agente encaminhe frases à medida que são geradas, em vez de esperar que todo o texto fique pronto.

Pré-requisitos para a implantação

A configuração descrita pela AWS exige uma conta e permissões da AWS, AWS CDK v2 inicializado, Python 3.12 ou posterior, uv, Docker, uma versão compatível do Boto3 e a etiqueta de Docker exigida para streaming bidirecional do SageMaker. Também é necessário conhecer WebSockets e Starlette ou ASGI, a interface usada para conectar aplicações Python a servidores web.

A AWS também alerta que o contêiner de exemplo fixa uma versão antiga do PyTorch associada ao aviso PYSEC-2026-2286; segundo a AWS, o problema foi corrigido no PyTorch 2.10.0. Antes de usar o exemplo além de uma prova de conceito, revise essa dependência.

Implante o endpoint antes do agente

  1. Prepare o contêiner do Kokoro. Configure o modelo e as rotas de inferência do exemplo no contêiner personalizado. A rota bidirecional precisa aceitar as mensagens de streaming do SageMaker.
  2. Implante o endpoint do SageMaker AI. Deixe o endpoint pronto antes de implantar o agente que vai chamá-lo. A configuração descrita pela AWS usa a instância ml.g5.xlarge.
  3. Trate os quadros WebSocket como binários. O transporte bidirecional do SageMaker entrega quadros binários ao contêiner. Um manipulador Starlette que chama apenas receive_text() pode falhar com KeyError('text'), mesmo quando o endpoint aparece como InService. Aceite bytes e decodifique o conteúdo como UTF-8 quando a mensagem exigir texto.
  4. Mantenha a sessão aberta entre as frases. Reutilize a mesma conexão para as mensagens seguintes e encerre-a somente quando o cliente enviar uma mensagem explícita de fechamento. Cada síntese pode enviar quadros de início, áudio e conclusão; a conexão não precisa ser aberta de novo para cada frase.
  5. Envie frases completas e descarregue o trecho final. O cliente deve separar frases conforme o texto chega e encaminhar cada frase concluída ao Kokoro. Quando a geração termina, envie também o texto restante, mesmo que ele não termine com um delimitador de frase.
  6. Implante o agente depois do endpoint. Com o endpoint pronto, implante no Bedrock AgentCore o agente Strands que recebe os trechos de texto e encaminha as frases para síntese.

Para conferir o fluxo, teste quadros binários, não apenas o estado InService: verifique se uma mensagem de texto inicia a síntese, se os quadros de áudio e conclusão chegam na mesma sessão e se a conexão só termina após a mensagem explícita de fechamento.

Escolha como entregar o áudio

Se o frontend já usa SSE, enviar o áudio em base64 pode facilitar a integração. A codificação aumenta o tamanho dos dados em cerca de 33%, e um bloco recebido pode cortar um quadro de áudio ao meio. Nesse caso, o cliente precisa armazenar os dados e remontar os quadros antes de reproduzi-los.

No trecho bidirecional entre o agente e o endpoint, o exemplo multiplexa áudio bruto e quadros de controle em JSON. O caminho do AgentCore até o navegador ainda usa base64, pois o runtime entrega dicionários serializáveis em JSON. A tabela reúne os tamanhos e as taxas de bits medidos pela AWS em um teste com 24 clipes.

Formato de áudioBytes sem codificaçãoBytes em base64Taxa de bits
PCM bruto2.396.4003.195.200384 kbps
MP3 48k308.304411.07249,5 kbps
AAC 32k fMP4258.039344.08441,6 kbps

Outras formas de executar Kokoro

A Trelis Research demonstrou inferência local com Kokoro-ONNX em CPU e um servidor separado com Kokoro-FastAPI em uma instância H100 da Runpod. No teste com concorrência, a Trelis Research relatou processamento de aproximadamente 55 a 78 horas de áudio por hora de tempo real. Esses exemplos usam configurações e métricas diferentes das medições de latência da AWS.

O que os testes de latência da AWS mediram

Em um teste isolado com um endpoint ativo, cinco tentativas por modo e um texto de 267 caracteres dividido em quatro frases, a AWS mediu tempo médio até o primeiro byte de áudio de 329,3 ms no modo em lote e 156,7 ms ao enviar primeiro apenas a primeira frase. A AWS calculou uma redução relativa de 52,4% nesse teste.

Na comparação de ponta a ponta, a AWS relatou que o modo bidirecional chegou ao primeiro áudio 2,4 vezes mais rápido no teste local e 3,5 vezes mais rápido no runtime implantado do AgentCore. São resultados das comparações descritas pela AWS, não uma garantia de latência para outras configurações.

Encerre os recursos que podem continuar gerando cobrança

Na limpeza do exemplo, remova primeiro o runtime do agente e depois o endpoint do SageMaker. Os comandos da AWS não removem o bucket do S3 usado como cache do modelo nem o repositório de imagens do ECR; esses recursos podem continuar gerando cobranças de armazenamento até serem excluídos separadamente.