Construindo Agentes de Voz em Tempo Real com Vision Agents e Amazon Nova 2 Sonic
Introdução
Construir agentes de voz de nível de produção que se sintam naturais e responsivos representa um desafio de engenharia complexo. É necessário orquestrar modelos de fala para fala (speech-to-speech), gerenciar o streaming de áudio de baixa latência e lidar com o ciclo de vida da conexão, tudo isso enquanto oferece experiências consistentes em aplicações web, mobile e desktop.
Neste artigo, Jackson, Engenheiro de Software Sênior e Arquiteto de Soluções da AITY, demonstra como combinar o framework open-source Vision Agents da Stream com Amazon Bedrock e Amazon Nova 2 Sonic para construir agentes de voz em tempo real que podem estar prontos para produção em minutos. Exploraremos a integração técnica, exemplos de código e capacidades avançadas como chamada de função, reconexão automática e suporte de voz multilíngue.
O Desafio
A criação de aplicações de IA habilitadas para voz exige a orquestração de múltiplos sistemas complexos que devem funcionar juntos de forma confiável. Enfrenta-se o desafio de gerenciar a infraestrutura de streaming de áudio em tempo real, enquanto se integra simultaneamente serviços de reconhecimento de fala, modelos de linguagem e serviços de texto para fala. Cada um possui suas próprias características de latência e modos de falha. Uma interação de voz típica envolve:
- Capturar áudio do microfone do usuário.
- Transmitir para um serviço de fala para texto.
- Processar a transcrição através de um modelo de linguagem.
- Gerar uma resposta.
- Converter essa resposta de volta para fala.
- Entregar ao usuário.
Tudo isso deve ocorrer em uma janela de algumas centenas de milissegundos para parecer natural. Atrasos nesse pipeline podem quebrar o fluxo conversacional e frustrar os usuários. Além do pipeline central de IA, aplicações de voz em produção precisam lidar com as realidades da implantação no mundo real: conexões de rede não confiáveis, problemas de compatibilidade do navegador, timeouts de sessão e degradação elegante quando os serviços ficam indisponíveis. Muitas vezes, gasta-se mais tempo construindo lógica de reconexão, gerenciando conexões WebRTC e lidando com casos de borda do que nas capacidades reais de IA. O Vision Agents abstrai a complexidade da infraestrutura, proporcionando a flexibilidade para personalizar a experiência de IA.
Visão Geral da Solução
A solução reúne três componentes chave:
- Amazon Nova 2 Sonic: Um modelo de fundação speech-to-speech disponível via Amazon Bedrock, que oferece streaming de áudio bidirecional em tempo real, detecção de turno nativa e capacidades de chamada de função. Ele lida com o pipeline completo de fala para fala, aceitando entrada de áudio e produzindo saída de áudio, eliminando a necessidade de serviços separados de STT e TTS.
- Stream's Vision Agents: Um framework Python open-source para construir agentes de IA de voz e vídeo em tempo real. Ele fornece uma arquitetura baseada em plugins com mais de 25 integrações, ferramentas de implantação em produção e SDKs de cliente para React, iOS, Android, Flutter e React Native. O sistema foi projetado com flexibilidade em seu núcleo, permitindo usar a rede de borda global da Stream ou integrar seu provedor de comunicação em tempo real (RTC) preferido.
- Stream's Edge Network: Uma rede de borda globalmente distribuída que geralmente entrega tempos de junção de sub-500ms e latência de áudio abaixo de 30ms, fornecendo a camada de transporte em tempo real entre os clientes e o backend do seu agente.
Juntos, esses componentes criam uma pilha completa: a Stream lida com o transporte de mídia em tempo real e a experiência do lado do cliente, o Amazon Nova 2 Sonic fornece a inteligência de IA, e o Vision Agents atua como o código "cola" que os une.
Arquitetura do Sistema
O sistema é projetado em torno de uma clara separação de preocupações: a infraestrutura da Stream lida com o transporte de mídia em tempo real e a conectividade do cliente, enquanto o Amazon Nova Sonic é executado na própria conta AWS do cliente e fornece a inteligência de IA. Esta separação ajuda a manter dados sensíveis e lógica de negócios sob o controle do cliente, enquanto a rede de borda globalmente distribuída da Stream oferece a experiência de mídia de baixa latência que os usuários esperam.
A rede de borda da Stream atua como o media broker entre os dispositivos do usuário final e os processos de worker do Vision Agent. Quando um usuário fala, o áudio é capturado, criptografado e transmitido como RTP sobre UDP para a SFU (Selective Forwarding Unit) da Stream mais próxima. A SFU encerra a conexão WebRTC, lida com NAT traversal e estimativa de largura de banda, e encaminha as trilhas de áudio para o worker do Vision Agent como se fosse outro participante da chamada. Isso significa que o agente se integra naturalmente ao modelo de chamada.
Os dados de áudio fluem bidirecionalmente através do sistema: a fala de entrada do usuário é decodificada para PCM bruto pelo worker do Vision Agent, transmitida para o Amazon Nova Sonic via API em tempo real do Bedrock, e os frames de áudio de resposta do Nova Sonic são recodificados, packetizados como RTP e entregues de volta através da SFU para o dispositivo cliente. A latência de ponta a ponta é tipicamente inferior a 500 milissegundos. A detecção de atividade de voz (VAD) é executada no worker para detectar limites de fala e eventos de barge-in, enquanto o cancelamento de eco no navegador ajuda a evitar que a própria saída do agente reative o loop VAD.
As contas da AWS são separadas: * Conta AWS do Cliente: Contém a lógica de negócios e orquestração (políticas do agente, ferramentas, acesso a dados) e a integração com Amazon Bedrock para acessar os modelos Amazon Nova. * Conta AWS da Stream: Gerencia o plano de mídia WebRTC/SFU global, TURN/STUN e sinalização, bem como o runtime do Vision Agent (processos de worker) que encerram o WebRTC como peers robôs e fazem a ponte com a integração do Amazon Bedrock do cliente.
Fluxo de Mídia Ponta a Ponta
- Usuário se conecta via web ou mobile.
- O aplicativo incorpora o SDK de cliente de áudio da Stream, solicita acesso ao microfone (e opcionalmente câmera) e entra em um tipo de chamada configurado para participação de IA.
- A mídia é enviada como RTP sobre UDP para baixa latência previsível e entrega livre de bloqueio.
- Terminação Regional da SFU.
- Um nó SFU da Stream na região mais próxima encerra a conexão WebRTC do usuário, lidando com estimativa de largura de banda, simulcast e NAT traversal.
- A SFU encaminha as trilhas de áudio relevantes para o worker do Vision Agent como se fosse outro participante.
- Vision Agent Worker.
- Um processo worker dedicado do Vision Agent mantém o estado da PeerConnection para aquela sessão.
- Ele decodifica o áudio para PCM bruto e o worker transmite frames PCM para o serviço Amazon Bedrock, encaminhando para o Amazon Nova 2 Sonic como uma sessão em tempo real na conta AWS do cliente.
- Amazon Nova 2 Sonic via Amazon Bedrock.
- O Amazon Nova 2 Sonic detecta limites de fala e realiza modelagem speech-to-speech (compreensão, raciocínio e TTS) com chamadas opcionais de ferramentas para sistemas do cliente (RDS, APIs, bases de conhecimento).
- Ele lida graciosamente com barge-in e mantém o contexto conversacional completo para que a conversa permaneça natural e coerente.
- Streaming da Resposta de Volta ao Usuário.
- À medida que o Amazon Nova Sonic produz frames de áudio de resposta, o worker do Vision Agent:
- Fatia e os encapsula em RTP com timestamps monotonicamente crescentes para evitar lacunas/desvios.
- Envia pacotes RTP através da mesma sessão WebRTC via SFU. A pilha WebRTC do navegador decodifica e reproduz o áudio com latência sub-500ms.
- À medida que o Amazon Nova Sonic produz frames de áudio de resposta, o worker do Vision Agent:
- Barge-in, Transcrições e Dados Laterais.
- O cancelamento de eco no navegador ajuda a evitar que a própria saída do agente reative o VAD.
- Quando o usuário interrompe, a nova fala dispara um sinal de interrupção via um RTCDataChannel, fazendo com que o worker pare de encaminhar a saída do Amazon Nova Sonic e reinicie seu buffer local.
Primeiros Passos: Construindo Seu Agente de Voz
Esta arquitetura pode parecer complexa, mas o Vision Agents abstrai grande parte dessa complexidade. Vejamos como o código real se apresenta.
Pré-requisitos:
- Credenciais AWS configuradas via variáveis de ambiente, IAM role ou perfil da AWS CLI. Para produção, use IAM roles anexadas aos seus recursos de computação. Para desenvolvimento local, use perfis da AWS CLI (
aws configure) ou AWS SSO. Não cometa arquivos.envcontendo credenciais para controle de versão. - Conta Stream com uma chave e segredo da API de Áudio (você deve receber 333.000 minutos de participante por mês sem custo adicional).
- Python 3.12 ou posterior instalado.
- Gerenciador de pacotes
uvinstalado (pip install uv). - Vision Agents instalado (
uv add vision-agents).
Passo 1: Crie um novo diretório de projeto e instale Vision Agents com o plugin AWS
mkdir voice-agent
cd voice-agent
uv init
uv add "vision-agents[getstream,aws]" python-dotenv
O extra vision-agents[aws] instala o plugin Amazon Bedrock junto com suas dependências, incluindo boto3, aws-sdk-bedrock-runtime e Silero VAD para detecção de atividade de voz.
Passo 2: Configure as variáveis de ambiente
Crie um arquivo .env na raiz do seu projeto para gerenciar sua configuração. Para credenciais AWS, recomendamos apontar para seu AWS_PROFILE neste arquivo para que o aplicativo possa acessar suas credenciais ao interagir com os recursos da AWS. Não recomendamos armazenar suas chaves de acesso AWS diretamente neste arquivo.
Para credenciais da API Stream, você pode usar uma biblioteca de terceiros como HashiCorp Vault ou AWS Secrets Manager, mas considerações de segurança não estão no escopo deste post.
# Stream API credentials
STREAM_API_KEY=test/geststream/api_key
STREAM_API_SECRET=test/getstream/api_secret
# AWS credentials
AWS_PROFILE=your_aws_profile_name
AWS_REGION=us-east-1
O Vision Agents descobre automaticamente essas variáveis de ambiente na inicialização, então você não precisa passá-las explicitamente para cada cliente.
Passo 3: Construa seu primeiro agente de voz
Crie um arquivo main.py com o seguinte código:
import asyncio
from dotenv import load_dotenv
from vision_agents.core import Agent, User, Runner
from vision_agents.core.agents import AgentLauncher
from vision_agents.plugins import aws, getstream
load_dotenv()
async def create_agent(**kwargs) -> Agent:
agent = Agent(
edge=getstream.Edge(),
agent_user=User(name="Helpful Assistant", id="agent"),
instructions="You are a helpful voice assistant. Be concise and friendly.",
llm=aws.Realtime(
model="amazon.nova-2-sonic-v1:0",
region_name="us-east-1",
voice_id="matthew",
),
)
return agent
async def join_call(agent: Agent, call_type: str, call_id: str, **kwargs) -> None:
call = await agent.create_call(call_type, call_id)
async with agent.join(call):
await asyncio.sleep(2)
await agent.llm.simple_response(
text="Greet the user warmly and ask how you can help."
)
await agent.finish() # Run until the call ends
if __name__ == "__main__":
Runner(AgentLauncher(create_agent=create_agent, join_call=join_call)).cli()
Passo 4: Execute o agente de voz
Execute o agente:
uv run main.py run
Em menos de 30 linhas de código, você tem um agente de voz totalmente funcional, em tempo real, alimentado pelo Amazon Nova Sonic, acessível a partir de um SDK de cliente Stream.
Integração com Amazon Bedrock: Detalhes Técnicos
Vamos analisar mais de perto como o plugin aws.Realtime funciona internamente.
Streaming Bidirecional com Amazon Nova 2 Sonic
O Amazon Nova 2 Sonic usa uma API de streaming bidirecional orientada a eventos. Em vez de usar um padrão de solicitação-resposta, essa abordagem permite que o áudio flua de forma quase contínua em ambas as direções simultaneamente. O plugin Vision Agents AWS gerencia essa complexidade através de uma sequência de eventos estruturada:
- Inicialização da sessão: Um evento
sessionStarté enviado com a configuração de inferência (temperatura, max tokens, top-p). - Configuração do prompt: Um evento
promptStartconfigura o formato de saída de áudio (PCM 24kHz), seleção de voz e definições de ferramentas. - Instruções do sistema: As instruções do sistema são enviadas como um bloco de conteúdo de texto com a função
SYSTEM. - Streaming de áudio: Os frames de áudio do microfone (~32ms cada) são transmitidos como eventos
audioInput. - Streaming de resposta: O Nova Sonic transmite de volta eventos
audioOutputcom a fala gerada. - Encerramento da sessão: Os eventos
promptEndesessionEndfecham a conexão de forma limpa.
Cada bloco de conteúdo segue um padrão de três partes: contentStart → payload de conteúdo → contentEnd. Essa estrutura hierárquica permite que o modelo mantenha o contexto adequado durante toda a interação.
Aqui está como o evento de início de sessão aparece no plugin:
def _create_session_start_event(self) -> Dict[str, Any]:
return {
"event": {
"sessionStart": {
"inferenceConfiguration": {
"maxTokens": 1024,
"topP": 0.9,
"temperature": 0.7,
}
},
"turnDetectionConfiguration": {
"endpointingSensitivity": "MEDIUM"
},
}
}
Adicionando Chamada de Função (Function Calling)
Uma das principais capacidades do Amazon Nova 2 Sonic é a chamada de função nativa durante conversas em tempo real. Isso permite que seu agente de voz execute ações como consultar bancos de dados, chamar APIs e acionar fluxos de trabalho, mantendo uma conversa natural.
Use o decorador @llm.register_function para definir funções que o modelo pode chamar:
import asyncio
from dotenv import load_dotenv
from typing import Dict, Any
from vision_agents.core import Agent, User, Runner
from vision_agents.core.agents import AgentLauncher
from vision_agents.plugins import aws, getstream
load_dotenv()
async def create_agent(**kwargs) -> Agent:
agent = Agent(
edge=getstream.Edge(),
agent_user=User(name="Weather Assistant", id="agent"),
instructions="""You are a helpful weather assistant. When users ask
about weather, use the get_weather function to fetch current conditions.
You can also help with simple calculations.""",
llm=aws.Realtime(
model="amazon.nova-2-sonic-v1:0",
region_name="us-east-1",
),
)
@agent.llm.register_function(
name="get_weather",
description="Get the current weather for a given city"
)
async def get_weather(location: str) -> Dict[str, Any]:
# In production, call a real weather API
return {
"city": location,
"temperature": 72,
"condition": "Sunny",
"humidity": "45%"
}
@agent.llm.register_function(
name="calculate",
description="Perform a mathematical calculation"
)
def calculate(operation: str, a: float, b: float) -> dict:
operations = {
"add": lambda x, y: x + y,
"subtract": lambda x, y: x - y,
"multiply": lambda x, y: x * y,
"divide": lambda x, y: x / y if y != 0 else None,
}
result = operations.get(operation, lambda x, y: None)(a, b)
return {"operation": operation, "a": a, "b": b, "result": result}
return agent
async def join_call(agent: Agent, call_type: str, call_id: str, **kwargs) -> None:
await agent.create_user()
call = await agent.create_call(call_type, call_id)
async with agent.join(call):
await asyncio.sleep(2)
await agent.llm.simple_response(
text="Greet the user and let them know you can check the weather."
)
await agent.finish()
if __name__ == "__main__":
Runner(AgentLauncher(create_agent=create_agent, join_call=join_call)).cli()
Como funciona a chamada de função com Amazon Nova 2 Sonic:
Quando o modelo decide invocar uma função, a seguinte sequência ocorre:
- O Nova 2 Sonic emite um evento
toolUsecontendo o nome da função e os argumentos. - O plugin Vision Agents intercepta este evento, desserializa os argumentos e executa a função Python registrada.
- O resultado é enviado de volta ao Nova via um evento
toolResult, encapsulado no padrãocontentStart→toolResult→contentEndpadrão. - O Nova 2 Sonic incorpora o resultado da função em sua resposta e continua a conversa falada naturalmente.
Você pode construir fluxos de trabalho complexos e de várias etapas com esta abordagem. Por exemplo, um agente de voz poderia procurar um registro de cliente, verificar o inventário e fazer um pedido, tudo dentro de uma única conversa natural.
Opções Avançadas de LLM e TTS
Além do speech-to-speech em tempo real, o plugin AWS também oferece uma integração padrão de LLM via aws.LLM. Isso é útil para arquiteturas de pipeline personalizadas onde você deseja emparelhar um modelo Amazon Bedrock com provedores de STT e TTS separados:
from vision_agents.core import Agent, User
from vision_agents.plugins import aws, getstream, cartesia, deepgram, smart_turn
agent = Agent(
edge=getstream.Edge(),
agent_user=User(name="Custom Pipeline Agent"),
instructions="Be helpful and concise.",
llm=aws.LLM(
model="anthropic.claude-3-haiku-20240307-v1:0",
region_name="us-east-1"
),
tts=cartesia.TTS(),
stt=deepgram.STT(),
turn_detection=smart_turn.TurnDetection(
buffer_duration=2.0,
confidence_threshold=0.5
),
)
O LLM padrão suporta streaming de respostas via converse_stream(), gerenciamento completo do histórico de conversas, entradas de visão para modelos como Claude e chamada de ferramentas multi-rodada com até 3 rodadas de execução de função por solicitação.
Text-to-speech com Amazon Polly
Para arquiteturas de pipeline personalizadas, o plugin AWS também inclui uma integração TTS do Amazon Polly. Isso é útil quando você está usando um LLM não em tempo real (como Claude no Amazon Bedrock ou outro provedor) e precisa de síntese de voz de alta qualidade:
from vision_agents.plugins import aws
tts = aws.TTS(
region_name="us-east-1",
voice_id="Joanna",
engine="neural", # 'standard' or 'neural'
language_code="en-US"
)
O Amazon Polly TTS suporta motores padrão e neurais, entrada SSML para controle de fala granular e múltiplos idiomas e vozes. O motor neural produz fala com som mais natural, tornando-o uma excelente escolha ao construir um pipeline STT → LLM → TTS personalizado na infraestrutura AWS.
Limpeza de Recursos
Para deletar a chamada da Stream e encerrar os processos do Vision Agent em execução:
uv run main.py stop
Importante: Cobranças do Amazon Bedrock se aplicam a todas as chamadas de API para o Amazon Nova 2 Sonic. Você pode executar o comando de limpeza para encerrar as sessões e evitar cobranças contínuas. Sessões ativas podem continuar a incorrer em custos até serem explicitamente encerradas.
Casos de Uso Práticos
Com a fundação técnica estabelecida, vale a pena explorar onde essas capacidades se traduzem em impacto significativo no mundo real. A combinação de voz de baixa latência, gerenciamento de conversas e integração de ferramentas abre uma ampla gama de aplicações em indústrias onde a interação falada natural pode substituir ou aumentar as interfaces tradicionais.
-
Interfaces de Voz para Ambientes Sem Tela e de Baixa Atenção
- Vision Agents combinado com Amazon Nova 2 Sonic é ideal para ambientes onde os usuários não podem interagir de forma confiável com uma tela, como durante a condução, serviço de campo, logística, saúde ou operações no local.
- Com Amazon Nova 2 Sonic, você obtém interações speech-to-speech em tempo real com baixa latência e turnos de fala naturais, permitindo que os usuários falem livremente, interrompam respostas e se corrijam sem quebrar o fluxo.
- Vision Agents gerencia o estado da conversa e a lógica da tarefa através dos turnos, traduzindo a entrada falada em ações estruturadas como recuperar a próxima atribuição de trabalho, atualizar o status da tarefa, registrar notas ou solicitar assistência humana.
-
Suporte Telefônico de Alto Volume em Escala
- Vision Agents combinado com Amazon Nova 2 Sonic é projetado para lidar com grandes volumes de chamadas de suporte de entrada onde agentes humanos se tornam um gargalo. Este caso de uso é fundamentalmente sobre escala: reduzir tempos de fila, desviar solicitações repetitivas e reservar agentes humanos para casos que exigem sua intervenção.
- Com Amazon Nova 2 Sonic, os chamadores podem ter conversas speech-to-speech de baixa latência e em tempo real, permitindo que expliquem problemas naturalmente em vez de navegar por árvores IVR roteirizadas.
- Vision Agents orquestra a detecção de intenção, o estado da conversa e as integrações de backend, como sistemas de pedidos, registros de contas ou serviços de tickets, para que solicitações comuns possam ser resolvidas automaticamente dentro da chamada.
Conclusão
Este artigo detalhou como construir agentes de voz em tempo real usando o framework Vision Agents da Stream e o Amazon Bedrock com Amazon Nova 2 Sonic. Cobrimos a arquitetura, o protocolo de streaming bidirecional, o tratamento de reconexão automática, a chamada de função, o suporte multilíngue e a implantação em produção.
A combinação da rede de borda de baixa latência da Stream e das capacidades nativas de speech-to-speech do Amazon Nova Sonic fornece uma base sólida para a construção de aplicações de IA de voz. O framework Vision Agents abstrai a orquestração complexa do gerenciamento do ciclo de vida da conexão, codificação de áudio, reconexão sensível ao VAD e execução de ferramentas, para que você possa se concentrar na lógica do seu agente e na experiência do usuário.
Se você está pronto para explorar ainda mais, encorajamos você a tentar estender seu agente com funções personalizadas para seu caso de uso específico ou explorar as capacidades multilíngues para aplicações globais. O repositório Vision Agents em https://github.com/GetStream/Vision-Agents é um bom ponto de partida. Lá você encontrará exemplos adicionais, documentação de plugins e discussões da comunidade. Para detalhes de integração mais aprofundados, a documentação do plugin AWS está disponível em https://visionagents.ai/integrations/aws-bedrock, e a documentação do Amazon Nova 2 Sonic no AWS Nova User Guide fornece uma referência abrangente para a API de streaming bidirecional. Você pode se inscrever para uma conta de desenvolvedor da Stream em https://getstream.io/ e começar a construir hoje mesmo sem custo adicional.
Aguardando Login...