En este instructivo, se muestra cómo integrar una aplicación de modelo de lenguaje grande (LLM) basada en la generación mejorada por recuperación (RAG) con archivos PDF que subes a un bucket de Cloud Storage.
En esta guía, se usa una base de datos como un motor de búsqueda semántica y de almacenamiento que contiene las representaciones (incorporaciones) de los documentos subidos. Usas el framework de Langchain para interactuar con las incorporaciones y usas los modelos de Gemini disponibles a través de Vertex AI.
LangChain es un framework de Python de código abierto popular que simplifica muchas tareas de aprendizaje automático y tiene interfaces para integrarse con diferentes bases de datos de vectores y servicios de IA.
Este instructivo está dirigido a administradores y arquitectos de plataformas de nube, ingenieros de AA y profesionales de MLOps (DevOps) interesados en implementar aplicaciones de LLM de RAG en GKE y Cloud Storage.
Objetivos
En este instructivo, aprenderás a realizar lo siguiente:
- Compila y, luego, implementa una aplicación para crear y almacenar incorporaciones de documentos en una base de datos de vectores.
- Automatizar la aplicación para activar cargas de documentos nuevos a un bucket de Cloud Storage
- Implementar una aplicación de chatbot que use la búsqueda semántica para responder preguntas según el contenido del documento
Arquitectura de implementación
En este instructivo, crearás un bucket de Cloud Storage, un activador de Eventarc y los siguientes servicios:
embed-docs
: Eventarc activa este servicio cada vez que un usuario carga un documento nuevo al bucket de Cloud Storage. El servicio inicia un trabajo de Kubernetes que crea incorporaciones para el documento subido y las inserta en una base de datos vectorial.chatbot
: Este servicio responde preguntas en lenguaje natural sobre los documentos subidos con la búsqueda semántica y la API de Gemini.
En el siguiente diagrama, se muestra el proceso de carga y vectorización de documentos:
En el diagrama, el usuario sube archivos al bucket de Cloud Storage.
Eventarc se suscribe a los eventos metadataUpdated
del objeto para el bucket y usa el servidor de reenvío de eventos de Eventarc, que es una carga de trabajo de Kubernetes, para llamar al servicio embed-docs
cuando subes un documento nuevo. Luego, el servicio crea incorporaciones para el documento subido. El servicio embed-docs
almacena las incorporaciones en una base de datos de vectores con el modelo de incorporación de Vertex AI.
En el siguiente diagrama, se muestra el proceso de hacer preguntas sobre el contenido del documento subido con el servicio chatbot
:
Los usuarios pueden hacer preguntas con lenguaje natural, y el chatbot genera respuestas solo en función del contenido de los archivos subidos. El chatbot recupera el contexto de la base de datos de vectores con la búsqueda semántica y, luego, envía la pregunta y el contexto a Gemini.
Costos
En este documento, usarás los siguientes componentes facturables de Google Cloud:
Para generar una estimación de costos en función del uso previsto, usa la calculadora de precios.
Cuando finalices las tareas que se describen en este documento, puedes borrar los recursos que creaste para evitar que continúe la facturación. Para obtener más información, consulta Cómo realizar una limpieza.
Antes de comenzar
En este instructivo, usarás Cloud Shell para ejecutar comandos. Cloud Shell es un entorno de shell que se usa para administrar recursos alojados en Google Cloud. Cloud Shell ya viene instalado en las herramientas de línea de comandos de Google Cloud CLI, kubectl y Terraform. Si no usas Cloud Shell, instala Google Cloud CLI.
- Sign in to your Google Cloud account. If you're new to Google Cloud, create an account to evaluate how our products perform in real-world scenarios. New customers also get $300 in free credits to run, test, and deploy workloads.
- Install the Google Cloud CLI.
-
To initialize the gcloud CLI, run the following command:
gcloud init
-
Create or select a Google Cloud project.
-
Create a Google Cloud project:
gcloud projects create PROJECT_ID
Replace
PROJECT_ID
with a name for the Google Cloud project you are creating. -
Select the Google Cloud project that you created:
gcloud config set project PROJECT_ID
Replace
PROJECT_ID
with your Google Cloud project name.
-
-
Make sure that billing is enabled for your Google Cloud project.
-
Enable the Vertex AI, Cloud Build, Eventarc, Artifact Registry APIs:
gcloud services enable aiplatform.googleapis.com
cloudbuild.googleapis.com eventarc.googleapis.com artifactregistry.googleapis.com - Install the Google Cloud CLI.
-
To initialize the gcloud CLI, run the following command:
gcloud init
-
Create or select a Google Cloud project.
-
Create a Google Cloud project:
gcloud projects create PROJECT_ID
Replace
PROJECT_ID
with a name for the Google Cloud project you are creating. -
Select the Google Cloud project that you created:
gcloud config set project PROJECT_ID
Replace
PROJECT_ID
with your Google Cloud project name.
-
-
Make sure that billing is enabled for your Google Cloud project.
-
Enable the Vertex AI, Cloud Build, Eventarc, Artifact Registry APIs:
gcloud services enable aiplatform.googleapis.com
cloudbuild.googleapis.com eventarc.googleapis.com artifactregistry.googleapis.com -
Grant roles to your user account. Run the following command once for each of the following IAM roles:
eventarc.admin
gcloud projects add-iam-policy-binding PROJECT_ID --member="user:USER_IDENTIFIER" --role=ROLE
- Replace
PROJECT_ID
with your project ID. -
Replace
USER_IDENTIFIER
with the identifier for your user account. For example,user:myemail@example.com
. - Replace
ROLE
with each individual role.
- Replace
Crea un clúster
Crea un clúster de Qdrant, Elasticsearch o Postgres:
Qdrant
Sigue las instrucciones que se indican en Implementa una base de datos vectorial de Qdrant en GKE para crear un clúster de Qdrant que se ejecute en un clúster de GKE en modo Autopilot o en modo estándar.
Elasticsearch
Sigue las instrucciones de Implementa una base de datos vectorial de Elasticsearch en GKE para crear un clúster de Elasticsearch que se ejecute en un clúster de GKE en modo Autopilot o Standard.
PGVector
Sigue las instrucciones de Implementa una base de datos vectorial de PostgreSQL en GKE para crear un clúster de Postgres con PGVector ejecutándose en un clúster de GKE en modo Autopilot o Standard.
Weaviate
Sigue las instrucciones para implementar una base de datos vectorial de Weaviate en GKE y crear un clúster de Weaviate que se ejecute en un clúster de GKE en modo Autopilot o Standard.
Configure su entorno
Configura tu entorno con Cloud Shell:
Configura las variables de entorno de tu proyecto:
Qdrant
export PROJECT_ID=PROJECT_ID export KUBERNETES_CLUSTER_PREFIX=qdrant export REGION=us-central1 export DB_NAMESPACE=qdrant
Reemplaza
PROJECT_ID
por el ID de tu proyecto de Google Cloud .Elasticsearch
export PROJECT_ID=PROJECT_ID export KUBERNETES_CLUSTER_PREFIX=elasticsearch export REGION=us-central1 export DB_NAMESPACE=elastic
Reemplaza
PROJECT_ID
por el ID de tu proyecto de Google Cloud .PGVector
export PROJECT_ID=PROJECT_ID export KUBERNETES_CLUSTER_PREFIX=postgres export REGION=us-central1 export DB_NAMESPACE=pg-ns
Reemplaza
PROJECT_ID
por el ID de tu proyecto de Google Cloud .Weaviate
export PROJECT_ID=PROJECT_ID export KUBERNETES_CLUSTER_PREFIX=weaviate export REGION=us-central1 export DB_NAMESPACE=weaviate
Reemplaza
PROJECT_ID
por el ID de tu proyecto de Google Cloud .Verifica que el clúster de GKE esté en ejecución:
gcloud container clusters list --project=${PROJECT_ID} --region=${REGION}
El resultado es similar a este:
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
Clona el repositorio de código de muestra de GitHub:
git clone https://github.com/GoogleCloudPlatform/kubernetes-engine-samples
Navega al directorio
databases
:cd kubernetes-engine-samples/databases
Prepara tu infraestructura
Crea un repositorio de Artifact Registry, compila imágenes de Docker y envíalas a Artifact Registry:
Crea un repositorio de Artifact Registry:
gcloud artifacts repositories create ${KUBERNETES_CLUSTER_PREFIX}-images \ --repository-format=docker \ --location=${REGION} \ --description="Vector database images repository" \ --async
Establece los permisos
storage.objectAdmin
yartifactregistry.admin
en la cuenta de servicio de Compute Engine para usar Cloud Build y compilar y enviar imágenes de Docker para los servicios deembed-docs
ychatbot
.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"
Reemplaza
PROJECT_NUMBER
por el número de proyecto de Google Cloud .Compila imágenes de Docker para los servicios de
embed-docs
ychatbot
. La imagenembed-docs
contiene código Python para la aplicación que recibe las solicitudes del reenviador de Eventarc y el trabajo de incorporación.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
Verifica las imágenes:
gcloud artifacts docker images list $DOCKER_REPO \ --project=$PROJECT_ID \ --format="value(IMAGE)"
El resultado es similar a este:
$REGION-docker.pkg.dev/$PROJECT_ID/${KUBERNETES_CLUSTER_PREFIX}-images/chatbot $REGION-docker.pkg.dev/$PROJECT_ID/${KUBERNETES_CLUSTER_PREFIX}-images/embed-docs
Implementa una cuenta de servicio de Kubernetes con permisos para ejecutar trabajos de 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 -
Cuando usas Terraform para crear el clúster de GKE y tienes
create_service_account
configurado como verdadero, el clúster y los nodos crean y usan una cuenta de servicio independiente. Otorga el rolartifactregistry.serviceAgent
a esta cuenta de servicio de Compute Engine para permitir que los nodos extraigan imágenes del Artifact Registry creado paraembed-docs
ychatbot
.export CLUSTER_SERVICE_ACCOUNT=$(gcloud container clusters describe ${KUBERNETES_CLUSTER_PREFIX}-cluster \ --region=${REGION} \ --format="value(nodeConfig.serviceAccount)") gcloud projects add-iam-policy-binding ${PROJECT_ID} \ --member="serviceAccount:${CLUSTER_SERVICE_ACCOUNT}" \ --role="roles/artifactregistry.serviceAgent"
Si no otorgas acceso a la cuenta de servicio, es posible que tus nodos tengan problemas de permiso cuando intenten extraer imágenes de Artifact Registry cuando implementes los servicios
embed-docs
ychatbot
.Implementa una implementación de Kubernetes para los servicios
embed-docs
ychatbot
. Un Deployment es un objeto de la API de Kubernetes que te permite ejecutar varias réplicas de Pods que se distribuyen entre los nodos de un clúster: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 -
Habilita los activadores de Eventarc para GKE:
gcloud eventarc gke-destinations init
Cuando se te solicite, ingresa
y
.Implementa el bucket de Cloud Storage y crea un activador de Eventarc con 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}
Cuando se te solicite, escribe
yes
. Es posible que el comando tarde varios minutos en completarse.Terraform crea los siguientes recursos:
- Un bucket de Cloud Storage para subir los documentos
- Un activador de Eventarc
- Una cuenta de servicio de Google Cloud denominada
service_account_eventarc_name
con permiso para usar Eventarc - Una cuenta de servicio de Google Cloud denominada
service_account_bucket_name
con permiso para leer el bucket y acceder a los modelos de Vertex AI.
El resultado es similar a este:
... # Several lines of output omitted Apply complete! Resources: 15 added, 0 changed, 0 destroyed. ... # Several lines of output omitted
Carga documentos y ejecuta consultas de chatbot
Sube los documentos de demostración y ejecuta consultas para buscar en ellos con el chatbot:
Sube el documento
carbon-free-energy.pdf
de ejemplo a tu bucket:gsutil cp vector-database/documents/carbon-free-energy.pdf gs://${PROJECT_ID}-${KUBERNETES_CLUSTER_PREFIX}-training-docs
Verifica que el trabajo del incorporador de documentos se haya completado correctamente:
kubectl get job -n ${DB_NAMESPACE}
El resultado es similar a este:
NAME COMPLETIONS DURATION AGE docs-embedder1716570453361446 1/1 32s 71s
Obtén la dirección IP externa del balanceador de cargas:
export EXTERNAL_IP=$(kubectl -n ${DB_NAMESPACE} get svc chatbot --output jsonpath='{.status.loadBalancer.ingress[0].ip}') echo http://${EXTERNAL_IP}:80
Abre la dirección IP externa en tu navegador web:
http://EXTERNAL_IP
El chatbot responde con un mensaje similar al siguiente:
How can I help you?
Haz preguntas sobre el contenido de los documentos subidos. Si el chatbot no puede encontrar nada, responde
I don't know
. Por ejemplo, puedes preguntar lo siguiente:You: Hi, what are Google plans for the future?
Un ejemplo de resultado del chatbot es similar al siguiente:
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.
Hazle al chatbot una pregunta que no esté relacionada con el contexto del documento subido. Por ejemplo, podrías preguntar lo siguiente:
You: What are Google plans to colonize Mars?
Un ejemplo de resultado del chatbot es similar al siguiente:
Bot: I don't know. The provided context does not mention anything about Google's plans to colonize Mars.
Información acerca del código de la aplicación
En esta sección, se explica cómo funciona el código de la aplicación. Hay tres secuencias de comandos dentro de las imágenes de Docker:
endpoint.py
: Recibe eventos de Eventarc en cada carga de documentos y, luego, inicia los trabajos de Kubernetes para procesarlos.embedding-job.py
: Descarga documentos del bucket, crea incorporaciones y las inserta en la base de datos de vectores.chat.py
: Ejecuta consultas sobre el contenido de los documentos almacenados.
En el diagrama, se muestra el proceso de generación de respuestas con los datos de los documentos:
En el diagrama, la aplicación carga un archivo PDF, lo divide en fragmentos, luego en vectores y, luego, envía los vectores a una base de datos de vectores. Más tarde, un usuario le hace una pregunta al chatbot. La cadena de RAG usa la búsqueda semántica para buscar en la base de datos de vectores y, luego, muestra el contexto junto con la pregunta al LLM. El LLM responde la pregunta y la almacena en el historial de chat.
Acerca de endpoint.py
Este archivo procesa los mensajes de Eventarc, crea un trabajo de Kubernetes para incorporar el documento y acepta solicitudes desde cualquier lugar en el puerto 5001.
Qdrant
Elasticsearch
PGVector
Weaviate
Acerca de embedding-job.py
Este archivo procesa los documentos y los envía a la base de datos de vectores.
Qdrant
Elasticsearch
PGVector
Weaviate
Acerca de chat.py
Este archivo configura el modelo para responder preguntas usando solo el contexto proporcionado y las respuestas anteriores. Si el contexto o el historial de conversaciones no coinciden con ningún dato, el modelo muestra I don't know
.
Qdrant
Elasticsearch
PGVector
Weaviate
Limpia
Para evitar que se apliquen cargos a tu cuenta de Google Cloud por los recursos usados en este instructivo, borra el proyecto que contiene los recursos o conserva el proyecto y borra los recursos individuales.
Borra el proyecto
La manera más fácil de evitar la facturación es borrar el proyecto que creaste para el instructivo.
Delete a Google Cloud project:
gcloud projects delete PROJECT_ID
Si borraste el proyecto, tu limpieza se completó. Si no borraste el proyecto, borra los recursos individuales.
Borra los recursos individuales
Borra el repositorio de Artifact Registry:
gcloud artifacts repositories delete ${KUBERNETES_CLUSTER_PREFIX}-images \ --location=${REGION} \ --async
Cuando se te solicite, escribe
y
.Borra el bucket de Cloud Storage y el activador de 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}
Cuando se te solicite, escribe
yes
.Eventarc requiere que tengas un destino de extremo válido durante la creación y la eliminación.
¿Qué sigue?
- Conoce las prácticas recomendadas para implementar bases de datos en GKE.
- Descubre soluciones para ejecutar cargas de trabajo con uso intensivo de datos con GKE.