AWS ensina agentes de voz com IA a falar desde a primeira frase com o Kokoro-82M
A AWS descreveu uma arquitetura em que o agente de voz com IA não espera o modelo terminar de gerar a resposta inteira. Cada frase pronta segue imediatamente para o Kokoro-82M, implantado no SageMaker AI, e a fala começa já na primeira frase. Antes, o cliente ficava cerca de cinco segundos em silêncio, embora uma resposta curta seja gerada em 600 ms. O modelo tem apenas 82 milhões de parâmetros e roda em uma única GPU ml.g5.xlarge. Entre o cliente e o contêiner há uma única sessão WebSocket bidirecional: áudio e comandos JSON trafegam pelo mesmo canal, sem base64 e sem reconexões desnecessárias. • O base64 em SSE aumenta o áudio em cerca de 33%: MP3 48k — 308 304 bytes, e 411 072 depois da codificação • O erro KeyError('text') ocorre porque o SageMaker envia apenas frames binários • O agente em Strands + Bedrock AgentCore, no modo bidi, sobrepõe geração e síntese
Processado por IA de AWS Machine Learning Blog; editado por Hamidun News
O usuário faz uma pergunta a um agente de voz e espera. A resposta já foi parcialmente gerada, mas não há som: as integrações de text-to-speech costumam aguardar o fim de todo o texto. O modelo produz uma frase em 600 ms, mas uma resposta longa completa leva cerca de cinco segundos. Durante todo esse tempo, o cliente ouve silêncio. Em seu blog, a AWS mostrou como eliminar essa lacuna: enviar cada frase ao sintetizador Kokoro-82M no Amazon SageMaker AI assim que o agente a conclui.
Modelo pequeno, uma GPU e duas rotas
O Kokoro-82M tem 82 milhões de parâmetros, o suficiente para rodar em uma única instância com GPU de médio porte. O modelo é executado em um contêiner customizado, em um endpoint em tempo real do SageMaker AI, com instância do tipo ml.g5.xlarge. O contêiner expõe duas rotas: POST /invocations, para resposta em streaming a uma entrada completa, e WS /invocations-bidirectional-stream, em que uma única conexão permanece aberta e troca várias mensagens nos dois sentidos. O contêiner precisa declarar o rótulo Docker com.amazonaws.sagemaker.capabilities.bidirectional-streaming=true.
O deploy se resume a dois comandos baseados no AWS CDK: `uv run speech-infra deploy kokoro-82m` sobe o endpoint (roles do IAM, cache de pesos no S3, imagem do contêiner, modelo e configuração), e `uv run agent-infra deploy --bedrock-model-id <id>` implanta o agente em Strands no ambiente Amazon Bedrock AgentCore. A ordem importa: o agente acessa um endpoint que já existe. É necessário Python 3.12+, porque o cliente HTTP/2 só é distribuído em wheels prontos para essas versões. Os autores fazem um alerta à parte: o exemplo fixa uma versão antiga do PyTorch com a vulnerabilidade conhecida PYSEC-2026-2286 (corrigida no torch 2.10.0), e ela precisa ser atualizada antes de qualquer uso além de uma prova de valor (proof-of-value).
Três armadilhas do streaming bidirecional
A primeira armadilha é o tipo de frame WebSocket. O SageMaker entrega cada mensagem do cliente como um frame binário. Um handler típico em Starlette chama receive_text(), lê message["text"] e falha com KeyError. Se o tratador de exceções genérico enviar str(e) ao cliente, ele vê o erro «'text'», que parece um campo ausente, e não um problema de framing. Enquanto isso, o endpoint aparece normalmente como InService: aceita conexões e responde a cada mensagem, mas com erro. A solução é aceitar os dois tipos de frame e decodificar os bytes como UTF-8 quando não houver o campo text.
A segunda é o fechamento prematuro da sessão. Depois de enviar o áudio e o frame de controle synthesis_complete, o contêiner deve voltar a receive() e esperar a próxima mensagem. A conexão só deve ser encerrada com um {"type": "close"} explícito. Caso contrário, cada frase exigiria uma nova conexão, e o ganho de latência desapareceria.
A terceira é o fatiamento do fluxo em frases. A classe IncrementalSentenceChunker recebe o texto em porções por meio de feed(), separa as frases completas com uma expressão regular e retém o trecho final. No fim, flush() recolhe o resto, que não tem ponto final. Os autores ressalvam: isso não é síntese paralela. O handler é estritamente sequencial — receber a mensagem, sintetizar, enviar o áudio, enviar synthesis_complete. O ganho está apenas em que a síntese da primeira frase começa logo depois que ela aparece. Em um endpoint em funcionamento, foram testadas três frases em uma única sessão:
- «Hello there.» — 73 200 bytes de áudio, 1,525 s
- «This is a post deployment check.» — 108 000 bytes, 2,250 s
- «It has three sentences.» — 98 400 bytes, 2,050 s
SSE com base64 versus multiplexação binária
Para entregar o áudio ao navegador, a AWS comparou duas abordagens. A primeira é o SSE, já conhecido: o áudio é codificado em base64 e embalado em um evento JSON. Em 24 clipes, foi medido o custo dessa escolha (a qualidade, avaliada pelo Amazon Transcribe, não dependeu da codificação):
- PCM bruto: 2 396 400 bytes, em base64 — 3 195 200, bitrate de 384 kbit/s
- MP3 48k: 308 304 bytes, em base64 — 411 072, 49,5 kbit/s
- AAC 32k fMP4: 258 039 bytes, em base64 — 344 084, 41,6 kbit/s
O base64 acrescenta os esperados 33%, ou quase isso. Há ainda um problema menos óbvio: os limites dos eventos SSE (linha em branco) não coincidem com os limites dos frames MP3 nem com a forma como o transporte divide os dados. Em uma medição, quatro frames MP3 lógicos chegaram em seis chunks, dois deles interrompidos no meio de um frame. Um consumidor que trata cada chunk como completo quebra mesmo com tráfego saudável. A solução é um buffer: acumular os bytes e só processar o quadro depois de encontrar o separador `\n\n`.
A segunda abordagem é abrir mão totalmente de base64 e SSE no trecho até o modelo. O áudio binário e os comandos JSON trafegam pela mesma sessão bidirecional e são distinguidos por uma única regra: se o chunk inteiro puder ser interpretado como um objeto JSON, é um frame de controle; caso contrário, é áudio. Verificar o primeiro byte não funciona: o PCM pode começar com 0x7b, ou seja, com «{». Mas um chunk PCM completo praticamente nunca se torna um JSON válido.
O agente completo
Na configuração completa, o agente em Strands, com um modelo do Amazon Bedrock, roda no runtime do Bedrock AgentCore e usa três canais: SSE para o navegador, chamada em streaming ao Bedrock para o texto e sessão bidirecional com o Kokoro para a síntese. A requisição tem o campo mode: «bidi» ou «batch». Em run_bidi, duas tarefas trabalham em paralelo: uma lê o fluxo do Bedrock e entrega ao chunker as frases prontas, e a outra lê as respostas do Kokoro e emite o áudio.
Ambas colocam o resultado em uma fila compartilhada, de modo que o som das primeiras frases pode chegar ao chamador enquanto o Bedrock ainda escreve as últimas. O run_batch espera o texto inteiro e faz uma única chamada de síntese, o que serve como base honesta de comparação.
No trecho entre o agente e o chamador, o base64 continua presente: o entrypoint do BedrockAgentCoreApp precisa devolver dicionários serializáveis em JSON, que o próprio SDK converte em frames `data: {json}`. Não é possível passar um frame binário por ali. Esse custo é igual nos dois modos, então a diferença nas medições reflete apenas o tempo até o primeiro chunk de áudio.
O que escolher na prática
Se o front-end já usa SSE para o texto, o base64 dentro do evento é uma escolha pragmática: +33% de tamanho e um buffer para a montagem, mas com a infraestrutura pronta. Se o canal de voz está sendo construído do zero ou a latência é crítica, um esquema binário único com controle em JSON elimina os dois custos e aproveita a conexão que já transporta o texto. Em qualquer caso, vale testar justamente com frames binários, verificar a montagem pelos limites dos quadros MP3 e não fechar a sessão após cada frase. E, antes de ir para produção, atualizar o PyTorch fixado.
- 29 de out. de 2026Cloudflare lança modelos open source Clef: 98,5% no BFCL e 38,8 ms
- 29 de out. de 2026Anthropic mostra no S-1: 11 900 clientes pagam a partir de $100 mil por ano
- 28 de out. de 2026Keystone tira o nome do modelo do código: gateway de LLM open source adiciona 0,64 ms
- 28 de out. de 2026Wired testou 6 agentes de IA em 24 horas: Dots lidera, Gemini Spark erra o almoço
Perguntas frequentes sobre a notícia
O que se sabe sobre Modelo pequeno, uma GPU e duas rotas?
O Kokoro-82M tem 82 milhões de parâmetros, o suficiente para rodar em uma única instância com GPU de médio porte. O modelo é executado em um contêiner customizado, em um endpoint em tempo real do SageMaker AI, com instância do tipo ml.g5.xlarge. O contêiner expõe duas rotas: POST /invocations, para resposta em streaming a uma entrada completa, e WS /invocations-bidirectional-stream, em que uma única conexão permanece aberta e troca várias mensagens nos dois sentidos. O contêiner precisa declarar o rótulo Docker com.amazonaws.sagemaker.capabilities.bidirectional-streaming=tr
O que se sabe sobre Três armadilhas do streaming bidirecional?
A primeira armadilha é o tipo de frame WebSocket. O SageMaker entrega cada mensagem do cliente como um frame binário. Um handler típico em Starlette chama receive_text(), lê message["text"] e falha com KeyError. Se o tratador de exceções genérico enviar str(e) ao cliente, ele vê o erro «'text'», que parece um campo ausente, e não um problema de framing. Enquanto isso, o endpoint aparece normalmente como InService: aceita conexões e responde a cada mensagem, mas com erro. A solução é aceitar os dois tipos de frame e decodificar os bytes como UTF-8 quando não houver o campo t
O que se sabe sobre SSE com base64 versus multiplexação binária?
Para entregar o áudio ao navegador, a AWS comparou duas abordagens. A primeira é o SSE, já conhecido: o áudio é codificado em base64 e embalado em um evento JSON. Em 24 clipes, foi medido o custo dessa escolha (a qualidade, avaliada pelo Amazon Transcribe, não dependeu da codificação): PCM bruto: 2 396 400 bytes, em base64 — 3 195 200, bitrate de 384 kbit/s MP3 48k: 308 304 bytes, em base64 — 411 072, 49,5 kbit/s AAC 32k fMP4: 258 039 bytes, em base64 — 344 084, 41,6 kbit/s O base64 acrescenta os esperados 33%, ou quase isso. Há ainda um problema menos óbvio: os limites dos
Delegate Deep Research, Coding & Multi-Step Workflows to Nomad Agent
Deploy autonomous task execution with Nomad Agent (agent.nomadnet.ai) — automated web research, data synthesis, code generation, and MCP tool orchestration.
O essencial da IA — uma vez por semana
Sete histórias que realmente importaram, escolhidas a dedo. Sem ruído nem releases.
Pronto! Verifique seu e-mail para a confirmação.