Neste tutorial, mostramos como integrar um aplicativo de modelo de linguagem grande (LLM, na sigla em inglês) baseado na geração aumentada de recuperação (RAG, na sigla em inglês) com arquivos PDF que você faz upload para um bucket do Cloud Storage.
Este guia usa um banco de dados como um mecanismo de armazenamento e de pesquisa semântica que armazena as representações (embeddings) dos documentos enviados. Você usa o framework Langchain para interagir com os embeddings e usa modelos do Gemini disponíveis na Vertex AI.
O Langchain é um framework Python de código aberto conhecido que simplifica muitas tarefas de machine learning e tem interfaces para integração com diferentes bancos de dados vetoriais e serviços de IA.
Este tutorial é destinado a administradores e arquitetos da plataforma de nuvem, engenheiros de ML e profissionais de MLOps (DevOps) interessados em implantar aplicativos RAG LLM no GKE e no Cloud Storage.
Objetivos
Neste tutorial, você aprenderá a realizar as seguintes tarefas:
- Crie e implante um aplicativo para criar e armazenar embeddings de documentos em um banco de dados de vetores.
- Automatize o aplicativo para acionar novos uploads de documentos para um bucket do Cloud Storage.
- Implante um aplicativo de chatbot que usa a pesquisa semântica para responder a perguntas com base no conteúdo do documento.
Arquitetura de implantação
Neste tutorial, você vai criar um bucket do Cloud Storage, um gatilho do Eventarc e os seguintes serviços:
embed-docs: o Eventarc aciona esse serviço sempre que um usuário faz o upload de um novo documento para o bucket doo Cloud Storage. O serviço inicia um job do Kubernetes que cria embeddings para o documento enviado e os insere em um banco de dados de vetores.chatbot: esse serviço responde a perguntas em linguagem natural sobre os documentos enviados pelo usuário usando a pesquisa semântica e a API Gemini.
O diagrama a seguir mostra o processo de upload e vetorização de documentos:
No diagrama, o usuário faz upload de arquivos no bucket do Cloud Storage.
O Eventarc se inscreve em eventos metadataUpdated de objetos para o
bucket e usa o encaminhador de eventos do Eventarc, que é uma carga de trabalho
do Kubernetes, para chamar o serviço embed-docs quando você faz upload de um novo documento. O
serviço cria embeddings para o documento enviado. O serviço embed-docs
armazena os embeddings em um banco de dados de vetores usando o modelo de embedding da Vertex AI.
O diagrama a seguir mostra o processo de fazer perguntas sobre o conteúdo do documento enviado
usando o serviço chatbot:
Os usuários podem fazer perguntas usando a linguagem natural. O chatbot gera respostas com base apenas no conteúdo dos arquivos enviados. O chatbot recupera o contexto do banco de dados de vetores usando a pesquisa semântica e, em seguida, envia a pergunta e o contexto para o Gemini.
Custos
Neste documento, você vai usar os seguintes componentes faturáveis do Google Cloud:
Para gerar uma estimativa de custo baseada na projeção de uso deste tutorial, use a calculadora de preços.
Ao concluir as tarefas descritas neste documento, é possível evitar o faturamento contínuo excluindo os recursos criados. Para mais informações, consulte Limpeza.
Antes de começar
Neste tutorial, use o Cloud Shell para executar os comandos. O Cloud Shell é um ambiente shell para gerenciar recursos hospedados no Google Cloud. O Cloud Shell vem pré-instalado com as ferramentas de linha de comando Google Cloud CLI, kubectl e Terraform. Se você não usa o Cloud Shell, instale a CLI do Google Cloud.
- Faça login na sua conta do Google Cloud . Se você começou a usar o Google Cloud, crie uma conta para avaliar o desempenho de nossos produtos em situações reais. Clientes novos também recebem US$ 300 em créditos para executar, testar e implantar cargas de trabalho.
-
Instale a CLI do Google Cloud.
-
Ao usar um provedor de identidade (IdP) externo, primeiro faça login na gcloud CLI com sua identidade federada.
-
Para inicializar a gcloud CLI, execute o seguinte comando:
gcloud init -
Crie ou selecione um Google Cloud projeto.
Funções necessárias para selecionar ou criar um projeto
- Selecionar um projeto: não é necessário um papel específico do IAM para selecionar um projeto. Você pode escolher qualquer projeto em que tenha recebido um papel.
-
Criar um projeto: para criar um projeto, é necessário ter o papel de Criador de projetos
(
roles/resourcemanager.projectCreator), que contém a permissãoresourcemanager.projects.create. Saiba como conceder papéis.
-
Crie um projeto do Google Cloud :
gcloud projects create PROJECT_ID
Substitua
PROJECT_IDpor um nome para o projeto Google Cloud que você está criando. -
Selecione o projeto Google Cloud que você criou:
gcloud config set project PROJECT_ID
Substitua
PROJECT_IDpelo nome do projeto do Google Cloud .
-
Verifique se o faturamento está ativado para o projeto do Google Cloud .
Ative as APIs Vertex AI, Cloud Build, Eventarc e Artifact Registry:
Funções necessárias para ativar APIs
Para ativar as APIs, é necessário ter o papel do IAM de administrador do Service Usage (
roles/serviceusage.serviceUsageAdmin), que contém a permissãoserviceusage.services.enable. Saiba como conceder papéis.gcloud services enable aiplatform.googleapis.com
cloudbuild.googleapis.com eventarc.googleapis.com artifactregistry.googleapis.com -
Instale a CLI do Google Cloud.
-
Ao usar um provedor de identidade (IdP) externo, primeiro faça login na gcloud CLI com sua identidade federada.
-
Para inicializar a gcloud CLI, execute o seguinte comando:
gcloud init -
Crie ou selecione um Google Cloud projeto.
Funções necessárias para selecionar ou criar um projeto
- Selecionar um projeto: não é necessário um papel específico do IAM para selecionar um projeto. Você pode escolher qualquer projeto em que tenha recebido um papel.
-
Criar um projeto: para criar um projeto, é necessário ter o papel de Criador de projetos
(
roles/resourcemanager.projectCreator), que contém a permissãoresourcemanager.projects.create. Saiba como conceder papéis.
-
Crie um projeto do Google Cloud :
gcloud projects create PROJECT_ID
Substitua
PROJECT_IDpor um nome para o projeto Google Cloud que você está criando. -
Selecione o projeto Google Cloud que você criou:
gcloud config set project PROJECT_ID
Substitua
PROJECT_IDpelo nome do projeto do Google Cloud .
-
Verifique se o faturamento está ativado para o projeto do Google Cloud .
Ative as APIs Vertex AI, Cloud Build, Eventarc e Artifact Registry:
Funções necessárias para ativar APIs
Para ativar as APIs, é necessário ter o papel do IAM de administrador do Service Usage (
roles/serviceusage.serviceUsageAdmin), que contém a permissãoserviceusage.services.enable. Saiba como conceder papéis.gcloud services enable aiplatform.googleapis.com
cloudbuild.googleapis.com eventarc.googleapis.com artifactregistry.googleapis.com -
Atribua papéis à sua conta de usuário. Execute o seguinte comando uma vez para cada um dos seguintes papéis do IAM:
eventarc.admingcloud projects add-iam-policy-binding PROJECT_ID --member="user:USER_IDENTIFIER" --role=ROLE
Substitua:
PROJECT_ID: o ID do projeto.USER_IDENTIFIER: o identificador da sua conta de usuário . Por exemplo,myemail@example.com.ROLE: o papel do IAM concedido à sua conta de usuário.
Criar um cluster
Crie um cluster do Qdrant, do Elasticsearch ou do Postgres:
Qdrant
Siga as instruções em Implantar um banco de dados de vetores Qdrant no GKE para criar um cluster do Qdrant em execução no modo Autopilot ou no modo padrão do cluster do GKE.
Elasticsearch
Siga as instruções em Implantar um banco de dados de vetores do Elasticsearch no GKE para criar um cluster do Elasticsearch em execução em um cluster do GKE no modo Autopilot ou padrão.
PGVector
Siga as instruções em Implantar um banco de dados de vetores PostgreSQL no GKE para criar um cluster do Postgres com o PGVector em execução em um cluster do GKE no modo Autopilot ou Standard.
Weaviate
Siga as instruções para implantar um banco de dados de vetores do Weaviate no GKE e criar um cluster do Weaviate em execução em um cluster do GKE no modo Autopilot ou Padrão.
Configurar o ambiente
Configure o ambiente com o Cloud Shell:
Defina as variáveis de ambiente do projeto:
Qdrant
export PROJECT_ID=PROJECT_ID export KUBERNETES_CLUSTER_PREFIX=qdrant export CONTROL_PLANE_LOCATION=us-central1 export REGION=us-central1 export DB_NAMESPACE=qdrantSubstitua
PROJECT_IDpelo ID do projetoGoogle Cloud .Elasticsearch
export PROJECT_ID=PROJECT_ID export KUBERNETES_CLUSTER_PREFIX=elasticsearch export CONTROL_PLANE_LOCATION=us-central1 export REGION=us-central1 export DB_NAMESPACE=elasticSubstitua
PROJECT_IDpelo ID do projetoGoogle Cloud .PGVector
export PROJECT_ID=PROJECT_ID export KUBERNETES_CLUSTER_PREFIX=postgres export CONTROL_PLANE_LOCATION=us-central1 export REGION=us-central1 export DB_NAMESPACE=pg-nsSubstitua
PROJECT_IDpelo ID do projetoGoogle Cloud .Weaviate
export PROJECT_ID=PROJECT_ID export KUBERNETES_CLUSTER_PREFIX=weaviate export CONTROL_PLANE_LOCATION=us-central1 export REGION=us-central1 export DB_NAMESPACE=weaviateSubstitua
PROJECT_IDpelo ID do projetoGoogle Cloud .Verifique se o cluster do GKE está em execução:
gcloud container clusters list --project=${PROJECT_ID} --location=${CONTROL_PLANE_LOCATION}O resultado será assim:
NAME LOCATION MASTER_VERSION MASTER_IP MACHINE_TYPE NODE_VERSION NUM_NODES STATUS [KUBERNETES_CLUSTER_PREFIX]-cluster us-central1 1.30.1-gke.1329003 <EXTERNAL IP> e2-standard-2 1.30.1-gke.1329003 6 RUNNINGClone o repositório de exemplo de código do GitHub:
git clone https://github.com/GoogleCloudPlatform/kubernetes-engine-samplesNavegue até o diretório
databases:cd kubernetes-engine-samples/databases
Preparar sua infraestrutura
Crie um repositório do Artifact Registry, gere imagens do Docker e envie imagens Docker para o Artifact Registry:
Crie um repositório do Artifact Registry:
gcloud artifacts repositories create ${KUBERNETES_CLUSTER_PREFIX}-images \ --repository-format=docker \ --location=${REGION} \ --description="Vector database images repository" \ --asyncDefina as permissões
storage.objectAdmineartifactregistry.adminna conta de serviço do Compute Engine para usar o Cloud Build para criar e enviar imagens Docker para os serviçosembed-docsechatbot.export PROJECT_NUMBER=PROJECT_NUMBER gcloud projects add-iam-policy-binding ${PROJECT_ID} \ --member="serviceAccount:${PROJECT_NUMBER}-compute@developer.gserviceaccount.com" \ --role="roles/storage.objectAdmin" gcloud projects add-iam-policy-binding ${PROJECT_ID} \ --member="serviceAccount:${PROJECT_NUMBER}-compute@developer.gserviceaccount.com" \ --role="roles/artifactregistry.admin"Substitua
PROJECT_NUMBERpelo número do projeto doGoogle Cloud .Crie imagens do Docker para os serviços
embed-docsechatbot. A imagemembed-docscontém o código Python para o aplicativo que recebe solicitações de encaminhamento do Eventarc e o job de embedding.Qdrant
export DOCKER_REPO="${REGION}-docker.pkg.dev/${PROJECT_ID}/${KUBERNETES_CLUSTER_PREFIX}-images" gcloud builds submit qdrant/docker/chatbot --region=${REGION} \ --tag ${DOCKER_REPO}/chatbot:1.0 --async gcloud builds submit qdrant/docker/embed-docs --region=${REGION} \ --tag ${DOCKER_REPO}/embed-docs:1.0 --asyncElasticsearch
export DOCKER_REPO="${REGION}-docker.pkg.dev/${PROJECT_ID}/${KUBERNETES_CLUSTER_PREFIX}-images" gcloud builds submit elasticsearch/docker/chatbot --region=${REGION} \ --tag ${DOCKER_REPO}/chatbot:1.0 --async gcloud builds submit elasticsearch/docker/embed-docs --region=${REGION} \ --tag ${DOCKER_REPO}/embed-docs:1.0 --asyncPGVector
export DOCKER_REPO="${REGION}-docker.pkg.dev/${PROJECT_ID}/${KUBERNETES_CLUSTER_PREFIX}-images" gcloud builds submit postgres-pgvector/docker/chatbot --region=${REGION} \ --tag ${DOCKER_REPO}/chatbot:1.0 --async gcloud builds submit postgres-pgvector/docker/embed-docs --region=${REGION} \ --tag ${DOCKER_REPO}/embed-docs:1.0 --asyncWeaviate
export DOCKER_REPO="${REGION}-docker.pkg.dev/${PROJECT_ID}/${KUBERNETES_CLUSTER_PREFIX}-images" gcloud builds submit weaviate/docker/chatbot --region=${REGION} \ --tag ${DOCKER_REPO}/chatbot:1.0 --async gcloud builds submit weaviate/docker/embed-docs --region=${REGION} \ --tag ${DOCKER_REPO}/embed-docs:1.0 --asyncVerifique as imagens:
gcloud artifacts docker images list $DOCKER_REPO \ --project=$PROJECT_ID \ --format="value(IMAGE)"O resultado será assim:
$REGION-docker.pkg.dev/$PROJECT_ID/${KUBERNETES_CLUSTER_PREFIX}-images/chatbot $REGION-docker.pkg.dev/$PROJECT_ID/${KUBERNETES_CLUSTER_PREFIX}-images/embed-docsImplante uma conta de serviço do Kubernetes com permissões para executar jobs do Kubernetes:
Qdrant
sed "s/<PROJECT_ID>/$PROJECT_ID/;s/<CLUSTER_PREFIX>/$KUBERNETES_CLUSTER_PREFIX/" qdrant/manifests/05-rag/service-account.yaml | kubectl -n qdrant apply -f -Elasticsearch
sed "s/<PROJECT_ID>/$PROJECT_ID/;s/<CLUSTER_PREFIX>/$KUBERNETES_CLUSTER_PREFIX/" elasticsearch/manifests/05-rag/service-account.yaml | kubectl -n elastic apply -f -PGVector
sed "s/<PROJECT_ID>/$PROJECT_ID/;s/<CLUSTER_PREFIX>/$KUBERNETES_CLUSTER_PREFIX/" postgres-pgvector/manifests/03-rag/service-account.yaml | kubectl -n pg-ns apply -f -Weaviate
sed "s/<PROJECT_ID>/$PROJECT_ID/;s/<CLUSTER_PREFIX>/$KUBERNETES_CLUSTER_PREFIX/" weaviate/manifests/04-rag/service-account.yaml | kubectl -n weaviate apply -f -Ao usar o Terraform para criar o cluster do GKE e definir
create_service_accountcomo verdadeiro, uma conta de serviço separada será criada e usada pelo cluster e pelos nós. Conceda o papelartifactregistry.serviceAgenta esta conta de serviço do Compute Engine para permitir que os nós extraiam a imagem do Artifact Registry criado paraembed-docsechatbot.export CLUSTER_SERVICE_ACCOUNT=$(gcloud container clusters describe ${KUBERNETES_CLUSTER_PREFIX}-cluster \ --location=${CONTROL_PLANE_LOCATION} \ --format="value(nodeConfig.serviceAccount)") gcloud projects add-iam-policy-binding ${PROJECT_ID} \ --member="serviceAccount:${CLUSTER_SERVICE_ACCOUNT}" \ --role="roles/artifactregistry.serviceAgent"Sem o acesso à conta de serviço, os nós podem ter problemas de permissão ao tentar extrair a imagem do Artifact Registry ao implantar os serviços
embed-docsechatbot.Implante uma implantação do Kubernetes para os serviços
embed-docsechatbot. Uma implantação é um objeto da API Kubernetes que permite executar várias réplicas de pods distribuídos entre os nós de um cluster:Qdrant
sed "s|<DOCKER_REPO>|$DOCKER_REPO|" qdrant/manifests/05-rag/chatbot.yaml | kubectl -n qdrant apply -f - sed "s|<DOCKER_REPO>|$DOCKER_REPO|" qdrant/manifests/05-rag/docs-embedder.yaml | kubectl -n qdrant apply -f -Elasticsearch
sed "s|<DOCKER_REPO>|$DOCKER_REPO|" elasticsearch/manifests/05-rag/chatbot.yaml | kubectl -n elastic apply -f - sed "s|<DOCKER_REPO>|$DOCKER_REPO|" elasticsearch/manifests/05-rag/docs-embedder.yaml | kubectl -n elastic apply -f -PGVector
sed "s|<DOCKER_REPO>|$DOCKER_REPO|" postgres-pgvector/manifests/03-rag/chatbot.yaml | kubectl -n pg-ns apply -f - sed "s|<DOCKER_REPO>|$DOCKER_REPO|" postgres-pgvector/manifests/03-rag/docs-embedder.yaml | kubectl -n pg-ns apply -f -Weaviate
sed "s|<DOCKER_REPO>|$DOCKER_REPO|" weaviate/manifests/04-rag/chatbot.yaml | kubectl -n weaviate apply -f - sed "s|<DOCKER_REPO>|$DOCKER_REPO|" weaviate/manifests/04-rag/docs-embedder.yaml | kubectl -n weaviate apply -f -Ative os gatilhos do Eventarc para o GKE:
gcloud eventarc gke-destinations initQuando solicitado, digite
y.Implante o bucket do Cloud Storage e crie um gatilho do Eventarc usando o Terraform:
export GOOGLE_OAUTH_ACCESS_TOKEN=$(gcloud auth print-access-token) terraform -chdir=vector-database/terraform/cloud-storage init terraform -chdir=vector-database/terraform/cloud-storage apply \ -var project_id=${PROJECT_ID} \ -var region=${REGION} \ -var cluster_prefix=${KUBERNETES_CLUSTER_PREFIX} \ -var db_namespace=${DB_NAMESPACE}Quando solicitado, digite
yes. O comando pode demorar uns minutos para ser executado.O Terraform cria os seguintes recursos:
- Um bucket do Cloud Storage para fazer upload dos documentos
- Um gatilho do Eventarc
- Uma conta de serviço do Google Cloud chamada
service_account_eventarc_namecom permissão para usar o Eventarc. - Uma conta de serviço Google Cloud chamada
service_account_bucket_namecom permissão para ler o bucket e acessar modelos da Vertex AI.
O resultado será o seguinte:
... # Several lines of output omitted Apply complete! Resources: 15 added, 0 changed, 0 destroyed. ... # Several lines of output omitted
Carregar documentos e executar consultas de chatbot
Faça upload dos documentos de demonstração e execute consultas para pesquisar nos documentos de demonstração usando o chatbot:
Faça upload do documento para o bucket
carbon-free-energy.pdf:gcloud storage cp vector-database/documents/carbon-free-energy.pdf gs://${PROJECT_ID}-${KUBERNETES_CLUSTER_PREFIX}-training-docsVerifique se o job de incorporação de documentos foi concluído:
kubectl get job -n ${DB_NAMESPACE}O resultado será assim:
NAME COMPLETIONS DURATION AGE docs-embedder1716570453361446 1/1 32s 71sTenha o endereço IP externo do balanceador de carga:
export EXTERNAL_IP=$(kubectl -n ${DB_NAMESPACE} get svc chatbot --output jsonpath='{.status.loadBalancer.ingress[0].ip}') echo http://${EXTERNAL_IP}:80Abra o endereço IP externo no navegador da Web:
http://EXTERNAL_IPO chatbot responde com uma mensagem semelhante a esta:
How can I help you?Faça perguntas sobre o conteúdo dos documentos enviados. Se o chatbot não encontrar nada, ele vai responder
I don't know. Por exemplo, você pode perguntar o seguinte:You: Hi, what are Google plans for the future?Um exemplo de saída do chatbot é semelhante ao seguinte:
Bot: Google intends to run on carbon-free energy everywhere, at all times by 2030. To achieve this, it will rely on a combination of renewable energy sources, such as wind and solar, and carbon-free technologies, such as battery storage.Faça uma pergunta ao chatbot que não esteja relacionada ao documento enviado. Por exemplo, pergunte:
You: What are Google plans to colonize Mars?Um exemplo de saída do chatbot é semelhante ao seguinte:
Bot: I don't know. The provided context does not mention anything about Google's plans to colonize Mars.
Sobre o código do aplicativo
Esta seção explica como o código do aplicativo funciona. Há três scripts nas imagens Docker:
endpoint.py: recebe eventos do Eventarc em cada upload de documento e inicia os jobs do Kubernetes para processá-los.embedding-job.py: faz o download de documentos do bucket, cria embeddings e insere embeddings no banco de dados vetorial.chat.py: executa consultas sobre o conteúdo dos documentos armazenados.
O diagrama mostra o processo de geração de respostas usando os dados dos documentos:
No diagrama, o aplicativo carrega um arquivo PDF, o divide em blocos, vetores e, em seguida, envia os vetores para um banco de dados de vetores. Mais tarde, um usuário faz uma pergunta ao chatbot. A cadeia RAG usa a pesquisa semântica para pesquisar o banco de dados de vetores e, em seguida, retorna o contexto com a pergunta para o LLM. O LLM responde à pergunta e a armazena no histórico de chat.
Sobre endpoint.py
Esse arquivo processa mensagens do Eventarc, cria um job do Kubernetes para incorporar o documento e aceita solicitações de qualquer lugar na porta 5001.
Qdrant
Elasticsearch
PGVector
Weaviate
Sobre embedding-job.py
Esse arquivo processa documentos e os envia para o banco de dados vetorial.
Qdrant
Elasticsearch
PGVector
Weaviate
Sobre chat.py
Esse arquivo configura o modelo para responder a perguntas usando apenas o contexto
fornecido e as respostas anteriores. Se o contexto ou o histórico de conversa não
corresponder a nenhum dado, o modelo vai retornar I don't know.
Qdrant
Elasticsearch
PGVector
Weaviate
Limpeza
Para evitar cobranças na sua conta do Google Cloud pelos recursos usados no tutorial, exclua o projeto que os contém ou mantenha o projeto e exclua os recursos individuais.
Exclua o projeto
A maneira mais fácil de evitar o faturamento é excluir o projeto criado para o tutorial.
Excluir um projeto do Google Cloud :
gcloud projects delete PROJECT_ID
Se você tiver excluído o projeto, a limpeza estará completa. Se você não excluiu o projeto, exclua os recursos individuais.
Excluir recursos individuais
Exclua o repositório do Artifact Registry:
gcloud artifacts repositories delete ${KUBERNETES_CLUSTER_PREFIX}-images \ --location=${REGION} \ --asyncQuando solicitado, digite
y.Exclua o bucket do Cloud Storage e o gatilho do Eventarc:
export GOOGLE_OAUTH_ACCESS_TOKEN=$(gcloud auth print-access-token) terraform -chdir=vector-database/terraform/cloud-storage destroy \ -var project_id=${PROJECT_ID} \ -var region=${REGION} \ -var cluster_prefix=${KUBERNETES_CLUSTER_PREFIX} \ -var db_namespace=${DB_NAMESPACE}Quando solicitado, digite
yes.O Eventarc exige que você tenha um destino de endpoint válido durante a criação e a exclusão.
A seguir
- Conheça as práticas recomendadas para implantar bancos de dados no GKE.
- Descubra soluções para executar cargas de trabalho com uso intensivo de dados usando o GKE.