Tworzenie generatora quizów za pomocą generatywnej AI i Cloud Run

1. Wprowadzenie

W tym module utworzysz usługę internetową do generowania quizów z ciekawostkami i zintegrujesz ją z zabawną, działającą aplikacją. Będziesz używać innego języka programowania niż dotychczas: angielskiego.

Co musisz zrobić...

  • Utworzysz prompta, który wygeneruje quiz z pytaniami na podstawie określonych kryteriów.
  • Utworzysz prostą aplikację internetową i sprawdzisz, czy działa ona zgodnie z oczekiwaniami w środowisku programistycznym.
  • Będziesz stopniowo dodawać logikę do aplikacji internetowej, aby przekształcić ją w serwer interfejsu API, który generuje quizy zgodnie z zestawem parametrów wejściowych.
  • Zobaczysz, jak łatwo wdrożyć usługę generowania quizów w chmurze za pomocą Google Cloud Run.
  • Na koniec skonfigurujesz prawdziwą aplikację ( quizaic.com), aby korzystała z wdrożonej usługi generatora quizów, i będziesz mieć możliwość przeprowadzania quizów na żywo na podstawie wygenerowanych wyników.

Czego się nauczysz...

  • Jak utworzyć prompt oparty na szablonie dla dużego modelu językowego (LLM).
  • Jak utworzyć prostą aplikację serwera WWW w Pythonie.
  • Jak dodać obsługę dużego modelu językowego Google do aplikacji internetowej.
  • Jak wdrożyć aplikację w chmurze, aby każdy mógł wypróbować Twoje nowe dzieło.
  • Jak zintegrować generator quizów z większą aplikacją.

Co będzie Ci potrzebne...

  • przeglądarki Chrome,
  • konto Google,
  • Projekt w chmurze z włączonymi płatnościami

Ten moduł jest przeznaczony dla deweloperów na wszystkich poziomach zaawansowania, w tym dla początkujących. Chociaż będziesz używać Pythona, nie musisz znać tego języka programowania, aby zrozumieć, co się dzieje, ponieważ wyjaśnimy cały kod, który zobaczysz.

2. Konfiguracja

a08aa5878e36b60c.png

W tej sekcji znajdziesz wszystko, co musisz zrobić, aby rozpocząć ten moduł.

Samodzielne konfigurowanie środowiska

  1. Zaloguj się w konsoli Google Cloud i utwórz nowy projekt lub użyj istniejącego. Jeśli nie masz jeszcze konta Gmail ani Google Workspace, musisz je utworzyć.

fbef9caa1602edd0.png

a99b7ace416376c4.png

5e3ff691252acf41.png

  • Nazwa projektu to wyświetlana nazwa uczestników tego projektu. Jest to ciąg znaków, który nie jest używany przez interfejsy API Google. Zawsze możesz ją zaktualizować.
  • Identyfikator projektu jest unikalny we wszystkich projektach Google Cloud i nie można go zmienić po ustawieniu. Konsola Cloud automatycznie generuje unikalny ciąg znaków. Zwykle nie musisz się tym przejmować. W większości ćwiczeń z programowania musisz odwoływać się do identyfikatora projektu (zwykle oznaczanego jako PROJECT_ID). Jeśli wygenerowany identyfikator Ci się nie podoba, możesz wygenerować inny losowy identyfikator. Możesz też spróbować własnej nazwy i sprawdzić, czy jest dostępna. Po tym kroku nie można go zmienić i pozostaje on taki przez cały czas trwania projektu.
  • Warto wiedzieć, że istnieje też trzecia wartość, numer projektu, której używają niektóre interfejsy API. Więcej informacji o tych 3 wartościach znajdziesz w dokumentacji.
  1. Następnie musisz włączyć płatności w konsoli Cloud, aby korzystać z zasobów i interfejsów API Google Cloud. Wykonanie tego laboratorium nie będzie kosztować dużo, a może nawet nic. Aby wyłączyć zasoby i uniknąć naliczania opłat po zakończeniu tego samouczka, możesz usunąć utworzone zasoby lub projekt. Nowi użytkownicy Google Cloud mogą skorzystać z bezpłatnego okresu próbnego, w którym mają do dyspozycji środki w wysokości 300 USD.

Uruchom Cloud Shell.

W tym module będziesz pracować w sesji Cloud Shell, czyli w interpreterze poleceń hostowanym przez maszynę wirtualną działającą w chmurze Google. Możesz równie łatwo uruchomić tę sekcję lokalnie na własnym komputerze, ale korzystanie z Cloud Shell zapewnia wszystkim możliwość odtworzenia działania w spójnym środowisku. Po zakończeniu modułu możesz spróbować ponownie wykonać tę sekcję na własnym komputerze.

4a95152439f0159b.png

Aktywowanie Cloud Shell

  1. W konsoli Cloud kliknij Aktywuj Cloud Shell 853e55310c205094.png.

3c1dabeca90e44e5.png

Jeśli uruchamiasz Cloud Shell po raz pierwszy, zobaczysz ekran pośredni z opisem tego środowiska. Jeśli pojawił się ekran pośredni, kliknij Dalej.

9c92662c6a846a5c.png

Uzyskanie dostępu do środowiska Cloud Shell i połączenie się z nim powinno zająć tylko kilka chwil.

9f0e51b578fecce5.png

Ta maszyna wirtualna zawiera wszystkie potrzebne narzędzia dla programistów. Zawiera również stały katalog domowy o pojemności 5 GB i działa w Google Cloud, co znacznie zwiększa wydajność sieci i usprawnia proces uwierzytelniania. Większość zadań w tym module, a być może wszystkie, możesz wykonać w przeglądarce.

Po połączeniu z Cloud Shell zobaczysz, że uwierzytelnianie zostało już przeprowadzone, a projekt jest już ustawiony na Twój identyfikator projektu.

  1. Aby potwierdzić, że uwierzytelnianie zostało przeprowadzone, uruchom w Cloud Shell to polecenie:
gcloud auth list

Wynik polecenia

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

To set the active account, run:
    $ gcloud config set account `ACCOUNT`
  1. Aby potwierdzić, że polecenie gcloud zna Twój projekt, uruchom w Cloud Shell to polecenie:
gcloud config list project

Wynik polecenia

[core]
project = <PROJECT_ID>

Jeśli nie, możesz go ustawić za pomocą tego polecenia:

gcloud config set project <PROJECT_ID>

Wynik polecenia

Updated property [core/project].

Włączanie niektórych interfejsów API

W dalszych krokach dowiesz się, gdzie i dlaczego te usługi są potrzebne. Na razie uruchom to polecenie, aby przyznać projektowi dostęp do Cloud Build, Artifact Registry, Vertex AI i Cloud Run:

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

Powinien wyświetlić się komunikat o powodzeniu podobny do tego:

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

3. Promptowanie – programowanie w języku naturalnym

92f630373224ead8.png

Zaczniemy od nauki tworzenia promptów dla dużego modelu językowego. Otwórz konsolę Google Cloud > Vertex AI > Vertex AI Studio (Język). Powinna pojawić się strona podobna do tej:

bfe5706041ae6454.png

W sekcji Generate Text kliknij przycisk Text Prompt. W następnym oknie wpisz prompt, który Twoim zdaniem może być skuteczny w generowaniu quizu zgodnie z tymi wymaganiami:

  • Temat: historia świata
  • Liczba pytań: 5
  • Poziom trudności: średniozaawansowany
  • Język: angielski

Aby zobaczyć dane wyjściowe, kliknij przycisk Prześlij.

Jak widać na zrzucie ekranu poniżej, w panelu po prawej stronie możesz wybrać model, którego chcesz użyć, i dostosować niektóre ustawienia:

8aa89a1970ea9335.png

Dostępne są te ustawienia:

  • Region, w którym ma być uruchomione żądanie generowania.
  • Model wybiera duży model językowy, którego chcesz używać. W tym ćwiczeniu używaj modelu „gemini-1.0-pro-001”.
  • Temperatura decyduje o stopniu losowości wyboru tokenów. Niższe temperatury są przydatne w przypadku promptów, na które oczekuje się prawdziwej lub poprawnej odpowiedzi, a wyższe mogą prowadzić do bardziej różnorodnych lub nieoczekiwanych wyników.
  • Limit tokenów określa maksymalną ilość tekstu generowanego w odpowiedzi na jeden prompt. Token ma około 4 znaków. Wartość domyślna to 1024.
  • Parametr Top-K zmienia sposób, w jaki model wybiera tokeny w celu wygenerowania odpowiedzi. Top-K o wartości 1 oznacza, że wybierany jest najbardziej prawdopodobny token spośród wszystkich tokenów w słowniku modelu (jest to też nazywane dekodowaniem zachłannym), natomiast Top-K o wartości 3 oznacza, że następny token jest wybierany spośród 3 najbardziej prawdopodobnych (z użyciem temperatury). Wartość domyślna parametru górnego K to 40.
  • Parametr Top-P zmienia sposób, w jaki model wybiera tokeny w celu wygenerowania odpowiedzi. Tokeny są wybierane od najbardziej do najmniej prawdopodobnego do momentu, aż suma ich prawdopodobieństw będzie równa wartości Top-P.
  • Maksymalna liczba odpowiedzi to maksymalna liczba odpowiedzi modelu generowanych na 1 prompta.
  • Sekwencja zatrzymania to seria znaków (łącznie ze spacjami), która zatrzymuje generowanie odpowiedzi, jeśli model ją napotka.
  • Przesyłanie odpowiedzi na bieżąco określa, czy odpowiedzi mają być drukowane w miarę ich generowania, czy zapisywane i wyświetlane po zakończeniu.
  • Próg filtra bezpieczeństwa dostosowuje prawdopodobieństwo napotkania odpowiedzi, które mogą być szkodliwe.

Gdy uzyskasz prompt, który wydaje się generować rozsądny quiz zgodnie z wymaganiami wymienionymi powyżej, możemy przeanalizować ten quiz za pomocą niestandardowego kodu. Czy nie byłoby jednak lepiej, gdyby LLM generował quiz w ustrukturyzowanym formacie, który możemy bezpośrednio wczytać do naszego programu? Program, którego użyjemy w dalszej części tego laboratorium do wywoływania generatora, oczekuje, że quizy będą wyrażone w formacie JSON, który jest popularnym formatem międzyjęzykowym do reprezentowania danych strukturalnych.

Quizy w tym laboratorium są wyrażone jako tablica obiektów, z których każdy zawiera pytanie, tablicę możliwych odpowiedzi na to pytanie i poprawną odpowiedź. Oto kodowanie JSON dla quizów w tym module:

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

    ...
]

Sprawdź, czy możesz zmodyfikować prompt, aby quiz był teraz generowany w wymaganym formacie JSON.

  1. Opisz słowami dokładny format, którego szukasz (np. powyższe zdanie zapisane kursywą).
  2. W prompcie podaj przykład pożądanego formatu JSON.

Gdy prompt będzie generować quizy zgodnie z Twoimi oczekiwaniami, kliknij przycisk GET CODE w prawym górnym rogu strony, aby wyświetlić kod w języku Python, który można wykorzystać do programowego przesyłania prompta do modelu LLM Vertex AI. Jeśli chcesz używać innego języka programowania niż Python, zajrzyj na https://cloud.google.com/vertex-ai/docs/samples?text=generative.

4. Tworzenie prostego serwera WWW

c73008bb8a72b57b.png

Teraz, gdy masz już działający prompt, chcemy zintegrować go z większą aplikacją. Oczywiście możemy umieścić prompt w kodzie źródłowym większej aplikacji, ale chcemy, aby generator działał jako mikroserwis, który udostępnia usługę generowania quizów dla innych aplikacji. Aby to zrobić, musimy utworzyć prosty serwer WWW i udostępnić go publicznie. Zrobimy to w kolejnych krokach.

Zacznij od kliknięcia przycisku Open Editor u góry panelu Cloud Shell. Wygląda on następująco:

e2a06b5304079efc.png

Następnie przejdziesz do środowiska IDE podobnego do Visual Studio Code, w którym możesz tworzyć projekty, edytować kod źródłowy, uruchamiać programy itp.

Jeśli ekran jest zbyt mały, możesz powiększyć lub zmniejszyć linię podziału między konsolą a oknem edycji lub terminala, przeciągając poziomy pasek między tymi dwoma obszarami, który jest tutaj wyróżniony:

8dea35450851af53.png

Możesz przełączać się między edytorem a terminalem, klikając odpowiednio przyciski Open EditorOpen Terminal. Spróbuj teraz przełączać się między tymi dwoma środowiskami.

Następnie utwórz folder, w którym będziesz przechowywać pliki z tego modułu. W tym celu kliknij przycisk dodawania folderu 5f4e64909bc15e30.png, wpisz quiz-generator i naciśnij Enter. Wszystkie pliki utworzone w tym module i wszystkie zadania wykonane w Cloud Shell będą znajdować się w tym folderze.

Teraz utwórz plik requirements.txt. Dzięki temu Python wie, od których bibliotek zależy Twoja aplikacja. W przypadku tej prostej aplikacji internetowej użyjesz popularnego modułu Pythona do tworzenia serwerów WWW o nazwie Flask, biblioteka klienta google-cloud-aiplatform oraz platformy serwera WWW o nazwie gunicorn. W panelu nawigacji po plikach kliknij prawym przyciskiem myszy folder quiz-generator i wybierz element menu New file, jak pokazano poniżej:

613eb3de4b9b750a.png

Gdy pojawi się prośba o podanie nazwy nowego pliku, wpisz requirements.txt i naciśnij klawisz Enter. Upewnij się, że nowy plik trafił do folderu projektu quiz-generator.

Wklej do nowego pliku te wiersze, aby określić, że Twoja aplikacja jest zależna od pakietu Pythona flask, serwera WWW gunicorn i biblioteki klienta google-cloud-aiplatform wraz z odpowiednimi wersjami każdego z nich.

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

Nie musisz zapisywać tego pliku, ponieważ Edytor w chmurze automatycznie zapisuje zmiany.

Korzystając z tej samej techniki, utwórz kolejny nowy plik o nazwie main.py. Będzie to główny (i jedyny) plik źródłowy Pythona w Twojej aplikacji. Ponownie upewnij się, że nowy plik trafił do folderu quiz-generator.

Wstaw do tego pliku ten kod:

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)

Wróć do terminala i przejdź do folderu projektu za pomocą tego polecenia:

cd quiz-generator

Aby zainstalować zależności projektu, uruchom to polecenie:

pip3 install -r requirements.txt

Po zainstalowaniu zależności powinny pojawić się dane wyjściowe kończące się w ten sposób:

Successfully installed flask-3.0.0

Teraz uruchom aplikację, wpisując w terminalu to polecenie:

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

W tym momencie aplikacja działa na maszynie wirtualnej przypisanej do sesji Cloud Shell. Cloud Shell zawiera mechanizm proxy, który umożliwia dostęp do serwerów internetowych (takich jak ten, który właśnie został uruchomiony) działających na maszynie wirtualnej z dowolnego miejsca w globalnej sieci internet.

Kliknij przycisk web preview, a następnie element menu Preview on Port 8080:

7f938c0bc1b4154c.png

Spowoduje to otwarcie karty przeglądarki z aplikacją do biegania, która powinna wyglądać mniej więcej tak:

aaaf366f9bf74a28.png

5. Dodawanie metody generowania z parsowaniem parametrów

Chcemy teraz dodać obsługę nowego pola o nazwie generate. Aby to zrobić, dodaj instrukcję importu, która będzie manipulować żądaniem HTTP i modyfikować główną trasę w celu przeanalizowania tego żądania i wydrukowania parametrów, jak pokazano poniżej:

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)

Teraz wczytaj ponownie istniejącą kartę przeglądarki, aby zobaczyć wyniki. Tym razem powinna się wyświetlić „Generator quizów” wraz z parametrem zapytania automatycznie dodanym do adresu URL (authuser). Spróbuj dodać 2 dodatkowe parametry, dopisując ciąg znaków „`&param1=val1&param2=val2`” na końcu adresu URL na pasku adresu przeglądarki. Odśwież stronę. Powinno się wyświetlić coś takiego:

6e223ca358e4e009.png

Teraz, gdy wiemy już, jak wysyłać i parsować parametry zapytania w adresie URL, dodamy obsługę konkretnych parametrów, które chcemy wysyłać do generatora quizów. Są to:

  • topic – wybrany temat quizu.
  • num_q – liczba pytań, które chcesz zadać.
  • diff – wybrany poziom trudności (łatwy, średni, trudny).
  • lang – wybrany język testu.
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)

Teraz wczytaj ponownie istniejącą kartę przeglądarki, aby zobaczyć wyniki. Powinna pojawić się strona internetowa podobna do tej:

15eed60f6a805212.png

Spróbuj zmienić adres URL, aby ustawić wartości różnych parametrów. Na przykład spróbuj użyć sufiksu „?authuser=0&topic=Literature&num_q=10&diff=easy&lang=French” na końcu adresu URL w pasku adresu:

f629dba5fa207cef.png

6. Dodawanie i formatowanie prompta

Następnie dodamy obsługę konkretnych parametrów, które chcemy wysyłać do generatora quizów. Są to:

  • topic – wybrany temat quizu.
  • num_q – liczba pytań, które chcesz zadać.
  • diff – wybrany poziom trudności (łatwy, średni, trudny).
  • lang – wybrany język testu.

Skopiuj prompt opracowany w Vertex Generative AI Studio w poprzednim kroku, ale zmień zakodowane na stałe wartości tematu, liczby pytań i poziomu trudności na te ciągi znaków:

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

Teraz wczytaj ponownie istniejącą kartę przeglądarki, aby zobaczyć wyniki. Powinna pojawić się strona internetowa podobna do tej:

3c2b9dfcfba86b7a.png

Spróbuj zmodyfikować adres URL, aby zmienić te 4 parametry.

7. Dodawanie biblioteki klienta Vertex AI

Teraz możemy użyć biblioteki klienta Vertex AI w Pythonie, aby wygenerować quiz. Spowoduje to zautomatyzowanie interaktywnego promptowania, które zostało wykonane w kroku 3, i zapewni usłudze generatora programowy dostęp do funkcji modeli LLM Google. Zaktualizuj plik main.py w ten sposób:

Pamiętaj, aby zastąpić „YOUR_PROJECT” identyfikatorem swojego projektu.

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)

Teraz wczytaj ponownie istniejącą kartę przeglądarki, aby zobaczyć wyniki. Pamiętaj, że może to potrwać kilka sekund, ponieważ teraz wysyłasz żądanie do LLM. Powinna pojawić się strona internetowa podobna do tej:

f43d3ba5102857b8.png

Spróbuj zmodyfikować adres URL, aby poprosić o inny temat quizu, liczbę pytań i poziom trudności.

To wszystko. Twój mikroserwis jest gotowy. Gratulacje! W następnym kroku dowiesz się, jak wdrożyć usługę w chmurze, aby każdy mógł uzyskać do niej dostęp z dowolnego miejsca.

8. Do chmury!

67c99bf45a7b7805.png

Gdy już utworzysz własny generator quizów, zechcesz podzielić się nim ze światem, więc czas wdrożyć go w chmurze. Chcesz jednak zrobić coś więcej niż tylko udostępnić film. Chcesz mieć pewność, że:

  • działa niezawodnie – w przypadku awarii komputera, na którym działa aplikacja, automatycznie uzyskasz odporność na błędy;
  • automatycznie się skaluje – Twoja aplikacja będzie w stanie obsłużyć ogromny ruch i automatycznie zmniejszy swoje wykorzystanie, gdy nie będzie używana;
  • minimalizuje koszty, ponieważ nie obciąża Cię opłatami za zasoby, których nie używasz – opłaty są naliczane tylko za zasoby wykorzystywane podczas odpowiadania na ruch;
  • jest dostępna pod niestandardową nazwą domeny – masz dostęp do rozwiązania, które pozwala przypisać do usługi niestandardową nazwę domeny jednym kliknięciem;
  • oferuje doskonały czas reakcji – uruchomienia „na zimno” są dość szybkie, ale możesz je dostroić, określając konfigurację minimalnej liczby instancji;
  • obsługuje szyfrowanie typu end-to-end za pomocą standardowego zabezpieczenia internetowego SSL/TLS – gdy wdrażasz usługę, automatycznie i bezpłatnie otrzymujesz standardowe szyfrowanie internetowe oraz odpowiednie wymagane certyfikaty;

Wdrażając aplikację w Google Cloud Run, uzyskasz wszystkie wymienione wyżej korzyści i nie tylko. Podstawowym elementem składowym udostępniania aplikacji w Cloud Run jest kontener.

Kontenery umożliwiają tworzenie modułowych „pudełek”, w których można uruchamiać aplikacje wraz ze wszystkimi zależnościami. Kontenery można stosować na niemal każdym serwerze wirtualnym lub fizycznym, co pozwala nam wdrażać aplikację w dowolnym miejscu, od środowiska lokalnego po chmurę, a nawet przenosić ją od jednego dostawcy usług do drugiego.

Więcej informacji o kontenerach i ich działaniu w Google Cloud Run znajdziesz w samouczku Dev to Prod in Three Easy Steps with Cloud Run.

Wdrażanie aplikacji w Cloud Run

Cloud Run to usługa regionalna, co oznacza, że infrastruktura, na której działają usługi Cloud Run, znajduje się w określonym regionie i jest zarządzana przez Google w taki sposób, aby była redundantnie dostępna we wszystkich strefach w tym regionie. W tym module dla uproszczenia użyjemy zakodowanego na stałe regionu us-central1.

Użyjemy narzędzia o nazwie buildpack, aby automatycznie wygenerować kontener. W edytorze Cloud Shell utwórz nowy plik o nazwie Procfile i wstaw ten wiersz tekstu:

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

Informuje to system buildpack, jak uruchomić aplikację w automatycznie wygenerowanym kontenerze. Następnie uruchom to polecenie w terminalu Cloud Shell (w tym samym katalogu quiz-generator) :

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

To polecenie informuje polecenie gcloud, że chcesz użyć pakietów kompilacji do utworzenia obrazu kontenera na podstawie plików źródłowych znalezionych w bieżącym katalogu (dot w --source . to skrót oznaczający bieżący katalog). Usługa obsługuje obraz kontenera w sposób niejawny, więc nie musisz go określać w tym poleceniu gcloud.

Poczekaj chwilę na zakończenie wdrażania. Jeśli polecenie gcloud zostanie wykonane, wyświetli się URL nowej usługi:

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

Adres URL usługi możesz też pobrać za pomocą tego polecenia:

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

Powinien pojawić się komunikat podobny do tego:

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

Ten link to dedykowany adres URL z zabezpieczeniami TLS dla Twojej usługi Cloud Run. Ten link jest stały (dopóki nie wyłączysz usługi) i można go używać w dowolnym miejscu w internecie. Nie korzysta z opisanego wcześniej mechanizmu serwera proxy Cloud Shell, który zależał od tymczasowej maszyny wirtualnej.

Kliknij wyróżniony symbol Service URL, aby otworzyć kartę przeglądarki internetowej z uruchomioną aplikacją. Sprawdź, czy wynik jest taki sam jak w środowisku programistycznym. Sprawdź też, czy możesz dostosować wygenerowany quiz, podając parametry na końcu adresu URL.

Gratulacje! Twoja aplikacja działa już w chmurze Google. Twoja aplikacja jest publicznie dostępna, z szyfrowaniem TLS (HTTPS) i automatycznym skalowaniem do niewyobrażalnych poziomów ruchu.

9. Łączenie wszystkich elementów

9927db1725bcd5d6.png

W tym ostatnim kroku możemy uruchomić generator quizów w ramach aplikacji quizaic. Otwórz adres URL quizaic, zaloguj się na konto Google i kliknij kartę Create Quiz. Wybierz typ generatora Custom, wklej adres URL Cloud Run w odpowiednim polu, wypełnij pozostałe wymagane pola i prześlij formularz.

328ee05579ea05f9.png

Po chwili powinien pojawić się nowy quiz (patrz „Mój nowy quiz” na obrazie poniżej) z wygenerowaną przez AI miniaturą, którą możesz edytować, odtwarzać, klonować lub usuwać za pomocą odpowiednich przycisków. Ten nowy test został utworzony za pomocą usługi internetowej, którą właśnie wdrożono na podstawie prompta z szablonu.

1719169140978b63.png

10. Czyszczenie

c1592d590c563428.png

Cloud Run nie nalicza opłat, gdy usługa nie jest używana, ale może zostać pobrana należność za przechowywanie utworzonego obrazu kontenera.

Możesz usunąć projekt GCP, co spowoduje zaprzestanie naliczania opłat za wszelkie zasoby wykorzystywane w ramach tego projektu, albo usunąć tylko obraz kontenera przy użyciu tego polecenia:

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>

Aby usunąć usługę Cloud Run, użyj tego polecenia:

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

11. Udało się!

910162be58c0f6d6.png

Gratulacje – udało Ci się utworzyć prompt LLM i wdrożyć mikrousługę Cloud Run przy użyciu tego promptu. Teraz możesz programować w języku naturalnym i udostępniać swoje dzieła całemu światu.

Chcę Ci zadać jedno ważne pytanie:

Gdy aplikacja zaczęła działać w środowisku deweloperskim, ile wierszy kodu trzeba było zmodyfikować, aby wdrożyć ją w chmurze ze wszystkimi atrybutami klasy produkcyjnej oferowanymi przez Cloud Run?

Odpowiedź to oczywiście zero. :)

Inne ćwiczenia, które warto sprawdzić...

Dokumentacja referencyjna...

12. Wezwanie do działania

Jeśli podobały Ci się te ćwiczenia z programowania i chcesz poświęcić więcej czasu na praktyczne korzystanie z Google Cloud, już dziś dołącz do programu Google Cloud Innovators.

498cab7d87ec12d3.png

Program Google Cloud Innovators jest bezpłatny i obejmuje:

  • Prowadzone na żywo dyskusje, sesje pytań i odpowiedzi oraz sesje dotyczące harmonogramu, podczas których możesz poznać najnowsze informacje bezpośrednio od pracowników Google.
  • najnowsze wiadomości o Google Cloud prosto do Twojej skrzynki odbiorczej;
  • Cyfrowe logo i tło rozmowy wideo
  • 500 punktów na moduły i naukę na platformie Skills Boost

Kliknij tutaj, aby się zarejestrować.