Colocando Gateways de LLM em Produção: Arquitetura, Compromissos e Lições Difíceis — Kanish Manuja, Twilio

AAI Engineer
Computing/SoftwareManagementInternet Technology

Transcript

00:00:00Sou o Ganesh Manuja. Sou engenheiro principal na Twilio. Vamos começar com um rápido levantamento de mãos.
00:00:20Quem aqui já viu a mensagem “algo deu errado, tente novamente”?
00:00:27Bem, temos alguns afortunados e outros que almoçaram muito bem.
00:00:33Portanto, por trás dessa mensagem simples, há na verdade um sistema muito complexo que exibe essa mensagem para você, apesar de os provedores de modelos estarem fora do ar.
00:00:45E é isso que vamos colocar em produção hoje, ou discutir como colocar em produção.
00:00:50Então, o que é um gateway de LLM?
00:00:52Um gateway de LLM é um ponto de entrada ou um middleware entre seus aplicativos e os provedores de modelos por trás deles.
00:00:58Ele faz várias coisas: roteamento, autenticação, fallback, limites de taxa, todo tipo de governança que você possa imaginar.
00:01:08E bem no coração do gateway há uma disputa entre quatro coisas.
00:01:13São elas: disponibilidade, latência, mecanismos de segurança e custos.
00:01:18Em caso de degradação, você não consegue maximizar todas as quatro.
00:01:22Você precisa escolher o que quer.
00:01:25Portanto, com esta palestra, se você usa um gateway de LLM, quero ajudar você a fazer essa escolha para o seu caso de uso.
00:01:35E se você projeta um gateway, quero que projete ou forneça essas opções aos seus chamadores e clientes para que eles fiquem satisfeitos.
00:01:46Vamos começar com a disponibilidade.
00:01:50Se você tem um único provedor de modelo, o limite dele é o seu limite.
00:01:56A queda dele é a sua queda.
00:02:03Portanto, na engenharia de software típica, a forma de lidar com uma dependência não confiável é fazendo novas tentativas.
00:02:11Novas tentativas com backoff exponencial e variação aleatória (jitter).
00:02:15E quando tudo isso falha, você tem um disjuntor (circuit breaker) que é acionado após falhas suficientes, e você para de chamar essa coisa.
00:02:24Isso não é suficiente para LLMs.
00:02:26As LLMs são muito diferentes em comparação com suas APIs rápidas e baratas nas quais você faz novas tentativas.
00:02:32Tentar novamente uma API de LLM consome o seu orçamento de latência muito rapidamente.
00:02:38E além disso, acionar um disjuntor quando você tem outro provedor de modelo perfeitamente funcional para o qual rotear não faz sentido.
00:02:47Você deve usar o segundo provedor de modelo.
00:02:48E terceiro, como eu disse, as chamadas são lentas e caras.
00:02:53Portanto, novas tentativas cegas apenas multiplicam seus custos e suas latências de cauda.
00:02:58Então, qual é a melhor ideia aqui?
00:03:02Na verdade, é um fallback por requisição.
00:03:05O que isso significa é que você pode tentar o provedor de modelo A e depois, em sequência, tentar o provedor de modelo B se a sua requisição para o provedor A falhar.
00:03:14Outra opção a considerar aqui é disparar requisições para ambos os provedores em paralelo, mas isso apenas se você for altamente, altamente obcecado por latências, porque isso vai apenas duplicar o seu custo.
00:03:26Alguns dos padrões semelhantes de disjuntores também se aplicam aqui às LLMs.
00:03:32Se você sabe que o seu provedor principal está falhando há algum tempo, não faz sentido tentar usá-lo novamente.
00:03:40Você o retira do balanceador de carga ou do seu caminho de requisição, coloca-o em período de resfriamento (cooldown) e, depois que alguns minutos se passarem, tenta reintegrá-lo.
00:03:51Uma escolha interessante que você precisa fazer aqui é onde ficam armazenadas as suas contagens de falhas.
00:03:59Você pode decidir manter as contagens de falhas na memória das instâncias que atendem ao seu tráfego, ou pode ter informações compartilhadas, onde as contagens de falhas são distribuídas por todo o cluster.
00:04:12Há compensações (trade-offs).
00:04:14Se você quer failovers rápidos, ter dados compartilhados em todo o cluster ajuda.
00:04:19E com contadores de estado local por instância, o problema que você enfrenta é que, sempre que altera o tamanho da implantação, sua configuração e suas expectativas mudam.
00:04:30Portanto, é algo a se considerar.
00:04:34O que aquele diagrama limpo realmente não mostrou são alguns dos outros detalhes problemáticos que vou discutir.
00:04:39Portanto, fallbacks não são transparentes.
00:04:41Embora a indústria esteja convergindo para um formato compatível com a API da OpenAI, eu diria que ainda existem nuances.
00:04:49Portanto, você realmente precisa testar bem os seus fallbacks.
00:04:52Eles podem apresentar diferenças em seus esquemas de chamadas de ferramentas (tool calling), limites de tokens, motivos de parada e o que mais houver.
00:04:58Portanto, com gateways de LLM, você pode ter uma camada de normalização capaz de garantir que você também realize fallbacks entre diferentes provedores.
00:05:08Outro aspecto é o streaming.
00:05:15Basicamente, ninguém quer esperar 30 segundos para ver uma parede de texto aparecer na sua frente.
00:05:22Portanto, há casos de uso em que o streaming é absolutamente necessário.
00:05:26Mas isso cobra um preço.
00:05:27Você abre mão das suas alavancas de controle.
00:05:29Você não pode — uma vez que decidiu ir com o Provedor A, você tem que continuar com o Provedor A.
00:05:36Você não pode mudar de provedor no meio da transmissão.
00:05:39Tudo o que já foi enviado para o cliente está feito.
00:05:42E é aí que entra a mensagem de que algo deu errado.
00:05:46Essa é a mensagem que você vê.
00:05:48Não é por preguiça.
00:05:49É por design que você vê isso.
00:05:52E é uma dessas compensações (trade-offs).
00:05:54Gostaria de destacar outra coisa em que tenho visto equipes tropeçarem repetidamente.
00:06:00Elas provisionam e testam seus provedores principais muito bem.
00:06:05Mas o segundo provedor, o provedor de fallback, não recebe necessariamente o mesmo nível de atenção.
00:06:11E eu argumentaria que sua capacidade de processamento (throughput), sua capacidade ou sua margem de segurança (headroom) deveriam ser ainda maiores para o segundo provedor ou provedor de fallback.
00:06:21Porque essa é a sua última linha de defesa.
00:06:23Se ele cair, a sua aplicação cairá.
00:06:29Vamos discutir as latências.
00:06:31As falhas de disponibilidade aparecem bem na sua cara.
00:06:34Elas falham.
00:06:36Você recebe um alerta.
00:06:37Você é acionado (paged).
00:06:38Mas latências altas podem ser silenciosas.
00:06:42E elas precisam receber mais atenção do que, eu diria, apenas ajustar seus serviços para a disponibilidade.
00:06:49Uma coisa a destacar.
00:06:54Um gateway pode executar cargas de trabalho mistas.
00:06:58E você pode ter requisições de embeddings que levam menos de um segundo.
00:07:04Você pode ter requisições de classificação que levam menos de um segundo.
00:07:07Você tem requisições de chat levando três segundos.
00:07:10E requisições de raciocínio demorando bastante.
00:07:13Um rápido levantamento de mãos.
00:07:15Levantem a mão rapidamente se vocês medem a latência agregada para todo o seu serviço.
00:07:20Bem, essa foi uma pergunta pegadinha.
00:07:23Desculpem.
00:07:24Vocês não deveriam.
00:07:25Isso não faz sentido.
00:07:26É uma ilusão.
00:07:27Você deveria estar monitorando o seu P99 por modelo, por rota, e não um número que englobe todo o gateway.
00:07:32Um número geral do gateway não faz sentido, especialmente se você estiver executando cargas de trabalho mistas.
00:07:36E espero que vocês não façam isso, para aqueles que levantaram a mão.
00:07:40Outra coisa que pode realmente — eu não consigo enfatizar isso o suficiente — é definir timeouts por classe de modelo e por rota.
00:07:49Essa é a principal causa raiz de uma interrupção silenciosa.
00:07:54Se você não tiver um timeout, o seu gateway acha que a sua requisição está sendo atendida com sucesso, quando na verdade não está.
00:08:00E eu deixo esta mensagem para vocês, especificamente sobre latências.
00:08:05O tempo normal de operação de um modelo de raciocínio equivale a uma interrupção para um modelo de chat.
00:08:09Portanto, você definitivamente precisa monitorar a latência por rota.
00:08:13Ok, este é o tópico mais doloroso ou o slide que mais me causou sustos, que são os modelos de raciocínio e de roteamento.
00:08:24É aqui que a latência é verdadeiramente imprevisível.
00:08:29E os modelos de raciocínio não oferecem a você — eles são altamente não determinísticos, mais não determinísticos do que os seus modelos normais.
00:08:40Na maioria dos casos, não é possível definir a temperatura como zero.
00:08:43E o mesmo prompt pode levar de dois segundos a 60 segundos.
00:08:48E vimos isso em produção, onde o P99 de repente disparou para 60 segundos sem nenhum motivo aparente.
00:08:53Portanto, embora não haja uma solução mágica para isso, eu recomendaria que você pelo menos comece ajustando o nível de raciocínio por rota.
00:09:03Com os modelos de roteamento, eles ocultam essa abstração de você.
00:09:08Tipo, eles escolhem quais modelos executar.
00:09:11E eu recomendo fortemente que você faça o máximo possível para tornar as requisições tão determinísticas quanto possível dentro de um sistema não determinístico.
00:09:23Outra ideia é proteger-se contra a cauda longa (hedging the tail).
00:09:26Você pode disparar uma nova requisição se a sua requisição principal já tiver consumido, digamos, o P90 do seu orçamento de latência.
00:09:37Isso pode mitigar significativamente a cauda do P99 para os seus serviços.
00:09:44Muito bem, este é um dos meus favoritos.
00:09:47Para manter seu modelo seguro, você precisa ter barreiras de proteção (guardrails).
00:09:53Com isso, as barreiras são necessárias para evitar ataques de injeção de prompt em seus serviços, manter filtros de PII (informações de identificação pessoal) ativos, implementar filtros de toxicidade e impedir que as LLMs xinguem seus clientes.
00:10:08Todas essas coisas boas.
00:10:11Mas assim como um provedor de modelos, também existem compensações (trade-offs).
00:10:15As barreiras de proteção funcionam como qualquer outro serviço.
00:10:18Elas podem sair do ar.
00:10:19Elas podem ser instáveis.
00:10:21E é aí que você precisa escolher.
00:10:24Você adota o modo de falha aberta (fail open) ou falha fechada (fail close)?
00:10:27Quando digo falha aberta, significa que você ainda pode atender à requisição mesmo que suas barreiras de proteção estejam inoperantes.
00:10:32Na falha fechada, você bloqueia a requisição e diz: olhe, não estou disponível.
00:10:36Esse é o meio-termo entre disponibilidade e segurança até certo ponto.
00:10:41Embora não haja uma resposta universal, isso realmente depende do seu caso de uso.
00:10:45Você pode decidir, por exemplo, que se um filtro de toxicidade não estiver funcionando, você ainda pode atender à requisição.
00:10:53Portanto, a escolha padrão deve ser o pior cenário com o qual você consegue conviver.
00:11:02Há algumas coisas que você pode fazer para melhorar o comportamento dos seus sistemas diante de mecanismos de proteção fora do ar e gerenciar a própria instabilidade deles.
00:11:17A primeira é o orçamento de tempo.
00:11:20Sua requisição nunca deve ficar limitada pelo tempo de execução das proteções.
00:11:25O LLM deve ser sempre a etapa que determina a taxa de envio.
00:11:29Portanto, certifique-se de definir limites de tempo e de que essas proteções rodem com um orçamento de tempo específico.
00:11:38Outra coisa importante é o fallback.
00:11:40Você já ouviu -- provavelmente sabe, e eu já falei sobre isso, sempre discutimos fallbacks em relação aos provedores de modelos.
00:11:47Mas as proteções também são serviços críticos, onde você pode considerar fallbacks, ter provedores secundários, verificações secundárias e armazenar decisões em cache para manter o serviço disponível quando um provedor de proteção estiver fora do ar.
00:12:03Outra escolha interessante que surge em relação às proteções é a localização delas.
00:12:10Normalmente, você pode posicionar a proteção de três maneiras.
00:12:15Você pode ter um pré-gancho (prehook) em execução -- onde a proteção é aplicada na entrada.
00:12:19Você pode -- e essa é provavelmente a mais segura, mas ela adiciona latência serial às suas requisições.
00:12:26Outra opção é em paralelo.
00:12:29Essa é uma das minhas favoritas, mas vale notar que o streaming não funciona muito bem aqui com o processamento paralelo.
00:12:35Portanto, se você estiver produzindo saídas estruturadas, por favor, evite usar streaming.
00:12:40Tente economizar latência e execute essas proteções de forma concorrente para suas saídas estruturadas.
00:12:46Outra opção são os pós-ganchos (post hooks).
00:12:48Eles são ideais para monitoramento de saída, auditoria de resultados e assim por diante.
00:12:58Então, até agora, discutimos tudo o que pode dar errado em relação às nossas dependências.
00:13:06Ainda não mencionamos que estamos adicionando mais uma dependência no próprio caminho da requisição, que é o gateway de LLM central -- ou o próprio gateway.
00:13:15Há algumas situações em que sofremos com problemas e aprendemos lições que quero compartilhar com vocês, caso estejam trabalhando em um gateway de LLM ou usando um.
00:13:25A primeira são limites compartilhados.
00:13:28Certifique-se de que suas chaves de API estejam segregadas por rota, por caso de uso, da forma mais granular possível -- o mais granular que você puder imaginar.
00:13:40Ter um inquilino barulhento (noisy tenant) pode ser um dos maiores problemas aqui.
00:13:47Outra coisa é o descarte de carga (load shedding).
00:13:50Este é um recurso que você deve, como parte de seus runbooks e simulações de crise (game days), garantir que o gateway utilizado suporte.
00:13:59Porque, quando você enfrenta uma tempestade de novas tentativas (retry storm), fica muito difícil simplesmente escalar horizontalmente.
00:14:03Você simplesmente não consegue escalar serviços que estão sob uma tempestade de novas tentativas.
00:14:07E todos esses servidores web possuem uma fila interna, e elas são configuráveis.
00:14:13Certifique-se de que elas tenham limites e não possam aceitar requisições de forma ilimitada.
00:14:19E se você quiser implementar alguma lógica personalizada, também é possível usar priorização de tráfego aqui, garantindo que, sob carga, seus casos de uso mais importantes sejam bem atendidos.
00:14:29A última coisa que quero discutir é a ideia de um gateway central em si.
00:14:38Ele é um ponto único de falha.
00:14:40Portanto, se você está pensando em ter um gateway central para toda a empresa para gerenciar os LLMs, eu recomendo repensar isso e analisar quais são os motivos reais para querer um.
00:14:52O que tenho percebido é que, na maioria dos cenários, o que eles querem não é um gateway central.
00:14:57Eles querem governança centralizada.
00:15:00E existe um caminho viável onde você pode descentralizar o gateway e ainda assim centralizar a governança.
00:15:07Portanto, não tente centralizar o seu tráfego, mas você pode usar plugins e códigos personalizados para centralizar a governança.
00:15:17A governança pode assumir a forma de controle de custos, gerenciamento de limites de taxa e outras soluções possíveis.
00:15:24Então, explore essas opções antes de se lançar na implementação de um único gateway central para a sua empresa inteira.
00:15:30Ele pode ser gerenciado por uma única equipe, mas eu não recomendaria implantá-lo como uma única instância de implantação para toda a empresa, mesmo que seja distribuído.
00:15:43Dito isso, quero encerrar esta palestra com uma nota pessoal.
00:15:47Hoje é aniversário do meu filho, e estou aqui falando com estranhos sobre disjuntores de circuito (circuit breakers).
00:15:54Portanto, o mínimo que você pode fazer por mim é ir lá e evitar pelo menos um incidente para mim e para os seus clientes.
00:16:02Obrigado.
00:16:03Se vocês tiverem alguma pergunta, é só falar.
00:16:06.

Key Takeaway

A implementação de gateways de LLM exige equilibrar disponibilidade, latência e custos por meio de fallbacks granulares, timeouts por rota e gerenciamento de barreiras de proteção sem sobrecarregar um único ponto central.

Highlights

  • Um gateway de LLM opera no meio de um conflito entre disponibilidade, latência, mecanismos de segurança e custos.

  • O fallback por requisição tenta um provedor de modelo secundário apenas quando a requisição primária falha, evitando multiplicar custos e latências de cauda.

  • Modelos de raciocínio apresentam comportamento altamente não determinístico e o mesmo prompt pode demorar de dois a sessenta segundos.

  • O monitoramento de latência deve ocorrer por rota e por modelo de forma isolada, em vez de utilizar uma métrica agregada para todo o gateway.

  • A descentralização das instâncias de gateway combinada com plugins centralizados de governança evita que o componente central se torne um ponto único de falha absoluto.

Timeline

Arquitetura e Conflitos Centrais dos Gateways de LLM

  • O gateway de LLM atua como um middleware de entrada entre aplicativos e provedores de modelos.
  • A operação do gateway fundamenta-se na disputa entre disponibilidade, latência, mecanismos de segurança e custos.

Sistemas complexos escondem-se por trás de mensagens genéricas de erro quando provedores externos falham. O gateway centraliza funções como roteamento, autenticação, aplicação de limites de taxa e governança. Durante cenários de degradação, é impossível maximizar simultaneamente todas as quatro dimensões fundamentais da arquitetura.

Disponibilidade e Estratégias de Fallback

  • Novas tentativas e disjuntores tradicionais multiplicam custos e geram latências excessivas em APIs de LLM.
  • O mecanismo de fallback por requisição aciona um provedor secundário de forma sequencial após a falha do principal.

A dependência de um único provedor limita a estabilidade do sistema. Tentativas cegas esgotam rapidamente o orçamento de latência. O armazenamento de contagens de falhas pode ocorrer de forma local na memória por instância ou distribuída pelo cluster para failovers mais rápidos. A capacidade de processamento do provedor secundário deve ser dimensionada com margem de segurança superior à do primário.

Gerenciamento de Latência e Modelos de Raciocínio

  • O monitoramento de latência agregado mascara problemas em cargas de trabalho mistas e deve ser medido por rota e modelo.
  • Modelos de raciocínio geram alta volatilidade de tempo de resposta e exigem definição rigorosa de timeouts por classe.

Cargas de trabalho mistas combinam embeddings rápidos com requisições longas de raciocínio. A ausência de timeouts por rota resulta em interrupções silenciosas no serviço. Modelos de raciocínio impedem a configuração de temperatura zero e apresentam variações drásticas na duração das respostas sem motivos aparentes.

Barreiras de Proteção e Governança Centralizada

  • Barreiras de proteção contra injeção de prompt e vazamento de dados funcionam como serviços externos sujeitos a instabilidades.
  • A descentralização das instâncias de gateway com plugins de governança centralizada evita pontos únicos de falha corporativos.

Sistemas de segurança exigem a definição de modos de falha aberta ou fechada com base na criticidade da aplicação. Chaves de API segregadas por rota mitigam o impacto de inquilinos barulhentos. A centralização total do tráfego corporativo em uma única instância de gateway introduz riscos operacionais severos.

Community Posts

View all posts