Crea un generador de cuestionarios con IA generativa y Cloud Run

1. Introducción

En este lab, compilarás un servicio web para generar cuestionarios de trivia y, luego, integrarlo en una app divertida y funcional. Utilizarás un lenguaje de programación distinto del que probablemente usaste 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 creación nueva.
  • Cómo integrar el 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. Si bien usarás Python, no es necesario que estés familiarizado con la programación de ese lenguaje para entender qué está sucediendo, ya que te 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 con 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.

8c1dabeca90e44e5.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.

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 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].

Habilita algunas APIs

Más adelante, 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

Comenzaremos 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 mundial
  • 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 qué modelo de lenguaje extenso deseas usar. Para este codelab, continúa con "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 k superior 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 k superior 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 se guardan, y se muestran cuando se completan.
  • El umbral del filtro de seguridad ajusta la probabilidad de ver respuestas que podrían ser dañinas.

Una vez que tengas una instrucción que parezca generar un cuestionario razonable de acuerdo con los requisitos mencionados anteriormente, podríamos analizar este cuestionario usando 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"
    },

    ...
]

Intenta modificar la instrucción para que el cuestionario muestre el formato JSON requerido.

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

Una vez que tengas la instrucción que genera cuestionarios de acuerdo con 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 tu instrucción a un LLM de Vertex AI de manera programática. 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 sencillo

c73008bb8a72b57b.png

Ahora que tienes una instrucción funcional, queremos integrarla en una app más grande. Por supuesto, podríamos incorporar tu instrucción al 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 que esto suceda, tendremos que crear un servidor web simple y hacer que esté disponible públicamente. 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 IDE similar a Visual Studio Code, en el que podrás 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

Puedes alternar entre el editor y la terminal haciendo 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ás tu trabajo para este lab. Para ello, haz clic en el botón de agregar carpeta 5f4e64909bc15e30.png, ingresa quiz-generator y presiona Intro. Todos los archivos que crees en este lab y todo el trabajo que hagas en Cloud Shell tendrán lugar en esta carpeta.

Ahora, crea un archivo requirements.txt. Esto le indica a Python de qué bibliotecas depende tu app. En esta app web sencilla, usarás un módulo popular de Python para compilar servidores web llamado Flask,, la biblioteca cliente de 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 la tecla 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 de Cloud guardará automáticamente los cambios.

Con la misma técnica, crea otro archivo nuevo llamado main.py. Este será el archivo fuente de Python principal (y único) 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)

Vuelve 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 termina de la siguiente manera:

Successfully installed flask-3.0.0

Ahora inicia tu app ejecutando este comando en la terminal:

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

En este punto, tu app se está ejecutando 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

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

aaaf366f9bf74a28.png

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

Ahora queremos agregar compatibilidad con el campo de un nuevo método llamado generate. Para ello, agrega una sentencia import a fin de manipular la solicitud HTTP y modificar la ruta principal para analizar esta solicitud y, luego, imprimir 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 existente del navegador web 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). Pruebe agregar dos parámetros adicionales. Para ello, agregue 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 esto:

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 queremos enviar a nuestro generador de cuestionarios, que son los siguientes:

  • topic: El asunto deseado para el cuestionario
  • num_q: La cantidad de preguntas deseadas
  • diff: Es el nivel de dificultad deseado (fácil, intermedio o difícil).
  • lang: El idioma deseado para el cuestionario
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 existente del navegador web 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, prueba 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: El asunto deseado para el cuestionario
  • num_q: La cantidad de preguntas deseadas
  • diff: Es el nivel de dificultad deseado (fácil, intermedio o difícil).
  • lang: El idioma deseado para el cuestionario

Copia la instrucción que desarrollaste con Vertex Generative AI Studio en un paso anterior, pero cambia los valores hard-coded para el tema, la cantidad de preguntas y el nivel de dificultad con 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 existente del navegador web para ver los resultados. Deberías ver algo como la siguiente página web:

8c2b9dfcfba86b7a.png

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

7. Agrega la biblioteca cliente de Vertex AI

Ya está todo listo para que uses la biblioteca cliente de Vertex AI para Python con el objetivo de generar tu 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 tu archivo main.py de la siguiente manera:

Asegúrate de reemplazar “YOUR_PROJECT” por el ID del 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 existente del navegador web 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 algo como la siguiente página web:

f43d3ba5102857b8.png

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

Felicitaciones. Así, tu microservicio finalizó. En el siguiente paso, aprenderás a implementar tu servicio en Cloud para que cualquiera pueda acceder a él desde cualquier lugar.

8. ¡A la nube!

67c99bf45a7b7805.png

Ahora que compilaste tu propio generador de cuestionarios, querrás compartir esta genialidad con el resto del mundo, por lo que es hora de implementarlo en Cloud. Pero realmente quieres hacer algo más que solo compartirlo. Debes asegurarte de lo siguiente:

  • funciona de manera confiable. Obtienes tolerancia a errores automática en caso de que falle una computadora que ejecuta tu aplicación.
  • Escala automáticamente: tu app se mantiene al día con los amplios niveles de tráfico y reduce automáticamente su huella cuando no se usa.
  • Minimiza los costos, ya que no te cobra por los recursos que no usas: se te cobra solo por los recursos consumidos mientras respondes al tráfico
  • es accesible con un nombre de dominio personalizado: tienes acceso a una solución de un solo clic para asignar un nombre de dominio personalizado a tu servicio
  • ofrece un tiempo de respuesta excelente: los inicios en frío responden de una manera razonable, pero se puede ajustar si especificas 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, obtendrás todo lo anterior y mucho más. El componente básico para compartir tu app con Cloud Run es un contenedor.

Los contenedores nos permiten crear una caja modular en la que se puede ejecutar una aplicación con todas sus dependencias agrupadas. Debido a que los contenedores se pueden usar en casi cualquier servidor virtual o real, esto nos proporciona una forma de implementar tu aplicación en cualquier lugar que desees, desde la infraestructura local a la nube, y hasta trasladar tu aplicación 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 Desarrolla a producción 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 los 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 lo que se llama buildpack para generar automáticamente su contenedor. Crea un archivo nuevo llamado Procfile en Cloud Editor 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). Como 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 del servicio con el siguiente 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 que no inhabilites el servicio) 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 de tu app en ejecución. Verifica que el resultado sea el mismo que viste en tu entorno de desarrollo. Además, verifica que puedas ajustar el cuestionario generado si proporcionas parámetros al final de la URL.

¡Felicitaciones! Tu app ahora se ejecuta en Google Cloud. Sin tener que pensarlo, tu app está disponible públicamente, con encriptación TLS (HTTPS) y ajuste de escala automático a niveles de tráfico asombrosos.

9. Reunir todas las piezas

9927db1725bcd5d6.png

En este paso final, ya puedes ejecutar tu 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 de URL, completa los demás campos obligatorios y envía el formulario.

328ee05579ea05f9.png

En unos momentos, deberías tener un nuevo cuestionario (consulta “Mi nuevo cuestionario” en la imagen a continuación) con una imagen de 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 según 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.

Puedes borrar tu proyecto de GCP para evitar incurrir en cargos, lo que detendrá la facturación de todos los recursos usados en ese proyecto, o simplemente borrar tu imagen de 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 este 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 una pregunta importante:

Una vez que la app funcionaba 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 para echar un vistazo...

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 también incluye lo siguiente:

  • Debates, sesiones de preguntas 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 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.