Informacje o tym ćwiczeniu (w Codelabs)
1. Omówienie
Aplikacje korzystające z generatywnej AI wymagają możliwości obserwacji jak każda inna aplikacja. Czy w przypadku generatywnej AI są wymagane specjalne techniki obserwowalności?
W tym module utworzysz prostą aplikację wykorzystującą generatywną AI. Wdróż ją w Cloud Run. Dodaj do niego niezbędne funkcje monitorowania i logowania, korzystając z usług i produktów dostrzegalności Google Cloud.
Czego się nauczysz
- napisać aplikację korzystającą z Vertex AI za pomocą edytora Cloud Shell.
- Przechowywanie kodu aplikacji w GitHubie
- Wdrażanie kodu źródłowego aplikacji w Cloud Run za pomocą interfejsu wiersza poleceń gcloud
- Dodawanie funkcji monitorowania i logowania do aplikacji z generatywną AI
- Korzystanie ze wskaźników opartych na logach
- Implementacja logowania i monitorowania za pomocą pakietu Open Telemetry SDK
- Informacje o odpowiedzialnym przetwarzaniu danych przez AI
2. Wymagania wstępne
Jeśli nie masz jeszcze konta Google, utwórz nowe konto.
3. Konfigurowanie projektu
- Zaloguj się w konsoli Google Cloud za pomocą konta Google.
- Utwórz nowy projekt lub użyj istniejącego. Zapisz identyfikator projektu, który został właśnie utworzony lub wybrany.
- Włącz płatności w projekcie.
- Przeprowadzenie tego ćwiczenia powinno kosztować mniej niż 5 USD.
- Aby uniknąć dalszych opłat, możesz usunąć zasoby, wykonując czynności podane na końcu tego laboratorium.
- Nowi użytkownicy mogą skorzystać z bezpłatnego okresu próbnego, w którym mają do dyspozycji środki w wysokości 300 USD.
- Sprawdź, czy płatności są włączone w sekcji Moje projekty w Rozliczeniach usługi Google Cloud.
- Jeśli w kolumnie
Billing account
nowego projektu widać wartośćBilling is disabled
:- Kliknij 3 kropki w kolumnie
Actions
. - Kliknij Zmień rozliczenia.
- Wybierz konto rozliczeniowe, którego chcesz użyć.
- Kliknij 3 kropki w kolumnie
- Jeśli uczestniczysz w wydarzeniu na żywo, konto będzie prawdopodobnie nazywać się Próbne konto rozliczeniowe Google Cloud Platform.
- Jeśli w kolumnie
4. Przygotowanie edytora Cloud Shell
- Otwórz Edytor Cloud Shell. Jeśli pojawi się to pytanie o autoryzację Cloud Shell do wywoływania gcloud za pomocą Twoich danych logowania, kliknij Autoryzuj, aby kontynuować.
- Otwórz okno terminala
- Kliknij menu z 3 kreskami
- Kliknij Terminal.
- Kliknij Nowy terminal
.
- Kliknij menu z 3 kreskami
- W terminalu skonfiguruj identyfikator projektu:
Zastąpgcloud config set project [PROJECT_ID]
[PROJECT_ID]
identyfikatorem projektu. Jeśli np. identyfikator projektu tolab-example-project
, polecenie będzie wyglądać tak: Jeśli pojawi się komunikat, że gcloud prosi o Twoje dane logowania do interfejsu GCPI API, kliknij Autoryzuj, aby kontynuować.gcloud config set project lab-project-id-example
Po pomyślnym wykonaniu tej czynności powinien wyświetlić się komunikat: Jeśli widziszUpdated property [core/project].
WARNING
i pojawia się pytanieDo you want to continue (Y/N)?
, prawdopodobnie nieprawidłowo wpisano identyfikator projektu. Gdy znajdziesz prawidłowy identyfikator projektu, naciśnijN
, a potemEnter
i spróbuj ponownie uruchomić poleceniegcloud config set project
. - (Opcjonalnie) Jeśli masz problem ze znalezieniem identyfikatora projektu, uruchom to polecenie, aby wyświetlić identyfikatory wszystkich swoich projektów posortowane według czasu utworzenia w kolejności malejącej:
gcloud projects list \
--format='value(projectId,createTime)' \
--sort-by=~createTime
5. Włączanie interfejsów API Google
W terminalu włącz interfejsy API Google wymagane w tym module:
gcloud services enable \
run.googleapis.com \
cloudbuild.googleapis.com \
aiplatform.googleapis.com \
logging.googleapis.com \
monitoring.googleapis.com \
cloudtrace.googleapis.com
Wykonanie tego polecenia może trochę potrwać. W efekcie wyświetli się komunikat o udanym przeprowadzeniu operacji podobny do tego:
Operation "operations/acf.p2-73d90d00-47ee-447a-b600" finished successfully.
Jeśli pojawi się komunikat o błędzie rozpoczynający się od ERROR: (gcloud.services.enable) HttpError accessing
i zawierający informacje o błędzie podobne do tych poniżej, powtórz polecenie po 1–2 minutach.
"error": { "code": 429, "message": "Quota exceeded for quota metric 'Mutate requests' and limit 'Mutate requests per minute' of service 'serviceusage.googleapis.com' ...", "status": "RESOURCE_EXHAUSTED", ... }
6. Tworzenie aplikacji generatywnej AI
Na tym etapie napiszesz kod prostej aplikacji działającej na podstawie żądań, która korzysta z modelu Gemini, aby wyświetlać 10 ciekawych faktów o wybranym przez Ciebie zwierzęciu. Aby utworzyć kod aplikacji, wykonaj te czynności.
- Utwórz w terminalu katalog
codelab-o11y
:mkdir "${HOME}/codelab-o11y"
- Zmień bieżący katalog na
codelab-o11y
:cd "${HOME}/codelab-o11y"
- Pobierz kod bootstrap aplikacji w Javie za pomocą narzędzia startowego frameworku Spring:
curl https://start.spring.io/starter.zip \
-d dependencies=web \
-d javaVersion=17 \
-d type=maven-project \
-d bootVersion=3.4.1 -o java-starter.zip - Wypakuj kod bootstrap do bieżącego folderu:
unzip java-starter.zip
- Usuń plik archiwum z folderu:
rm java-starter.zip
- Utwórz plik
project.toml
, aby określić wersję środowiska wykonawczego Java, która ma być używana podczas wdrażania kodu w Cloud Run:cat > "${HOME}/codelab-o11y/project.toml" << EOF
[[build.env]]
name = "GOOGLE_RUNTIME_VERSION"
value = "17"
EOF - Dodaj zależności pakietu Google Cloud SDK do pliku
pom.xml
:- Dodaj pakiet Google Cloud Core:
sed -i 's/<dependencies>/<dependencies>\
\
<dependency>\
<groupId>com.google.cloud<\/groupId>\
<artifactId>google-cloud-core<\/artifactId>\
<version>2.49.1<\/version>\
<\/dependency>\
/g' "${HOME}/codelab-o11y/pom.xml" - Dodaj pakiet Google Cloud Vertex AI:
sed -i 's/<dependencies>/<dependencies>\
\
<dependency>\
<groupId>com.google.cloud<\/groupId>\
<artifactId>google-cloud-vertexai<\/artifactId>\
<version>1.16.0<\/version>\
<\/dependency>\
/g' "${HOME}/codelab-o11y/pom.xml"
- Dodaj pakiet Google Cloud Core:
- Otwórz plik
DemoApplication.java
w edytorze Cloud Shell: W oknie edytora nad terminalem powinien pojawić się szkielet kodu źródłowego plikucloudshell edit "${HOME}/codelab-o11y/src/main/java/com/example/demo/DemoApplication.java"
DemoApplication.java
. Kod źródłowy pliku będzie wyglądał mniej więcej tak:package com.example.demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
} - Zastąp kod w edytorze wersją widoczną poniżej. Aby zastąpić kod, usuń zawartość pliku, a potem skopiuj do edytora kod poniżej:
Po kilku sekundach edytor Cloud Shell automatycznie zapisze kod.package com.example.demo;
import java.io.IOException;
import java.util.Collections;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import com.google.cloud.ServiceOptions;
import com.google.cloud.vertexai.VertexAI;
import com.google.cloud.vertexai.api.GenerateContentResponse;
import com.google.cloud.vertexai.generativeai.GenerativeModel;
import com.google.cloud.vertexai.generativeai.ResponseHandler;
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
String port = System.getenv().getOrDefault("PORT", "8080");
SpringApplication app = new SpringApplication(DemoApplication.class);
app.setDefaultProperties(Collections.singletonMap("server.port", port));
app.run(args);
}
}
@RestController
class HelloController {
private final String projectId = ServiceOptions.getDefaultProjectId();
private VertexAI vertexAI;
private GenerativeModel model;
@PostConstruct
public void init() {
vertexAI = new VertexAI(projectId, "us-central1");
model = new GenerativeModel("gemini-1.5-flash", vertexAI);
}
@PreDestroy
public void destroy() {
vertexAI.close();
}
@GetMapping("/")
public String getFacts(@RequestParam(defaultValue = "dog") String animal) throws IOException {
String prompt = "Give me 10 fun facts about " + animal + ". Return this as html without backticks.";
GenerateContentResponse response = model.generateContent(prompt);
return ResponseHandler.getText(response);
}
}
Wdrażanie kodu aplikacji generatywnej AI w Cloud Run
- W oknie terminala uruchom polecenie, aby wdrożyć kod źródłowy aplikacji do Cloud Run.
Jeśli zobaczysz taki komunikat, oznacza to, że polecenie utworzy nowe repozytorium. Kliknijgcloud run deploy codelab-o11y-service \
--source="${HOME}/codelab-o11y/" \
--region=us-central1 \
--allow-unauthenticatedEnter
. Proces wdrażania może potrwać kilka minut. Po zakończeniu procesu wdrażania zobaczysz dane wyjściowe podobne do tych:Deploying from source requires an Artifact Registry Docker repository to store built containers. A repository named [cloud-run-source-deploy] in region [us-central1] will be created. Do you want to continue (Y/n)?
Service [codelab-o11y-service] revision [codelab-o11y-service-00001-t2q] has been deployed and is serving 100 percent of traffic. Service URL: https://codelab-o11y-service-12345678901.us-central1.run.app
- Skopiuj wyświetlony adres URL usługi Cloud Run na osobną kartę lub do osobnego okna w przeglądarce. Możesz też uruchomić to polecenie w terminalu, aby wydrukować adres URL usługi, a potem kliknąć wyświetlony adres URL, przytrzymując klawisz Ctrl, aby go otworzyć:
Po otwarciu adresu URL może pojawić się błąd 500 lub komunikat:gcloud run services list \
--format='value(URL)' \
--filter='SERVICE:"codelab-o11y-service"' Oznacza to, że usługi nie zostały wdrożone. Zaczekaj chwilę i odśwież stronę. Na końcu zobaczysz tekst zaczynający się od słów Ciekawostki o psach i zawierający 10 ciekawostek o tych zwierzętach.Sorry, this is just a placeholder...
Spróbuj wejść w interakcję z aplikacją, aby dowiedzieć się ciekawych faktów o różnych zwierzętach. Aby to zrobić, dodaj parametr animal
do adresu URL, np. ?animal=[ANIMAL]
, gdzie [ANIMAL]
to nazwa zwierzęcia. Na przykład dodaj ?animal=cat
, aby uzyskać 10 ciekawostek o kotach, lub ?animal=sea turtle
, aby uzyskać 10 ciekawostek o żółwiach morskich.
7. Sprawdzanie wywołań interfejsu Vertex API
Audyt wywołań interfejsu Google API pozwala uzyskać odpowiedzi na pytania w rodzaju „kto, gdzie i kiedy wywołał dany interfejs API?”. Weryfikacja jest ważna podczas rozwiązywania problemów z aplikacją, badania wykorzystania zasobów lub przeprowadzania analizy kryminalistycznej oprogramowania.
Logi kontrolne umożliwiają śledzenie działań administracyjnych i systemowych, a także rejestrowanie wywołań operacji interfejsu API „odczytywanie danych” i „zapisywanie danych”. Aby sprawdzić żądania Vertex AI dotyczące generowania treści, musisz włączyć logi kontrolne „Odczyt danych” w konsoli Cloud.
- Kliknij przycisk poniżej, aby otworzyć stronę Dzienniki kontrolne w konsoli Google Cloud
- Upewnij się, że na stronie wybrany jest projekt utworzony na potrzeby tego laboratorium. Wybrany projekt jest widoczny w lewym górnym rogu strony obok menu hamburgera:
W razie potrzeby wybierz odpowiedni projekt z menu. - W tabeli Konfiguracja logów kontrolnych dostępu do danych w kolumnie Usługa znajdź usługę
Vertex AI API
i kliknij pole wyboru po lewej stronie jej nazwy. - W panelu informacyjnym po prawej stronie wybierz typ audytu „Odczyt danych”.
- Kliknij Zapisz.
Aby wygenerować dzienniki kontrolne, otwórz adres URL usługi. Aby uzyskać inne wyniki, odśwież stronę, zmieniając wartość parametru ?animal=
.
Poznawanie dzienników kontrolnych
- Kliknij przycisk poniżej, aby otworzyć stronę Eksplorator logów w konsoli Google Cloud:
- Wklej ten filtr w panelu Zapytanie.
Panel Zapytanie to edytor znajdujący się u góry strony Eksplorator logów:LOG_ID("cloudaudit.googleapis.com%2Fdata_access") AND
protoPayload.serviceName="aiplatform.googleapis.com" - Kliknij Uruchom zapytanie.
- Wybierz jeden z wpisów w dzienniku kontrolnym i rozwiń pola, aby sprawdzić informacje zarejestrowane w dzienniku.
Możesz zobaczyć szczegóły wywołania interfejsu Vertex API, w tym użytą metodę i model. Możesz też zobaczyć tożsamość wywołującego i uprawnienia autoryzujące wywołanie.
8. Rejestrowanie interakcji z generatywną AI
W dziennikach kontrolnych nie ma parametrów żądania ani danych odpowiedzi interfejsu API. Te informacje mogą jednak być ważne w przypadku problemów z analizą aplikacji i przepływu pracy. W tym kroku wypełniamy tę lukę, dodając rejestrowanie aplikacji.
Implementacja używa Logback z Spring Boot do drukowania logów aplikacji na standardowe wyjście. Ta metoda wykorzystuje możliwość Cloud Run do przechwytywania informacji drukowanych na standardowym wyjściu i automatycznego przesyłania ich do Cloud Logging. Aby rejestrowane dane były uporządkowane, wydrukowane dzienniki należy odpowiednio sformatować. Aby dodać do aplikacji funkcję uporządkowanych logów, postępuj zgodnie z instrukcjami podanymi poniżej.
- Wróć do okna (lub karty) Cloud Shell w przeglądarce.
- Utwórz i otwórz nowy plik
LoggingEventGoogleCloudEncoder.java
w edytorze Cloud Shell:cloudshell edit "${HOME}/codelab-o11y/src/main/java/com/example/demo/LoggingEventGoogleCloudEncoder.java"
- Skopiuj i wklej ten kod, aby zaimplementować koder Logback, który koduje log w postaci ciągu znaków JSON zgodnie ze strukturyzowanym formatem logów Google Cloud:
package com.example.demo;
import static ch.qos.logback.core.CoreConstants.UTF_8_CHARSET;
import java.time.Instant;
import ch.qos.logback.core.encoder.EncoderBase;
import ch.qos.logback.classic.Level;
import ch.qos.logback.classic.spi.ILoggingEvent;
import java.util.HashMap;
import com.google.gson.Gson;
public class LoggingEventGoogleCloudEncoder extends EncoderBase<ILoggingEvent> {
private static final byte[] EMPTY_BYTES = new byte[0];
private final Gson gson = new Gson();
@Override
public byte[] headerBytes() {
return EMPTY_BYTES;
}
@Override
public byte[] encode(ILoggingEvent e) {
var timestamp = Instant.ofEpochMilli(e.getTimeStamp());
var fields = new HashMap<String, Object>() {
{
put("timestamp", timestamp.toString());
put("severity", severityFor(e.getLevel()));
put("message", e.getMessage());
}
};
var params = e.getKeyValuePairs();
if (params != null && params.size() > 0) {
params.forEach(kv -> fields.putIfAbsent(kv.key, kv.value));
}
var data = gson.toJson(fields) + "\n";
return data.getBytes(UTF_8_CHARSET);
}
@Override
public byte[] footerBytes() {
return EMPTY_BYTES;
}
private static String severityFor(Level level) {
switch (level.toInt()) {
case Level.TRACE_INT:
return "DEBUG";
case Level.DEBUG_INT:
return "DEBUG";
case Level.INFO_INT:
return "INFO";
case Level.WARN_INT:
return "WARNING";
case Level.ERROR_INT:
return "ERROR";
default:
return "DEFAULT";
}
}
} - Utwórz i otwórz nowy plik
logback.xml
w edytorze Cloud Shell:cloudshell edit "${HOME}/codelab-o11y/src/main/resources/logback.xml"
- Aby skonfigurować Logback do korzystania z kodera z załącznikiem Logback, który drukuje dzienniki na standardowe wyjście, skopiuj i wklej ten kod XML:
<?xml version="1.0" encoding="UTF-8"?>
<configuration debug="true">
<appender name="Console" class="ch.qos.logback.core.ConsoleAppender">
<encoder class="com.example.demo.LoggingEventGoogleCloudEncoder"/>
</appender>
<root level="info">
<appender-ref ref="Console" />
</root>
</configuration> - Ponownie otwórz plik
DemoApplication.java
w edytorze Cloud Shell:cloudshell edit "${HOME}/codelab-o11y/src/main/java/com/example/demo/DemoApplication.java"
- Aby rejestrować żądania i odpowiedzi Gen AI, zastąp kod w edytorze wersją widoczną poniżej. Aby zastąpić kod, usuń zawartość pliku, a potem skopiuj do edytora kod poniżej:
package com.example.demo;
import java.io.IOException;
import java.util.Collections;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import com.google.cloud.ServiceOptions;
import com.google.cloud.vertexai.VertexAI;
import com.google.cloud.vertexai.api.GenerateContentResponse;
import com.google.cloud.vertexai.generativeai.GenerativeModel;
import com.google.cloud.vertexai.generativeai.ResponseHandler;
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
String port = System.getenv().getOrDefault("PORT", "8080");
SpringApplication app = new SpringApplication(DemoApplication.class);
app.setDefaultProperties(Collections.singletonMap("server.port", port));
app.run(args);
}
}
@RestController
class HelloController {
private final String projectId = ServiceOptions.getDefaultProjectId();
private VertexAI vertexAI;
private GenerativeModel model;
private final Logger LOGGER = LoggerFactory.getLogger(HelloController.class);
@PostConstruct
public void init() {
vertexAI = new VertexAI(projectId, "us-central1");
model = new GenerativeModel("gemini-1.5-flash", vertexAI);
}
@PreDestroy
public void destroy() {
vertexAI.close();
}
@GetMapping("/")
public String getFacts(@RequestParam(defaultValue = "dog") String animal) throws IOException {
String prompt = "Give me 10 fun facts about " + animal + ". Return this as html without backticks.";
GenerateContentResponse response = model.generateContent(prompt);
LOGGER.atInfo()
.addKeyValue("animal", animal)
.addKeyValue("prompt", prompt)
.addKeyValue("response", response)
.log("Content is generated");
return ResponseHandler.getText(response);
}
}
Po kilku sekundach edytor Cloud Shell automatycznie zapisuje zmiany.
Wdrażanie kodu aplikacji generatywnej AI w Cloud Run
- W oknie terminala uruchom polecenie, aby wdrożyć kod źródłowy aplikacji do Cloud Run.
Jeśli zobaczysz taki komunikat, oznacza to, że polecenie utworzy nowe repozytorium. Kliknijgcloud run deploy codelab-o11y-service \
--source="${HOME}/codelab-o11y/" \
--region=us-central1 \
--allow-unauthenticatedEnter
. Proces wdrażania może potrwać kilka minut. Po zakończeniu procesu wdrażania zobaczysz dane wyjściowe podobne do tych:Deploying from source requires an Artifact Registry Docker repository to store built containers. A repository named [cloud-run-source-deploy] in region [us-central1] will be created. Do you want to continue (Y/n)?
Service [codelab-o11y-service] revision [codelab-o11y-service-00001-t2q] has been deployed and is serving 100 percent of traffic. Service URL: https://codelab-o11y-service-12345678901.us-central1.run.app
- Skopiuj wyświetlony adres URL usługi Cloud Run na osobną kartę lub do osobnego okna w przeglądarce. Możesz też uruchomić to polecenie w terminalu, aby wydrukować adres URL usługi, a potem kliknąć wyświetlony adres URL, przytrzymując klawisz Ctrl, aby go otworzyć:
Po otwarciu adresu URL może pojawić się błąd 500 lub komunikat:gcloud run services list \
--format='value(URL)' \
--filter='SERVICE:"codelab-o11y-service"' Oznacza to, że usługi nie zostały wdrożone. Zaczekaj chwilę i odśwież stronę. Na końcu zobaczysz tekst zaczynający się od słów Ciekawostki o psach i zawierający 10 ciekawostek o tych zwierzętach.Sorry, this is just a placeholder...
Aby wygenerować dzienniki aplikacji, otwórz adres URL usługi. Aby uzyskać inne wyniki, odśwież stronę, zmieniając wartość parametru ?animal=
.
Aby wyświetlić logi aplikacji:
- Kliknij przycisk poniżej, aby otworzyć stronę Eksplorator logów w konsoli Google Cloud:
- Wklej ten filtr w panelu Zapytanie (pozycja 2 w interfejsie Eksploratora logów):
LOG_ID("run.googleapis.com%2Fstdout") AND
severity=DEBUG - Kliknij Uruchom zapytanie.
Wynik zapytania zawiera logi z promptem i odpowiedzią Vertex AI, w tym oceny bezpieczeństwa.
9. Liczenie interakcji z generatywną AI
Cloud Run zapisuje dane zarządzane, których można używać do monitorowania wdrożonych usług. Dane monitorowania zarządzane przez użytkowników zapewniają większą kontrolę nad danymi i częstotliwością ich aktualizacji. Wdrożenie takiej metryki wymaga napisania kodu, który zbiera dane i zapisują je w Cloud Monitoring. Aby dowiedzieć się, jak zaimplementować tę funkcję za pomocą pakietu OpenTelemetry SDK, przejdź do następnego (opcjonalnego) kroku.
Ten krok pokazuje alternatywę dla implementowania danych o użytkownikach w kodzie – dane oparte na logach. Dane oparte na logach umożliwiają generowanie danych monitorowania na podstawie wpisów logów zapisywanych przez aplikację w Cloud Logging. Do zdefiniowania danych typu licznik na podstawie dzienników aplikacji użyjemy dzienników aplikacji zaimplementowanych w poprzednim kroku. Dane zliczają liczbę udanych wywołań interfejsu Vertex API.
- Spójrz na okno Eksploratora logów, którego użyliśmy w poprzednim kroku. W panelu Zapytanie odszukaj menu Działania i kliknij je, aby je otworzyć. Menu znajdziesz na zrzucie ekranu poniżej:
- W otwartym menu kliknij Utwórz wskaźnik, aby otworzyć panel Utwórz wskaźnik oparty na logach.
- Aby skonfigurować nowy wskaźnik licznika w panelu Utwórz dane oparte na logach:
- Ustaw Typ wskaźnika: wybierz Licznik.
- W sekcji Szczegóły ustaw te pola:
- Nazwa wskaźnika logu: ustaw nazwę na
model_interaction_count
. Obowiązują pewne ograniczenia dotyczące nazw. Szczegółowe informacje znajdziesz w rozdziale dotyczącym rozwiązywania problemów z ograniczeniami dotyczącymi nazw. - Opis: wpisz opis danych. na przykład
Number of log entries capturing successful call to model inference.
. - Jednostki: pozostaw to pole puste lub wstaw cyfrę
1
.
- Nazwa wskaźnika logu: ustaw nazwę na
- Pozostaw wartości w sekcji Wybór filtra. Pamiętaj, że pole Filtrowanie wersji zawiera ten sam filtr, który został użyty do wyświetlenia dzienników aplikacji.
- (Opcjonalnie) Dodaj etykietę, która pomoże zliczać liczbę połączeń dla każdego zwierzęcia. UWAGA: ta etykieta może znacznie zwiększyć liczebność danych i nie jest zalecana do użytku w produkcji:
- Kliknij Dodaj etykietę.
- W sekcji Etykiety ustaw te pola:
- Nazwa etykiety: ustaw nazwę na
animal
. - Opis: wpisz opis etykiety. Na przykład:
Animal parameter
. - Typ etykiety: kliknij
STRING
. - Nazwa pola: wpisz
jsonPayload.animal
. - Wyrażenie regularne: pozostaw puste.
- Nazwa etykiety: ustaw nazwę na
- Kliknij przycisk Gotowe.
- Aby utworzyć dane, kliknij Utwórz dane.
Możesz też utworzyć wskaźnik oparty na logach na stronie Wskaźniki oparte na logach, używając gcloud logging metrics create
polecenia wiersza poleceń lub google_logging_metric
zasobu Terraform.
Aby wygenerować dane, otwórz adres URL usługi. Odśwież otwartą stronę kilka razy, aby wykonać kilka wywołań modelu. Podobnie jak wcześniej, spróbuj użyć w tym parametrze różnych zwierząt.
Wpisz zapytanie PromQL, aby wyszukać dane wskaźnika opartego na logach. Aby wpisać zapytanie PromQL:
- Kliknij przycisk poniżej, aby otworzyć stronę Eksplorator danych w konsoli Google Cloud:
- Na pasku narzędzi w panelu kreatora zapytań kliknij przycisk o nazwie < > MQL lub < > PromQL. Lokalizacja przycisku – patrz obraz poniżej.
- Sprawdź, czy w opcji Język wybrana jest opcja PromQL. Przełącznik języka znajduje się na tej samej belce narzędzi, która umożliwia formatowanie zapytania.
- Wpisz zapytanie w edytorze Zapytania:
Więcej informacji o używaniu PromQL znajdziesz w artykule PromQL w Cloud Monitoring.sum(rate(logging_googleapis_com:user_model_interaction_count{monitored_resource="cloud_run_revision"}[${__interval}]))
- Kliknij Uruchom zapytanie. Zobaczysz wykres liniowy podobny do tego:
Pamiętaj, że gdy włączony jest przełącznik Automatyczne uruchamianie, przycisk Uruchom zapytanie nie jest widoczny.
10. (Opcjonalnie) Używanie OpenTelemetry do monitorowania i śledzenia
Jak wspomnieliśmy w poprzednim kroku, dane można implementować za pomocą pakietu OpenTelemetry (Otel) SDK. Zalecane jest używanie usługi OTel w architekturach wielousługowych. Ten krok pokazuje dodawanie pomiarów OTel do aplikacji Spring Boot. Na tym etapie wykonasz te czynności:
- Dodawanie do aplikacji Spring Boot możliwości automatycznego śledzenia
- Wdrożenie licznika do monitorowania liczby udanych wywołań modelu
- Korelacja śledzenia z logami aplikacji
Zalecana architektura usług na poziomie usługi polega na użyciu kolektora Otel do zbierania i przetwarzania wszystkich danych dotyczących możliwości obserwacji z wielu usług. Ze względu na prostotę kod na tym etapie nie korzysta z kolekcjonera. Zamiast tego używa eksportów OTel, które zapisują dane bezpośrednio w Google Cloud.
Konfigurowanie aplikacji Spring Boot z komponentami OTel i automatycznym śledzeniem
- Wróć do okna (lub karty) Cloud Shell w przeglądarce.
- W terminalu zaktualizuj plik
application.permissions
, dodając do niego dodatkowe parametry konfiguracji: Te parametry definiują eksportowanie danych o obserwowalności do Cloud Trace i Cloud Monitoring oraz wymuszają próbkowanie wszystkich śladów.cat >> "${HOME}/codelab-o11y/src/main/resources/application.properties" << EOF
otel.logs.exporter=none
otel.traces.exporter=google_cloud_trace
otel.metrics.exporter=google_cloud_monitoring
otel.resource.attributes.service.name=codelab-o11y-service
otel.traces.sampler=always_on
EOF - Dodaj do pliku
pom.xml
wymagane zależności OpenTelemetry:sed -i 's/<dependencies>/<dependencies>\
\
<dependency>\
<groupId>io.opentelemetry.instrumentation<\/groupId>\
<artifactId>opentelemetry-spring-boot-starter<\/artifactId>\
<\/dependency>\
<dependency>\
<groupId>com.google.cloud.opentelemetry<\/groupId>\
<artifactId>exporter-auto<\/artifactId>\
<version>0.33.0-alpha<\/version>\
<\/dependency>\
<dependency>\
<groupId>com.google.cloud.opentelemetry<\/groupId>\
<artifactId>exporter-trace<\/artifactId>\
<version>0.33.0<\/version>\
<\/dependency>\
<dependency>\
<groupId>com.google.cloud.opentelemetry<\/groupId>\
<artifactId>exporter-metrics<\/artifactId>\
<version>0.33.0<\/version>\
<\/dependency>\
/g' "${HOME}/codelab-o11y/pom.xml" - Dodaj plik BOM OpenTelemetry do pliku
pom.xml
:sed -i 's/<\/properties>/<\/properties>\
<dependencyManagement>\
<dependencies>\
<dependency>\
<groupId>io.opentelemetry.instrumentation<\/groupId>\
<artifactId>opentelemetry-instrumentation-bom<\/artifactId>\
<version>2.12.0<\/version>\
<type>pom<\/type>\
<scope>import<\/scope>\
<\/dependency>\
<\/dependencies>\
<\/dependencyManagement>\
/g' "${HOME}/codelab-o11y/pom.xml" - Ponownie otwórz plik
DemoApplication.java
w edytorze Cloud Shell:cloudshell edit "${HOME}/codelab-o11y/src/main/java/com/example/demo/DemoApplication.java"
- Zastąp bieżący kod wersją, która zwiększa dane o skuteczności. Aby zastąpić kod, usuń zawartość pliku, a potem skopiuj do edytora kod poniżej:
package com.example.demo;
import io.opentelemetry.api.common.AttributeKey;
import io.opentelemetry.api.common.Attributes;
import io.opentelemetry.api.OpenTelemetry;
import io.opentelemetry.api.metrics.LongCounter;
import java.io.IOException;
import java.util.Collections;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import com.google.cloud.ServiceOptions;
import com.google.cloud.vertexai.VertexAI;
import com.google.cloud.vertexai.api.GenerateContentResponse;
import com.google.cloud.vertexai.generativeai.GenerativeModel;
import com.google.cloud.vertexai.generativeai.ResponseHandler;
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
String port = System.getenv().getOrDefault("PORT", "8080");
SpringApplication app = new SpringApplication(DemoApplication.class);
app.setDefaultProperties(Collections.singletonMap("server.port", port));
app.run(args);
}
}
@RestController
class HelloController {
private final String projectId = ServiceOptions.getDefaultProjectId();
private VertexAI vertexAI;
private GenerativeModel model;
private final Logger LOGGER = LoggerFactory.getLogger(HelloController.class);
private static final String INSTRUMENTATION_NAME = "genai-o11y/java/workshop/example";
private static final AttributeKey<String> ANIMAL = AttributeKey.stringKey("animal");
private final LongCounter counter;
public HelloController(OpenTelemetry openTelemetry) {
this.counter = openTelemetry.getMeter(INSTRUMENTATION_NAME)
.counterBuilder("model_call_counter")
.setDescription("Number of successful model calls")
.build();
}
@PostConstruct
public void init() {
vertexAI = new VertexAI(projectId, "us-central1");
model = new GenerativeModel("gemini-1.5-flash", vertexAI);
}
@PreDestroy
public void destroy() {
vertexAI.close();
}
@GetMapping("/")
public String getFacts(@RequestParam(defaultValue = "dog") String animal) throws IOException {
String prompt = "Give me 10 fun facts about " + animal + ". Return this as html without backticks.";
GenerateContentResponse response = model.generateContent(prompt);
LOGGER.atInfo()
.addKeyValue("animal", animal)
.addKeyValue("prompt", prompt)
.addKeyValue("response", response)
.log("Content is generated");
counter.add(1, Attributes.of(ANIMAL, animal));
return ResponseHandler.getText(response);
}
} - Ponownie otwórz plik
LoggingEventGoogleCloudEncoder.java
w edytorze Cloud Shell:cloudshell edit "${HOME}/codelab-o11y/src/main/java/com/example/demo/LoggingEventGoogleCloudEncoder.java"
- Zastąp bieżący kod wersją, która dodaje atrybuty śledzenia do zapisanych dzienników. Dodanie atrybutów umożliwia powiązanie logów z odpowiednimi przedziałami śledzenia. Aby zastąpić kod, usuń zawartość pliku, a potem skopiuj do edytora kod poniżej:
package com.example.demo;
import static ch.qos.logback.core.CoreConstants.UTF_8_CHARSET;
import java.time.Instant;
import java.util.HashMap;
import ch.qos.logback.core.encoder.EncoderBase;
import ch.qos.logback.classic.Level;
import ch.qos.logback.classic.spi.ILoggingEvent;
import com.google.cloud.ServiceOptions;
import io.opentelemetry.api.trace.Span;
import io.opentelemetry.api.trace.SpanContext;
import io.opentelemetry.context.Context;
import com.google.gson.Gson;
public class LoggingEventGoogleCloudEncoder extends EncoderBase<ILoggingEvent> {
private static final byte[] EMPTY_BYTES = new byte[0];
private final Gson gson;
private final String projectId;
private final String tracePrefix;
public LoggingEventGoogleCloudEncoder() {
this.gson = new Gson();
this.projectId = lookUpProjectId();
this.tracePrefix = "projects/" + (projectId == null ? "" : projectId) + "/traces/";
}
private static String lookUpProjectId() {
return ServiceOptions.getDefaultProjectId();
}
@Override
public byte[] headerBytes() {
return EMPTY_BYTES;
}
@Override
public byte[] encode(ILoggingEvent e) {
var timestamp = Instant.ofEpochMilli(e.getTimeStamp());
var fields = new HashMap<String, Object>() {
{
put("timestamp", timestamp.toString());
put("severity", severityFor(e.getLevel()));
put("message", e.getMessage());
SpanContext context = Span.fromContext(Context.current()).getSpanContext();
if (context.isValid()) {
put("logging.googleapis.com/trace", tracePrefix + context.getTraceId());
put("logging.googleapis.com/spanId", context.getSpanId());
put("logging.googleapis.com/trace_sampled", Boolean.toString(context.isSampled()));
}
}
};
var params = e.getKeyValuePairs();
if (params != null && params.size() > 0) {
params.forEach(kv -> fields.putIfAbsent(kv.key, kv.value));
}
var data = gson.toJson(fields) + "\n";
return data.getBytes(UTF_8_CHARSET);
}
@Override
public byte[] footerBytes() {
return EMPTY_BYTES;
}
private static String severityFor(Level level) {
switch (level.toInt()) {
case Level.TRACE_INT:
return "DEBUG";
case Level.DEBUG_INT:
return "DEBUG";
case Level.INFO_INT:
return "INFO";
case Level.WARN_INT:
return "WARNING";
case Level.ERROR_INT:
return "ERROR";
default:
return "DEFAULT";
}
}
}
Po kilku sekundach edytor Cloud Shell automatycznie zapisuje zmiany.
Wdrażanie kodu aplikacji generatywnej AI w Cloud Run
- W oknie terminala uruchom polecenie, aby wdrożyć kod źródłowy aplikacji do Cloud Run.
Jeśli zobaczysz taki komunikat, oznacza to, że polecenie utworzy nowe repozytorium. Kliknijgcloud run deploy codelab-o11y-service \
--source="${HOME}/codelab-o11y/" \
--region=us-central1 \
--allow-unauthenticatedEnter
. Proces wdrażania może potrwać kilka minut. Po zakończeniu procesu wdrażania zobaczysz dane wyjściowe podobne do tych:Deploying from source requires an Artifact Registry Docker repository to store built containers. A repository named [cloud-run-source-deploy] in region [us-central1] will be created. Do you want to continue (Y/n)?
Service [codelab-o11y-service] revision [codelab-o11y-service-00001-t2q] has been deployed and is serving 100 percent of traffic. Service URL: https://codelab-o11y-service-12345678901.us-central1.run.app
- Skopiuj wyświetlony adres URL usługi Cloud Run na osobną kartę lub do osobnego okna w przeglądarce. Możesz też uruchomić to polecenie w terminalu, aby wydrukować adres URL usługi, a potem kliknąć wyświetlony adres URL, przytrzymując klawisz Ctrl, aby go otworzyć:
Po otwarciu adresu URL może pojawić się błąd 500 lub komunikat:gcloud run services list \
--format='value(URL)' \
--filter='SERVICE:"codelab-o11y-service"' Oznacza to, że usługi nie zostały wdrożone. Zaczekaj chwilę i odśwież stronę. Na końcu zobaczysz tekst zaczynający się od słów Ciekawostki o psach i zawierający 10 ciekawostek o tych zwierzętach.Sorry, this is just a placeholder...
Aby wygenerować dane telemetryczne, otwórz adres URL usługi. Aby uzyskać inne wyniki, odśwież stronę, zmieniając wartość parametru ?animal=
.
Analiza śladów aplikacji
- Kliknij przycisk poniżej, aby otworzyć stronę Eksplorator logów czasu w konsoli Cloud:
- Wybierz jeden z najnowszych śladów. Powinieneś/powinnaś zobaczyć 5 lub 6 elementów, które wyglądają jak na zrzucie ekranu poniżej.
- Znajdź blok kodu, który śledzi wywołanie do metody obsługi zdarzenia (metoda
fun_facts
). Będzie to ostatni element o nazwie/
. - W panelu Szczegóły śledzenia kliknij Logi i zdarzenia. Zobaczysz logi aplikacji powiązane z tym konkretnym spanem. Korelacja jest wykrywana na podstawie identyfikatorów śledzenia i spanu w logu czasu. Powinieneś zobaczyć log aplikacji, który zawiera prompt i odpowiedź interfejsu Vertex API.
Wskaźnik licznika
- Kliknij przycisk poniżej, aby otworzyć stronę Eksplorator danych w konsoli Google Cloud:
- Na pasku narzędzi w panelu kreatora zapytań kliknij przycisk o nazwie < > MQL lub < > PromQL. Lokalizacja przycisku – patrz obraz poniżej.
- Sprawdź, czy w opcji Język wybrana jest opcja PromQL. Przełącznik języka znajduje się na tej samej belce narzędzi, która umożliwia formatowanie zapytania.
- Wpisz zapytanie w edytorze Zapytania:
sum(rate(workload_googleapis_com:model_call_counter{monitored_resource="generic_task"}[${__interval}]))
- Kliknij Uruchom zapytanie.Gdy włączony jest przełącznik Automatyczne uruchamianie, przycisk Uruchom zapytanie nie jest widoczny.
11. (Opcjonalnie) Zaciemnione informacje poufne z logów
W kroku 10 odnotowaliśmy informacje o interakcjach aplikacji z modelem Gemini. Informacje te obejmowały nazwę zwierzęcia, prompt i odpowiedź modelu. Przechowywanie tych informacji w dzienniku powinno być bezpieczne, ale niekoniecznie w wielu innych przypadkach. Prośba może zawierać dane osobowe lub wrażliwe, których użytkownik nie chce przechowywać. Aby to rozwiązać, możesz zafałszować dane wrażliwe zapisywane w Cloud Logging. Aby zminimalizować modyfikacje kodu, zalecamy zastosowanie tego rozwiązania.
- Tworzenie tematu Pub/Sub do przechowywania przychodzących wpisów w logach
- Utwórz ujście logów, które przekierowuje pozyskane logi do tematu Pub/Sub.
- Utwórz potok Dataflow, który modyfikuje dzienniki przekierowywane do tematu Pub/Sub. Aby to zrobić:
- Czytanie wpisu w logu z tematu PubSub
- Sprawdzanie danych wejściowych rekordu pod kątem informacji poufnych za pomocą interfejsu DLP inspection API
- Usuń informacje poufne z ładunku za pomocą jednej z metod zapobiegania utracie danych.
- Zapisywanie zafałszowanego wpisu w pliku logów w Cloud Logging
- Wdrażanie potoku
12. (Opcjonalnie) Czyszczenie
Aby uniknąć opłat za zasoby i interfejsy API używane w tym samouczku, zalecamy wyczyszczenie po jego ukończeniu. Najprostszym sposobem na uniknięcie płatności jest usunięcie projektu utworzonego na potrzeby tego samouczka.
- Aby usunąć projekt, uruchom w terminalu polecenie usuwania projektu:
Usunięcie projektu Cloud powoduje zaprzestanie naliczania opłat za wszystkie zasoby i interfejsy API używane w tym projekcie. Powinien pojawić się komunikat, w którymPROJECT_ID=$(gcloud config get-value project)
gcloud projects delete ${PROJECT_ID} --quietPROJECT_ID
będzie identyfikatorem projektu:Deleted [https://cloudresourcemanager.googleapis.com/v1/projects/PROJECT_ID]. You can undo this operation for a limited period by running the command below. $ gcloud projects undelete PROJECT_ID See https://cloud.google.com/resource-manager/docs/creating-managing-projects for information on shutting down projects.
- (Opcjonalnie) Jeśli pojawi się błąd, w kroku 5 sprawdź, jak znaleźć identyfikator projektu użyty w tym module. Zastąp nim polecenie w pierwszej instrukcji. Jeśli np. identyfikator projektu to
lab-example-project
, polecenie będzie wyglądać tak:gcloud projects delete lab-project-id-example --quiet
13. Gratulacje
W tym module udało Ci się utworzyć aplikację generatywnej AI, która do prognozowania korzysta z modela Gemini. W aplikacji zostały też zaimplementowane podstawowe funkcje monitorowania i logowania. Wdrożysz aplikację i zmiany z kodu źródłowego w Cloud Run. Następnie możesz używać usług Google Cloud Observability do śledzenia wydajności aplikacji, aby mieć pewność, że jest ona niezawodna.
Jeśli chcesz wziąć udział w badaniu wrażeń użytkowników (UX), aby ulepszyć produkty, z których korzystasz, zarejestruj się tutaj.
Oto kilka opcji dalszej nauki:
- Codelab Wdrażanie aplikacji do czatu opartej na Gemini w Cloud Run
- Codelab Jak używać wywoływania funkcji Gemini z Cloud Run
- Jak za pomocą interfejsu Cloud Run Jobs Video Intelligence API przetwarzać filmy według scen
- Warsztat na żądanie Google Kubernetes Engine – wprowadzenie
- Dowiedz się więcej o konfigurowaniu wskaźników licznika i rozkładu za pomocą dzienników aplikacji
- Zapisywanie wskaźników OTLP za pomocą podrzędnego komponentu OpenTelemetry
- Informacje o korzystaniu z Open Telemetry w Google Cloud