Este tutorial mostra como integrar uma aplicação de modelo de linguagem grande (LLM) baseada na geração aumentada de obtenção (RAG) com ficheiros PDF que carrega para um contentor do Cloud Storage.
Este guia usa uma base de dados como um motor de pesquisa semântica e de armazenamento que contém as representações (incorporações) dos documentos carregados. Usa a framework Langchain para interagir com as incorporações e usa os modelos do Gemini disponíveis através do Vertex AI.
O Langchain é uma framework Python de código aberto popular que simplifica muitas tarefas de aprendizagem automática e tem interfaces para integração com diferentes bases de dados vetoriais e serviços de IA.
Este tutorial destina-se a administradores e arquitetos da plataforma na nuvem, engenheiros de ML e profissionais de MLOps (DevOps) interessados na implementação de aplicações LLM RAG no GKE e no Cloud Storage.
Crie um cluster
Crie um cluster Qdrant, Elasticsearch ou Postgres:
Qdrant
Siga as instruções no artigo Implemente uma base de dados de vetores Qdrant no GKE para criar um cluster Qdrant em execução num cluster GKE no modo Autopilot ou no modo Standard.
Elasticsearch
Siga as instruções em Implemente uma base de dados vetorial do Elasticsearch no GKE para criar um cluster do Elasticsearch em execução num cluster do GKE no modo Autopilot ou no modo Standard.
PGVector
Siga as instruções em Implemente uma base de dados vetorial PostgreSQL no GKE para criar um cluster Postgres com o PGVector em execução num cluster GKE no modo Autopilot ou no modo Standard.
Weaviate
Siga as instruções para Implementar uma base de dados de vetores do Weaviate no GKE para criar um cluster do Weaviate em execução num cluster do GKE no modo Autopilot ou Standard.
Configure o seu ambiente
Configure o seu ambiente com o Cloud Shell:
Defina as variáveis de ambiente para o seu 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=qdrant
Substitua
PROJECT_ID
pelo ID do seu projeto.Google CloudElasticsearch
export PROJECT_ID=PROJECT_ID export KUBERNETES_CLUSTER_PREFIX=elasticsearch export CONTROL_PLANE_LOCATION=us-central1 export REGION=us-central1 export DB_NAMESPACE=elastic
Substitua
PROJECT_ID
pelo ID do seu projeto.Google CloudPGVector
export PROJECT_ID=PROJECT_ID export KUBERNETES_CLUSTER_PREFIX=postgres export CONTROL_PLANE_LOCATION=us-central1 export REGION=us-central1 export DB_NAMESPACE=pg-ns
Substitua
PROJECT_ID
pelo ID do seu projeto.Google CloudWeaviate
export PROJECT_ID=PROJECT_ID export KUBERNETES_CLUSTER_PREFIX=weaviate export CONTROL_PLANE_LOCATION=us-central1 export REGION=us-central1 export DB_NAMESPACE=weaviate
Substitua
PROJECT_ID
pelo ID do seu projeto.Google CloudVerifique se o cluster do GKE está em execução:
gcloud container clusters list --project=${PROJECT_ID} --location=${CONTROL_PLANE_LOCATION}
O resultado é semelhante ao seguinte:
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 RUNNING
Clone o repositório de código de exemplo do GitHub:
git clone https://github.com/GoogleCloudPlatform/kubernetes-engine-samples
Navegue para o diretório
databases
:cd kubernetes-engine-samples/databases
Prepare a sua infraestrutura
Crie um repositório do Artifact Registry, crie imagens 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" \ --async
Defina as autorizações
storage.objectAdmin
eartifactregistry.admin
na conta de serviço do Compute Engine para usar o Cloud Build para criar e enviar imagens do Docker para os serviçosembed-docs
echatbot
.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_NUMBER
pelo seu Google Cloud número do projeto.Crie imagens Docker para os serviços
embed-docs
echatbot
. Aembed-docs
imagem contém código Python para a aplicação que recebe pedidos do encaminhador do Eventarc e a tarefa de incorporação.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 --async
Elasticsearch
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 --async
PGVector
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 --async
Weaviate
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 --async
Valide as imagens:
gcloud artifacts docker images list $DOCKER_REPO \ --project=$PROJECT_ID \ --format="value(IMAGE)"
O resultado é semelhante ao seguinte:
$REGION-docker.pkg.dev/$PROJECT_ID/${KUBERNETES_CLUSTER_PREFIX}-images/chatbot $REGION-docker.pkg.dev/$PROJECT_ID/${KUBERNETES_CLUSTER_PREFIX}-images/embed-docs
Implemente uma conta de serviço do Kubernetes com autorizações para executar tarefas 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 -
Quando usa o Terraform para criar o cluster do GKE e tem
create_service_account
definido como verdadeiro, é criada uma conta de serviço separada e usada pelo cluster e pelos nós. Conceda a funçãoartifactregistry.serviceAgent
a esta conta de serviço do Compute Engine para permitir que os nós extraiam a imagem do Artifact Registry criada paraembed-docs
echatbot
.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"
Se não conceder acesso à conta de serviço, os seus nós podem ter um problema de autorização ao tentar obter a imagem do Artifact Registry quando implementar os serviços
embed-docs
echatbot
.Implemente uma implementação do Kubernetes para os serviços
embed-docs
echatbot
. Uma implementação é um objeto da API Kubernetes que lhe permite executar várias réplicas de pods distribuídos entre os nós num 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 acionadores do Eventarc para o GKE:
gcloud eventarc gke-destinations init
Quando lhe for pedido, introduza
y
.Implemente o contentor do Cloud Storage e crie um acionador do Eventarc com 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 lhe for pedido, escreva
yes
. O comando pode demorar alguns minutos a ser concluído.O Terraform cria os seguintes recursos:
- Um contentor do Cloud Storage para carregar os documentos
- Um acionador do Eventarc
- Uma Google Cloud conta de serviço denominada
service_account_eventarc_name
com autorização para usar o Eventarc. - Uma Google Cloud conta de serviço denominada
service_account_bucket_name
com autorização para ler o contentor e aceder aos modelos do Vertex AI.
O resultado é semelhante ao seguinte:
... # Several lines of output omitted Apply complete! Resources: 15 added, 0 changed, 0 destroyed. ... # Several lines of output omitted
Carregue documentos e execute consultas de chatbot
Carregue os documentos de demonstração e execute consultas para pesquisar nos documentos de demonstração usando o chatbot:
Carregue o documento de exemplo
carbon-free-energy.pdf
para o seu contentor:gcloud storage cp vector-database/documents/carbon-free-energy.pdf gs://${PROJECT_ID}-${KUBERNETES_CLUSTER_PREFIX}-training-docs
Verifique se a tarefa do incorporador de documentos foi concluída com êxito:
kubectl get job -n ${DB_NAMESPACE}
O resultado é semelhante ao seguinte:
NAME COMPLETIONS DURATION AGE docs-embedder1716570453361446 1/1 32s 71s
Obtenha 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}:80
Abra o endereço IP externo no navegador de Internet:
http://EXTERNAL_IP
O chatbot responde com uma mensagem semelhante à seguinte:
How can I help you?
Fazer perguntas sobre o conteúdo dos documentos carregados. Se o chatbot não conseguir encontrar nada, responde
I don't know
. Por exemplo, pode fazer as seguintes perguntas: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.
Fazer uma pergunta ao bot de chat que não esteja relacionada com o documento carregado. Por exemplo, pode fazer as seguintes perguntas:
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.
Acerca do código da aplicação
Esta secção explica como funciona o código da aplicação. Existem três scripts nas imagens do Docker:
endpoint.py
: recebe eventos do Eventarc em cada carregamento de documentos e inicia as tarefas do Kubernetes para os processar.embedding-job.py
: transfere documentos do contentor, cria incorporações e insere incorporações na base de dados vetorial.chat.py
: executa consultas sobre o conteúdo de documentos armazenados.
O diagrama mostra o processo de geração de respostas com os dados dos documentos:
No diagrama, a aplicação carrega um ficheiro PDF, divide-o em partes e, em seguida, em vetores. Depois, envia os vetores para uma base de dados de vetores. Mais tarde, um utilizador faz uma pergunta ao chatbot. A cadeia RAG usa a pesquisa semântica para pesquisar a base de dados de vetores e, em seguida, devolve o contexto juntamente com a pergunta ao MDG. O MDG responde à pergunta e armazena-a no histórico do chat.
Acerca de endpoint.py
Este ficheiro processa mensagens do Eventarc, cria um Kubernetes Job para incorporar o documento e aceita pedidos de qualquer lugar na porta 5001
Qdrant
Elasticsearch
PGVector
Weaviate
Acerca de embedding-job.py
Este ficheiro processa documentos e envia-os para a base de dados vetorial.
Qdrant
Elasticsearch
PGVector
Weaviate
Acerca de chat.py
Este ficheiro configura o modelo para responder a perguntas usando apenas o contexto fornecido e as respostas anteriores. Se o contexto ou o histórico de conversas não corresponderem a nenhum dado, o modelo devolve I don't know
.