Usar Vertex AI Search en PDF (datos no estructurados) en Cloud Storage desde un servicio de Cloud Run

1. Introducción

Descripción general

Vertex AI Search and Conversation (antes conocido como Generative AI App Builder) permite a los desarrolladores aprovechar el poder de los modelos de base, la experiencia de búsqueda y las tecnologías de IA conversacional de Google para crear aplicaciones de IA generativa de nivel empresarial. Este codelab se enfoca en el uso de Vertex AI Search, con el que puedes compilar una app de búsqueda con calidad de Google con tus propios datos y, además, incorporar una barra de búsqueda en tus páginas web o apps.

Cloud Run es una plataforma de procesamiento administrada que te permite ejecutar contenedores directamente sobre la infraestructura escalable de Google. Puedes implementar código escrito en cualquier lenguaje de programación de Cloud Run (que se pueda colocar dentro de un contenedor) con la opción de implementación basada en el código fuente.

En este codelab, crearás un servicio de Cloud Run mediante la implementación basada en código fuente para recuperar resultados de la búsqueda de contenido no estructurado en archivos PDF en un bucket de Cloud Storage. Obtén más información para transferir contenido no estructurado aquí.

Qué aprenderás

  • Cómo crear una app de Vertex AI Search para datos no estructurados como PDFs transferidos desde un bucket de Cloud Storage
  • Cómo crear un extremo HTTP con una implementación basada en el código fuente en Cloud Run
  • Cómo crear una cuenta de servicio según el principio de privilegio mínimo para que el servicio de Cloud Run use con el objetivo de realizar consultas en la app de Vertex AI Search
  • Cómo invocar el servicio de Cloud Run para realizar consultas en la app de Vertex AI Search

2. Configuración y requisitos

Requisitos previos

Activar Cloud Shell

  1. En la consola de Cloud, haz clic en Activar Cloud Shelld1264ca30785e435.png.

cb81e7c8e34bc8d.png

Si es la primera vez que inicias Cloud Shell, verás una pantalla intermedia que describe en qué consiste. Si apareció una pantalla intermedia, haz clic en Continuar.

d95252b003979716.png

El aprovisionamiento y la conexión a Cloud Shell solo tomará unos minutos.

7833d5e1c5d18f54.png

Esta máquina virtual está cargada con todas las herramientas de desarrollo necesarias. Ofrece un directorio principal persistente de 5 GB y se ejecuta en Google Cloud, lo que mejora considerablemente el rendimiento de la red y la autenticación. Gran parte de tu trabajo en este codelab, si no todo, se puede hacer con un navegador.

Una vez que te conectes a Cloud Shell, deberías ver que estás autenticado y que el proyecto está configurado con tu ID del proyecto.

  1. En Cloud Shell, ejecuta el siguiente comando para confirmar que tienes la autenticación:
gcloud auth list

Resultado del comando

 Credentialed Accounts
ACTIVE  ACCOUNT
*       <my_account>@<my_domain.com>

To set the active account, run:
    $ gcloud config set account `ACCOUNT`
  1. Ejecuta el siguiente comando en Cloud Shell para confirmar que el comando de gcloud conoce tu proyecto:
gcloud config list project

Resultado del comando

[core]
project = <PROJECT_ID>

De lo contrario, puedes configurarlo con el siguiente comando:

gcloud config set project <PROJECT_ID>

Resultado del comando

Updated property [core/project].

3. Habilita las APIs

Antes de que puedas comenzar a usar Vertex AI Search, hay varias APIs que deberás habilitar.

En primer lugar, este codelab requiere el uso de las APIs de Vertex AI Search and Conversation, BigQuery y Cloud Storage. Puedes habilitar esas APIs aquí.

Luego, sigue estos pasos para habilitar la API de Vertex AI Search and Conversation:

  1. En la consola de Google Cloud, navega a la consola de Vertex AI Search and Conversation.
  2. Lee y acepta las Condiciones del Servicio y, luego, haz clic en Continuar y activa la API.

4. Crea una app de búsqueda para datos no estructurados de Cloud Storage

  1. En la consola de Google Cloud, dirígete a Buscar y Página de la conversación Haz clic en Nueva aplicación.
  2. En el panel Selecciona el tipo de app, selecciona Búsqueda.
  3. Asegúrate de que las funciones empresariales estén habilitadas para recibir respuestas extraídas de tus documentos al pie de la letra.
  4. Asegúrate de que la opción Funciones avanzadas de LLM esté habilitada para recibir un resumen de la búsqueda.
  5. En el campo Nombre de la aplicación, ingresa un nombre para tu aplicación. El ID de tu app aparece debajo del nombre de la app.
  6. Selecciona global (Global) como la ubicación de tu app y, luego, haz clic en Continuar.
  7. En el panel Almacenes de datos, haz clic en Crear almacén de datos nuevo.
  8. En el panel Selecciona una fuente de datos, elige Cloud Storage.
  9. En el panel Importar datos de GCS (Import data from GCS), asegúrate de que la opción Carpeta esté seleccionada.
  10. En el campo gs://, ingresa el siguiente valor: cloud-samples-data/gen-app-builder/search/stanford-cs-224. Este bucket de Cloud Storage contiene archivos PDF de una carpeta de Cloud Storage disponible de forma pública para realizar pruebas.
  11. Selecciona Documentos no estructurados y, luego, haz clic en Continuar.
  12. En el panel Configura tu almacén de datos, selecciona global (Global) como la ubicación de tu almacén de datos.
  13. Ingresa un nombre para tu almacén de datos. Usarás este nombre más adelante en este codelab cuando implementes tu servicio de Cloud Run. Haz clic en Crear.
  14. En el panel Almacenes de datos, selecciona tu nuevo almacén de datos y haz clic en Crear.
  15. En la página Datos del almacén de datos, haz clic en la pestaña Actividad para ver el estado de la transferencia de datos. Se mostrará el mensaje Importación completada en la columna Estado cuando finalice el proceso de importación.
  16. Haz clic en la pestaña Documentos para ver la cantidad de documentos importados.
  17. En el menú de navegación, haz clic en Vista previa para probar la app de búsqueda.
  18. En la barra de búsqueda, ingresa final lab due date y, luego, presiona Intro para ver los resultados.

5. Crea el servicio de Cloud Run

En esta sección, crearás un servicio de Cloud Run que acepte una cadena de consulta para tus términos de búsqueda. Este servicio usará las bibliotecas cliente de Python para la API de Discovery Engine. Para ver otros entornos de ejecución compatibles, puedes consultar la lista aquí.

Crea el código fuente para la función

Primero, crea un directorio y desplázate a él con el comando cd.

mkdir docs-search-service-python && cd $_

Luego, crea un archivo requirements.txt con el siguiente contenido:

blinker==1.6.3
cachetools==5.3.1
certifi==2023.7.22
charset-normalizer==3.3.0
click==8.1.7
Flask==3.0.0
google-api-core==2.12.0
google-auth==2.23.3
google-cloud-discoveryengine==0.11.2
googleapis-common-protos==1.61.0
grpcio==1.59.0
grpcio-status==1.59.0
idna==3.4
importlib-metadata==6.8.0
itsdangerous==2.1.2
Jinja2==3.1.2
MarkupSafe==2.1.3
numpy==1.26.1
proto-plus==1.22.3
protobuf==4.24.4
pyasn1==0.5.0
pyasn1-modules==0.3.0
requests==2.31.0
rsa==4.9
urllib3==2.0.7
Werkzeug==3.0.1
zipp==3.17.0

A continuación, crea un archivo fuente main.py con el siguiente contenido:

from typing import List
import json
import os
from flask import Flask
from flask import request

app = Flask(__name__)

from google.api_core.client_options import ClientOptions
from google.cloud import discoveryengine_v1 as discoveryengine

project_id = os.environ.get('PROJECT_ID')
location = "global"  # Values: "global", "us", "eu"
data_store_id = os.environ.get('SEARCH_ENGINE_ID')

print(project_id)
print(data_store_id)

@app.route("/")
def search_storage():

    search_query = request.args.get("searchQuery")

    result = search_sample(project_id, location, data_store_id, search_query)
    return result

def search_sample(
    project_id: str,
    location: str,
    data_store_id: str,
    search_query: str,
) -> str:
    #  For more information, refer to:
    # https://cloud.google.com/generative-ai-app-builder/docs/locations#specify_a_multi-region_for_your_data_store
    client_options = (
        ClientOptions(api_endpoint=f"{location}-discoveryengine.googleapis.com")
        if location != "global"
        else None
    )

    # Create a client
    client = discoveryengine.SearchServiceClient(client_options=client_options)

    # The full resource name of the search engine serving config
    # e.g. projects/{project_id}/locations/{location}/dataStores/{data_store_id}/servingConfigs/{serving_config_id}
    serving_config = client.serving_config_path(
        project=project_id,
        location=location,
        data_store=data_store_id,
        serving_config="default_config",
    )

    # Optional: Configuration options for search
    # Refer to the `ContentSearchSpec` reference for all supported fields:
    # https://cloud.google.com/python/docs/reference/discoveryengine/latest/google.cloud.discoveryengine_v1.types.SearchRequest.ContentSearchSpec
    content_search_spec = discoveryengine.SearchRequest.ContentSearchSpec(
        # For information about snippets, refer to:
        # https://cloud.google.com/generative-ai-app-builder/docs/snippets
        snippet_spec=discoveryengine.SearchRequest.ContentSearchSpec.SnippetSpec(
            return_snippet=True
        ),
        # For information about search summaries, refer to:
        # https://cloud.google.com/generative-ai-app-builder/docs/get-search-summaries
        summary_spec=discoveryengine.SearchRequest.ContentSearchSpec.SummarySpec(
            summary_result_count=5,
            include_citations=True,
            ignore_adversarial_query=True,
            ignore_non_summary_seeking_query=True,
        ),
    )


    # Refer to the `SearchRequest` reference for all supported fields:
    # https://cloud.google.com/python/docs/reference/discoveryengine/latest/google.cloud.discoveryengine_v1.types.SearchRequest
    request = discoveryengine.SearchRequest(
        serving_config=serving_config,
        query=search_query,
        page_size=10,
        content_search_spec=content_search_spec,
        query_expansion_spec=discoveryengine.SearchRequest.QueryExpansionSpec(
            condition=discoveryengine.SearchRequest.QueryExpansionSpec.Condition.AUTO,
        ),
        spell_correction_spec=discoveryengine.SearchRequest.SpellCorrectionSpec(
            mode=discoveryengine.SearchRequest.SpellCorrectionSpec.Mode.AUTO
        ),
    )

    response = client.search(request)

    return response.summary.summary_text

if __name__ == "__main__":
    app.run(debug=True, host="0.0.0.0", port=int(os.environ.get("PORT", 8080)))

Configura variables de entorno

En este código, crearás algunas variables de entorno para mejorar la legibilidad de los comandos gcloud que se usan en este codelab.

PROJECT_ID=$(gcloud config get-value project)

SERVICE_NAME="search-storage-pdfs-python"
SERVICE_REGION="us-central1"

# update with your data store name
SEARCH_ENGINE_ID=<your-data-store-name>

Crea una cuenta de servicio

En este codelab, se muestra cómo crear una cuenta de servicio para que el servicio de Cloud Run acceda a la API de Vertex AI Search.

SERVICE_ACCOUNT="cloud-run-vertex-ai-search"
SERVICE_ACCOUNT_ADDRESS=$SERVICE_ACCOUNT@$PROJECT_ID.iam.gserviceaccount.com

gcloud iam service-accounts create $SERVICE_ACCOUNT \
  --display-name="Cloud Run Vertex AI Search service account"

gcloud projects add-iam-policy-binding $PROJECT_ID \
  --member serviceAccount:$SERVICE_ACCOUNT_ADDRESS \
  --role='roles/discoveryengine.editor'

Implementa el servicio de Cloud Run

Ahora puedes usar una implementación basada en el código fuente para crear contenedores automáticamente para tu servicio de Cloud Run.

gcloud run deploy $SERVICE_NAME \
--region=$SERVICE_REGION \
--source=. \
--service-account $SERVICE_ACCOUNT \
--update-env-vars SEARCH_ENGINE_ID=$SEARCH_ENGINE_ID,PROJECT_ID=$PROJECT_ID \
--no-allow-unauthenticated

Luego, puedes guardar la URL de Cloud Run como una variable de entorno para usarla más tarde.

ENDPOINT_URL="$(gcloud run services describe $SERVICE_NAME --region=$SERVICE_REGION --format='value(status.url)')"

6. Llama al servicio de Cloud Run

Ahora puedes llamar a tu servicio de Cloud Run con una cadena de consulta para preguntarle a What is the final lab due date?.

curl -H "Authorization: bearer $(gcloud auth print-identity-token)" "$ENDPOINT_URL?searchQuery=what+is+the+final+lab+due+date"

Tus resultados deberían ser similares al resultado de ejemplo a continuación:

The final lab is due on Tuesday, March 21 at 4:30 PM [1].

7. ¡Felicitaciones!

¡Felicitaciones por completar el codelab!

Te recomendamos que revises la documentación sobre Vertex AI Search y Cloud Run.

Temas abordados

  • Cómo crear una app de Vertex AI Search para datos no estructurados como PDFs transferidos desde un bucket de Cloud Storage
  • Cómo crear un extremo HTTP con una implementación basada en el código fuente en Cloud Run
  • Cómo crear una cuenta de servicio según el principio de privilegio mínimo que debe usar el servicio de Cloud Run para realizar consultas en la app de Vertex AI Search.
  • Cómo invocar el servicio de Cloud Run para realizar consultas en la app de Vertex AI Search

8. Limpia

Para evitar cargos involuntarios (por ejemplo, si esta Cloud Function se invoca de forma involuntaria más veces que tu asignación mensual de invocación de Cloud Function en el nivel gratuito), puedes borrar la Cloud Function o borrar el proyecto que creaste en el paso 2.

Para borrar la Cloud Function, ve a la consola de Cloud Function en https://console.cloud.google.com/functions/ y borra la función imagen_vqa (o $FUNCTION_NAME si usaste otro nombre).

Si decides borrar el proyecto completo, puedes ir a https://console.cloud.google.com/cloud-resource-manager, seleccionar el proyecto que creaste en el paso 2 y elegir Borrar. Si borras el proyecto, deberás cambiar los proyectos en tu SDK de Cloud. Para ver la lista de todos los proyectos disponibles, ejecuta gcloud projects list.