Crea un generador de cuestionarios con IA generativa y Cloud Run

1. Introducción

En este lab, crearás un servicio web para generar cuestionarios de trivia y, luego, lo integrarás en una app divertida y funcional. Usarás un lenguaje de programación diferente al que hayas usado antes: ¡inglés!

Actividades

  • Crearás una instrucción que genere un cuestionario de trivia según un conjunto de criterios.
  • Compilarás una app web simple y verificarás que se ejecute como se espera en tu entorno de desarrollo.
  • Agregarás lógica de forma incremental a tu app web para convertirla en un servidor de API que genere cuestionarios en función de un conjunto de parámetros de entrada.
  • Verás lo fácil que es implementar tu servicio de generación de cuestionarios en la nube con Google Cloud Run.
  • Por último, configurarás una app real ( quizaic.com) para usar el servicio de generador de cuestionarios implementado y podrás reproducir cuestionarios en vivo basados en el resultado.

Qué aprenderás

  • Cómo crear una instrucción con plantilla para un modelo de lenguaje extenso (LLM)
  • Cómo crear una app de servidor web sencilla en Python
  • Cómo agregar compatibilidad con el LLM de Google a tu app web
  • Cómo implementar tu app en la nube para que cualquiera pueda probar tu nueva creación
  • Cómo integrar tu generador de cuestionarios en una app más grande

Qué necesitarás

  • Navegador web Chrome
  • Una Cuenta de Google
  • Un proyecto de Cloud con la facturación habilitada

Este lab está dirigido a desarrolladores de todos los niveles, incluidos principiantes. Aunque usarás Python, no es necesario que sepas programar en ese lenguaje para entender lo que se hace, ya que explicaremos todo el código que verás.

2. Configuración

a08aa5878e36b60c.png

En esta sección, se explica todo lo que debes hacer para comenzar este lab.

Configuración del entorno de autoaprendizaje

  1. Accede a Google Cloud Console y crea un proyecto nuevo o reutiliza uno existente. Si aún no tienes una cuenta de Gmail o de Google Workspace, debes crear una.

fbef9caa1602edd0.png

a99b7ace416376c4.png

5e3ff691252acf41.png

  • El Nombre del proyecto es el nombre visible de los participantes de este proyecto. Es una cadena de caracteres que no se utiliza en las APIs de Google. Puedes actualizarla cuando quieras.
  • El ID del proyecto es único en todos los proyectos de Google Cloud y es inmutable (no se puede cambiar después de configurarlo). La consola de Cloud genera automáticamente una cadena única. Por lo general, no importa cuál sea. En la mayoría de los codelabs, deberás hacer referencia al ID de tu proyecto (suele identificarse como PROJECT_ID). Si no te gusta el ID que se generó, podrías generar otro aleatorio. También puedes probar uno propio y ver si está disponible. No se puede cambiar después de este paso y se usa el mismo durante todo el proyecto.
  • Recuerda que hay un tercer valor, un número de proyecto, que usan algunas APIs. Obtén más información sobre estos tres valores en la documentación.
  1. A continuación, deberás habilitar la facturación en la consola de Cloud para usar las APIs o los recursos de Cloud. Ejecutar este codelab no costará mucho, tal vez nada. Para cerrar recursos y evitar que se generen cobros más allá de este instructivo, puedes borrar los recursos que creaste o borrar el proyecto. Los usuarios nuevos de Google Cloud son aptos para participar en el programa Prueba gratuita de $300.

Inicia Cloud Shell.

En este lab, trabajarás en una sesión de Cloud Shell, que es un intérprete de comandos alojado en una máquina virtual que se ejecuta en la nube de Google. Podrías ejecutar fácilmente esta sección de forma local, en tu computadora, pero Cloud Shell brinda una experiencia reproducible en un entorno coherente para todo el mundo. Después de este lab, puedes volver a probar esta sección en tu computadora.

4a95152439f0159b.png

Activar Cloud Shell

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

3c1dabeca90e44e5.png

Si es la primera vez que inicias Cloud Shell, aparecerá una pantalla intermedia que describe en qué consiste. Si se te presentó una pantalla intermedia, haz clic en Continuar.

9c92662c6a846a5c.png

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

9f0e51b578fecce5.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 permite mejorar 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 se te autenticó y que el proyecto se configuró con tu ID de 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].

Habilita algunas APIs

En pasos posteriores, verás en qué momento se necesitan estos servicios y por qué. Por ahora, ejecuta este comando para que tu proyecto pueda acceder a Cloud Build, Artifact Registry, Vertex AI y Cloud Run:

gcloud services enable cloudbuild.googleapis.com        \
                       artifactregistry.googleapis.com  \
                       aiplatform.googleapis.com        \
                       run.googleapis.com          

Esto debería producir un mensaje exitoso similar al siguiente:

Operation "operations/acf.cc11852d-40af-47ad-9d59-477a12847c9e" finished successfully.

3. Instrucciones: Programación en Natural Language

92f630373224ead8.png

Empezaremos por aprender a desarrollar una instrucción para un modelo de lenguaje extenso. Navega a la consola de Google Cloud > Vertex AI > Vertex AI Studio (Lenguaje). Deberías ver una página como la siguiente:

bfe5706041ae6454.png

En Generate Text, haz clic en el botón Text Prompt. En el siguiente diálogo, ingresa una consigna que crees que podría ser efectiva para generar un cuestionario de trivia de acuerdo con los siguientes requisitos:

  • Tema: Historia universal
  • Cantidad de preguntas: 5
  • Nivel de dificultad: intermedio
  • Idioma: inglés

Haz clic en el botón Enviar para ver el resultado.

Como se muestra en la siguiente captura de pantalla, el panel de la derecha te permite seleccionar el modelo que deseas usar y ajustar algunos de los parámetros de configuración:

8aa89a1970ea9335.png

Podrás configurar los siguientes parámetros:

  • La región es donde se debe ejecutar tu solicitud de generación.
  • El modelo selecciona el modelo de lenguaje grande que deseas usar. Para este codelab, usa “gemini-1.0-pro-001”.
  • La temperatura controla el grado de aleatorización en la selección de tokens. Las temperaturas más bajas son buenas para las instrucciones que esperan una respuesta verdadera o correcta, mientras que las temperaturas más altas pueden generar resultados más diversos o inesperados.
  • El límite de tokens determina la cantidad máxima de salida de texto a partir de una instrucción. Un token tiene aproximadamente cuatro caracteres. El valor predeterminado es 1,024.
  • K superior cambia la manera en que el modelo selecciona tokens para la salida. Un Top-K de 1 significa que el token seleccionado es el más probable entre todos los tokens en el vocabulario del modelo (también llamado decodificación codiciosa), mientras que un Top-K de 3 significa que el siguiente token se selecciona de los 3 tokens más probables (usando la temperatura). El valor predeterminado de k superior es 40.
  • P superior cambia la manera en la que el modelo selecciona tokens para la salida. Los tokens se seleccionan del más al menos probable hasta que la suma de sus probabilidades sea igual al valor de p superior.
  • La cantidad máxima de respuestas es la cantidad máxima de respuestas del modelo generadas por instrucción.
  • Una secuencia de detención es una serie de caracteres (incluidos los espacios) que detienen la generación de respuesta si el modelo la encuentra.
  • Las respuestas de transmisión seleccionan si las respuestas se deben imprimir a medida que se generan o guardar y mostrar cuando estén completas.
  • El umbral del filtro de seguridad ajusta la probabilidad de que veas respuestas que podrían ser perjudiciales.

Una vez que tengas una instrucción que parezca generar un cuestionario razonable según los requisitos mencionados anteriormente, podríamos analizar este cuestionario con código personalizado, pero ¿no sería mejor que el LLM genere el cuestionario en un formato estructurado que podamos cargar directamente en nuestro programa? El programa que usaremos más adelante en este lab para llamar al generador espera que los cuestionarios se expresen en JSON, un formato popular entre lenguajes para representar datos estructurados.

Los cuestionarios de este lab se expresan como un array de objetos, en el que cada objeto contiene una pregunta, un array de respuestas posibles a esa pregunta y una respuesta correcta. Esta es la codificación JSON para los cuestionarios de este lab:

[
    {
        "question": "Who was the first person to walk on the moon?",
          "responses": [
              "Neil Armstrong",
              "Buzz Aldrin",
              "Michael Collins",
              "Yuri Gagarin"
           ],
           "correct": "Neil Armstrong"
    },
    {
        "question": "What was the name of the war that took place between the British and the French in North America from 1754 to 1763??",
          "responses": [
              "The French and Indian War",
              "The Seven Years' War",
              "The War of the Austrian Succession",
              "The Great War"
           ],
           "correct": "The French and Indian War"
    },

    ...
]

Comprueba si puedes modificar la instrucción para que ahora genere el cuestionario en el formato JSON requerido.

  1. Especifica con palabras el formato exacto que buscas (p.ej., la oración en cursiva anterior).
  2. Incluye en la instrucción un ejemplo del formato JSON deseado.

Una vez que tengas tu instrucción para generar cuestionarios según la especificación deseada, haz clic en el botón GET CODE en la esquina superior derecha de la página para ver el código de Python que se puede usar para enviar de forma programática tu instrucción a un LLM de Vertex AI. Si te interesa usar un lenguaje de programación distinto de Python, consulta https://cloud.google.com/vertex-ai/docs/samples?text=generative.

4. Compila un servidor web simple

c73008bb8a72b57b.png

Ahora que tienes una instrucción que funciona, queremos integrarla en una app más grande. Por supuesto, podríamos incorporar tu instrucción en el código fuente de la app más grande, pero queremos que tu generador funcione como un microservicio que proporcione un servicio de generación de cuestionarios para otras apps. Para ello, necesitaremos crear un servidor web simple y ponerlo a disposición del público. Lo haremos en los siguientes pasos.

Para comenzar, haz clic en el botón Open Editor que se encuentra en la parte superior del panel de Cloud Shell. El aspecto resultante será el siguiente:

e2a06b5304079efc.png

Luego, te encontrarás en un entorno de IDE similar a Visual Studio Code, en el que puedes crear proyectos, editar código fuente, ejecutar tus programas, etcétera.

Si la pantalla está demasiado abarrotada, puedes expandir o reducir la línea divisoria entre la consola y la ventana de edición o terminal arrastrando la barra horizontal entre esas dos regiones, destacadas aquí:

8dea35450851af53.png

Para alternar entre el editor y la terminal, haz clic en los botones Open Editor y Open Terminal, respectivamente. Ahora, intenta alternar entre estos dos entornos.

A continuación, crea una carpeta en la que almacenar tu trabajo para este lab. Para ello, haz clic en el botón para agregar una carpeta 5f4e64909bc15e30.png, escribe quiz-generator y presiona Intro. Todos los archivos que crees en este lab y todo el trabajo que realices en Cloud Shell se llevarán a cabo en esta carpeta.

Ahora, crea un archivo requirements.txt. Esto le indica a Python de qué bibliotecas depende tu app. Para esta app web simple, usarás un módulo popular de Python para compilar servidores web llamado Flask,, la biblioteca cliente google-cloud-aiplatform y un framework de servidor web llamado gunicorn. En el panel de navegación de archivos, haz clic con el botón derecho en la carpeta quiz-generator y selecciona el elemento de menú New file, de la siguiente manera:

613eb3de4b9b750a.png

Cuando se te solicite el nombre del archivo nuevo, ingresa requirements.txt y presiona Intro. Asegúrate de que el archivo nuevo termine en la carpeta del proyecto quiz-generator.

Pega las siguientes líneas en el archivo nuevo para especificar que tu app depende del paquete flask de Python, el servidor web gunicorn y la biblioteca cliente google-cloud-aiplatform, junto con las versiones asociadas de cada uno.

flask==3.0.0
gunicorn==21.2.0
google-cloud-aiplatform==1.47.0

No es necesario que guardes este archivo de forma explícita, ya que el Editor en la nube guardará los cambios automáticamente.

Con la misma técnica, crea otro archivo nuevo llamado main.py. Este será el archivo fuente principal (y único) de Python de tu app. Nuevamente, asegúrate de que el archivo nuevo termine en la carpeta quiz-generator.

Inserta el siguiente código en este archivo:

from flask import Flask
import os

app = Flask(__name__)  # Create a Flask object.
PORT = os.environ.get("PORT")  # Get PORT setting from environment.
if not PORT:
    PORT = 8080

# The app.route decorator routes any GET requests sent to the root path
# to this function, which responds with a "Hello world!" HTML document.
@app.route("/", methods=["GET"])
def say_hello():
    html = "<h1>Hello world!</h1>"
    return html

# This code ensures that your Flask app is started and listens for
# incoming connections on the local interface and port 8080.
if __name__ == "__main__":
    app.run(host="0.0.0.0", port=PORT)

Regresa a la terminal y cambia a la carpeta del proyecto con este comando:

cd quiz-generator

Ejecuta el siguiente comando para instalar las dependencias de tu proyecto:

pip3 install -r requirements.txt

Después de instalar las dependencias, deberías ver un resultado que finaliza de la siguiente manera:

Successfully installed flask-3.0.0

Ahora, ejecuta el siguiente comando en la terminal para iniciar la app:

flask --app main.py --debug run --port 8080

En este punto, tu app se ejecuta en la máquina virtual dedicada a tu sesión de Cloud Shell. Cloud Shell incluye un mecanismo de proxy que te permite acceder a servidores web (como el que acabas de iniciar) que se ejecutan en tu máquina virtual desde cualquier lugar de Internet global.

Haz clic en el botón web preview y, luego, en el elemento de menú Preview on Port 8080 de la siguiente manera:

7f938c0bc1b4154c.png

Se abrirá una pestaña del navegador web en tu app en ejecución, que debería verse de la siguiente manera:

aaaf366f9bf74a28.png

5. Se agregó un método de generación con el análisis de parámetros

Ahora, queremos agregar compatibilidad para enviar un nuevo método llamado generate. Para ello, agrega una sentencia de importación para manipular la solicitud HTTP y modifica la ruta principal para analizar esta solicitud y, luego, imprime los parámetros, de la siguiente manera:

from flask import Flask
from flask import request                       #<-CHANGED
import os

app = Flask(__name__)  # Create a Flask object.
PORT = os.environ.get("PORT")  # Get PORT setting from environment.
if not PORT:
    PORT = 8080

# The app.route decorator routes any GET requests sent to the /generate
# path to this function, which responds with "Generating:" followed by
# the body of the request.
@app.route("/", methods=["GET"])                #<-CHANGED
def generate():                                 #<-CHANGED
    params = request.args.to_dict()             #<-CHANGED
    html = f"<h1>Quiz Generator</h1>"           #<-CHANGED
    for param in params:                        #<-CHANGED
        html += f"<br>{param}={params[param]}"  #<-CHANGED
    return html                                 #<-CHANGED

# This code ensures that your Flask app is started and listens for
# incoming connections on the local interface and port 8080.
if __name__ == "__main__":
    app.run(host="0.0.0.0", port=PORT)

Ahora, vuelve a cargar la pestaña del navegador web existente para ver los resultados. Esta vez, deberías ver el "Generador de cuestionarios", junto con un parámetro de consulta agregado automáticamente a tu URL (authuser). Intenta agregar dos parámetros adicionales agregando la cadena "`&param1=val1&param2=val2" al final de la URL en la barra de direcciones del navegador. Vuelve a cargar la página. Deberías ver algo como lo siguiente:

6e223ca358e4e009.png

Ahora que vimos cómo enviar y analizar parámetros de consulta en una URL, agregaremos compatibilidad con los parámetros específicos que le enviaremos a nuestro generador de cuestionarios, que son los siguientes:

  • topic: El asunto deseado para el cuestionario
  • num_q: Es la cantidad de preguntas deseadas.
  • diff: Es el nivel de dificultad deseado (fácil, intermedio o difícil).
  • lang: Es el idioma del cuestionario deseado.
from flask import Flask
from flask import request
import os

# Default quiz settings  #<-CHANGED
TOPIC = "History"        #<-CHANGED
NUM_Q = "5"              #<-CHANGED
DIFF = "intermediate"    #<-CHANGED
LANG = "English"         #<-CHANGED

app = Flask(__name__)  # Create a Flask object.
PORT = os.environ.get("PORT")  # Get PORT setting from environment.
if not PORT:
    PORT = 8080

# This function takes a dictionary, a name, and a default value.
# If the name exists as a key in the dictionary, the corresponding
# value is returned. Otherwise, the default value is returned.
def check(args, name, default):  #<-CHANGED
    if name in args:             #<-CHANGED
        return args[name]        #<-CHANGED
    return default               #<-CHANGED

# The app.route decorator routes any GET requests sent to the /generate
# path to this function, which responds with "Generating:" followed by
# the body of the request.
@app.route("/", methods=["GET"])
# This function generates a quiz using Vertex AI.
def generate():
    args = request.args.to_dict()        #<-CHANGED
    topic = check(args, "topic", TOPIC)  #<-CHANGED
    num_q = check(args, "num_q", NUM_Q)  #<-CHANGED
    diff = check(args, "diff", DIFF)     #<-CHANGED
    lang = check(args, "lang", LANG)     #<-CHANGED
    html = f"""
        <h1>Quiz Generator</h1><br>
        {topic=}<br>
        {num_q=}<br>
        {diff=}<br>
        {lang=}"""                       #<-CHANGED
    return html

# This code ensures that your Flask app is started and listens for
# incoming connections on the local interface and port 8080.
if __name__ == "__main__":
    app.run(host="0.0.0.0", port=PORT)

Ahora, vuelve a cargar la pestaña del navegador web existente para ver los resultados. Deberías ver algo como la siguiente página web:

15eed60f6a805212.png

Intenta cambiar la URL para establecer valores para varios parámetros. Por ejemplo, intenta usar el sufijo "?authuser=0&topic=Literature&num_q=10&diff=easy&lang=French" al final de la URL en la barra de direcciones:

f629dba5fa207cef.png

6. Agrega una instrucción y aplícale formato

A continuación, agregaremos compatibilidad con los parámetros específicos que queremos enviar a nuestro generador de cuestionarios, que son los siguientes:

  • topic: Es el tema del cuestionario deseado.
  • num_q: Es la cantidad de preguntas deseadas.
  • diff: Es el nivel de dificultad deseado (fácil, intermedio o difícil).
  • lang: Es el idioma del cuestionario deseado.

Copia la instrucción que desarrollaste con Generative AI Studio de Vertex en un paso anterior, pero cambia los valores codificados de tema, cantidad de preguntas y nivel de dificultad por estas cadenas:

  • {topic}
  • {num_q}
  • {diff}
  • {lang}
from flask import Flask
from flask import request
import os

# Default quiz settings
TOPIC = "History"
NUM_Q = 5
DIFF = "intermediate"
LANG = "English"

PROMPT = """
Generate a quiz according to the following specifications:

- topic: {topic}
- num_q: {num_q}
- diff:  {diff}
- lang:  {lang}

Output should be (only) an unquoted json array of objects with keys:
"Question", "responses", and "correct".

"""  #<-CHANGED

app = Flask(__name__)  # Create a Flask object.
PORT = os.environ.get("PORT")  # Get PORT setting from environment.
if not PORT:
    PORT = 8080

# This function takes a dictionary, a name, and a default value.
# If the name exists as a key in the dictionary, the corresponding
# value is returned. Otherwise, the default value is returned.
def check(args, name, default):
    if name in args:
        return args[name]
    return default

# The app.route decorator routes any GET requests sent to the /generate
# path to this function, which responds with "Generating:" followed by
# the body of the request.
@app.route("/", methods=["GET"])
# This function generates a quiz using Vertex AI.
def generate():
    args = request.args.to_dict()
    topic = check(args, "topic", TOPIC)
    num_q = check(args, "num_q", NUM_Q)
    diff = check(args, "diff", DIFF)
    lang = check(args, "lang", LANG)
    prompt = PROMPT.format(topic=topic, num_q=num_q, diff=diff, lang=lang)  #<-CHANGED 
    html = f"<h1>Prompt:</h1><br><pre>{prompt}</pre>"                       #<-CHANGED
    return html

# This code ensures that your Flask app is started and listens for
# incoming connections on the local interface and port 8080.
if __name__ == "__main__":
    app.run(host="0.0.0.0", port=PORT)

Ahora, vuelve a cargar la pestaña del navegador web existente para ver los resultados. Deberías ver una página web similar a la siguiente:

8c2b9dfcfba86b7a.png

Intenta modificar la URL para alterar esos cuatro parámetros.

7. Agrega la biblioteca cliente de Vertex AI

Ahora ya podemos usar la biblioteca cliente de Python de Vertex AI para generar el cuestionario. Esto automatizará las instrucciones interactivas que usaste en el paso 3 y le darás a tu servicio de generador acceso programático a las capacidades de LLM de Google. Actualiza el archivo main.py de la siguiente manera:

Asegúrate de reemplazar "YOUR_PROJECT" por el ID de tu proyecto real.

from flask import Flask
from flask import request
from flask import Response                                          #<-CHANGED
import os

import vertexai    
from vertexai.generative_models import GenerativeModel  #<-CHANGED

# Default quiz settings
TOPIC = "History"
NUM_Q = 5
DIFF = "intermediate"
LANG = "English"
MODEL = "gemini-1.0-pro"  #<-CHANGED

PROMPT = """
Generate a quiz according to the following specifications:

- topic: {topic}
- num_q: {num_q}
- diff:  {diff}
- lang:  {lang}

Output should be (only) an unquoted json array of objects with keys "question", "responses", and "correct".

"""

app = Flask(__name__)  # Create a Flask object.
PORT = os.environ.get("PORT")  # Get PORT setting from environment.
if not PORT:
    PORT = 8080

# Initialize Vertex AI access.
vertexai.init(project="YOUR_PROJECT", location="us-central1")  #<-CHANGED
parameters = {                                                 #<-CHANGED
    "candidate_count": 1,                                      #<-CHANGED
    "max_output_tokens": 1024,                                 #<-CHANGED
    "temperature": 0.5,                                        #<-CHANGED
    "top_p": 0.8,                                              #<-CHANGED
    "top_k": 40,                                               #<-CHANGED
}                                                              #<-CHANGED
model = GenerativeModel(MODEL)             #<-CHANGED

# This function takes a dictionary, a name, and a default value.
# If the name exists as a key in the dictionary, the corresponding
# value is returned. Otherwise, the default value is returned.
def check(args, name, default):
    if name in args:
        return args[name]
    return default

# The app.route decorator routes any GET requests sent to the /generate
# path to this function, which responds with "Generating:" followed by
# the body of the request.
@app.route("/", methods=["GET"])
# This function generates a quiz using Vertex AI.
def generate():
    args = request.args.to_dict()
    topic = check(args, "topic", TOPIC)
    num_q = check(args, "num_q", NUM_Q)
    diff = check(args, "diff", DIFF)
    lang = check(args, "lang", LANG)
    prompt = PROMPT.format(topic=topic, num_q=num_q, diff=diff, lang=lang)
    response = model.generate_content(prompt, generation_config=parameters)  #<-CHANGED
    print(f"Response from Model: {response.text}")           #<-CHANGED
    html = f"{response.text}"                                #<-CHANGED
    return Response(html, mimetype="application/json")       #<-CHANGED

# This code ensures that your Flask app is started and listens for
# incoming connections on the local interface and port 8080.
if __name__ == "__main__":
    app.run(host="0.0.0.0", port=PORT)

Ahora, vuelve a cargar la pestaña del navegador web existente para ver los resultados. Ten en cuenta que esto puede tardar varios segundos porque ahora estás realizando una solicitud de LLM. Deberías ver una página web similar a la siguiente:

f43d3ba5102857b8.png

Intenta modificar la URL para solicitar un tema, una cantidad de preguntas y un nivel de dificultad diferentes.

Con eso, se terminó tu microservicio. ¡Felicitaciones! En el siguiente paso, aprenderás a implementar tu servicio en la nube para que cualquier persona pueda acceder a él desde cualquier lugar.

8. ¡A la nube!

67c99bf45a7b7805.png

Ahora que creaste tu propio generador de cuestionarios, querrás compartirlo con el resto del mundo, así que es hora de implementarlo en la nube. Pero te gustaría hacer algo más que solo compartirlo. Te gustaría asegurarte de que cumpla con los siguientes requisitos:

  • se ejecuta de forma confiable (obtienes tolerancia a fallas automática en caso de que falle una computadora que ejecuta tu app)
  • Se escala automáticamente: Tu app se mantendrá al día con grandes niveles de tráfico y reducirá automáticamente su espacio cuando no se use.
  • minimiza tus costos, ya que no te cobra por los recursos que no usas; solo se te cobra por los recursos consumidos mientras se responde al tráfico
  • Se puede acceder a través de un nombre de dominio personalizado: tienes acceso a una solución de un clic para asignar un nombre de dominio personalizado a tu servicio
  • ofrece un tiempo de respuesta excelente: los inicios en frío son bastante responsivos, pero puedes ajustarlos especificando una configuración de instancia mínima
  • admite la encriptación de extremo a extremo con la seguridad web SSL/TLS estándar: cuando se implementa un servicio, se obtiene de forma gratuita y automática la encriptación web estándar y los certificados correspondientes

Si implementas tu app en Google Cloud Run, obtienes todo lo anterior y mucho más. El elemento básico para compartir tu app con Cloud Run es un contenedor.

Los contenedores nos permiten crear una caja modular en la que ejecutar una aplicación con todas sus dependencias agrupadas. Dado que los contenedores se pueden usar en casi cualquier servidor virtual o real, esto nos brinda una forma de implementar tu aplicación en cualquier lugar que desees, desde las instalaciones locales hasta la nube, y hasta de trasladarla de un proveedor de servicios a otro.

Para obtener más información sobre los contenedores y cómo funcionan en Google Cloud Run, consulta el codelab De dev a prod en tres pasos sencillos con Cloud Run.

Implementa tu app en Cloud Run

Cloud Run es un servicio regional, lo que significa que la infraestructura que ejecuta tus servicios se ubica en una región específica y Google la administra para que esté disponible de manera redundante en todas las zonas de esa región. Para simplificar, en este lab usaremos la región codificada us-central1.

Usaremos un objeto llamado buildpack para generar automáticamente tu contenedor. Crea un archivo nuevo llamado Procfile en el editor de Cloud y, luego, inserta esta línea de texto:

web: gunicorn --bind :$PORT --workers 1 --threads 8 --timeout 0 main:app

Esto le indica al sistema de paquete de compilación cómo ejecutar tu app en el contenedor generado automáticamente. Luego, ejecuta el siguiente comando en la terminal de Cloud Shell (desde ese mismo directorio quiz-generator) :

gcloud run deploy quiz-generator  \
    --source .                    \
    --region us-central1          \
    --allow-unauthenticated

Esto le indica al comando gcloud que deseas que use paquetes de compilación para crear tu imagen de contenedor, en función de los archivos de origen que encuentre en el directorio actual (dot en --source . es la abreviatura del directorio actual). Debido a que el servicio se encarga de la imagen del contenedor de forma implícita, no necesitas especificar una imagen en este comando gcloud.

Espere un momento a que finalice la implementación. Si la operación es exitosa, el comando gcloud mostrará la URL del servicio nuevo:

Building using Buildpacks and deploying container to Cloud Run service [quiz-generator] in project [YOUR_PROJECT] region [YOUR_REGION]
OK Building and deploying new service... Done.                                                                          
  OK Creating Container Repository...                                                                                   
  OK Uploading sources...                                                                                               
  OK Building Container... Logs are available at [https://console.cloud.google.com/cloud-build/builds/0cf1383f-35db-412d
  -a973-557d5e2cd4a4?project=780573810218].                                                                             
  OK Creating Revision...                                                                                               
  OK Routing traffic...                                                                                                 
  OK Setting IAM Policy...                                                                                              
Done.                                                                                                                   
Service [quiz-generator] revision [quiz-generator-00001-xnr] has been deployed and is serving 100 percent of traffic.
Service URL: https://quiz-generator-co24gukjmq-uc.a.run.app

También puedes recuperar la URL de tu servicio con este comando:

gcloud run services describe quiz-generator  \
  --region us-central1                       \
  --format "value(status.url)"

Se debería mostrar algo como lo siguiente:

https://quiz-generator-co24gukjmq-uc.a.run.app

Este vínculo es una URL dedicada, con seguridad TLS, para tu servicio de Cloud Run. Este vínculo es permanente (siempre y cuando no lo inhabilites) y se puede usar en cualquier lugar de Internet. No usa el mecanismo de proxy de Cloud Shell mencionado anteriormente, que dependía de una máquina virtual transitoria.

Haz clic en el Service URL destacado para abrir una pestaña del navegador web en la app en ejecución. Verifica que el resultado sea el mismo que viste en tu entorno de desarrollo. También verifica que puedas ajustar el cuestionario generado proporcionando parámetros al final de la URL.

¡Felicitaciones! Tu app ahora se ejecuta en Google Cloud. Sin tener que pensar en ello, tu app estará disponible para el público, con encriptación TLS (HTTPS) y escalamiento automático a niveles asombrosos de tráfico.

9. Cómo unir todas las piezas

9927db1725bcd5d6.png

En este último paso, ya está todo listo para ejecutar el generador de cuestionarios como parte de la app de quizaic. Visita la URL de quizaic, accede a tu Cuenta de Google y navega a la pestaña Create Quiz. Selecciona el tipo de generador Custom, pega tu URL de Cloud Run en el campo URL, completa los otros campos obligatorios y envía el formulario.

328ee05579ea05f9.png

En unos momentos, deberías tener un cuestionario nuevo (consulta "Mi cuestionario nuevo" en la imagen que aparece a continuación), con una miniatura generada por IA, que puedes editar, reproducir, clonar o borrar con los botones correspondientes. Este nuevo cuestionario se creó con el servicio web que acabas de implementar en función de tu instrucción con plantilla.

1719169140978b63.png

10. Limpieza

c1592d590c563428.png

Si bien Cloud Run no cobra cuando el servicio no se usa, es posible que se te cobre por el almacenamiento de la imagen del contenedor compilada.

Para evitar esto, puedes borrar el proyecto de GCP, lo que detendrá la facturación de todos los recursos usados en ese proyecto, o puedes borrar la imagen del contenedor con el siguiente comando:

gcloud config set artifacts/repository cloud-run-source-deploy
gcloud config set artifacts/location us-central1
gcloud artifacts docker images list

# Note image tag for resulting list

gcloud artifacts docker images delete <IMAGE-TAG>

Para borrar tu servicio de Cloud Run, usa el siguiente comando:

gcloud run services delete quiz-generator --region us-central1 --quiet

11. ¡Lo lograste!

910162be58c0f6d6.png

Felicitaciones. Creaste con éxito una instrucción de LLM y, además, implementaste un microservicio de Cloud Run con ella. Ahora puedes programar en lenguaje natural y compartir tus creaciones con el mundo.

Quiero dejarte con una pregunta importante:

Una vez que tu app funcione en tu entorno de desarrollador, ¿cuántas líneas de código tuviste que modificar para implementarla en la nube, con todos los atributos de nivel de producción que ofrece Cloud Run?

Por supuesto, la respuesta es cero. :)

Otros codelabs que puedes consultar…

Documentos de referencia

12. Llamado a la acción

Si te gustó este codelab y es probable que dediques más tiempo a la práctica con Google Cloud, deberías unirte a Google Cloud Innovators hoy mismo.

498cab7d87ec12d3.png

Google Cloud Innovators es gratuito y ofrece lo siguiente:

  • Debates, AMAs y sesiones de planificación en vivo para conocer las novedades más recientes directamente de los Googlers
  • las noticias más recientes de Google Cloud directamente en tu bandeja de entrada
  • Insignia digital y fondo de videoconferencia
  • 500 créditos de labs y aprendizaje en Skills Boost

Haz clic aquí para registrarte.