O problema da OpenAI com WebRTC
(moq.dev)- WebRTC prioriza baixa latência, como em chamadas de conferência, então descarta pacotes de áudio de forma agressiva quando a rede está ruim; porém, em Voice AI, a corrupção do prompt de voz pode prejudicar mais a qualidade da resposta do que uma resposta lenta
- TTS consegue gerar áudio mais rápido do que em tempo real, então o buffering no cliente pode esconder interrupções curtas de rede, mas o WebRTC exige espera artificial para enviar os pacotes na hora certa por causa da renderização baseada no tempo de chegada e de um pequeno jitter buffer
- O WebRTC tem configuração e operação complexas com portas efêmeras, ICE, DTLS, SCTP etc.; em multiplexação por porta única, é difícil rotear pacotes STUN, SRTP/SRTCP, DTLS e TURN para cada conexão
- Mesmo que a OpenAI exija configuração rápida de conexão, o WebRTC pode exigir no mínimo 8 RTT somando sinalização e procedimentos do servidor de mídia, e por causa da estrutura de suporte a P2P, o servidor precisa passar pelo mesmo processo mesmo tendo IP fixo
- Como alternativas, são propostos WebSockets e QUIC/WebTransport; o QUIC oferece suporte mais simples para porta única, mudança de endereço, balanceamento de carga sem estado e combinação de anycast com unicast por meio de
CONNECTION_ID, QUIC-LB epreferred_address
Por que o WebRTC não combina com Voice AI
- O WebRTC foi projetado para conversas rápidas de ida e volta, como chamadas de conferência, então, quando a rede está ruim, descarta pacotes de áudio agressivamente para manter a latência baixa
- Em Voice AI, é mais importante que o prompt seja transmitido com precisão, mesmo que o usuário tenha de esperar um pouco mais por uma resposta lenta
- Por exemplo, se um prompt de voz como “ir a pé até o lava-rápido ou ir dirigindo” for corrompido, a qualidade da resposta posterior também pode piorar
- A implementação de áudio WebRTC no navegador pressupõe fortemente latência em tempo real; segundo o texto, quando tentaram isso no Discord, não foi possível retransmitir pacotes de áudio WebRTC
- Em uma atualização, algumas pessoas do ecossistema WebRTC consideraram que talvez fosse possível ativar áudio com NACK, mas no Discord não encontraram a forma correta de manipular o SDP, e continuou existindo a limitação de o jitter buffer do WebRTC ser muito pequeno
- Mesmo que agentes de Voice AI um dia alcancem latências no nível de uma conversa, reduzir latência envolve trade-offs, e não está claro se vale a pena degradar deliberadamente o prompt de voz
O problema de buffering entre TTS e WebRTC
- A conversão de texto em fala (TTS) consegue gerar áudio mais rápido do que em tempo real
- Por exemplo, se uma GPU gerar 8 segundos de áudio em 2 segundos, idealmente seria possível transmitir o áudio durante esses 2 segundos de geração e o cliente reproduzi-lo por 8 segundos, acumulando buffer local
- Assim, mesmo que haja uma breve interrupção de rede, há chance de o usuário nem perceber
- O WebRTC não combina com esse modelo
- O WebRTC não faz buffering e renderiza com base no tempo de chegada, considerando que o timestamp não é uma referência rígida de reprodução
- Se houver vídeo junto, o problema fica ainda mais complicado
- Serviços como a OpenAI precisam esperar artificialmente antes de enviar cada pacote de áudio, para que ele chegue exatamente no momento em que deve ser reproduzido
- Se ocorrer congestionamento de rede, esse pacote de áudio será perdido e não será retransmitido
- No fim, a estrutura injeta latência artificial e depois descarta pacotes agressivamente em nome da “baixa latência”, algo parecido com mostrar um vídeo do YouTube por compartilhamento de tela sem buffering
- O WebRTC usa um jitter buffer de áudio ajustado dinamicamente entre 20 ms e 200 ms; isso serve para amortecer jitter de rede, mas o autor argumenta que não seria necessário se fosse possível enviar mais rápido do que em tempo real
Limites de portas e identificação de conexão
- Servidores TCP normalmente abrem uma porta como
443e aceitam conexões; a conexão é identificada pela combinação de IP e porta de origem e destino- Ex.:
123.45.67.89:54321 -> 192.168.1.2:443
- Ex.:
- Se um celular mudar de Wi-Fi para rede móvel ou se um NAT alterar o IP/porta de origem, a conexão TCP cai e é preciso abrir outra
- O handshake de TCP e TLS leva no mínimo 2 a 3 RTT, e em streaming ao vivo o usuário pode perceber a interrupção
- O WebRTC tenta resolver isso assumindo a atribuição de uma porta de destino efêmera para cada conexão
- Se a sessão for identificada apenas por IP/porta de destino, o mesmo usuário pode ser reconhecido mesmo quando o IP/porta de origem mudar
- Mas, combinada com a arquitetura da OpenAI, essa abordagem vira problema em operação em grande escala
- Há limite para a quantidade de portas disponíveis no servidor
- Firewalls frequentemente bloqueiam portas efêmeras
- Também não se encaixa bem em ambientes Kubernetes
Por que serviços WebRTC vão para multiplexação em porta única
- Muitos serviços não seguem a especificação WebRTC ao pé da letra e multiplexam várias conexões em uma única porta
- Na Twitch, os servidores WebRTC rodavam em
UDP:443- Originalmente,
443é porta de HTTPS/QUIC, mas assim era possível atravessar mais firewalls - Segundo o texto, a rede interna da Amazon permitia só cerca de 30 portas
- Originalmente,
- O Discord usava uma porta por núcleo de CPU em
50000-50032- Esse modelo pode ser bloqueado por mais redes corporativas
- O grande problema da multiplexação em porta única é que o WebRTC junta vários padrões diferentes
- Há 5 protocolos rodando diretamente sobre UDP; distinguir qual protocolo é cada pacote não é tão difícil, mas o difícil é decidir para qual conexão cada pacote deve ser roteado
-
Dificuldades de roteamento por protocolo
- STUN
- É possível escolher um
ufragúnico e rotear com base nele
- É possível escolher um
- SRTP/SRTCP
- O navegador escolhe um valor
ssrcarbitrário, e normalmente é possível rotear com base nele
- O navegador escolhe um valor
- DTLS
- Isso depende de esperar suporte amplo ao RFC9146
- TURN
- O autor afirma não ter experiência de implementação
- A OpenAI diz que só faz parsing de STUN e depois trata DTLS, RTP e RTCP como tráfego opaco com base em estado em cache
- Isso pode ser interpretado como uma arquitetura que espera que o IP/porta de origem do usuário não mudem
- O navegador também pode gerar o mesmo
ssrcaleatoriamente - Em caso de colisão, sem mapeamento de IP/porta de origem, o Discord identifica a conexão tentando descriptografar o pacote com cada chave possível até encontrar a correta
- STUN
A latência de ida e volta na configuração de conexões WebRTC
- A OpenAI apresentou como um dos requisitos “configuração rápida de conexão para que o usuário possa falar assim que a sessão começar”, mas o texto argumenta que a configuração de uma conexão WebRTC exige no mínimo 8 RTT
-
Exemplo com servidor de sinalização
- Com um servidor de sinalização como WHIP, são necessárias as seguintes idas e voltas
- 1 RTT para TCP
- 1 RTT para TLS 1.3
- 1 RTT para HTTP
- Com um servidor de sinalização como WHIP, são necessárias as seguintes idas e voltas
-
Servidor de mídia
- 1 RTT para ICE
- 2 RTT para DTLS 1.2
- 2 RTT para SCTP
- Alguns protocolos podem evitar 0,5 RTT com pipelining, então a conta exata é mais complexa, mas no geral são muitas idas e voltas
- Esse processo existe porque o WebRTC precisa suportar P2P, então mesmo que o servidor tenha IP fixo ele passa pelo mesmo ritual
- Quando servidor de sinalização e servidor de mídia rodam no mesmo host ou processo, há handshakes redundantes e caros acontecendo duas vezes
Uma arquitetura que acaba levando a um fork de WebRTC
- O autor argumenta que o WebRTC, por suas muitas limitações, na prática empurra as empresas para fazer um fork do protocolo
- O WebRTC é composto por cerca de 45 RFCs e rascunhos de padrão de fato, como TWCC e REMB, o que torna a implementação pesada
- As implementações de navegador são controladas pelo Google e ajustadas ao Google Meet, o que seria uma ameaça existencial para apps de videoconferência
- O texto também sugere que o motivo de apps de conferência, exceto o Google Meet, incentivarem instalação de apps nativos é justamente evitar o uso de WebRTC
- No cliente nativo, o Discord fez um fork pesado de WebRTC e não implementa grande parte de SDP, ICE, STUN, TURN, DTLS, SCTP, SRTP etc.; mas, para o cliente web, ainda precisa implementar tudo
- A OpenAI provavelmente também teria recursos para isso, mas o autor defende que seria melhor trocar por outra abordagem com suporte no navegador do que fazer fork do WebRTC
Alternativas: WebSockets e QUIC
- Como alternativa inicial ao WebRTC em Voice AI, o texto propõe WebSockets
- Dá para aproveitar a infraestrutura existente de TCP/HTTP
- Não é preciso criar um balanceador de carga WebRTC customizado
- Funciona bem com Kubernetes e pode escalar
- O head-of-line blocking, nesse contexto, pode não ser um defeito e sim uma experiência de usuário desejável
- A premissa é que entregar em ordem é melhor do que perder partes do prompt de voz
- Se um dia for necessário descartar alguns pacotes ou aplicar prioridades, o texto sugere que a OpenAI deveria usar WebTransport, como no MoQ
- A configuração de conexão do QUIC pode ser feita em QUIC+TLS 1 RTT, algo mais simples do que os múltiplos handshakes do WebRTC
Vantagens do Connection ID no QUIC
- O QUIC abandona o roteamento com base em IP/porta de origem e inclui
CONNECTION_IDem todos os pacotesCONNECTION_IDpode ter de 0 a 20 bytes- O ponto importante é que quem escolhe esse valor é o receptor
- O servidor QUIC pode gerar um
CONNECTION_IDúnico para cada conexão- Assim, é possível usar uma única porta e ainda identificar conexões cujo IP/porta de origem mudaram
- Quando o endereço de origem muda, o QUIC troca automaticamente para o novo endereço sem derrubar a conexão como no TCP
- O texto considera que a ideia do RFC9146 foi tirada do QUIC
Balanceamento de carga sem estado
- O balanceador da OpenAI depende de estado compartilhado, como muitos outros balanceadores
- É preciso armazenar o mapeamento entre IP/porta de origem e servidor de backend
- Como o balanceador pode reiniciar ou falhar, esse armazenamento é necessário
- A OpenAI usa uma instância Redis para guardar o mapeamento entre IP/porta de origem e servidor de backend
- O texto avalia isso como uma solução simples e fácil
- O QUIC-LB oferece uma alternativa mais simples, sem banco de dados
- Quando o cliente inicia uma conexão QUIC, o balanceador encaminha o pacote para um backend válido
- Ao concluir o handshake, o backend codifica seu próprio ID no
CONNECTION_ID - Depois disso, todos os pacotes QUIC carregam o ID do servidor de backend
- O balanceador só precisa decodificar os primeiros bytes e encaminhar o pacote ao servidor correspondente, sem chave de criptografia nem tabela de roteamento
- Mesmo que o servidor reinicie, esse modelo pode continuar funcionando
- Se é sem estado, então também não há estado global
- O balanceador pode receber em um endereço anycast global e encaminhar globalmente ao backend indicado
- Segundo o texto, a Cloudflare usa isso amplamente
- O AWS NLB oferece balanceamento de carga QUIC usando QUIC-LB
Combinação de anycast e unicast
- Na arquitetura da OpenAI, aparentemente as conexões são atribuídas a balanceadores regionais; funcionalmente isso pode funcionar, mas o texto defende que anycast seria uma abordagem melhor
- O
preferred_addressdo QUIC é visto como um recurso importante para balanceamento -
Como funciona
- Vários servidores de backend ao redor do mundo anunciam o mesmo endereço anycast
1.2.3.4 - Quando o cliente tenta se conectar a
1.2.3.4, os roteadores da internet entregam o pacote a um dos servidores - Cada servidor QUIC também pode ter um endereço unicast próprio, como
5.6.7.8 - O anycast é usado no handshake, e a conexão com estado é mantida em unicast
- Vários servidores de backend ao redor do mundo anunciam o mesmo endereço anycast
-
Exemplo de fluxo
- O servidor recebe pacotes QUIC em
1.2.3.4e5.6.7.8 - O cliente envia os pacotes do handshake QUIC para
1.2.3.4 - O servidor cria a conexão QUIC e informa
preferred_address=5.6.7.8 - Depois disso, o cliente passa a enviar pacotes para
5.6.7.8 - Se o servidor estiver sobrecarregado e não quiser aceitar novas conexões, basta parar de anunciar
1.2.3.4 - As conexões existentes não caem, porque estão em unicast
- O endereço anycast acaba funcionando, na prática, como um health check
- Nessa arquitetura, o texto argumenta que nem seria necessário um balanceador dedicado
- O servidor recebe pacotes QUIC em
Limites e conclusão
- O autor reconhece que os engenheiros da OpenAI são muito bons e estão sob pressão para escalar rapidamente em grande volume
- Ainda assim, sustenta que, embora o WebRTC pareça uma escolha óbvia para Voice AI, ele não se encaixa bem no produto e também é difícil de escalar
- O MoQ também não seria perfeito para Voice AI
- Em áudio 1:1, boa parte da semântica de cache e fan-out não tem utilidade
- Ainda assim, a conclusão é que QUIC deve ser usado
1 comentários
Comentários do Hacker News
Não li o texto até o fim, mas acho que o autor entende, em termos fundamentais, o propósito do WebRTC. Ele pode até ser especialista e realmente ter construído SFUs em Go/Rust em várias empresas, mas histórico técnico não garante por si só que a conclusão esteja correta
Posso ter entendido errado, mas parece tratar STUN e DTLS como fatores acumulados relacionados no problema de tempo de ida e volta, quando na prática são elementos bem ortogonais. Também senti que ele perde a linha do argumento ao gastar tempo demais falando que não há retransmissão de pacotes e repetindo que no Discord fizeram um esforço enorme nisso
O RTC de WebRTC é comunicação em tempo real, e às vezes as pessoas odeiam mais áudio atrasado ou com velocidade oscilando do que um som com alguns pacotes perdidos. Estamos falando aqui de voz humana
Se você não quer aceitar perda de pacotes, então use um protocolo baseado em TCP em vez de UDP. Mas, em redes ruins, se você enviar voz por TCP, o receptor vai travar esperando o próximo pacote correto. Quando os pacotes finalmente chegarem segundos depois, será preciso decidir se toca o áudio acumulado na velocidade normal ou se acelera para alcançar os outros canais, e em geral as pessoas não gostam dessa experiência
Se por um instante você esquecer o WebRTC e pensar em TCP versus UDP para voz, há um motivo para VoIP ser baseado em UDP desde os anos 90
Primeiro, respondendo à parte técnica, acho que existe um futuro que não seja WebRTC. Só não sei se essa direção coincide com a de WebTransport+WebCodecs e afins
A ideia de que o usuário toparia esperar mais 200 ms para um prompt lento/caro ficar mais preciso é o oposto exato do feedback que eu recebo. Usuários querem resposta imediata. Se houver latência para gerar a resposta ou lidar com interrupções, a sensação de magia desaparece. Além disso, eles também não querem que se envie mais rápido do que em tempo real. Se o usuário interromper o modelo no meio, você terá desperdiçado banda enviando 3 minutos de áudio dos quais só 10 segundos foram reproduzidos
Sobre a afirmação de que TTS é mais rápido que tempo real, a IA de voz mais moderna/na direção atual está saindo do modelo descrito pelo autor: https://research.nvidia.com/labs/adlr/personaplex/ e indo para entrada/saída em pequenos blocos de 20 ms
A parte sobre desejar que o IP/porta original do usuário não mude é suportada. Se chegar um novo IP no ufrag, dá para tratar
A afirmação de que são necessários no mínimo 8 RTTs também está errada: https://datatracker.ietf.org/doc/draft-hancke-webrtc-sped/
Escolher fazer streaming de áudio por WebSocket significa perder recursos como AEC e empurrar complexidade para o cliente. A simplicidade do WebRTC, isto é, o fluxo createOffer -> setRemoteDescription, permite que as pessoas comecem rápido. Com Realtime API + WebSocket, muitos desenvolvedores sofreram porque havia muito código e muita coisa para tratar manualmente
Se fosse para eu escolher, manteria o modelo Offer/Answer, mas usaria QUIC no lugar de DTLS+SCTP. Talvez até desse para fazer RTP sobre QUIC. Não tenho preferência forte pelo protocolo em si, mas não sei bem como lidar com um footprint de código muito maior distribuído para vários clientes e para clientes dos clientes
Não sou especialista em TTS, mas não entendo qual é a vantagem de ir soltando o resultado aos poucos. Silício não se importa com a rapidez com que os números de tempo avançam
Há casos em que o cliente consegue saber que o próprio IP mudou e fazer renegociação ICE, mas muitas vezes não consegue, e em geral se espera que o servidor detecte a mudança. Só que, na configuração atual de load balancer, isso é impossível. Não é um grande problema, mas é frustrante quando já há tantos procedimentos obrigatórios para atravessar
Se esse rascunho quer dizer 7 RTT em vez de 8 RTT, então o número real pode ser ainda menor, já que parte disso pode ser pipelineada. Mas o problema real é que, só porque P2P pode ser usado, você acaba com um servidor de sinalização obrigatório e um handshake TLS duplo
O motivo de o WebRTC parecer fácil para novos desenvolvedores é que ele é um app de conferência em caixa-preta. Mas, em empresas grandes como a OpenAI, essa caixa-preta começa a criar problemas que poderiam ser resolvidos com primitivas mais de baixo nível
Eu realmente gostaria de experimentar RTP over QUIC e até ajudaria nisso. Se o tamanho do código for a preocupação, navegadores e, algum dia, o sistema operacional vão oferecer bibliotecas QUIC. Se você migrar para algo mais próximo de MoQ, o QUIC cuida de fragmentação, retransmissão, controle de congestionamento etc., então a aplicação fica surpreendentemente pequena
A grande limitação de RoQ/MoQ é que o QUIC faz controle de congestionamento até para datagramas, então não dá para implementar GCC. Ao enviar pelo navegador, por enquanto você fica preso a cubic/BBR
Hoje trabalho com conferência de voz/vídeo e chamadas 1:1, e a complexidade do WebRTC é enorme. Ele até ajuda a lançar o produto rápido, mas, quando você faz algo fora do comum, fica difícil corrigir, mesmo com um fork para uso no cliente
Eu poderia escrever uma longa reclamação sobre TURN. Na verdade, o pacote inteiro de protocolos do WebRTC parece ter sido projetado para uma internet que não existe
Em TURN, quando o cliente pede uma alocação, ele deveria receber um rendezvous id em vez de uma porta temporária. Aí o peer poderia se conectar ao servidor TURN por uma porta de serviço e pedir uma conexão para esse rendezvous id, sem que o cliente precise conhecer o endereço do peer e adicionar permission. Isso reduziria a quantidade de comunicação necessária até para conexões retransmitidas ponta a ponta. Clusters mais avançados poderiam codificar informação no id para que cliente e peer se conectem cada um ao servidor TURN mais próximo, e os servidores conversem entre si. Clusters menos avançados teriam de compartilhar junto com o id o IP do servidor TURN e a porta de serviço
A parte sobre por que alguém precisaria saber os timestamps reais de exibição e como eles correspondem ao tempo real me acertou em cheio. Parece que ninguém que criou o WebRTC jamais tentou sincronizar fluxos de dados de origens diferentes com precisão de milissegundos
Fiz uma demo de estabilização de vídeo no navegador usando webcam e um módulo IMU, e a latência do caminho video->rtc->browser e do caminho sensor->websocket->browser era muito diferente e inconsistente. A solução óbvia seria enviar timestamps UTC nos dados do sensor e sincronizar no navegador, mas isso era impossível porque o vídeo não tinha uma referência de timestamp UTC
Se você controlar os dois lados do pipe WebRTC, dá para fazer coisas curiosas como enviar um timestamp UTC do início do stream, mas isso não resolve o jitter do navegador. Funcionou bem o bastante como prova de conceito, mas a solução completa teve de ser redesenhada
Tenho muita experiência nessa área e até alguns pedidos de patente. Na Alexa, o dispositivo abria uma conexão com o servidor e a mantinha aberta; quando detectava a wake word, enviava por essa conexão algo basicamente parecido com HTTP2/SPDY. Assim, era possível começar o processamento de STT antes mesmo de o usuário terminar de falar, e só restava a latência do processamento dos últimos fragmentos
A resposta também voltava pela mesma conexão
No caso da OpenAI, é mais difícil manter conexões persistentes sempre abertas como na Alexa, mas, em celular, se você usar HTTP2, iOS e Android praticamente gerenciam essa conexão sozinhos
O autor está certo. Não há necessidade de um protocolo em tempo real, e é mais importante receber todos os dados. O usuário mal percebe latência até passar de 500 ms. Especialmente na era mobile, a maioria das pessoas já está acostumada a haver latência até em comunicação em tempo real entre humanos
Se eu trabalhasse na OpenAI ou Anthropic, você poderia entrar em contato. Posso falar mais a fundo sobre isso
A latência de transporte já é somada em cima de várias outras latências grandes
Então imagino que tenham escolhido a solução de menor latência possível para reduzir a latência ponta a ponta do pipeline inteiro
A analogia com latência de voz entre humanos não serve. Nesse caso, você está tratando o ser humano como se fosse uma entidade sem latência
500 ms é praticamente o piso do que se consegue hoje em implementações de voz de ponta, quando você dá sorte, não economiza dinheiro e ainda usa técnicas caras como speculative decoding e reasoning. Só a etapa de LLM leva 450 ms. Em IA de voz comercial, cada ms importa, e acrescentar só 200~300 ms já piora muito a qualidade da conversa
Nosso negócio lida principalmente com voz para usuários não técnicos. No ano passado, quando a latência entre turnos estava em 1200~1500 ms, havia muita confusão dos usuários, interrupções, abandono da conversa e, no geral, uma experiência desagradável. Hoje estamos em algo perto de 700 ms, dependendo do uso de ferramentas necessário, e já nos aproximamos de uma experiência razoável comparável à interação com uma pessoa real. Estamos gastando bastante para cortar mais 100 ms a partir daqui
Também fazemos coisas caras e desperdiçadoras, como speculative LLM pass e speculative tool execution. Durante a fala do usuário, rodamos várias inferências de LLM, mas não executamos de fato chamadas de ferramenta não idempotentes até saber que aquele pass pode ser usado e que o usuário não deixou algo importante para o final da frase, economizando assim 100~200 ms. Dizer que 500 ms não importam me parece falar de outro caso de uso, não de interação de voz humano-IA
Os problemas realmente difíceis em IA de voz não são os pacotes WebRTC que ocasionalmente se perdem, mas sim ruído de fundo forte, eco e sotaque. A implementação bem refinada de AEC no WebRTC ajuda bastante pelo menos com eco. Eu entendo que é um protocolo muito chato de implementar no porte da OpenAI, mas, para aplicações fora de hiperescala, há muitos provedores comerciais como a Daily e soluções decentes. Os problemas reais a resolver estão em outro lugar. Ainda assim, se eu adicionar 500 ms ao meu orçamento de latência, a aplicação morre
Infelizmente, há poucos protocolos tão desagradáveis de implementar quanto o WebRTC. Só para subir um cliente simples, você precisa se adaptar rápido a um handshake complexo repleto de SDP, TURN/STUN, ICE candidates, offer, protocolo P2P, tudo reimplementado do zero todas as vezes
É difícil até imaginar reescrever de novo todo esse trench coat de protocolo com camadas e mais camadas de “boas práticas” acidentais
Espero que esteja melhorando com mais material educacional e bibliotecas. Também é surpreendente como ferramentas como o Codex agora conseguem avançar bem nesse tipo de coisa
APIs de navegador, no geral, têm muitos casos de borda não documentados, e isso não é um problema exclusivo do WebRTC
É um texto irritantemente unilateral. O WebRTC realmente tem limitações, mas apostar no padrão traz muita precisão e reduz custo de engenharia no longo prazo. O fato de o WebRTC ser complexo não significa que esteja errado; significa que mídia em tempo real na internet pública é complexa
Redes são inerentemente stateful. NAT traversal, jitter buffer, controle de congestionamento, perda de pacotes, estado de codec, criptografia e roteamento de sessão não desaparecem só porque você colocou o áudio em TCP ou WebSocket. Fingir que desaparecem não é clareza arquitetural; é apenas mover a complexidade para um lugar menos visível
Há 1 ano, no Discord, ele reescreveu uma SFU WebRTC em Rust, então dá para ver um padrão se repetindo
O WebRTC é composto por cerca de 45 RFCs que vêm se acumulando desde o começo dos anos 2000, além de padrões de fato como TWCC e REMB, que tecnicamente ainda são drafts. Quando você precisa implementar tudo isso, não tem graça nenhuma
Dá para considerá-lo um especialista certificado em WebRTC e, por isso mesmo, ele diz que nunca mais quer usar WebRTC
Ele já tentou bastante do jeito convencional, então me parece que tem todo o direito de ter uma visão na direção oposta, não?
Não tenho posição sobre o tema em si, mas o texto tinha claramente uma textura humana, e gostei disso
Se foi escrito por IA, aí estamos realmente perdidos
Já é 2026 e videoconferência remota continua sendo uma bagunça. Há bilhões de dólares em jogo, e o Zoom, no seu melhor dia, é apenas mediano; às vezes chega a ser tão ruim quanto aquele troço da Microsoft. Nunca vi reunião remota que não fosse um caos desajeitado e grosseiro
Texto excelente. Seria ótimo se desse para premiar posts de blog quando o autor realmente é especialista no assunto
Sobre a frase “o WebRTC foi projetado para degradar e descartar meu prompt em condições ruins de rede”, isso é justamente o preço a pagar se você quer tempo real. Se você não quer tempo real e imagina tudo como STT -> Prompt -> TTS, talvez nem precise enviar áudio pela rede em primeiro lugar
Toda aplicação de baixa latência precisa definir um compromisso de experiência do usuário entre qualidade e latência. Congestionamento cria filas, ou seja, latência; para evitá-la, você precisa pular alguma coisa, o que reduz a qualidade
O controle de latência versus qualidade do WebRTC é fixo. Ele é excelente para minimizar latência, mas falta flexibilidade. Ainda assim, continuo tentando usar WebRTC porque, com o suporte dos navegadores, ele ainda é uma das poucas opções viáveis de fato
Mas agora existe WebTransport. Com um protocolo genérico, dá para construir um comportamento parecido com o do WebRTC. A aplicação pode decidir quanto tempo esperar antes de dar drop/reset em streams, sem que essa decisão seja tomada por ela
O ponto do texto é que os usuários em geral querem streaming, mas não querem drops. Streaming de entrada e saída de áudio obviamente é possível sem WebRTC. A aplicação deveria poder definir quando um pacote de áudio está perdido para sempre: 50 ms, 500 ms ou 5000 ms. A tese é que IA de voz não deveria escolher a opção de 50 ms
Quando a OpenAI responde, ela já tem a maior parte do áudio antes do momento em que o usuário precisa ouvi-lo. Ela gera áudio mais rápido do que em tempo real, então um protocolo em tempo real não é a escolha adequada
Estamos rodando a Gemini Live API sobre uma malha gerenciada de nuvem WebRTC e está funcionando muito bem, em operação há 2 anos. Dá para tentar WebSocket e cuidar manualmente de chaves temporárias etc., mas, quando você conversa com pessoas que operam agentes de voz em grande escala nessa área, muito disso já foi resolvido com WebRTC, Pipecat e o grande volume de recursos investidos em problemas já solucionados
Sem dúvida parece exagerado, e talvez realmente seja, mas, depois que a conexão se estabelece, a coisa fica bem mágica. Tempo de inicialização e buffering também já foram resolvidos para conexões de voz mais rápidas: https://github.com/pipecat-ai/pipecat-examples/tree/main/instant-voice vídeo é ainda mais difícil