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 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 preguntas y respuestas según un conjunto de criterios.
  • Compilarás una app web simple y verificarás que se ejecute según lo previsto 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 según 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 generación de cuestionarios implementado y podrás jugar cuestionarios en vivo basados en el resultado.

Qué aprenderás

  • Cómo crear una instrucción basada en plantillas para un modelo de lenguaje grande (LLM)
  • Cómo crear una app de servidor web simple 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 cualquier persona 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 en la que se describirá qué es. 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 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 te autenticaste y que el proyecto se configuró 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. En Cloud Shell, ejecuta el siguiente comando para confirmar que el comando 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          

Si se realizó correctamente, se mostrará un mensaje similar al siguiente:

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

3. Instrucciones: Programación en lenguaje natural

92f630373224ead8.png

Primero, aprenderemos a desarrollar una instrucción para un modelo de lenguaje grande. Navega a la consola de Google Cloud > Vertex AI > Vertex AI Studio (Language). Deberías ver una página como esta:

bfe5706041ae6454.png

En Generate Text, haz clic en el botón Text Prompt. En el siguiente diálogo, ingresa una instrucción que creas que podría ser eficaz para generar un cuestionario de trivia según 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:

  • Es la región en la que 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 que se generan 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.
  • La opción Streaming responses selecciona si las respuestas se deben imprimir a medida que se generan o si se deben guardar y mostrar cuando estén completas.
  • El umbral del filtro de seguridad ajusta la probabilidad de ver 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 generara 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 a tu generador espera que los cuestionarios se expresen en JSON, que es un formato popular en varios idiomas 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 posibles respuestas a esa pregunta y una respuesta correcta. A continuación, se muestra la codificación JSON para los cuestionarios en 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 ahora genere el cuestionario en el formato JSON requerido.

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

Una vez que tengas tu instrucción que genere cuestionarios según las especificaciones deseadas, 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 de forma programática a un LLM de Vertex AI. Si te interesa usar un lenguaje de programación que no sea 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 que eso suceda, tendremos que crear un servidor web simple y hacerlo disponible de forma pública. Lo haremos en los siguientes pasos.

Para comenzar, haz clic en el botón Open Editor 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 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 de terminal arrastrando la barra horizontal entre esas dos regiones, que se destaca 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, haz clic en el botón para agregar una carpeta 5f4e64909bc15e30.png, ingresa quiz-generator y presiona Intro para crear una carpeta en la que almacenarás tu trabajo para este lab. 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 sencilla app web, usarás un módulo de Python popular 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, como se muestra a continuación:

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á 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 del proyecto:

pip3 install -r requirements.txt

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

Successfully installed flask-3.0.0

Ahora, ejecuta tu app con este comando en la terminal:

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.

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 la 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 para implementar un nuevo método llamado generate. Para ello, agrega una instrucción de importación para manipular la solicitud HTTP y modifica la ruta principal para analizar esta solicitud y los parámetros de impresión, 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 búsqueda que se agregó automáticamente a tu URL (authuser). Intenta agregar dos parámetros adicionales anexando la cadena "`&param1=val1&param2=val2`" al final de la URL en la barra de direcciones de tu navegador, vuelve a cargar la página y 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 querremos 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, difícil).
  • lang: Es el idioma deseado del 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 una página web similar a la siguiente:

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 y da formato a tu instrucción

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, difícil).
  • lang: Es el idioma deseado del cuestionario.

Copia la instrucción que desarrollaste con Vertex Generative AI Studio en un paso anterior, pero cambia los valores codificados de forma rígida para el tema, la cantidad de preguntas y el 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 existente del navegador web para ver los resultados. Deberías ver una página web similar a la siguiente:

3c2b9dfcfba86b7a.png

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

7. Agrega la biblioteca cliente de Vertex AI

Ahora ya puedes usar la biblioteca cliente de Python de Vertex AI para generar tu cuestionario. Esto automatizará las instrucciones interactivas que realizaste en el paso 3 y le dará a tu servicio de generador acceso programático a las capacidades del LLM de Google. Actualiza tu 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 existente del navegador web para ver los resultados. Ten en cuenta que esto puede tardar varios segundos porque ahora estás haciendo una solicitud al 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 para el cuestionario.

Con esto, terminaste 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 compartir esta maravilla con el resto del mundo, por lo que es hora de implementarlo en la nube. Pero te gustaría hacer algo más que 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 ajusta automáticamente: Tu app se mantendrá al día con grandes niveles de tráfico y reducirá automáticamente su huella cuando no se use.
  • Minimiza tus costos, ya que no se te cobra por los recursos que no usas. Solo se te cobra por los recursos consumidos mientras respondes al tráfico.
  • Se puede acceder a él a través de un nombre de dominio personalizado: Tienes acceso a una solución con un solo clic para asignar un nombre de dominio personalizado a tu servicio.
  • Ofrece un excelente tiempo de respuesta: los inicios en frío son razonablemente rápidos, pero puedes ajustar eso especificando una configuración de instancia mínima.
  • Admite la encriptación de extremo a extremo con la seguridad web estándar de SSL/TLS: Cuando implementas un servicio, obtienes la encriptación web estándar y los certificados requeridos correspondientes de forma gratuita y automática.

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. Dado que los contenedores se pueden usar en casi cualquier servidor virtual o real, esto nos permite implementar tu aplicación en cualquier lugar que desees, desde las instalaciones locales hasta la nube, e incluso 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 Dev to Prod in Three Easy Steps with Cloud Run.

Implementa tu app en Cloud Run

Cloud Run es un servicio regional, lo que significa que la infraestructura que ejecuta tus servicios de Cloud Run 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 el proceso, en este lab usaremos la región codificada us-central1.

Usaremos algo llamado buildpack para generar automáticamente tu 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 paquetes de compilación cómo ejecutar tu app en el contenedor generado automáticamente. A continuación, ejecuta el siguiente comando en la terminal de Cloud Shell (desde el 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, según los archivos fuente que encuentre en el directorio actual (dot en --source . es una abreviatura del directorio actual). Dado que el servicio se encarga de la imagen del contenedor de forma implícita, no es necesario que especifiques una imagen en este comando gcloud.

Espera 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)"

Debería aparecer algo similar a lo siguiente:

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

Esta URL es exclusiva y cuenta con seguridad de TLS para tu servicio de Cloud Run. Este vínculo es permanente (siempre y cuando no inhabilite su servicio) y se puede usar en cualquier lugar de Internet. No usa el mecanismo de proxy de Cloud Shell que se mencionó antes, el cual 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 puedes ajustar el cuestionario generado proporcionando parámetros al final de la URL.

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

9. Cómo unir todas las piezas

9927db1725bcd5d6.png

En este último paso, ya puedes 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 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 en 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 basada en plantillas.

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 este comando:

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

11. ¡Lo lograste!

910162be58c0f6d6.png

Felicitaciones. Creaste correctamente una instrucción de LLM y, luego, implementaste un microservicio de Cloud Run con esa instrucción. Ahora puedes programar en lenguaje natural y compartir tus creaciones con el mundo.

Quiero dejarte una pregunta importante:

Una vez que tu app funcionó en tu entorno de desarrollo, ¿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?

La respuesta, por supuesto, es cero. :)

Otros codelabs que puedes consultar:

Documentos de referencia

12. Llamado a la acción

Si disfrutaste de este codelab y es probable que pases más tiempo usando Google Cloud, te recomendamos que te unas a Google Cloud Innovators hoy mismo.

498cab7d87ec12d3.png

Google Cloud Innovators es gratuito y ofrece lo siguiente:

  • Debates, sesiones de preguntas y sesiones de planificación en vivo para conocer las novedades más recientes directamente con los Googlers
  • Las últimas noticias 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.