Créer un générateur de quiz avec l'IA générative et Cloud Run

1. Introduction

Dans cet atelier, vous allez créer un service Web pour générer des quiz et les intégrer dans une application fonctionnelle et amusante. Vous allez devoir utiliser un langage de programmation différent de celui que vous avez pu utiliser auparavant: l'anglais !

Ce que vous allez effectuer...

  • Vous élaborerez une requête qui générera un quiz de culture générale en fonction d'un ensemble de critères.
  • Vous allez créer une application Web simple et vérifier qu'elle s'exécute comme prévu dans votre environnement de développement.
  • Vous ajouterez progressivement une logique à votre application Web pour la transformer en serveur d'API qui génère des questionnaires en fonction d'un ensemble de paramètres d'entrée.
  • Vous verrez à quel point il est facile de déployer votre service de génération de quiz dans le cloud à l'aide de Google Cloud Run.
  • Enfin, vous configurerez une application réelle ( quizaic.com) pour qu'elle utilise le service de génération de questionnaires que vous avez déployé. Vous pourrez ensuite jouer à des quiz en direct en fonction du résultat obtenu.

Ce que vous allez apprendre...

  • Créer une requête modélisée pour un grand modèle de langage (LLM)
  • Créer une application de serveur Web simple en Python
  • Ajouter la prise en charge du LLM de Google à votre application Web
  • Découvrez comment déployer votre application dans le cloud pour que tout le monde puisse essayer votre nouvelle création.
  • Intégrer votre générateur de quiz dans une application plus volumineuse

Ce dont vous avez besoin...

  • Navigateur Web Chrome
  • Un compte Google
  • Un projet Cloud pour lequel la facturation est activée

Cet atelier s'adresse aux développeurs de tous niveaux, y compris aux débutants. Bien que vous deviez utiliser Python, vous n'avez pas besoin d'être familiarisé avec la programmation Python pour comprendre ce qui se passe, car nous allons vous expliquer tout le code que vous verrez.

2. Configuration

a08aa5878e36b60c.png

Cette section décrit tout ce que vous devez faire pour commencer cet atelier.

Configuration de l'environnement au rythme de chacun

  1. Connectez-vous à la console Google Cloud, puis créez un projet ou réutilisez un projet existant. Si vous n'avez pas encore de compte Gmail ou Google Workspace, vous devez en créer un.

fbef9caa1602edd0.png

a99b7ace416376c4.png

5e3ff691252acf41.png

  • Le nom du projet est le nom à afficher pour les participants au projet. Il s'agit d'une chaîne de caractères non utilisée par les API Google. Vous pourrez toujours le modifier.
  • L'ID du projet est unique parmi tous les projets Google Cloud et non modifiable une fois défini. La console Cloud génère automatiquement une chaîne unique (en général, vous n'y accordez d'importance particulière). Dans la plupart des ateliers de programmation, vous devrez indiquer l'ID de votre projet (généralement identifié par PROJECT_ID). Si l'ID généré ne vous convient pas, vous pouvez en générer un autre de manière aléatoire. Vous pouvez également en spécifier un et voir s'il est disponible. Après cette étape, l'ID n'est plus modifiable et restera donc le même pour toute la durée du projet.
  • Pour information, il existe une troisième valeur (le numéro de projet) que certaines API utilisent. Pour en savoir plus sur ces trois valeurs, consultez la documentation.
  1. Vous devez ensuite activer la facturation dans la console Cloud pour utiliser les ressources/API Cloud. L'exécution de cet atelier de programmation est très peu coûteuse, voire sans frais. Pour désactiver les ressources et éviter ainsi que des frais ne vous soient facturés après ce tutoriel, vous pouvez supprimer le projet ou les ressources que vous avez créées. Les nouveaux utilisateurs de Google Cloud peuvent participer au programme d'essai sans frais pour bénéficier d'un crédit de 300 $.

Démarrez Cloud Shell.

Dans cet atelier, vous allez travailler dans une session Cloud Shell, un interpréteur de commandes hébergé par une machine virtuelle exécutée dans le cloud de Google. Vous pourriez tout aussi facilement effectuer les tâches de cette section en local sur votre propre ordinateur, mais le fait d'utiliser Cloud Shell permet à chacun de bénéficier d'une expérience reproductible dans un environnement cohérent. Après l'atelier, libre à vous de reproduire cette section sur votre ordinateur.

4a95152439f0159b.png

Activer Cloud Shell

  1. Dans Cloud Console, cliquez sur Activer Cloud Shell 853e55310c205094.png.

3c1dabeca90e44e5.png

Si vous démarrez Cloud Shell pour la première fois, un écran intermédiaire vous explique de quoi il s'agit. Si un écran intermédiaire s'est affiché, cliquez sur Continuer.

9c92662c6a846a5c.png

Le provisionnement et la connexion à Cloud Shell ne devraient pas prendre plus de quelques minutes.

9f0e51b578fecce5.png

Cette machine virtuelle contient tous les outils de développement nécessaires. Elle comprend un répertoire d'accueil persistant de 5 Go et s'exécute dans Google Cloud, ce qui améliore considérablement les performances du réseau et l'authentification. Une grande partie, voire la totalité, de votre travail dans cet atelier de programmation peut être effectué dans un navigateur.

Une fois connecté à Cloud Shell, vous êtes authentifié et le projet est défini sur votre ID de projet.

  1. Exécutez la commande suivante dans Cloud Shell pour vérifier que vous êtes authentifié :
gcloud auth list

Résultat de la commande

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

To set the active account, run:
    $ gcloud config set account `ACCOUNT`
  1. Exécutez la commande suivante dans Cloud Shell pour vérifier que la commande gcloud connaît votre projet:
gcloud config list project

Résultat de la commande

[core]
project = <PROJECT_ID>

Si vous obtenez un résultat différent, exécutez cette commande :

gcloud config set project <PROJECT_ID>

Résultat de la commande

Updated property [core/project].

Activer certaines API

Lors des prochaines étapes, vous verrez où ces services sont nécessaires (et pourquoi). Pour l'instant, exécutez la commande suivante afin d'autoriser votre projet à accéder à Cloud Build, Artifact Registry, Vertex AI et Cloud Run:

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

Un message de réussite semblable à celui-ci devrait s'afficher:

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

3. Requêtes : programmation en langage naturel

92f630373224ead8.png

Nous allons commencer par apprendre à développer une requête pour un grand modèle de langage. Accédez à la console Google Cloud > Vertex AI > Vertex AI Studio (langage) Une page semblable à celle-ci doit s'afficher:

bfe5706041ae6454.png

Sous Generate Text, cliquez sur le bouton Text Prompt. Dans la boîte de dialogue suivante, saisissez une requête qui, selon vous, pourrait être efficace pour générer un quiz de culture générale selon les exigences suivantes:

  • Sujet: Histoire du monde
  • Nombre de questions: 5
  • Niveau de difficulté: intermédiaire
  • Langue : anglais

Cliquez sur le bouton "Submit" (Envoyer) pour afficher le résultat.

Comme le montre la capture d'écran suivante, le panneau de droite vous permet de sélectionner le modèle à utiliser et d'ajuster certains paramètres:

8aa89a1970ea9335.png

Voici les paramètres disponibles :

  • La région est l'endroit où votre requête de génération doit être exécutée.
  • "Modèle" sélectionne le grand modèle de langage que vous souhaitez utiliser. Pour cet atelier de programmation, conservez "gemini-1.0-pro-001".
  • La température permet de contrôler le degré de hasard dans la sélection des jetons. Des températures basses sont idéales pour les requêtes visant une réponse vraie ou correcte, tandis que des températures plus élevées peuvent entraîner des résultats plus diversifiés ou inattendus.
  • La limite de jetons détermine la quantité maximale de texte pouvant être générée à partir d'une requête. Un jeton correspond environ à quatre caractères. La valeur par défaut est 1024.
  • Top K modifie la façon dont le modèle sélectionne les jetons pour la sortie. Une valeur Top K de 1 signifie que le jeton sélectionné est le plus probable parmi tous les jetons du vocabulaire du modèle (également appelé décodage glouton), tandis qu'un Top K de 3 signifie que le jeton suivant est sélectionné parmi les trois jetons les plus probables (à l'aide de la température). La valeur de Top K est fixée par défaut à 40.
  • Top P modifie la façon dont le modèle sélectionne les jetons pour la sortie. Les jetons sont sélectionnés du plus probable au moins probable, jusqu'à ce que la somme de leurs probabilités soit égale à la valeur Top P.
  • Le nombre maximal de réponses correspond au nombre maximal de réponses du modèle générées par requête.
  • Une séquence d'arrêt est une série de caractères (espaces compris) qui arrête la génération de réponse si le modèle la rencontre.
  • Les réponses en flux continu permettent de spécifier si les réponses doivent être imprimées au fur et à mesure qu'elles sont générées ou enregistrées, puis s'affichent une fois l'opération terminée.
  • Le seuil du filtre de sécurité ajuste la probabilité que des réponses potentiellement dangereuses s'affichent.

Une fois que votre requête semble générer un quiz raisonnable selon les exigences indiquées ci-dessus, nous pouvons l'analyser à l'aide d'un code personnalisé. Mais ne serait-il pas plus pratique que le LLM génère le quiz dans un format structuré que nous pouvons charger directement dans notre programme ? Dans la suite de cet atelier, le programme que nous utiliserons pour appeler votre générateur s'attend à ce que les quiz soient exprimés au format JSON, un format multilingue populaire pour représenter des données structurées.

Dans cet atelier, les quiz sont exprimés sous la forme d'un tableau d'objets, où chaque objet contient une question, un tableau de réponses possibles à cette question et une réponse correcte. Voici l'encodage JSON des questionnaires de cet atelier:

[
    {
        "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"
    },

    ...
]

Essayez de modifier votre requête pour générer le quiz au format JSON requis.

  1. Indiquez avec des mots le format précis que vous recherchez (par exemple, la phrase en italique ci-dessus).
  2. Incluez dans votre requête un exemple du format JSON souhaité.

Une fois que votre requête génère des questionnaires selon la spécification souhaitée, cliquez sur le bouton GET CODE en haut à droite de la page pour afficher le code Python permettant d'envoyer votre requête de manière programmatique à un LLM Vertex AI. Si vous souhaitez utiliser un langage de programmation autre que Python, consultez la page https://cloud.google.com/vertex-ai/docs/samples?text=generative.

4. Créer un serveur Web simple

c73008bb8a72b57b.png

Maintenant que vous disposez d'une requête fonctionnelle, nous voulons l'intégrer à une application plus volumineuse. Bien entendu, nous pourrions intégrer votre requête dans le code source de l'application dans son ensemble, mais nous voulons que votre générateur fonctionne comme un microservice fournissant un service de génération de questionnaires pour les autres applications. Pour ce faire, nous devons créer un serveur Web simple et le rendre public. C'est ce que nous allons faire au cours des prochaines étapes.

Commencez par cliquer sur le bouton Open Editor en haut de votre panneau Cloud Shell. Elle se présente comme suit :

e2a06b5304079efc.png

Vous vous trouverez ensuite dans un environnement IDE semblable à Visual Studio Code, dans lequel vous pouvez créer des projets, modifier le code source, exécuter vos programmes, etc.

Si votre écran est trop étroit, vous pouvez agrandir ou réduire la séparation entre la console et la fenêtre de modification/terminal en faisant glisser la barre horizontale située entre ces deux zones, mises en surbrillance ici:

8dea35450851af53.png

Vous pouvez passer de l'éditeur au terminal en cliquant respectivement sur les boutons Open Editor et Open Terminal. Essayez de passer d'un environnement à l'autre dès maintenant.

Ensuite, créez un dossier dans lequel stocker votre travail pour cet atelier. Pour ce faire, cliquez sur le bouton Ajouter un dossier 5f4e64909bc15e30.png, saisissez quiz-generator, puis appuyez sur Entrée. Tous les fichiers que vous créerez dans cet atelier, ainsi que tout le travail que vous effectuerez dans Cloud Shell, seront stockés dans ce dossier.

Créez maintenant un fichier requirements.txt. Cela indique à Python de quelles bibliothèques dépend votre application. Pour cette application Web simple, vous allez utiliser un module Python populaire permettant de créer des serveurs Web, appelé Flask,, la bibliothèque cliente google-cloud-aiplatform, et un framework de serveur Web appelé gunicorn. Dans le volet de navigation des fichiers, effectuez un clic droit sur le dossier quiz-generator, puis sélectionnez l'élément de menu New file, comme suit:

613eb3de4b9b750a.png

Lorsque vous êtes invité à saisir le nom du nouveau fichier, saisissez requirements.txt et appuyez sur la touche Entrée. Assurez-vous que le nouveau fichier se trouve dans le dossier du projet quiz-generator.

Collez les lignes suivantes dans le nouveau fichier pour indiquer que votre application dépend du package Python flask, du serveur Web gunicorn, de la bibliothèque cliente google-cloud-aiplatform, ainsi que des versions associées de chacun d'eux.

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

Vous n'avez pas besoin d'enregistrer explicitement ce fichier, car l'éditeur Cloud enregistre automatiquement les modifications pour vous.

En utilisant la même technique, créez un autre fichier nommé main.py. Il s'agit du fichier source Python principal (et unique) de votre application. Là encore, assurez-vous que le nouveau fichier se trouve dans le dossier quiz-generator.

Insérez le code suivant dans ce fichier:

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)

Revenez au terminal et accédez au dossier du projet à l'aide de cette commande:

cd quiz-generator

Exécutez la commande suivante pour installer les dépendances de votre projet:

pip3 install -r requirements.txt

Après avoir installé les dépendances, vous devriez voir une sortie qui se termine comme ceci:

Successfully installed flask-3.0.0

À présent, lancez votre application en exécutant la commande suivante dans le terminal:

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

À ce stade, votre application s'exécute sur la machine virtuelle dédiée à votre session Cloud Shell. Cloud Shell inclut un mécanisme de proxy qui vous permet d'accéder aux serveurs Web (comme celui que vous venez de commencer) exécutés sur votre machine virtuelle depuis n'importe où sur Internet.

Cliquez sur le bouton web preview, puis sur l'élément de menu Preview on Port 8080 comme suit:

7f938c0bc1b4154c.png

Un onglet de navigateur Web s'ouvre pour votre application en cours d'exécution, qui devrait ressembler à ceci:

aaaf366f9bf74a28.png

5. Ajouter une méthode "generate" avec analyse des paramètres

Nous voulons maintenant ajouter la prise en charge du champ d'une nouvelle méthode appelée generate. Pour ce faire, ajoutez une instruction d'importation pour manipuler la requête HTTP et modifiez la route principale pour analyser cette requête et les paramètres d'impression, comme suit:

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)

À présent, actualisez l'onglet de votre navigateur Web pour voir les résultats. Cette fois, vous devriez voir le "Générateur de quiz" et un paramètre de requête ajouté automatiquement à votre URL (authuser). Essayez d'ajouter deux autres paramètres en y ajoutant la chaîne "`&param1=val1&param2=val2}" à la fin de l'URL dans la barre d'adresse de votre navigateur, actualisez la page. Vous devriez obtenir un résultat semblable au suivant:

6e223ca358e4e009.png

Maintenant que nous avons vu comment envoyer et analyser les paramètres de requête d'une URL, nous allons prendre en charge les paramètres spécifiques que nous voulons envoyer au générateur de quiz, qui est le suivant:

  • topic : objet du questionnaire souhaité
  • num_q : nombre de questions souhaitées
  • diff : niveau de difficulté souhaité (facile, intermédiaire, difficile)
  • lang : la langue souhaitée pour le questionnaire
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)

À présent, actualisez l'onglet de votre navigateur Web pour voir les résultats. Une page Web semblable à la suivante doit s'afficher:

15eed60f6a805212.png

Essayez de modifier l'URL pour définir des valeurs pour différents paramètres. Par exemple, essayez d'utiliser le suffixe "?authuser=0&topic=Literature&num_q=10&diff=easy&lang=French" à la fin de l'URL dans la barre d'adresse:

f629dba5fa207cef.png

6. Ajouter et mettre en forme votre requête

Nous allons maintenant prendre en charge les paramètres spécifiques que nous voulons envoyer à notre générateur de quiz, qui sont les suivants:

  • topic : objet du questionnaire souhaité
  • num_q : nombre de questions souhaitées
  • diff : niveau de difficulté souhaité (facile, intermédiaire, difficile)
  • lang : la langue souhaitée pour le questionnaire

Copiez la requête que vous avez développée avec Vertex Generative AI Studio précédemment, mais modifiez les valeurs codées en dur pour le sujet, le nombre de questions et le niveau de difficulté à l'aide des chaînes suivantes:

  • {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)

À présent, actualisez l'onglet de votre navigateur Web pour voir les résultats. Une page Web semblable à la suivante doit s'afficher:

3c2b9dfcfba86b7a.png

Essayez de modifier l'URL pour changer ces quatre paramètres.

7. Ajouter la bibliothèque cliente Vertex AI

Nous sommes maintenant prêts à utiliser la bibliothèque cliente Vertex AI Python pour générer votre quiz. Cela automatisera les requêtes interactives exécutées à l'étape 3 et donnera à votre service de générateur un accès programmatique aux capacités des LLM de Google. Mettez à jour votre fichier main.py comme suit:

Veillez à remplacer "YOUR_PROJECT" par l'ID de votre projet.

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)

À présent, actualisez l'onglet de votre navigateur Web pour voir les résultats. Notez que cette opération peut prendre plusieurs secondes, car vous envoyez en fait une requête LLM. Une page Web semblable à la suivante doit s'afficher:

f43d3ba5102857b8.png

Modifiez l'URL pour que le sujet, le nombre de questions et le niveau de difficulté du quiz soient différents.

Votre microservice est maintenant terminé. Félicitations ! À l'étape suivante, vous allez apprendre à déployer votre service dans le cloud pour que tous les utilisateurs puissent y accéder où qu'ils se trouvent.

8. Vers le cloud !

67c99bf45a7b7805.png

Maintenant que vous avez créé votre propre générateur de questionnaires, vous allez pouvoir faire découvrir ces enseignements au reste du monde. Il est donc temps de le déployer dans le cloud. Mais vous aimeriez vraiment faire plus que simplement la partager. Vous voulez vous assurer qu'il:

  • s'exécute de manière fiable : vous bénéficiez d'une tolérance aux pannes automatique en cas de plantage d'un ordinateur exécutant votre application.
  • évolue automatiquement : votre application peut faire face à des niveaux de trafic importants et réduire automatiquement son encombrement lorsqu'elle n'est pas utilisée
  • réduit vos coûts en ne facturant pas les ressources que vous n'utilisez pas (vous ne payez que pour les ressources consommées lors de la réponse au trafic)
  • est accessible via un nom de domaine personnalisé. Vous avez ainsi accès à une solution en un clic pour attribuer un nom de domaine personnalisé à votre service.
  • offre un excellent temps de réponse. Les démarrages à froid sont raisonnablement réactifs, mais vous pouvez affiner ce paramètre en spécifiant une configuration minimale d'instance.
  • est compatible avec le chiffrement de bout en bout à l'aide de la sécurité Web standard SSL/TLS : lorsque vous déployez un service, vous bénéficiez du chiffrement Web standard et des certificats correspondants requis sans frais et automatiquement.

En déployant votre application sur Google Cloud Run, vous bénéficiez de tout ce qui précède et de bien d'autres. Le conteneur est l'élément de base du partage d'une application avec Cloud Run.

Les conteneurs nous permettent de créer une zone modulaire dans laquelle exécuter une application avec toutes ses dépendances regroupées. Comme les conteneurs peuvent être utilisés sur presque tous les serveurs virtuels ou réels, cela nous permet de déployer votre application où vous le souhaitez, de votre environnement sur site vers le cloud, et même de la déplacer d'un fournisseur de services à un autre.

Pour en savoir plus sur les conteneurs et leur fonctionnement dans Google Cloud Run, consultez l'atelier de programmation Développement en production en trois étapes simples avec Cloud Run.

Déployer votre application sur Cloud Run

Cloud Run est un service régional, ce qui signifie que l'infrastructure qui exécute vos services Cloud Run est située dans une région spécifique et gérée par Google pour être disponible de manière redondante dans toutes les zones de cette région. Pour plus de simplicité, dans cet atelier, nous utiliserons la région codée en dur us-central1.

Nous allons utiliser ce qu'on appelle un pack de création pour générer automatiquement votre conteneur. Créez un fichier nommé Procfile dans l'éditeur Cloud et insérez cette ligne de texte:

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

Cela indique au système buildpack comment exécuter votre application dans le conteneur généré automatiquement. Exécutez ensuite la commande suivante dans le terminal Cloud Shell (à partir du même répertoire quiz-generator) :

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

Cela indique à la commande gcloud que vous souhaitez qu'elle utilise des buildpacks pour créer votre image de conteneur, en fonction des fichiers sources qu'elle trouve dans le répertoire actuel (dot dans --source . est un raccourci pour le répertoire actuel). Comme le service gère implicitement l'image de conteneur, vous n'avez pas besoin de spécifier une image dans cette commande gcloud.

Patientez quelques instants jusqu'à la fin du déploiement. Si l'opération réussit, la commande gcloud affiche l'URL du nouveau service:

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

Vous pouvez également récupérer l'URL de votre service à l'aide de cette commande:

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

Le résultat devrait ressembler à ceci:

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

Ce lien est une URL dédiée, avec la sécurité TLS, à votre service Cloud Run. Ce lien est permanent (tant que vous ne désactivez pas votre service) et peut être utilisé partout sur Internet. Il n'utilise pas le mécanisme de proxy de Cloud Shell mentionné précédemment, qui dépend d'une machine virtuelle temporaire.

Cliquez sur le Service URL mis en évidence pour ouvrir un onglet de navigateur Web pour votre application en cours d'exécution. Vérifiez que le résultat est identique à celui obtenu dans votre environnement de développement. Vérifiez également que vous pouvez ajuster le questionnaire généré en fournissant des paramètres à la fin de l'URL.

Félicitations ! Votre application s'exécute désormais dans Google Cloud. Sans que vous ayez à vous en préoccuper, votre application est accessible au public, avec le chiffrement TLS (HTTPS) et un scaling automatique jusqu'à des niveaux de trafic époustouflants.

9. Assembler toutes les pièces

9927db1725bcd5d6.png

Lors de cette dernière étape, nous sommes prêts à exécuter votre générateur de quiz dans l'application Quizaic. Accédez à l'URL quizaic, connectez-vous à votre compte Google, puis accédez à l'onglet Create Quiz. Sélectionnez le type de générateur Custom, collez votre URL Cloud Run dans le champ d'URL, remplissez les autres champs obligatoires, puis envoyez le formulaire.

328ee05579ea05f9.png

Vous devriez avoir un nouveau quiz dans quelques instants (voir "Mon nouveau quiz" dans l'image ci-dessous) avec une vignette générée par IA. Vous pourrez ensuite modifier, lire, cloner ou supprimer le questionnaire à l'aide des boutons correspondants. Ce nouveau quiz a été créé à l'aide du service Web que vous venez de déployer, à partir de votre requête modélisée.

1719169140978b63.png

10. Nettoyage

c1592d590c563428.png

Bien que le service Cloud Run ne soit pas facturé lorsqu'il n'est pas utilisé, il se peut que des frais vous incombent pour le stockage de l'image de conteneur générée.

Vous pouvez soit supprimer votre projet GCP pour éviter que des frais ne vous soient facturés, ce qui interrompra la facturation de toutes les ressources utilisées dans ce projet, ou supprimer simplement votre image de conteneur à l'aide de la commande suivante:

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>

Pour supprimer votre service Cloud Run, utilisez la commande suivante:

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

11. Bravo !

910162be58c0f6d6.png

Félicitations ! Vous avez créé une requête LLM et déployé un microservice Cloud Run à l'aide de cette requête. Vous pouvez désormais programmer en langage naturel et partager vos créations avec le monde entier !

Je voudrais vous poser une question importante:

Une fois que votre application fonctionne dans votre environnement de développement, combien de lignes de code avez-vous dû modifier pour la déployer dans le cloud, avec tous les attributs de niveau production proposés par Cloud Run ?

Bien entendu, la réponse est zéro.

Autres ateliers de programmation à découvrir...

Documents de référence...

12. Incitation à l'action

Si vous avez apprécié cet atelier de programmation et que vous êtes susceptible de passer plus de temps à vous familiariser avec Google Cloud, rejoignez le programme Google Cloud Innovators dès aujourd'hui !

498cab7d87ec12d3.png

Le programme Google Cloud Innovators est sans frais et inclut:

  • Discussions, sessions AMA et sessions sur la feuille de route en direct pour découvrir les dernières actualités directement auprès des Googleurs
  • Les dernières actualités Google Cloud directement dans votre boîte de réception
  • Badge numérique et arrière-plan de la visioconférence
  • 500 crédits d'ateliers et de formations sur Skills Boost

Cliquez ici pour vous inscrire.