1. Descripción general
Las aplicaciones de IA generativa requieren observabilidad como cualquier otra. ¿Se requieren técnicas de observabilidad especiales para la IA generativa?
En este lab, crearás una aplicación de IA generativa simple. Implementarlo en Cloud Run Además, instálalo con funciones de registro y supervisión esenciales mediante los productos y servicios de observabilidad de Google Cloud.
Qué aprenderás
- Escribe una aplicación que use Vertex AI con el editor de Cloud Shell
- Almacena el código de tu aplicación en GitHub
- Usa gcloud CLI para implementar el código fuente de tu aplicación en Cloud Run
- Agrega capacidades de supervisión y registro a tu aplicación de IA generativa
- Usa métricas basadas en registros
- Implementa el registro y la supervisión con el SDK de Open Telemetry
- Obtén estadísticas sobre el manejo de datos de IA responsable
2. Requisitos previos
Si aún no tienes una Cuenta de Google, debes crear una nueva.
3. Configura el proyecto
- Accede a la consola de Google Cloud con tu Cuenta de Google.
- Crea un proyecto nuevo o elige reutilizar uno existente. Anota el ID del proyecto que acabas de crear o seleccionar.
- Habilita la facturación para el proyecto.
- Completar este lab debería costar menos de USD 5 en costos de facturación.
- Puedes seguir los pasos que se indican al final de este lab para borrar recursos y evitar cargos adicionales.
- Los usuarios nuevos son aptos para la prueba gratuita de USD 300.
- Confirma que la facturación esté habilitada en Mis proyectos en Facturación de Cloud
- Si tu proyecto nuevo dice
Billing is disabled
en la columnaBilling account
, haz lo siguiente:- Haz clic en los tres puntos de la columna
Actions
. - Haz clic en Cambiar la facturación.
- Selecciona la cuenta de facturación que quieres usar.
- Haz clic en los tres puntos de la columna
- Si asistes a un evento en vivo, es probable que la cuenta se llame Cuenta de facturación de prueba de Google Cloud Platform.
- Si tu proyecto nuevo dice
4. Prepara el editor de Cloud Shell
- Navega al editor de Cloud Shell. Si se te muestra el siguiente mensaje en el que se solicita que autorices a Cloud Shell a llamar a gcloud con tus credenciales, haz clic en Autorizar para continuar.
- Abre la ventana de la terminal
- Haz clic en el menú de opciones
.
- Haz clic en Terminal.
- Haz clic en Terminal nueva
.
- Haz clic en el menú de opciones
- En la terminal, configura el ID de tu proyecto:
Reemplazagcloud config set project [PROJECT_ID]
[PROJECT_ID]
por el ID de tu proyecto. Por ejemplo, si el ID de tu proyecto eslab-example-project
, el comando será el siguiente: Si aparece el siguiente mensaje que indica que gcloud solicita tus credenciales a la API de GCPI, haz clic en Autorizar para continuar.gcloud config set project lab-project-id-example
Si la ejecución se realiza correctamente, deberías ver el siguiente mensaje: Si ves unUpdated property [core/project].
WARNING
y se te preguntaDo you want to continue (Y/N)?
, es probable que hayas ingresado el ID del proyecto de forma incorrecta. PresionaN
, presionaEnter
y, luego, intenta volver a ejecutar el comandogcloud config set project
después de encontrar el ID de proyecto correcto. - (Opcional) Si tienes problemas para encontrar el ID del proyecto, ejecuta el siguiente comando para ver el ID de todos tus proyectos ordenados por hora de creación en orden descendente:
gcloud projects list \ --format='value(projectId,createTime)' \ --sort-by=~createTime
5. Habilita las APIs de Google
En la terminal, habilita las APIs de Google que se requieren para este lab:
gcloud services enable \
run.googleapis.com \
cloudbuild.googleapis.com \
aiplatform.googleapis.com \
logging.googleapis.com \
monitoring.googleapis.com \
cloudtrace.googleapis.com
Este comando tardará un tiempo en completarse. Finalmente, se mostrará un mensaje de éxito similar a este:
Operation "operations/acf.p2-73d90d00-47ee-447a-b600" finished successfully.
Si recibes un mensaje de error que comienza con ERROR: (gcloud.services.enable) HttpError accessing
y contiene detalles de error como los que se indican a continuación, vuelve a intentar el comando después de una demora de 1 a 2 minutos.
"error": { "code": 429, "message": "Quota exceeded for quota metric 'Mutate requests' and limit 'Mutate requests per minute' of service 'serviceusage.googleapis.com' ...", "status": "RESOURCE_EXHAUSTED", ... }
6. Crea una aplicación de IA generativa
En este paso, escribirás un código de la aplicación simple basada en solicitudes que usa el modelo de Gemini para mostrar 10 datos divertidos sobre un animal de tu elección. Sigue estos pasos para crear el código de la aplicación.
- En la terminal, crea el directorio
codelab-o11y
:mkdir "${HOME}/codelab-o11y"
- Cambia el directorio actual a
codelab-o11y
:cd "${HOME}/codelab-o11y"
- Descarga el código de arranque de la aplicación de Java con el activador del framework de Spring:
curl https://start.spring.io/starter.zip \ -d dependencies=web \ -d javaVersion=17 \ -d type=maven-project \ -d bootVersion=3.4.1 -o java-starter.zip
- Desarchiva el código de arranque en la carpeta actual:
unzip java-starter.zip
- Y quita el archivo de almacenamiento de la carpeta:
rm java-starter.zip
- Crea un archivo
project.toml
para definir la versión del entorno de ejecución de Java que se usará cuando se implemente el código en Cloud Run:cat > "${HOME}/codelab-o11y/project.toml" << EOF [[build.env]] name = "GOOGLE_RUNTIME_VERSION" value = "17" EOF
- Agrega dependencias del SDK de Google Cloud al archivo
pom.xml
:- Agrega el paquete de Google Cloud Core:
sed -i 's/<dependencies>/<dependencies>\ \ <dependency>\ <groupId>com.google.cloud<\/groupId>\ <artifactId>google-cloud-core<\/artifactId>\ <version>2.49.1<\/version>\ <\/dependency>\ /g' "${HOME}/codelab-o11y/pom.xml"
- Agrega el paquete de Vertex AI de Google Cloud:
sed -i 's/<dependencies>/<dependencies>\ \ <dependency>\ <groupId>com.google.cloud<\/groupId>\ <artifactId>google-cloud-vertexai<\/artifactId>\ <version>1.16.0<\/version>\ <\/dependency>\ /g' "${HOME}/codelab-o11y/pom.xml"
- Agrega el paquete de Google Cloud Core:
- Abre el archivo
DemoApplication.java
en el editor de código de Cloud Shell: Ahora debería aparecer un código fuente con andamiaje del archivocloudshell edit "${HOME}/codelab-o11y/src/main/java/com/example/demo/DemoApplication.java"
DemoApplication.java
en la ventana del editor sobre la terminal. El código fuente del archivo será similar al siguiente:package com.example.demo; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class DemoApplication { public static void main(String[] args) { SpringApplication.run(DemoApplication.class, args); } }
- Reemplaza el código del editor por la versión que se muestra a continuación. Para reemplazar el código, borra el contenido del archivo y, luego, copia el siguiente código en el editor:
Después de unos segundos, el editor de Cloud Shell guardará tu código automáticamente.package com.example.demo; import java.io.IOException; import java.util.Collections; import javax.annotation.PostConstruct; import javax.annotation.PreDestroy; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import com.google.cloud.ServiceOptions; import com.google.cloud.vertexai.VertexAI; import com.google.cloud.vertexai.api.GenerateContentResponse; import com.google.cloud.vertexai.generativeai.GenerativeModel; import com.google.cloud.vertexai.generativeai.ResponseHandler; @SpringBootApplication public class DemoApplication { public static void main(String[] args) { String port = System.getenv().getOrDefault("PORT", "8080"); SpringApplication app = new SpringApplication(DemoApplication.class); app.setDefaultProperties(Collections.singletonMap("server.port", port)); app.run(args); } } @RestController class HelloController { private final String projectId = ServiceOptions.getDefaultProjectId(); private VertexAI vertexAI; private GenerativeModel model; @PostConstruct public void init() { vertexAI = new VertexAI(projectId, "us-central1"); model = new GenerativeModel("gemini-1.5-flash", vertexAI); } @PreDestroy public void destroy() { vertexAI.close(); } @GetMapping("/") public String getFacts(@RequestParam(defaultValue = "dog") String animal) throws IOException { String prompt = "Give me 10 fun facts about " + animal + ". Return this as html without backticks."; GenerateContentResponse response = model.generateContent(prompt); return ResponseHandler.getText(response); } }
Implementa el código de la aplicación de IA generativa en Cloud Run
- En la ventana de la terminal, ejecuta el comando para implementar el código fuente de la aplicación en Cloud Run.
Si ves el mensaje que aparece a continuación, se te informará que el comando creará un repositorio nuevo. Haz clic engcloud run deploy codelab-o11y-service \ --source="${HOME}/codelab-o11y/" \ --region=us-central1 \ --allow-unauthenticated
Enter
. El proceso de implementación puede tardar unos minutos. Una vez que se complete el proceso de implementación, verás un resultado como el siguiente:Deploying from source requires an Artifact Registry Docker repository to store built containers. A repository named [cloud-run-source-deploy] in region [us-central1] will be created. Do you want to continue (Y/n)?
Service [codelab-o11y-service] revision [codelab-o11y-service-00001-t2q] has been deployed and is serving 100 percent of traffic. Service URL: https://codelab-o11y-service-12345678901.us-central1.run.app
- Copia la URL del servicio de Cloud Run que se muestra en una pestaña o ventana separada del navegador. Como alternativa, ejecuta el siguiente comando en la terminal para imprimir la URL del servicio y haz clic en la URL que se muestra mientras mantienes presionada la tecla Ctrl para abrirla:
Cuando se abra la URL, es posible que recibas un error 500 o veas el siguiente mensaje:gcloud run services list \ --format='value(URL)' \ --filter='SERVICE:"codelab-o11y-service"'
Significa que los servicios no terminaron su implementación. Espera unos momentos y actualiza la página. Al final, verás un texto que comienza con Datos curiosos sobre perros y contiene 10 datos curiosos sobre perros.Sorry, this is just a placeholder...
Intenta interactuar con la aplicación para obtener datos interesantes sobre diferentes animales. Para hacerlo, agrega el parámetro animal
a la URL, como ?animal=[ANIMAL]
, en la que [ANIMAL]
es el nombre de un animal. Por ejemplo, agrega ?animal=cat
para obtener 10 datos curiosos sobre los gatos o ?animal=sea turtle
para obtener 10 datos curiosos sobre las tortugas marinas.
7. Cómo auditar tus llamadas a la API de Vertex
La auditoría de las llamadas a la API de Google proporciona respuestas a preguntas como "¿Quién llama a una API en particular, dónde y cuándo?". La auditoría es importante cuando solucionas problemas en tu aplicación, investigas el consumo de recursos o realizas un análisis forense de software.
Los registros de auditoría te permiten hacer un seguimiento de las actividades administrativas y del sistema, así como registrar llamadas a operaciones de API de “lectura de datos” y “escritura de datos”. Para auditar las solicitudes de Vertex AI para generar contenido, debes habilitar los registros de auditoría de "Lectura de datos" en la consola de Cloud.
- Haz clic en el siguiente botón para abrir la página Registros de auditoría en la consola de Cloud.
- Asegúrate de que la página tenga seleccionado el proyecto que creaste para este lab. El proyecto seleccionado se muestra en la esquina superior izquierda de la página, justo en el menú de opciones:
Si es necesario, selecciona el proyecto correcto en el cuadro combinado. - En la tabla Configuración de los registros de auditoría de acceso a los datos, en la columna Servicio, busca el servicio
Vertex AI API
y selecciónalo marcando la casilla de verificación ubicada a la izquierda del nombre del servicio. - En el panel de información de la derecha, selecciona el tipo de auditoría "Lectura de datos".
- Haz clic en Guardar.
Para generar registros de auditoría, abre la URL del servicio. Actualiza la página mientras cambias el valor del parámetro ?animal=
para obtener resultados diferentes.
Explora los registros de auditoría
- Haz clic en el siguiente botón para abrir la página Explorador de registros en la consola de Cloud:
- Pega el siguiente filtro en el panel Consulta.
El panel Consulta es un editor que se encuentra cerca de la parte superior de la página Explorador de registros:LOG_ID("cloudaudit.googleapis.com%2Fdata_access") AND protoPayload.serviceName="aiplatform.googleapis.com"
- Haz clic en Ejecutar consulta.
- Selecciona una de las entradas del registro de auditoría y expande los campos para inspeccionar la información capturada en el registro.
Puedes ver detalles sobre la llamada a la API de Vertex, incluido el método y el modelo que se usó. También puedes ver la identidad del llamador y los permisos que autorizaron la llamada.
8. Registra las interacciones con la IA generativa
No encontrarás parámetros de solicitud ni datos de respuesta de la API en los registros de auditoría. Sin embargo, esta información puede ser importante para solucionar problemas de análisis de aplicaciones y flujos de trabajo. En este paso, completamos esta brecha agregando el registro de la aplicación.
La implementación usa Logback con Spring Boot para imprimir los registros de la aplicación en la salida estándar. Este método cuenta con la capacidad de Cloud Run para capturar información impresa en el resultado estándar y transferirla a Cloud Logging automáticamente. Para capturar información como datos estructurados, los registros impresos deben tener el formato adecuado. Sigue las instrucciones que se indican a continuación para agregar capacidades de registro estructurado a la aplicación.
- Regresa a la ventana (o pestaña) de "Cloud Shell" en tu navegador.
- Crea y abre un archivo
LoggingEventGoogleCloudEncoder.java
nuevo en el editor de Cloud Shell:cloudshell edit "${HOME}/codelab-o11y/src/main/java/com/example/demo/LoggingEventGoogleCloudEncoder.java"
- Copia y pega el siguiente código para implementar el codificador Logback que codifica el registro como un JSON con formato de cadena siguiendo el formato de registro estructurado de Google Cloud:
package com.example.demo; import static ch.qos.logback.core.CoreConstants.UTF_8_CHARSET; import java.time.Instant; import ch.qos.logback.core.encoder.EncoderBase; import ch.qos.logback.classic.Level; import ch.qos.logback.classic.spi.ILoggingEvent; import java.util.HashMap; import com.google.gson.Gson; public class LoggingEventGoogleCloudEncoder extends EncoderBase<ILoggingEvent> { private static final byte[] EMPTY_BYTES = new byte[0]; private final Gson gson = new Gson(); @Override public byte[] headerBytes() { return EMPTY_BYTES; } @Override public byte[] encode(ILoggingEvent e) { var timestamp = Instant.ofEpochMilli(e.getTimeStamp()); var fields = new HashMap<String, Object>() { { put("timestamp", timestamp.toString()); put("severity", severityFor(e.getLevel())); put("message", e.getMessage()); } }; var params = e.getKeyValuePairs(); if (params != null && params.size() > 0) { params.forEach(kv -> fields.putIfAbsent(kv.key, kv.value)); } var data = gson.toJson(fields) + "\n"; return data.getBytes(UTF_8_CHARSET); } @Override public byte[] footerBytes() { return EMPTY_BYTES; } private static String severityFor(Level level) { switch (level.toInt()) { case Level.TRACE_INT: return "DEBUG"; case Level.DEBUG_INT: return "DEBUG"; case Level.INFO_INT: return "INFO"; case Level.WARN_INT: return "WARNING"; case Level.ERROR_INT: return "ERROR"; default: return "DEFAULT"; } } }
- Crea y abre un archivo
logback.xml
nuevo en el editor de Cloud Shell:cloudshell edit "${HOME}/codelab-o11y/src/main/resources/logback.xml"
- Copia y pega el siguiente XML para configurar Logback para que use el codificador con el adjuntador de Logback que imprime registros en la salida estándar:
<?xml version="1.0" encoding="UTF-8"?> <configuration debug="true"> <appender name="Console" class="ch.qos.logback.core.ConsoleAppender"> <encoder class="com.example.demo.LoggingEventGoogleCloudEncoder"/> </appender> <root level="info"> <appender-ref ref="Console" /> </root> </configuration>
- Vuelve a abrir el archivo
DemoApplication.java
en el editor de Cloud Shell:cloudshell edit "${HOME}/codelab-o11y/src/main/java/com/example/demo/DemoApplication.java"
- Reemplaza el código del editor por la versión que se muestra a continuación para registrar la solicitud y la respuesta de la IA generativa. Para reemplazar el código, borra el contenido del archivo y, luego, copia el siguiente código en el editor:
package com.example.demo; import java.io.IOException; import java.util.Collections; import javax.annotation.PostConstruct; import javax.annotation.PreDestroy; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import com.google.cloud.ServiceOptions; import com.google.cloud.vertexai.VertexAI; import com.google.cloud.vertexai.api.GenerateContentResponse; import com.google.cloud.vertexai.generativeai.GenerativeModel; import com.google.cloud.vertexai.generativeai.ResponseHandler; @SpringBootApplication public class DemoApplication { public static void main(String[] args) { String port = System.getenv().getOrDefault("PORT", "8080"); SpringApplication app = new SpringApplication(DemoApplication.class); app.setDefaultProperties(Collections.singletonMap("server.port", port)); app.run(args); } } @RestController class HelloController { private final String projectId = ServiceOptions.getDefaultProjectId(); private VertexAI vertexAI; private GenerativeModel model; private final Logger LOGGER = LoggerFactory.getLogger(HelloController.class); @PostConstruct public void init() { vertexAI = new VertexAI(projectId, "us-central1"); model = new GenerativeModel("gemini-1.5-flash", vertexAI); } @PreDestroy public void destroy() { vertexAI.close(); } @GetMapping("/") public String getFacts(@RequestParam(defaultValue = "dog") String animal) throws IOException { String prompt = "Give me 10 fun facts about " + animal + ". Return this as html without backticks."; GenerateContentResponse response = model.generateContent(prompt); LOGGER.atInfo() .addKeyValue("animal", animal) .addKeyValue("prompt", prompt) .addKeyValue("response", response) .log("Content is generated"); return ResponseHandler.getText(response); } }
Después de unos segundos, el editor de Cloud Shell guarda los cambios automáticamente.
Implementa el código de la aplicación de IA generativa en Cloud Run
- En la ventana de la terminal, ejecuta el comando para implementar el código fuente de la aplicación en Cloud Run.
Si ves el mensaje que aparece a continuación, se te informará que el comando creará un repositorio nuevo. Haz clic engcloud run deploy codelab-o11y-service \ --source="${HOME}/codelab-o11y/" \ --region=us-central1 \ --allow-unauthenticated
Enter
. El proceso de implementación puede tardar unos minutos. Una vez que se complete el proceso de implementación, verás un resultado como el siguiente:Deploying from source requires an Artifact Registry Docker repository to store built containers. A repository named [cloud-run-source-deploy] in region [us-central1] will be created. Do you want to continue (Y/n)?
Service [codelab-o11y-service] revision [codelab-o11y-service-00001-t2q] has been deployed and is serving 100 percent of traffic. Service URL: https://codelab-o11y-service-12345678901.us-central1.run.app
- Copia la URL del servicio de Cloud Run que se muestra en una pestaña o ventana separada del navegador. Como alternativa, ejecuta el siguiente comando en la terminal para imprimir la URL del servicio y haz clic en la URL que se muestra mientras mantienes presionada la tecla Ctrl para abrirla:
Cuando se abra la URL, es posible que recibas un error 500 o veas el siguiente mensaje:gcloud run services list \ --format='value(URL)' \ --filter='SERVICE:"codelab-o11y-service"'
Significa que los servicios no terminaron su implementación. Espera unos momentos y actualiza la página. Al final, verás un texto que comienza con Datos curiosos sobre perros y contiene 10 datos curiosos sobre perros.Sorry, this is just a placeholder...
Para generar registros de la aplicación, abre la URL del servicio. Actualiza la página mientras cambias el valor del parámetro ?animal=
para obtener resultados diferentes.
Para ver los registros de la aplicación, haz lo siguiente:
- Haz clic en el siguiente botón para abrir la página del Explorador de registros en la consola de Cloud:
- Pega el siguiente filtro en el panel Consulta (#2 en la interfaz del Explorador de registros):
LOG_ID("run.googleapis.com%2Fstdout") AND severity=DEBUG
- Haz clic en Ejecutar consulta.
El resultado de la consulta muestra registros con la instrucción y la respuesta de Vertex AI, incluidas las calificaciones de seguridad.
9. Cuenta las interacciones con la IA generativa
Cloud Run escribe métricas administradas que se pueden usar para supervisar los servicios implementados. Las métricas de supervisión administradas por el usuario proporcionan más control sobre los datos y la frecuencia de actualización de las métricas. Para implementar esa métrica, debes escribir un código que recopile datos y los escriba en Cloud Monitoring. Consulta el siguiente paso (opcional) para saber cómo implementarlo con el SDK de OpenTelemetry.
En este paso, se muestra una alternativa para implementar la métrica del usuario en el código: las métricas basadas en registros. Las métricas basadas en registros te permiten generar métricas de supervisión a partir de las entradas de registro que tu aplicación escribe en Cloud Logging. Usaremos los registros de la aplicación que implementamos en el paso anterior para definir una métrica basada en registros del contador de tipo. La métrica contará la cantidad de llamadas correctas a la API de Vertex.
- Observa la ventana del Explorador de registros que usamos en el paso anterior. En el panel Búsqueda, busca el menú desplegable Acciones y haz clic en él para abrirlo. Consulta la captura de pantalla que aparece a continuación para encontrar el menú:
- En el menú que se abre, selecciona Crear métrica para abrir el panel Crear métrica basada en registros.
- Sigue estos pasos para configurar una nueva métrica de contador en el panel Crear métrica basada en registros:
- Para el Tipo de métrica, selecciona Contador.
- Configura los siguientes campos en la sección Detalles:
- Nombre de la métrica de registro: Establece el nombre como
model_interaction_count
. Se aplican algunas restricciones de denominación. Para obtener más detalles, consulta Solución de problemas. - Descripción: ingresa una descripción para la métrica. Por ejemplo,
Number of log entries capturing successful call to model inference.
- Unidades: Deja este campo en blanco o inserta el número
1
.
- Nombre de la métrica de registro: Establece el nombre como
- Deja los valores en la sección Selección de filtro. Ten en cuenta que el campo Build filter tiene el mismo filtro que usamos para ver los registros de la aplicación.
- (Opcional) Agrega una etiqueta que ayude a contar la cantidad de llamadas de cada animal. NOTA: Esta etiqueta tiene el potencial de aumentar en gran medida la cantidad de la métrica y no se recomienda su uso en producción:
- Haz clic en Agregar etiqueta.
- Configura los siguientes campos en la sección Etiquetas:
- Nombre de la etiqueta: Establece el nombre como
animal
. - Descripción: Ingresa la descripción de la etiqueta. Por ejemplo,
Animal parameter
- Tipo de etiqueta: Selecciona
STRING
. - Nombre del campo: Escribe
jsonPayload.animal
. - Expresión regular: Déjalo en blanco.
- Nombre de la etiqueta: Establece el nombre como
- Haga clic en Listo
- Haz clic en Crear métrica a fin de crear la métrica.
También puedes crear una métrica basada en registros desde la página Métricas basadas en registros con el comando de CLI gcloud logging metrics create
o con el recurso de Terraform google_logging_metric
.
Para generar datos de métricas, abre la URL del servicio. Actualiza la página abierta varias veces para realizar varias llamadas al modelo. Al igual que antes, intenta usar diferentes animales en el parámetro.
Ingresa la consulta de PromQL para buscar los datos de métricas basados en registros. Para ingresar una consulta de PromQL, haz lo siguiente:
- Haz clic en el siguiente botón para abrir la página Explorador de métricas en la consola de Cloud:
- En la barra de herramientas del panel del compilador de consultas, selecciona el botón cuyo nombre sea < > MQL o < > PromQL. Consulta la siguiente imagen para ver la ubicación del botón.
- Verifica que PromQL esté seleccionado en el botón de activación Lenguaje. El botón de activación de lenguaje se encuentra en la misma barra de herramientas que te permite dar formato a tu consulta.
- Ingresa tu consulta en el editor Consultas:
Para obtener más información sobre el uso de PromQL, consulta PromQL en Cloud Monitoring.sum(rate(logging_googleapis_com:user_model_interaction_count{monitored_resource="cloud_run_revision"}[${__interval}]))
- Haga clic en Ejecutar consulta. Verás un gráfico de líneas similar a esta captura de pantalla:
Ten en cuenta que, cuando el botón de activación Ejecutar automáticamente está habilitado, no se muestra el botón Ejecutar consulta.
10. Usa Open Telemetry para la supervisión y el seguimiento (opcional)
Como se mencionó en el paso anterior, es posible implementar métricas con el SDK de OpenTelemetry (Otel). Se recomienda usar OTel en arquitecturas de varios servicios. En este paso, se muestra cómo agregar la instrumentación de OTel a una aplicación de Spring Boot. En este paso, harás lo siguiente:
- Instrumentación de la aplicación de Spring Boot con capacidades de seguimiento automático
- Implementa una métrica de contador para supervisar una cantidad de llamadas de modelo exitosas
- Correlaciona el seguimiento con los registros de la aplicación
La arquitectura recomendada para los servicios a nivel del producto es usar el recopilador de OTel para recopilar y transferir todos los datos de observabilidad de varios servicios. El código de este paso no usa el recopilador para simplificar. En su lugar, usa exportaciones de OTel que escriben datos directamente en Google Cloud.
Configura la aplicación de Spring Boot con componentes de OTel y seguimiento automático
- Regresa a la ventana (o pestaña) de "Cloud Shell" en tu navegador.
- En la terminal, actualiza el archivo
application.permissions
con parámetros de configuración adicionales: Estos parámetros definen la exportación de datos de observabilidad a Cloud Trace y Cloud Monitoring, y aplican el muestreo de todos los seguimientos.cat >> "${HOME}/codelab-o11y/src/main/resources/application.properties" << EOF otel.logs.exporter=none otel.traces.exporter=google_cloud_trace otel.metrics.exporter=google_cloud_monitoring otel.resource.attributes.service.name=codelab-o11y-service otel.traces.sampler=always_on EOF
- Agrega las dependencias de OpenTelemetry requeridas al archivo
pom.xml
:sed -i 's/<dependencies>/<dependencies>\ \ <dependency>\ <groupId>io.opentelemetry.instrumentation<\/groupId>\ <artifactId>opentelemetry-spring-boot-starter<\/artifactId>\ <\/dependency>\ <dependency>\ <groupId>com.google.cloud.opentelemetry<\/groupId>\ <artifactId>exporter-auto<\/artifactId>\ <version>0.33.0-alpha<\/version>\ <\/dependency>\ <dependency>\ <groupId>com.google.cloud.opentelemetry<\/groupId>\ <artifactId>exporter-trace<\/artifactId>\ <version>0.33.0<\/version>\ <\/dependency>\ <dependency>\ <groupId>com.google.cloud.opentelemetry<\/groupId>\ <artifactId>exporter-metrics<\/artifactId>\ <version>0.33.0<\/version>\ <\/dependency>\ /g' "${HOME}/codelab-o11y/pom.xml"
- Agrega el BOM de OpenTelemetry al archivo
pom.xml
:sed -i 's/<\/properties>/<\/properties>\ <dependencyManagement>\ <dependencies>\ <dependency>\ <groupId>io.opentelemetry.instrumentation<\/groupId>\ <artifactId>opentelemetry-instrumentation-bom<\/artifactId>\ <version>2.12.0<\/version>\ <type>pom<\/type>\ <scope>import<\/scope>\ <\/dependency>\ <\/dependencies>\ <\/dependencyManagement>\ /g' "${HOME}/codelab-o11y/pom.xml"
- Vuelve a abrir el archivo
DemoApplication.java
en el editor de Cloud Shell:cloudshell edit "${HOME}/codelab-o11y/src/main/java/com/example/demo/DemoApplication.java"
- Reemplaza el código actual por la versión que incrementa una métrica de rendimiento. Para reemplazar el código, borra el contenido del archivo y, luego, copia el siguiente código en el editor:
package com.example.demo; import io.opentelemetry.api.common.AttributeKey; import io.opentelemetry.api.common.Attributes; import io.opentelemetry.api.OpenTelemetry; import io.opentelemetry.api.metrics.LongCounter; import java.io.IOException; import java.util.Collections; import javax.annotation.PostConstruct; import javax.annotation.PreDestroy; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import com.google.cloud.ServiceOptions; import com.google.cloud.vertexai.VertexAI; import com.google.cloud.vertexai.api.GenerateContentResponse; import com.google.cloud.vertexai.generativeai.GenerativeModel; import com.google.cloud.vertexai.generativeai.ResponseHandler; @SpringBootApplication public class DemoApplication { public static void main(String[] args) { String port = System.getenv().getOrDefault("PORT", "8080"); SpringApplication app = new SpringApplication(DemoApplication.class); app.setDefaultProperties(Collections.singletonMap("server.port", port)); app.run(args); } } @RestController class HelloController { private final String projectId = ServiceOptions.getDefaultProjectId(); private VertexAI vertexAI; private GenerativeModel model; private final Logger LOGGER = LoggerFactory.getLogger(HelloController.class); private static final String INSTRUMENTATION_NAME = "genai-o11y/java/workshop/example"; private static final AttributeKey<String> ANIMAL = AttributeKey.stringKey("animal"); private final LongCounter counter; public HelloController(OpenTelemetry openTelemetry) { this.counter = openTelemetry.getMeter(INSTRUMENTATION_NAME) .counterBuilder("model_call_counter") .setDescription("Number of successful model calls") .build(); } @PostConstruct public void init() { vertexAI = new VertexAI(projectId, "us-central1"); model = new GenerativeModel("gemini-1.5-flash", vertexAI); } @PreDestroy public void destroy() { vertexAI.close(); } @GetMapping("/") public String getFacts(@RequestParam(defaultValue = "dog") String animal) throws IOException { String prompt = "Give me 10 fun facts about " + animal + ". Return this as html without backticks."; GenerateContentResponse response = model.generateContent(prompt); LOGGER.atInfo() .addKeyValue("animal", animal) .addKeyValue("prompt", prompt) .addKeyValue("response", response) .log("Content is generated"); counter.add(1, Attributes.of(ANIMAL, animal)); return ResponseHandler.getText(response); } }
- Vuelve a abrir el archivo
LoggingEventGoogleCloudEncoder.java
en el editor de Cloud Shell:cloudshell edit "${HOME}/codelab-o11y/src/main/java/com/example/demo/LoggingEventGoogleCloudEncoder.java"
- Reemplaza el código actual por la versión que agrega atributos de seguimiento a los registros escritos. Si agregas los atributos, los registros se pueden correlacionar con los intervalos de seguimiento correctos. Para reemplazar el código, borra el contenido del archivo y, luego, copia el siguiente código en el editor:
package com.example.demo; import static ch.qos.logback.core.CoreConstants.UTF_8_CHARSET; import java.time.Instant; import java.util.HashMap; import ch.qos.logback.core.encoder.EncoderBase; import ch.qos.logback.classic.Level; import ch.qos.logback.classic.spi.ILoggingEvent; import com.google.cloud.ServiceOptions; import io.opentelemetry.api.trace.Span; import io.opentelemetry.api.trace.SpanContext; import io.opentelemetry.context.Context; import com.google.gson.Gson; public class LoggingEventGoogleCloudEncoder extends EncoderBase<ILoggingEvent> { private static final byte[] EMPTY_BYTES = new byte[0]; private final Gson gson; private final String projectId; private final String tracePrefix; public LoggingEventGoogleCloudEncoder() { this.gson = new Gson(); this.projectId = lookUpProjectId(); this.tracePrefix = "projects/" + (projectId == null ? "" : projectId) + "/traces/"; } private static String lookUpProjectId() { return ServiceOptions.getDefaultProjectId(); } @Override public byte[] headerBytes() { return EMPTY_BYTES; } @Override public byte[] encode(ILoggingEvent e) { var timestamp = Instant.ofEpochMilli(e.getTimeStamp()); var fields = new HashMap<String, Object>() { { put("timestamp", timestamp.toString()); put("severity", severityFor(e.getLevel())); put("message", e.getMessage()); SpanContext context = Span.fromContext(Context.current()).getSpanContext(); if (context.isValid()) { put("logging.googleapis.com/trace", tracePrefix + context.getTraceId()); put("logging.googleapis.com/spanId", context.getSpanId()); put("logging.googleapis.com/trace_sampled", Boolean.toString(context.isSampled())); } } }; var params = e.getKeyValuePairs(); if (params != null && params.size() > 0) { params.forEach(kv -> fields.putIfAbsent(kv.key, kv.value)); } var data = gson.toJson(fields) + "\n"; return data.getBytes(UTF_8_CHARSET); } @Override public byte[] footerBytes() { return EMPTY_BYTES; } private static String severityFor(Level level) { switch (level.toInt()) { case Level.TRACE_INT: return "DEBUG"; case Level.DEBUG_INT: return "DEBUG"; case Level.INFO_INT: return "INFO"; case Level.WARN_INT: return "WARNING"; case Level.ERROR_INT: return "ERROR"; default: return "DEFAULT"; } } }
Después de unos segundos, el editor de Cloud Shell guarda los cambios automáticamente.
Implementa el código de la aplicación de IA generativa en Cloud Run
- En la ventana de la terminal, ejecuta el comando para implementar el código fuente de la aplicación en Cloud Run.
Si ves el mensaje que aparece a continuación, se te informará que el comando creará un repositorio nuevo. Haz clic engcloud run deploy codelab-o11y-service \ --source="${HOME}/codelab-o11y/" \ --region=us-central1 \ --allow-unauthenticated
Enter
. El proceso de implementación puede tardar unos minutos. Una vez que se complete el proceso de implementación, verás un resultado como el siguiente:Deploying from source requires an Artifact Registry Docker repository to store built containers. A repository named [cloud-run-source-deploy] in region [us-central1] will be created. Do you want to continue (Y/n)?
Service [codelab-o11y-service] revision [codelab-o11y-service-00001-t2q] has been deployed and is serving 100 percent of traffic. Service URL: https://codelab-o11y-service-12345678901.us-central1.run.app
- Copia la URL del servicio de Cloud Run que se muestra en una pestaña o ventana separada del navegador. Como alternativa, ejecuta el siguiente comando en la terminal para imprimir la URL del servicio y haz clic en la URL que se muestra mientras mantienes presionada la tecla Ctrl para abrirla:
Cuando se abra la URL, es posible que recibas un error 500 o veas el siguiente mensaje:gcloud run services list \ --format='value(URL)' \ --filter='SERVICE:"codelab-o11y-service"'
Significa que los servicios no terminaron su implementación. Espera unos momentos y actualiza la página. Al final, verás un texto que comienza con Datos curiosos sobre perros y contiene 10 datos curiosos sobre perros.Sorry, this is just a placeholder...
Para generar datos de telemetría, abre la URL del servicio. Actualiza la página mientras cambias el valor del parámetro ?animal=
para obtener resultados diferentes.
Explora los seguimientos de la aplicación
- Haz clic en el siguiente botón para abrir la página del explorador de seguimiento en la consola de Cloud:
- Selecciona uno de los registros más recientes. Deberías ver 5 o 6 tramos que se ven como en la siguiente captura de pantalla.
- Busca el intervalo que registra la llamada al controlador de eventos (el método
fun_facts
). Será el último intervalo con el nombre/
. - En el panel Detalles de seguimiento, selecciona Registros y eventos. Verás los registros de la aplicación que se correlacionan con este intervalo en particular. La correlación se detecta con los IDs de seguimiento y de intervalo en el seguimiento y en el registro. Deberías ver el registro de la aplicación que escribió la instrucción y la respuesta de la API de Vertex.
Explora la métrica de contador
- Haz clic en el siguiente botón para abrir la página Explorador de métricas en la consola de Cloud:
- En la barra de herramientas del panel del compilador de consultas, selecciona el botón cuyo nombre sea < > MQL o < > PromQL. Consulta la siguiente imagen para ver la ubicación del botón.
- Verifica que PromQL esté seleccionado en el botón de activación Lenguaje. El botón de activación de lenguaje se encuentra en la misma barra de herramientas que te permite dar formato a tu consulta.
- Ingresa tu consulta en el editor Consultas:
sum(rate(workload_googleapis_com:model_call_counter{monitored_resource="generic_task"}[${__interval}]))
- Haz clic en Ejecutar consulta.Cuando el botón de activación Ejecutar automáticamente está habilitado, no se muestra el botón Ejecutar consulta.
11. Información sensible ofuscada de los registros (opcional)
En el paso 10, registramos información sobre la interacción de la aplicación con el modelo de Gemini. Esta información incluía el nombre del animal, la instrucción real y la respuesta del modelo. Si bien almacenar esta información en el registro debería ser seguro, no es necesariamente cierto en muchos otros casos. La instrucción puede incluir información personal o sensible que el usuario no desea que se almacene. Para abordar este problema, puedes ofuscar los datos sensibles que se escriben en Cloud Logging. Para minimizar las modificaciones de código, se recomienda la siguiente solución.
- Crea un tema de Pub/Sub para almacenar las entradas de registro entrantes
- Crea un receptor de registros que redireccione los registros transferidos al tema de Pub/Sub.
- Crea una canalización de Dataflow que modifique los registros redireccionados al tema de PubSub siguiendo estos pasos:
- Lee una entrada de registro del tema de Pub/Sub
- Inspecciona la carga útil de la entrada en busca de información sensible con la API de inspección de DLP
- Oculta la información sensible en la carga útil con uno de los métodos de ocultación de DLP.
- Escribe la entrada de registro ofuscada en Cloud Logging
- Implementa la canalización
12. (Opcional) Limpieza
Para evitar el riesgo de incurrir en cargos por los recursos y las APIs que se usaron en el codelab, se recomienda realizar la limpieza después de terminar el lab. La manera más fácil de eliminar la facturación es borrar el proyecto que creaste para el codelab.
- Para borrar el proyecto, ejecuta el comando delete project en la terminal:
Si borras tu proyecto de Cloud, se detendrá la facturación de todos los recursos y las APIs que se usen en ese proyecto. Deberías ver este mensaje, en el quePROJECT_ID=$(gcloud config get-value project) gcloud projects delete ${PROJECT_ID} --quiet
PROJECT_ID
será el ID de tu proyecto:Deleted [https://cloudresourcemanager.googleapis.com/v1/projects/PROJECT_ID]. You can undo this operation for a limited period by running the command below. $ gcloud projects undelete PROJECT_ID See https://cloud.google.com/resource-manager/docs/creating-managing-projects for information on shutting down projects.
- (Opcional) Si recibes un error, consulta el paso 5 para encontrar el ID del proyecto que usaste durante el lab. Reemplázalo por el comando en la primera instrucción. Por ejemplo, si el ID de tu proyecto es
lab-example-project
, el comando será el siguiente:gcloud projects delete lab-project-id-example --quiet
13. Felicitaciones
En este lab, creaste una aplicación de IA generativa que usa el modelo de Gemini para hacer predicciones. Y, además, instrumentaste la aplicación con capacidades de registro y supervisión esenciales. Implementaste la aplicación y los cambios del código fuente en Cloud Run. Luego, usarás los productos de Google Cloud Observability para hacer un seguimiento del rendimiento de la aplicación, de modo que puedas asegurarte de su confiabilidad.
Si te interesa participar en un estudio de investigación de experiencia del usuario (UX) para mejorar los productos con los que trabajaste hoy, regístrate aquí.
Estas son algunas opciones para continuar con tu aprendizaje:
- Codelab Cómo implementar una app de chat potenciada por Gemini en Cloud Run
- Codelab Cómo usar las llamadas a funciones de Gemini con Cloud Run
- Cómo usar la API de Video Intelligence de Cloud Run Jobs para procesar un video por escena
- Taller on demand Integración de Google Kubernetes Engine
- Obtén más información para configurar métricas de contador y distribución con registros de aplicaciones
- Escribe métricas de OTLP con un archivo adicional de OpenTelemetry
- Referencia para usar OpenTelemetry en Google Cloud