O blog da AWS

Como Criar um Assistente Virtual de Baixa Latência com Múltiplos Modelos Usando Serverless e Amazon Bedrock

Por Gabriel Leite e Peterson Larentis

Introdução

Nos tempos atuais, onde a velocidade e eficiência são essenciais para o sucesso empresarial, a incorporação de um atendente virtual usando Inteligência Artificial (IA) Generativa tornou-se um elemento crucial para escalar negócios. GenAI oferece uma oportunidade única para empresas de todos os tamanhos automatizarem o atendimento ao cliente, proporcionando respostas rápidas e precisas 24 horas por dia. Isso não só melhora a experiência do cliente, mas também libera recursos humanos para se concentrarem em tarefas mais complexas e estratégicas, potencializando o crescimento sustentável e a capacidade de resposta do negócio no competitivo mercado atual.

Contudo, para que os assistentes virtuais sejam verdadeiramente úteis e relevantes aos negócios, é essencial que tenham acesso à base de conhecimento específica da empresa. A dependência exclusiva da base geral de modelos de linguagem de grande escala (LLMs) não é suficiente para atender às necessidades personalizadas de cada organização, o que torna essencial selecionar e experimentar o modelo de IA correto que se alinhe às peculiaridades e expectativas do negócio. Além disso, é crucial garantir uma baixa latência nas respostas para manter a fluidez e eficácia do atendimento e evitar frustrações dos usuários. A engenharia de prompt também desempenha um papel fundamental, incorporando técnicas avançadas como ReAct e Prompt Chaining, que são essenciais para direcionar a IA de forma eficaz ao longo das conversas.

Neste post, detalharemos uma solução de assistente virtual aprimorada, capaz de atender os desafios de personalização, experimentação e resposta rápida em, por exemplo, serviços de atendimento ao cliente, utilizando AWS Lambda, AWS Step Functions e Amazon Bedrock.

Visão Geral da Solução

Nesta solução de Assistente Virtual com GenAI, exploramos a implementação simplificada de técnicas avançadas de engenharia de prompt e oferecemos flexibilidade para a experimentação com múltiplos modelos, utilizando o Bedrock e os recursos low-code do Step Functions. Além disso, usamos o Lambda com Lambda URL e o AWS Lambda Web Adapter para responder via stream, otimizando assim a latência nas respostas e melhorando a experiência do usuário.

Figura 1. Arquitetura da solução, tenda a Lambda sendo exposta ao cliente via Lambda URL, invocando uma máquina de estado do Step Functions, para depois invocar o modelo via Bedrock com response stream.

Como Funciona?

O exemplo usa Lambda para operar uma máquina de estados construída com o Workflow Express Síncrono do AWS Step Functions, projetada especificamente para orquestrar múltiplas solicitações às APIs do Amazon Bedrock.

Inicialmente, a Lambda invoca a máquina de estados, uma implementação de RAG, e a utiliza como entrada para acionar a API InvokeModelWithResponseStream do Bedrock, resultando em uma resposta transmitida em stream ao solicitante. Para essa implementação, utilizamos o AWS Lambda Web Adapter em conjunto com o FastAPI, permitindo que a função Lambda seja acessada por meio de uma URL do Lambda configurada no modo de Response Stream. Graças à resposta em stream, o TTFB (Time to First Byte) é reduzido, melhorando significativamente a experiência do usuário do assistente GenAI e se adequando aos cenários de serviços voltados para os clientes finais via web.

A arquitetura de engenharia de prompt desta solução emprega a técnica de Prompt Chaining, onde as funções Lambda recebem instruções através do parâmetro system, guiando o comportamento do modelo desde a primeira invocação. Este parâmetro contém as instruções para o assistente interagir com o usuário, incluindo especificações sobre o papel, o tom e diretrizes gerais para a interação. Inicialmente, o primeiro prompt é crucial para estabelecer técnicas complexas como Role Playing e Few-Shot Prompting.

A Lambda também atua como a última subtarefa do encadeamento de prompts, pronta para utilizar modelos poderosos como os da série Claude. Essa configuração permite a implementação da API InvokeModelWithResponseStream, que, embora envolva modelos com maior tempo de resposta, aproveita o TTFB para oferecer uma resposta com menor latência, melhorando significativamente a responsividade durante as interações com os usuários.

Nas invocações ao Bedrock, definidas nas tarefas do Step Function, cada tarefa que realiza a invocação ao Bedrock pode ter seu próprio prompt. Os prompts devem ser projetados de maneira concisa e direta nas tarefas das Step Functions, com foco na resolução de problemas específicos. Isso incentiva a experimentação com diferentes modelos para otimizar os resultados.

Como tirar proveito deste padrão?

A combinação de AWS Step Functions usando Workflows Express e a API de resposta em stream do Bedrock permite cenários onde o desenvolvedor pode usar tarefas da máquina de estados para definir subtarefas de encadeamento de prompts (Prompt Chaining).

Cada tarefa da Step Functions pode invocar a API do Amazon Bedrock com um Modelo de LLM específico, sequencialmente ou em paralelo para subtarefas de prompt independentes, e então orquestrar o resultado com outras APIs de serviços AWS, como AWS Lambda, Amazon API Gateway e APIs de terceiros.

Dividir tarefas de LLM em subtarefas facilita a engenharia de prompt, pois permite focar no resultado específico da subtarefa. Também torna mais fácil controlar os tokens de saída, o que reduz a latência das subtarefas que não necessitam gerar grandes saídas.

Por exemplo, você pode usar um prompt de usuário e solicitar a um LLM mais compacto, como o Meta Llama 3 8B, para retornar um valor booleano e usá-lo para definir um caminho determinístico em uma máquina de estados, verificando o valor verdadeiro/falso. Isso consumirá um número reduzido de tokens de saída, diminuindo a latência e o custo. A inferência para uma resposta final pode ser executada por Claude 3 Sonnet usando resposta em stream para melhorar a qualidade da resposta e o TTFB.

Aqui estão alguns cenários onde este padrão pode ser usado:

RAG: Use Step Functions para invocar Bedrock, enriquecendo a entrada do usuário com palavras-chave relevantes ao contexto da conversa e, em seguida, realizar uma busca semântica através das bases de conhecimento do Amazon Bedrock. As tarefas de adicionar palavras-chave e invocar bases de conhecimento, sendo de baixa latência, permitem que a resposta ao usuário seja gerada via stream, melhorando a experiência.

Router: Uma máquina de estado do Step Functions pode atuar como um roteador para combinar cenários determinísticos e não determinísticos, como identificar um potencial churn de cliente e iniciar um workflow de retenção.

Testes A/B: Utilize testes A/B nas Step Functions para uma implementação rápida e low-code, testando diferentes experimentos, fazendo ajustes e selecionando o melhor para seu negócio. Enquanto se concentra nas regras de negócio, a função Lambda serve como uma abstração de interface, eliminando a necessidade de alterar o código ou o contrato da API para cada experimento.

Chamadas de API: A entrada do usuário pode solicitar ao LLM que gere dados em formatos como JSON, XML ou uma consulta SQL baseada em uma estrutura de tabela. Esses dados podem então ser usados pelas Step Functions para realizar tarefas que envolvem chamar APIs e executar consultas SQL em bancos de dados. Além disso, a função Lambda pode utilizar a saída das Step Functions para fornecer respostas em stream e explicar os dados gerados.

Passo a Passo

Pré-requisitos

Para rodar a solução você irá precisar:

Para clonar o repositório, execute:

git clone https://github.com/aws-samples/serverless-genai-assistant.git

Deployment

Depois de clonar o repositório, execute os seguintes comandos do AWS SAM para construir e publicar a solução em sua conta.

cd serverless-genai-assistant/examples/serverless-assistant-rag
sam build sam deploy --guided

Para o passo a passo de deployment, defina as seguintes opções:

Stack Name []: # Escolha um nome para o stack
AWS Region [us-east-1]: # Selecione uma Região que suporte o Amazon Bedrock e os outros serviços AWS
Parameter KnowledgeBaseId []: # Insira o ID da KB https://docs.thinkwithwp.com/bedrock/latest/userguide/knowledge-base-manage.html#kb-
# Mostra as mudanças nos recursos a serem implantados e requer um 'Y' para iniciar a implantação
Confirm changes before deploy [y/N]:
# O SAM precisa de permissão para criar funções para conectar aos recursos em seu template
Allow SAM CLI IAM role creation [Y/n]:
# Preserva o estado dos recursos previamente provisionados quando uma operação falha
Disable rollback [y/N]:
FastAPIFunction Function Url has no authentication. Is this okay? [y/N]: y
Save arguments to configuration file [Y/n]:
SAM configuration file [samconfig.toml]:
SAM configuration environment [default]:

Copie o valor de TheFastAPIFunctionUrl, é a URL para invocar o Lambda.

Execução

Via Terminal
cd serverless-genai-assistant/examples/serverless-assistant-rag/tests
curl --no-buffer -H "Content-Type: application/json" -X POST -d @test.json <lambda-url>
Via Python
cd serverless-genai-assistant/examples/serverless-assistant-rag/tests
pip install requests
python test_stream_python_requests.py --lambda-url <lambda-url>
Com Streamlit
cd serverless-genai-assistant/examples/serverless-assistant-rag/tests
pip install requests
pip install streamlit
streamlit run st_serverless_assistant.py -- --lambda-url <lambda-url>

Detalhes da Implementação

Figura 2. Implementação da RAG com maquina de estado.

Usamos a máquina de estados em examples/serverless_assistant_rag para exemplificar como o fluxo de trabalho funciona, ela implementa uma arquitetura RAG que pode ser usada com modelos Claude que utilizam a API de Mensagens. Você também pode combinar com outros modelos que usam a API de Completamento, tratando o payload usando ASL:

  1. Recebe os dados de entrada do lambda e os paraleliza para duas tarefas da API Bedrock.
  2. A primeira tarefa aprimora a pergunta do usuário adicionando palavras-chave para aumentar a busca semântica.
  3. A segunda tarefa verifica o contexto da conversa e retorna verdadeiro/falso para validar se a recuperação de uma Base de Conhecimento é realmente necessária. Quando evitada, isso reduzirá a latência da resposta.
  4. Se o resultado for verdadeiro, a Base de Conhecimento é invocada usando a pergunta do usuário + as palavras-chave adicionadas, caso contrário, nenhum conteúdo será adicionado. Observe que há um manipulador de erro se a tarefa de Recuperação falhar. Ele adiciona o conteúdo do erro ao contex_output e usa o prompt_chain_data para modificar as instruções originais.
  5. Para passar uma resposta estruturada, o estado Pass é usado para formatar a saída JSON. Esta técnica pode ser usada para manter as Tarefas flexíveis e usar o estado de passagem para filtrar/formatar a saída para manter o contrato da API.

Cada Tarefa que realiza a invocação ao Bedrock tem um prompt específico, e você pode tentar modificar/adicionar/excluir para experimentar a solução. Neste exemplo, esses prompts não são usados diretamente para formatar a resposta final do usuário, e sim para determinar definir o comportamento da arquitetura RAG. O último passo de engenharia de prompt é tratado pelo lambda para executar a resposta em stream, e é possível transformar a instrução original através do parâmetro prompt_chain_data que pode ser inserido na máquina de estados do Step Functions.

Para mais detalhes da implementação acesse o repositório da solução.

Limpeza

Para excluir a infraestrutura criada, em um terminal execute:

cd serverless-genai-assistant/examples/serverless-assistant-rag
sam delete

Conclusão

Ao explorar o potencial da Inteligência Artificial Generativa para o atendimento ao cliente, fica claro que integrar tecnologias como AWS Lambda, AWS Step Functions e Amazon Bedrock pode melhorar a eficiência e a personalização das soluções. Esta solução de assistente virtual, descrita neste post, facilita a implementação de técnicas avançadas de engenharia de prompt e permite a experimentação rápida com modelos de linguagem de grande escala.

Utilizando respostas via stream e a arquitetura serverless do AWS Lambda, juntamente com a flexibilidade dos workflows do Step Functions, esta abordagem visa resolver eficazmente os desafios de latência e personalização. A implementação proposta busca oferecer uma experiência de usuário aprimorada, com respostas rápidas e contextualizadas.

Esta solução serve como um ponto de partida, a partir do qual podemos desenvolver muitas outras abordagens semelhantes, aproveitando as melhores práticas aqui apresentadas. Encorajamos os desenvolvedores a explorar e adaptar esta metodologia para aprimorar não apenas a eficiência operacional, mas também para oferecer um atendimento ao cliente mais eficaz. A experimentação e adaptação contínua são fundamentais para manter a relevância e competitividade no mercado atual.

Sobre os autores

Peterson Larentis é Arquiteto de Soluções Serverless Sênior Especialista na AWS, professor e coordenador de cursos de MBA, empreendedor e palestrante internacional. Na AWS, ele ajuda os maiores clientes da América Latina a construir arquiteturas seguras, confiáveis, elásticas e escaláveis com excelência operacional, utilizando as melhores práticas de engenharia de software ágil. Foi responsável pelas Trilhas de DevOps no AWS Summit Brasil por três edições e é o Arquiteto Líder da comunidade Serverless da AWS na América Latina. Ele possui um MBA em Marketing Digital pela Fundação Getúlio Vargas e seis certificações AWS.

 

 

Gabriel Leite é Arquiteto de Soluções para Parceiros na AWS. Com 18 anos de experiência em desenvolvimento de software, sistemas críticos e arquitetura de soluções, apoia os parceiros AWS a construirem sua jornada para desenvolvimento de novas competências. Fazendo parte da comunidade Serverless e AI/ML, foca na construção de aplicações de negócio utilizando a flexibilidade dos serviços Serverless integrados com IA Generativa para criação de soluções com alto valor para o negócio.

 

 

 

Sobre o revisor

Jaime Nagase atualmente atua como Gerente Sênior de Desenvolvimento de Negócios na AWS, Embaixador DevOps e possui mais de 10 anos liderando equipes em tecnologia. AWS lidera estratégias Go-To-Market de Serverless e Containers na América Latina se especializando em Transformação Digital e Estratégia de Modernização de Aplicações com clientes e parceiros a aproveitando as tecnologias de microserviços.