Ce tutoriel vous explique comment intégrer une application de grand modèle de langage (LLM) basée sur la génération augmentée par récupération (RAG) à des fichiers PDF que vous importez dans un bucket Cloud Storage.
Ce guide utilise une base de données comme moteur de stockage et de recherche sémantique qui contient les représentations (embeddings) des documents importés. Vous utilisez le framework Langchain pour interagir avec les embeddings et les modèles Gemini disponibles via Vertex AI.
Langchain est un framework Python Open Source populaire qui simplifie de nombreuses tâches de machine learning et qui dispose d'interfaces permettant de s'intégrer à différentes bases de données vectorielles et services d'IA.
Ce tutoriel est destiné aux administrateurs et architectes de plate-forme cloud, aux ingénieurs en ML et aux professionnels du MLOps (DevOps) qui souhaitent déployer des applications LLM RAG sur GKE et Cloud Storage.
Créer un cluster
Créez un cluster Qdrant, Elasticsearch ou Postgres :
Qdrant
Suivez les instructions de la section Déployer une base de données vectorielle Qdrant sur GKE pour créer un cluster Qdrant s'exécutant sur un cluster GKE en mode Autopilot ou Standard.
Elasticsearch
Suivez les instructions de la section Déployer une base de données vectorielle Elasticsearch sur GKE pour créer un cluster Elasticsearch s'exécutant sur un cluster GKE en mode Autopilot ou Standard.
PGVector
Suivez les instructions de la section Déployer une base de données vectorielle PostgreSQL sur GKE pour créer un cluster Postgres avec PGVector exécuté sur un cluster GKE en mode Autopilot ou Standard.
Weaviate
Suivez les instructions pour déployer une base de données vectorielle Weaviate sur GKE afin de créer un cluster Weaviate s'exécutant sur un cluster GKE en mode Autopilot ou Standard.
Configurer votre environnement
Configurez votre environnement avec Cloud Shell :
Définissez les variables d'environnement pour votre projet :
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
Remplacez
PROJECT_ID
par l'ID de votre projetGoogle 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=elastic
Remplacez
PROJECT_ID
par l'ID de votre projetGoogle 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-ns
Remplacez
PROJECT_ID
par l'ID de votre projetGoogle 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=weaviate
Remplacez
PROJECT_ID
par l'ID de votre projetGoogle Cloud .Vérifier que votre cluster GKE est en cours d'exécution :
gcloud container clusters list --project=${PROJECT_ID} --location=${CONTROL_PLANE_LOCATION}
Le résultat ressemble à ce qui suit :
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
Clonez l'exemple de dépôt de code depuis GitHub :
git clone https://github.com/GoogleCloudPlatform/kubernetes-engine-samples
Accédez au répertoire
databases
:cd kubernetes-engine-samples/databases
Préparer votre infrastructure
Créez un dépôt Artifact Registry, compilez des images Docker et transmettez-les à Artifact Registry :
Créer un dépôt Artifact Registry :
gcloud artifacts repositories create ${KUBERNETES_CLUSTER_PREFIX}-images \ --repository-format=docker \ --location=${REGION} \ --description="Vector database images repository" \ --async
Définissez les autorisations
storage.objectAdmin
etartifactregistry.admin
sur le compte de service Compute Engine pour utiliser Cloud Build afin de compiler et d'envoyer des images Docker pour les servicesembed-docs
etchatbot
.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"
Remplacez
PROJECT_NUMBER
par le numéro de votre projetGoogle Cloud .Compilez des images Docker pour les services
embed-docs
etchatbot
. L'imageembed-docs
contient le code Python de l'application qui reçoit les requêtes de redirection Eventarc et le job d'intégration.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
Vérifiez les images :
gcloud artifacts docker images list $DOCKER_REPO \ --project=$PROJECT_ID \ --format="value(IMAGE)"
Le résultat ressemble à ce qui suit :
$REGION-docker.pkg.dev/$PROJECT_ID/${KUBERNETES_CLUSTER_PREFIX}-images/chatbot $REGION-docker.pkg.dev/$PROJECT_ID/${KUBERNETES_CLUSTER_PREFIX}-images/embed-docs
Déployez un compte de service Kubernetes avec des autorisations pour exécuter des jobs 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 -
Lorsque vous utilisez Terraform pour créer le cluster GKE et que
create_service_account
est défini sur "true", un compte de service distinct est créé et utilisé par le cluster et les nœuds. Attribuez le rôleartifactregistry.serviceAgent
à ce compte de service Compute Engine pour permettre aux nœuds d'extraire l'image du registre Artifact Registry créé pourembed-docs
etchatbot
.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"
Si vous n'accordez pas l'accès au compte de service, vos nœuds peuvent rencontrer des problèmes d'autorisation lorsqu'ils tentent d'extraire l'image d'Artifact Registry lors du déploiement des services
embed-docs
etchatbot
.Déployez un déploiement Kubernetes pour les services
embed-docs
etchatbot
. Un déploiement est un objet de l'API Kubernetes qui vous permet d'exécuter plusieurs instances dupliquées de pods répartis entre les nœuds d'un 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 -
Activez les déclencheurs Eventarc pour GKE :
gcloud eventarc gke-destinations init
Lorsque vous y êtes invité, saisissez
y
.Déployez le bucket Cloud Storage et créez un déclencheur Eventarc à l'aide de 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}
Lorsque vous y êtes invité, saisissez
yes
. L'exécution de la commande peut prendre plusieurs minutes.Terraform crée les ressources suivantes :
- Un bucket Cloud Storage pour importer les documents
- Déclencheur Eventarc
- Un compte de service Google Cloud nommé
service_account_eventarc_name
avec l'autorisation d'utiliser Eventarc. - Un compte de service Google Cloud nommé
service_account_bucket_name
avec l'autorisation de lire le bucket et d'accéder aux modèles Vertex AI.
Le résultat ressemble à ce qui suit :
... # Several lines of output omitted Apply complete! Resources: 15 added, 0 changed, 0 destroyed. ... # Several lines of output omitted
Charger des documents et exécuter des requêtes de chatbot
Importez les documents de démonstration et exécutez des requêtes pour les rechercher à l'aide du chatbot :
Importez l'exemple de document
carbon-free-energy.pdf
dans le bucket :gcloud storage cp vector-database/documents/carbon-free-energy.pdf gs://${PROJECT_ID}-${KUBERNETES_CLUSTER_PREFIX}-training-docs
Vérifiez que le job d'intégration de documents a bien été effectué :
kubectl get job -n ${DB_NAMESPACE}
Le résultat ressemble à ce qui suit :
NAME COMPLETIONS DURATION AGE docs-embedder1716570453361446 1/1 32s 71s
Obtenez l'adresse IP externe de l'équilibreur de charge :
export EXTERNAL_IP=$(kubectl -n ${DB_NAMESPACE} get svc chatbot --output jsonpath='{.status.loadBalancer.ingress[0].ip}') echo http://${EXTERNAL_IP}:80
Ouvrez l'adresse IP externe dans votre navigateur :
http://EXTERNAL_IP
Le chatbot répond par un message semblable à celui-ci :
How can I help you?
Posez des questions sur le contenu des documents importés. Si le chatbot ne trouve rien, il répond
I don't know
. Par exemple, vous pouvez lui poser les questions suivantes :You: Hi, what are Google plans for the future?
Voici un exemple de réponse du chatbot :
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.
Posez au chatbot une question qui n'a aucun rapport avec le document importé. Par exemple, vous pouvez poser les questions suivantes :
You: What are Google plans to colonize Mars?
Voici un exemple de réponse du chatbot :
Bot: I don't know. The provided context does not mention anything about Google's plans to colonize Mars.
À propos du code d'application
Cette section explique le fonctionnement du code. Les images Docker contiennent trois scripts :
endpoint.py
: reçoit les événements Eventarc lors de chaque importation de document et lance les jobs Kubernetes pour les traiter.embedding-job.py
: télécharge les documents depuis le bucket, crée des embeddings et les insère dans la base de données vectorielle.chat.py
: exécute des requêtes sur le contenu des documents stockés.
Le schéma montre le processus de génération de réponses à l'aide des données des documents :
Dans le diagramme, l'application charge un fichier PDF, le divise en blocs, puis en vecteurs, et envoie ensuite les vecteurs à une base de données vectorielle. Plus tard, un utilisateur pose une question au chatbot. La chaîne RAG utilise la recherche sémantique pour rechercher dans la base de données vectorielle, puis renvoie le contexte avec la question au LLM. Le LLM répond à la question et l'enregistre dans l'historique du chat.
À propos de endpoint.py
Ce fichier traite les messages d'Eventarc, crée un job Kubernetes pour intégrer le document et accepte les requêtes depuis n'importe où sur le port 5001.
Qdrant
Elasticsearch
PGVector
Weaviate
À propos de embedding-job.py
Ce fichier traite les documents et les envoie à la base de données vectorielle.
Qdrant
Elasticsearch
PGVector
Weaviate
À propos de chat.py
Ce fichier configure le modèle pour qu'il réponde aux questions en utilisant uniquement le contexte fourni et les réponses précédentes. Si le contexte ou l'historique des conversations ne correspondent à aucune donnée, le modèle renvoie I don't know
.