Surpresa! Esta é uma postagem bônus da série AI for Web Devs que concluí recentemente. Se você ainda não leu essa série, eu o encorajo a ler
Esta postagem examinará a arquitetura de projeto existente e as maneiras pelas quais podemos melhorá-la tanto para desenvolvedores de aplicativos quanto para o usuário final.
Discutirei alguns conceitos gerais e usarei produtos específicos da Akamai em meus exemplos.
O aplicativo existente é bastante básico. Um usuário envia dois oponentes e, em seguida, o aplicativo transmite uma resposta gerada por IA sobre quem venceria uma luta.
A arquitetura também é simples:
O cliente envia uma solicitação a um servidor.
O servidor constrói um prompt e o encaminha para OpenAI.
OpenAI retorna uma resposta de streaming ao servidor.
O servidor faz os ajustes necessários e encaminha a resposta do streaming ao cliente.
Usei os serviços de computação em nuvem da Akamai (anteriormente
🤵 parece um garçom em um restaurante chique e 👁️🗨️ é “um olho”, ou IA. hahaha
Tecnicamente, isso funciona bem, mas existem alguns problemas, principalmente quando os usuários fazem solicitações duplicadas. Poderia ser mais rápido e econômico armazenar respostas em nosso servidor e acessar o OpenAI apenas para solicitações exclusivas.
Isso pressupõe que não precisamos que cada solicitação seja não determinística (a mesma entrada produz uma saída diferente). Vamos supor que não há problema em que a mesma entrada produza a mesma saída. Afinal, uma previsão sobre quem venceria uma luta provavelmente não mudaria.
Se quisermos armazenar respostas do OpenAI, um local prático para colocá-las é em algum tipo de banco de dados que permita uma consulta rápida e fácil usando os dois oponentes. Desta forma, quando uma solicitação for feita, podemos primeiro verificar o banco de dados:
O cliente envia uma solicitação a um servidor.
O servidor verifica se há uma entrada existente no banco de dados que corresponda à entrada do usuário.
Se existir um registro anterior, o servidor responde com esses dados e a solicitação é concluída. Pule as etapas a seguir.
Caso contrário, o servidor seguirá a etapa três do fluxo anterior.
Antes de fechar a resposta, o servidor armazena os resultados do OpenAI no banco de dados.
As linhas pontilhadas representam solicitações opcionais, e o 💽 parece um disco rígido.
Com esta configuração, quaisquer solicitações duplicadas serão tratadas pelo banco de dados. Ao tornar opcionais algumas das solicitações OpenAI, podemos reduzir potencialmente a quantidade de latência experimentada pelos usuários, além de economizar dinheiro reduzindo o número de solicitações de API.
Este é um bom começo, especialmente se o servidor e o banco de dados existirem na mesma região. Isso proporcionaria tempos de resposta muito mais rápidos do que ir aos servidores da OpenAI.
No entanto, à medida que nosso aplicativo se torna mais popular, poderemos começar a receber usuários de todo o mundo. Pesquisas mais rápidas no banco de dados são ótimas, mas o que acontece se o gargalo for a latência do tempo gasto em voo?
Podemos resolver essa preocupação aproximando as coisas do usuário.
Se você ainda não está familiarizado com o termo “edge”, esta parte pode ser confusa, mas tentarei explicá-la de forma simples. Edge refere-se ao conteúdo estar o mais próximo possível do usuário. Para algumas pessoas, isso pode significar dispositivos IoT ou torres de telefonia celular, mas no caso da web, o exemplo canônico é um
Vou poupar você dos detalhes, mas uma CDN é uma rede de computadores distribuídos globalmente que pode responder às solicitações dos usuários do nó mais próximo da rede (
Com a computação de ponta, podemos mover grande parte da nossa lógica de back-end para muito perto do usuário, e isso não para na computação. A maioria dos provedores de computação de borda também oferece algum tipo de armazenamento de valor-chave eventualmente consistente nos mesmos nós de borda.
Como isso poderia impactar nossa aplicação?
O cliente envia uma solicitação para nosso backend.
A rede de computação de borda roteia a solicitação para o nó de borda mais próximo.
O nó de borda verifica se há uma entrada existente no armazenamento de valores-chave que corresponda à entrada do usuário.
Se existir um registro anterior, o nó de borda responde com esses dados e a solicitação é concluída. Pule as etapas a seguir.
Caso contrário, o nó de borda encaminha a solicitação para o servidor de origem, que a repassa para OpenAI e blá, blá, blá.
Antes de fechar a resposta, o servidor armazena os resultados do OpenAI no armazenamento de valores-chave de borda.
O nó de borda é a caixa azul e é representado por 🔪 porque tem uma borda, EdgeWorker é o produto de computação de borda da Akamai representado por 🧑🏭 e EdgeKV é o armazenamento de valor-chave da Akamai representado por 🔑🤑🏪. A caixa de borda está mais próxima do cliente do que o servidor de origem na nuvem para representar a distância física.
O servidor de origem pode não ser estritamente necessário aqui, mas acho mais provável que esteja lá. Por uma questão de dados, computação e fluxo lógico, isso é basicamente igual à arquitetura anterior. A principal diferença é que os resultados armazenados anteriormente agora ficam muito próximos dos usuários e podem ser retornados quase imediatamente.
(Observação: embora os dados estejam sendo armazenados em cache na borda, a resposta ainda é construída dinamicamente. Se você não precisar de respostas dinâmicas, pode ser mais simples usar um CDN na frente do servidor de origem e definir os cabeçalhos HTTP corretos para armazene a resposta em cache. Há muitas nuances aqui e eu poderia dizer mais, mas... bem, estou cansado e realmente não quero. Sinta-se à vontade para entrar em contato se tiver alguma dúvida.)
Agora estamos cozinhando! Quaisquer solicitações duplicadas serão respondidas quase imediatamente, ao mesmo tempo que nos poupam de solicitações de API desnecessárias.
Isso resolve a arquitetura das respostas de texto, mas também temos imagens geradas por IA.
A última coisa que consideraremos hoje são as imagens. Ao lidar com imagens, precisamos pensar na entrega e no armazenamento. Tenho certeza de que o pessoal da OpenAI tem suas próprias soluções, mas algumas organizações desejam possuir toda a infraestrutura por motivos de segurança, conformidade ou confiabilidade. Alguns podem até executar seus próprios serviços de geração de imagens em vez de usar OpenAI.
No fluxo de trabalho atual, o usuário faz uma solicitação que finalmente chega ao OpenAI. OpenAI gera a imagem, mas não a retorna. Em vez disso, eles retornam uma resposta JSON com a URL da imagem, hospedada na infraestrutura da OpenAI.
Com esta resposta, uma tag <img>
pode ser adicionada à página usando o URL, o que inicia outra solicitação para a imagem real.
Se quisermos hospedar a imagem em nossa própria infraestrutura, precisamos de um local para armazená-la. Poderíamos gravar as imagens no disco do servidor de origem, mas isso poderia ocupar rapidamente o espaço em disco e teríamos que atualizar nossos servidores, o que pode ser caro.
Isso resolve a questão do armazenamento, mas os buckets de armazenamento de objetos geralmente são implantados em uma única região. Isso reflete o problema que tivemos ao armazenar texto em um banco de dados. Uma única região pode estar longe dos usuários, o que pode causar muita latência.
Tendo já introduzido a vantagem, seria bastante trivial adicionar recursos de CDN apenas para os ativos estáticos (francamente, todo site deveria ter um CDN). Depois de configurado, o CDN extrairá imagens do armazenamento de objetos na solicitação inicial e as armazenará em cache para quaisquer solicitações futuras de visitantes na mesma região.
Esta é a aparência do nosso fluxo de imagens:
Um cliente envia uma solicitação para gerar uma imagem baseada em seus oponentes.
A computação de borda verifica se os dados de imagem dessa solicitação já existem. Nesse caso, ele retorna o URL.
A imagem é adicionada à página com o URL e o navegador solicita a imagem.
Se a imagem já foi armazenada em cache no CDN, o navegador a carrega quase imediatamente. Este é o fim do fluxo.
Se a imagem não tiver sido armazenada em cache anteriormente, o CDN extrairá a imagem do local de armazenamento do objeto, armazenará em cache uma cópia dela para solicitações futuras e retornará a imagem ao cliente. Este é outro fim do fluxo.
Se os dados da imagem não estiverem no armazenamento de valor-chave de borda, a solicitação para gerar a imagem vai para o servidor e para o OpenAI, que gera a imagem e retorna as informações da URL. O servidor inicia uma tarefa para salvar a imagem no bucket de armazenamento de objetos, armazena os dados da imagem no armazenamento de valor-chave de borda e retorna os dados da imagem para a computação de borda.
Com os novos dados de imagem, o cliente cria a imagem que cria uma nova solicitação e continua a partir da etapa cinco acima.
A rede de entrega de conteúdo é indicada por um caminhão de entrega (🚚) e um sinal de rede (📶), e o armazenamento de objetos é indicado por meias em uma caixa (🧦📦) ou objetos armazenados. Esta legenda provavelmente não é necessária, pois acho que são claras, mas estou muito orgulhoso do meu jogo de emojis e preciso de validação. Obrigado por me ceder. Continuar.
Esta última arquitetura é, reconhecidamente, um pouco mais complexa, mas se a sua aplicação for lidar com tráfego intenso, vale a pena considerá-la.
Pode apostar! Com todas essas mudanças em vigor, criamos textos e imagens gerados por IA para solicitações exclusivas e fornecemos conteúdo em cache da borda para solicitações duplicadas. O resultado são tempos de resposta mais rápidos e uma experiência de usuário muito melhor (além de menos chamadas de API).
Mantive esses diagramas de arquitetura aplicáveis em vários bancos de dados, computação de borda, armazenamento de objetos e provedores de CDN propositalmente. Gosto que meu conteúdo seja amplamente aplicável. Mas vale a pena mencionar que integrar a vantagem envolve mais do que apenas desempenho. Existem muitos recursos de segurança muito interessantes que você também pode ativar.
Por exemplo, na rede da Akamai, você pode ter acesso a coisas como
Então, por enquanto, deixo um grande “obrigado” pela leitura. Espero que você tenha aprendido alguma coisa. E como sempre, sinta-se à vontade para entrar em contato a qualquer momento com comentários, perguntas ou preocupações.
Muito obrigado pela leitura. Se você gostou deste artigo e deseja me apoiar, a melhor maneira de fazer isso é
Publicado originalmente em