Praktische Methoden zur Beobachtbarkeit von Anwendungen mit generativer KI in Java

1. Übersicht

Für Anwendungen mit generativer KI ist wie für alle anderen Anwendungen eine Beobachtbarkeitslösung erforderlich. Sind für generative KI spezielle Observability-Techniken erforderlich?

In diesem Lab erstellen Sie eine einfache Gen AI-Anwendung. Stellen Sie sie in Cloud Run bereit. Außerdem müssen Sie sie mit wichtigen Monitoring- und Logging-Funktionen ausstatten, indem Sie die Observability-Dienste und -Produkte von Google Cloud verwenden.

Lerninhalte

  • Anwendung schreiben, die Vertex AI mit dem Cloud Shell-Editor verwendet
  • Anwendungscode in GitHub speichern
  • gcloud CLI verwenden, um den Quellcode Ihrer Anwendung in Cloud Run bereitzustellen
  • Monitoring- und Logging-Funktionen in Ihre Anwendung mit generativer KI einbinden
  • Logbasierte Messwerte verwenden
  • Logging und Monitoring mit dem OpenTelemetry SDK implementieren
  • Informationen zum verantwortungsbewussten Umgang mit KI-Daten

2. Vorbereitung

Wenn Sie noch kein Google-Konto haben, müssen Sie ein neues Konto erstellen.

3. Projekt einrichten

  1. Melden Sie sich mit Ihrem Google-Konto in der Google Cloud Console an.
  2. Erstellen Sie ein neues Projekt oder verwenden Sie ein vorhandenes Projekt wieder. Notieren Sie sich die Projekt-ID des Projekts, das Sie gerade erstellt oder ausgewählt haben.
  3. Aktivieren Sie die Abrechnung für das Projekt.
    • Die Kosten für dieses Lab sollten weniger als 5 $betragen.
    • Sie können die Schritte am Ende dieses Labs ausführen, um Ressourcen zu löschen und so weitere Kosten zu vermeiden.
    • Neue Nutzer haben Anspruch auf die kostenlose Testversion mit einem Guthaben von 300$.
  4. Prüfen Sie in der Cloud-Abrechnung unter Meine Projekte
      , ob die Abrechnung aktiviert ist.
    • Wenn in Ihrem neuen Projekt in der Spalte Billing account der Wert Billing is disabled angezeigt wird:
      1. Klicken Sie in der Spalte Actions auf das Dreipunkt-Menü.
      2. Klicken Sie auf Abrechnung ändern.
      3. Wählen Sie das gewünschte Rechnungskonto aus.
    • Wenn Sie an einer Live-Veranstaltung teilnehmen, heißt das Konto wahrscheinlich Google Cloud Platform-Testrechnungskonto.

4. Cloud Shell-Editor vorbereiten

  1. Rufen Sie den Cloud Shell-Editor auf. Wenn Sie die folgende Meldung erhalten, in der Sie aufgefordert werden, Cloud Shell zu autorisieren, gcloud mit Ihren Anmeldedaten aufzurufen, klicken Sie auf Autorisieren, um fortzufahren.
    Klicken Sie, um Cloud Shell zu autorisieren.
  2. Terminalfenster öffnen
    1. Klicken Sie auf das Dreistrich-Menü Symbol für das Dreistrich-Menü.
    2. Klicken Sie auf Terminal.
    3. Klicken Sie auf Neues Terminal
      Neues Terminal im Cloud Shell-Editor öffnen.
  3. Konfigurieren Sie im Terminal Ihre Projekt-ID:
    gcloud config set project [PROJECT_ID]
    
    Ersetzen Sie [PROJECT_ID] durch die ID Ihres Projekts. Wenn Ihre Projekt-ID beispielsweise lab-example-project lautet, sieht der Befehl so aus:
    gcloud config set project lab-project-id-example
    
    Wenn Sie die folgende Meldung erhalten, in der Sie aufgefordert werden, Ihre Anmeldedaten für die GCPI API anzugeben, klicken Sie auf Autorisieren, um fortzufahren.
    Klicken Sie, um Cloud Shell zu autorisieren.
    Bei erfolgreicher Ausführung wird die folgende Meldung angezeigt:
    Updated property [core/project].
    
    Wenn Sie WARNING sehen und Do you want to continue (Y/N)? gefragt werden, haben Sie die Projekt-ID wahrscheinlich falsch eingegeben. Drücken Sie N, dann Enter und versuchen Sie, den Befehl gcloud config set project noch einmal auszuführen, nachdem Sie die richtige Projekt-ID gefunden haben.
  4. (Optional) Wenn Sie Probleme haben, die Projekt-ID zu finden, führen Sie den folgenden Befehl aus, um die Projekt-ID aller Ihrer Projekte nach Erstellungszeit in absteigender Reihenfolge zu sehen:
    gcloud projects list \
         --format='value(projectId,createTime)' \
         --sort-by=~createTime
    

5. Google APIs aktivieren

Aktivieren Sie im Terminal die für dieses Lab erforderlichen Google APIs:

gcloud services enable \
     run.googleapis.com \
     cloudbuild.googleapis.com \
     aiplatform.googleapis.com \
     logging.googleapis.com \
     monitoring.googleapis.com \
     cloudtrace.googleapis.com

Die Ausführung dieses Befehls kann einige Zeit in Anspruch nehmen. Wenn die Aktivierung erfolgreich war, erhalten Sie eine Meldung, die ungefähr so aussieht:

Operation "operations/acf.p2-73d90d00-47ee-447a-b600" finished successfully.

Wenn Sie eine Fehlermeldung erhalten, die mit ERROR: (gcloud.services.enable) HttpError accessing beginnt und Fehlerdetails wie unten enthält, wiederholen Sie den Befehl nach einer Verzögerung von 1 bis 2 Minuten.

"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. Generative KI-Anwendung erstellen

In diesem Schritt schreiben Sie den Code für eine einfache anfragebasierte Anwendung, die das Gemini-Modell verwendet, um 10 interessante Fakten über ein Tier Ihrer Wahl anzuzeigen. So erstellen Sie den Anwendungscode:

  1. Erstellen Sie im Terminal das Verzeichnis codelab-o11y:
    mkdir "${HOME}/codelab-o11y"
    
  2. Ändern Sie das aktuelle Verzeichnis in codelab-o11y:
    cd "${HOME}/codelab-o11y"
    
  3. Laden Sie den Bootstrap-Code der Java-Anwendung mit dem Spring Framework-Starter herunter:
    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
    
  4. Entpacken Sie den Bootstrap-Code in den aktuellen Ordner:
    unzip java-starter.zip
    
  5. Entfernen Sie die Archivdatei aus dem Ordner:
    rm java-starter.zip
    
  6. Erstellen Sie eine project.toml-Datei, um die Java-Laufzeitversion zu definieren, die beim Bereitstellen des Codes in Cloud Run verwendet werden soll:
    cat > "${HOME}/codelab-o11y/project.toml" << EOF
    [[build.env]]
        name = "GOOGLE_RUNTIME_VERSION"
        value = "17"
    EOF
    
  7. Fügen Sie der pom.xml-Datei Google Cloud SDK-Abhängigkeiten hinzu:
    1. Fügen Sie das Google Cloud Core-Paket hinzu:
      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"
      
    2. Fügen Sie das Google Cloud Vertex AI-Paket hinzu:
      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"
      
  8. Öffnen Sie die Datei DemoApplication.java im Cloud Shell-Editor:
    cloudshell edit "${HOME}/codelab-o11y/src/main/java/com/example/demo/DemoApplication.java"
    
    Im Editorfenster über dem Terminal sollte jetzt ein Gerüst für den Quellcode der Datei DemoApplication.java angezeigt werden. Der Quellcode der Datei sieht in etwa so aus:
    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);
        }
    }
    
  9. Ersetzen Sie den Code im Editor durch die unten gezeigte Version. Löschen Sie den Inhalt der Datei, um den Code zu ersetzen, und kopieren Sie dann den folgenden Code in den Editor:
    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);
        }
    }
    
    Nach einigen Sekunden wird Ihr Code automatisch im Cloud Shell Editor gespeichert.

Code der GenAI-Anwendung in Cloud Run bereitstellen

  1. Führen Sie im Terminalfenster den Befehl aus, um den Quellcode der Anwendung in Cloud Run bereitzustellen.
    gcloud run deploy codelab-o11y-service \
         --source="${HOME}/codelab-o11y/" \
         --region=us-central1 \
         --allow-unauthenticated
    
    Wenn Sie die folgende Aufforderung sehen, die Sie darüber informiert, dass mit dem Befehl ein neues Repository erstellt wird. Klicken Sie auf Enter.
    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)?
    
    Die Bereitstellung kann einige Minuten dauern. Nach Abschluss der Bereitstellung wird in etwa folgende Ausgabe angezeigt:
    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
    
  2. Kopieren Sie die angezeigte Cloud Run-Dienst-URL in einen separaten Tab oder ein separates Fenster in Ihrem Browser. Alternativ können Sie den folgenden Befehl im Terminal ausführen, um die Dienst-URL auszugeben, und dann bei gedrückter Ctrl auf die angezeigte URL klicken, um sie zu öffnen:
    gcloud run services list \
         --format='value(URL)' \
         --filter='SERVICE:"codelab-o11y-service"'
    
    Wenn die URL geöffnet wird, erhalten Sie möglicherweise einen 500-Fehler oder die folgende Meldung:
    Sorry, this is just a placeholder...
    
    Das bedeutet, dass die Bereitstellung der Dienste nicht abgeschlossen wurde. Warten Sie einige Sekunden und aktualisieren Sie dann die Seite. Am Ende sehen Sie einen Text, der mit Fun Dog Facts beginnt und 10 Fun Facts über Hunde enthält.

Interagieren Sie mit der Anwendung, um interessante Fakten über verschiedene Tiere zu erhalten. Hängen Sie dazu den Parameter animal an die URL an, z. B. ?animal=[ANIMAL], wobei [ANIMAL] ein Tiername ist. Hängen Sie beispielsweise ?animal=cat an, um 10 Funfacts über Katzen zu erhalten, oder ?animal=sea turtle, um 10 Funfacts über Meeresschildkröten zu erhalten.

7. Vertex API-Aufrufe prüfen

Durch die Überprüfung von Google API-Aufrufen erhalten Sie Antworten auf Fragen wie „Wer hat eine bestimmte API wann und wo aufgerufen?“. Die Überwachung ist wichtig, wenn Sie Fehler in Ihrer Anwendung beheben, den Ressourcenverbrauch untersuchen oder eine Software-Forensik durchführen.

Mit Audit-Logs können Sie Administrator- und Systemaktivitäten nachverfolgen sowie Aufrufe von API-Vorgängen zum Lesen und Schreiben von Daten protokollieren. Wenn Sie Vertex AI-Anfragen zum Generieren von Inhalten prüfen möchten, müssen Sie Audit-Logs vom Typ „Daten lesen“ in der Cloud Console aktivieren.

  1. Klicken Sie auf die Schaltfläche unten, um die Seite „Audit-Logs“ in der Cloud Console zu öffnen.

  2. Achten Sie darauf, dass auf der Seite das Projekt ausgewählt ist, das Sie für dieses Lab erstellt haben. Das ausgewählte Projekt wird oben links auf der Seite direkt neben dem Dreistrich-Menü angezeigt:
    Google Cloud Console-Projekt-Dropdown-Menü
    Wählen Sie bei Bedarf das richtige Projekt aus der Kombinationsbox aus.
  3. Suchen Sie in der Tabelle Konfiguration für Audit-Logs zum Datenzugriff in der Spalte „Dienst“ nach dem Dienst Vertex AI API und wählen Sie den Dienst aus, indem Sie das Kästchen links neben dem Dienstnamen aktivieren.
    Vertex AI API auswählen
  4. Wählen Sie im Infobereich rechts den Audittyp „Daten lesen“ aus.
    Logs zum Lesen von Daten prüfen
  5. Klicken Sie auf Speichern.

Öffnen Sie die Dienst-URL, um Audit-Logs zu generieren. Aktualisieren Sie die Seite, während Sie den Wert des Parameters ?animal= ändern, um unterschiedliche Ergebnisse zu erhalten.

Audit-Logs ansehen

  1. Klicken Sie auf die Schaltfläche unten, um die Seite „Log-Explorer“ in der Cloud Console zu öffnen:

  2. Fügen Sie den folgenden Filter in den Bereich „Abfrage“ ein.
    LOG_ID("cloudaudit.googleapis.com%2Fdata_access") AND
    protoPayload.serviceName="aiplatform.googleapis.com"
    
    Der Bereich „Abfrage“ ist ein Editor oben auf der Seite „Log-Explorer“:
    Audit-Logs abfragen
  3. Klicken Sie auf Abfrage ausführen.
  4. Wählen Sie einen der Audit-Log-Einträge aus. Die Felder werden maximiert, damit Sie die im Log erfassten Informationen sehen können.
     Sie können Details zum Vertex API-Aufruf sehen, einschließlich der verwendeten Methode und des verwendeten Modells. Außerdem können Sie die Identität des Aufrufers und die Berechtigungen sehen, die den Aufruf autorisiert haben.

8. Interaktionen mit generativer KI protokollieren

Sie finden keine API-Anfrageparameter oder Antwortdaten in Audit-Logs. Diese Informationen können jedoch für die Fehlerbehebung bei der Analyse von Anwendungen und Workflows wichtig sein. In diesem Schritt schließen wir diese Lücke, indem wir die Anwendungs-Logging-Funktion hinzufügen.

Bei der Implementierung wird Logback mit Spring Boot verwendet, um Anwendungslogs in die Standardausgabe zu schreiben. Bei dieser Methode wird die Funktion von Cloud Run genutzt, Informationen, die in die Standardausgabe geschrieben werden, automatisch zu erfassen und in Cloud Logging aufzunehmen. Damit Informationen als strukturierte Daten erfasst werden können, müssen die gedruckten Logs entsprechend formatiert sein. Folgen Sie der Anleitung unten, um der Anwendung Funktionen für strukturiertes Logging hinzuzufügen.

  1. Kehren Sie in Ihrem Browser zum Fenster (oder Tab) „Cloud Shell“ zurück.
  2. Erstellen Sie im Cloud Shell-Editor eine neue Datei namens LoggingEventGoogleCloudEncoder.java und öffnen Sie sie:
    cloudshell edit "${HOME}/codelab-o11y/src/main/java/com/example/demo/LoggingEventGoogleCloudEncoder.java"
    
  3. Kopieren Sie den folgenden Code und fügen Sie ihn ein, um den Logback-Encoder zu implementieren, der das Log als stringifiziertes JSON im strukturierten Logformat von Google Cloud codiert:
    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";
            }
        }
    }
    
  4. Erstellen Sie im Cloud Shell-Editor eine neue Datei namens logback.xml und öffnen Sie sie:
    cloudshell edit "${HOME}/codelab-o11y/src/main/resources/logback.xml"
    
  5. Kopieren Sie den folgenden XML-Code und fügen Sie ihn ein, um Logback so zu konfigurieren, dass der Encoder mit dem Logback-Appender verwendet wird, der Logs in die Standardausgabe schreibt:
    <?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>
    
  6. Öffnen Sie die Datei DemoApplication.java noch einmal im Cloud Shell-Editor:
    cloudshell edit "${HOME}/codelab-o11y/src/main/java/com/example/demo/DemoApplication.java"
    
  7. Ersetzen Sie den Code im Editor durch die unten gezeigte Version, um Anfragen und Antworten von generativer KI zu protokollieren. Löschen Sie den Inhalt der Datei, um den Code zu ersetzen, und kopieren Sie dann den folgenden Code in den Editor:
    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);
        }
    }
    

Nach einigen Sekunden werden Ihre Änderungen automatisch in Cloud Shell Editor gespeichert.

Code der GenAI-Anwendung in Cloud Run bereitstellen

  1. Führen Sie im Terminalfenster den Befehl aus, um den Quellcode der Anwendung in Cloud Run bereitzustellen.
    gcloud run deploy codelab-o11y-service \
         --source="${HOME}/codelab-o11y/" \
         --region=us-central1 \
         --allow-unauthenticated
    
    Wenn Sie die folgende Aufforderung sehen, die Sie darüber informiert, dass mit dem Befehl ein neues Repository erstellt wird. Klicken Sie auf Enter.
    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)?
    
    Die Bereitstellung kann einige Minuten dauern. Nach Abschluss der Bereitstellung wird in etwa folgende Ausgabe angezeigt:
    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
    
  2. Kopieren Sie die angezeigte Cloud Run-Dienst-URL in einen separaten Tab oder ein separates Fenster in Ihrem Browser. Alternativ können Sie den folgenden Befehl im Terminal ausführen, um die Dienst-URL auszugeben, und dann bei gedrückter Ctrl auf die angezeigte URL klicken, um sie zu öffnen:
    gcloud run services list \
         --format='value(URL)' \
         --filter='SERVICE:"codelab-o11y-service"'
    
    Wenn die URL geöffnet wird, erhalten Sie möglicherweise einen 500-Fehler oder die folgende Meldung:
    Sorry, this is just a placeholder...
    
    Das bedeutet, dass die Bereitstellung der Dienste nicht abgeschlossen wurde. Warten Sie einige Sekunden und aktualisieren Sie dann die Seite. Am Ende sehen Sie einen Text, der mit Fun Dog Facts beginnt und 10 Fun Facts über Hunde enthält.

Öffnen Sie die Dienst-URL, um Anwendungslogs zu generieren. Aktualisieren Sie die Seite, während Sie den Wert des Parameters ?animal= ändern, um unterschiedliche Ergebnisse zu erhalten.
 So rufen Sie die Anwendungslogs auf:

  1. Klicken Sie auf die Schaltfläche unten, um die Seite „Log-Explorer“ in der Cloud Console zu öffnen:

  2. Fügen Sie den folgenden Filter in den Bereich „Abfrage“ (#2 in der Log-Explorer-Benutzeroberfläche) ein:
    LOG_ID("run.googleapis.com%2Fstdout") AND
    severity=DEBUG
    
  3. Klicken Sie auf Abfrage ausführen.

Das Ergebnis der Abfrage enthält Protokolle mit dem Prompt und der Vertex AI-Antwort, einschließlich Sicherheitsbewertungen.

9. Interaktionen mit generativer KI zählen

Cloud Run schreibt verwaltete Messwerte, mit denen bereitgestellte Dienste überwacht werden können. Mit nutzerverwalteten Überwachungsstatistiken haben Sie mehr Kontrolle über Daten und Häufigkeit der Statistikaktualisierung. Um einen solchen Messwert zu implementieren, müssen Sie Code schreiben, der Daten erfasst und in Cloud Monitoring schreibt. Im nächsten (optionalen) Schritt erfahren Sie, wie Sie dies mit dem OpenTelemetry SDK implementieren.

In diesem Schritt wird eine Alternative zur Implementierung von Nutzermesswerten im Code gezeigt: logbasierte Messwerte. Mit logbasierten Messwerten können Sie Monitoring-Messwerte aus den Logeinträgen generieren, die Ihre Anwendung in Cloud Logging schreibt. Wir verwenden die Anwendungslogs, die wir im vorherigen Schritt implementiert haben, um einen logbasierten Messwert vom Typ „Zähler“ zu definieren. Mit diesem Messwert wird die Anzahl der erfolgreichen Aufrufe an die Vertex API gezählt.

  1. Sehen Sie sich das Fenster des Log-Explorers an, das wir im vorherigen Schritt verwendet haben. Suchen Sie im Bereich „Abfrage“ nach dem Drop-down-Menü Aktionen und klicken Sie darauf, um es zu öffnen. Im Screenshot unten sehen Sie, wo sich das Menü befindet:
    Symbolleiste für Abfrageergebnisse mit dem Drop-down-Menü „Aktionen“
  2. Wählen Sie im geöffneten Menü Messwert erstellen aus, um den Bereich Logbasierten Messwert erstellen zu öffnen.
  3. So konfigurieren Sie einen neuen Zählermesswert im Bereich Logbasierten Messwert erstellen:
    1. Legen Sie den Messwerttyp fest: Wählen Sie Zähler aus.
    2. Legen Sie im Abschnitt Details die folgenden Felder fest:
      • Name des Logmesswerts: Legen Sie den Namen auf model_interaction_count fest. Für die Benennung gelten einige Einschränkungen. Weitere Informationen dazu finden Sie unter Fehlerbehebung.
      • Beschreibung: Geben Sie eine Beschreibung für den Messwert ein. z. B. Number of log entries capturing successful call to model inference..
      • Einheiten: Lassen Sie dieses Feld leer oder geben Sie die Zahl 1 ein.
    3. Übernehmen Sie die Werte im Abschnitt Filterauswahl. Das Feld Build-Filter enthält denselben Filter, den wir zum Aufrufen von Anwendungslogs verwendet haben.
    4. Optional: Fügen Sie ein Label hinzu, mit dem Sie die Anzahl der Anrufe für jedes Tier zählen können. HINWEIS: Dieses Label kann die Kardinalität von Messwerten erheblich erhöhen und wird nicht für den Einsatz in der Produktion empfohlen:
      1. Klicken Sie auf Label hinzufügen.
      2. Legen Sie im Abschnitt Labels die folgenden Felder fest:
        • Labelname: Legen Sie als Namen animal fest.
        • Beschreibung: Geben Sie die Beschreibung des Labels ein. Beispiel: Animal parameter.
        • Labeltyp: Wählen Sie STRING aus.
        • Feldname: Geben Sie jsonPayload.animal ein.
        • Regulärer Ausdruck: Lassen Sie das Feld leer.
      3. Klicken Sie auf Fertig.
    5. Klicken Sie auf Messwert erstellen, um den Messwert zu erstellen.

Sie können auch einen logbasierten Messwert auf der Seite Logbasierte Messwerte mit dem gcloud logging metrics create CLI-Befehl oder mit der google_logging_metric Terraform-Ressource erstellen.

Öffnen Sie die Dienst-URL, um Messwertdaten zu generieren. Aktualisieren Sie die geöffnete Seite mehrmals, um mehrere Aufrufe des Modells zu generieren. Verwenden Sie wie zuvor verschiedene Tiere im Parameter.

Geben Sie die PromQL-Abfrage ein, mit der nach den logbasierten Messwertdaten gesucht werden soll. So geben Sie eine PromQL-Abfrage ein:

  1. Klicken Sie auf die Schaltfläche unten, um die Seite „Metrics Explorer“ in der Cloud Console zu öffnen:

  2. Klicken Sie in der Symbolleiste des Bereichs „Query Builder“ auf die Schaltfläche, deren Name entweder < > MQL oder < > PromQL ist. Die Position der Schaltfläche sehen Sie auf dem Bild unten.
    Position der MQL-Schaltfläche im Metrics Explorer
  3. Prüfen Sie, ob im Ein-/Aus-Button Sprache PromQL ausgewählt ist. Die Sprachschaltfläche befindet sich in derselben Symbolleiste, mit der Sie Ihre Abfrage formatieren können.
  4. Geben Sie Ihre Abfrage in den Editor Abfragen ein:
    sum(rate(logging_googleapis_com:user_model_interaction_count{monitored_resource="cloud_run_revision"}[${__interval}]))
    
    Weitere Informationen zur Verwendung von PromQL finden Sie unter PromQL in Cloud Monitoring.
  5. Klicken Sie auf Abfrage ausführen. Es wird ein Liniendiagramm wie in diesem Screenshot angezeigt:
    Abgefragte Messwerte anzeigen

    Hinweis: Wenn der Ein/Aus-Schalter Automatisch ausführen aktiviert ist, wird der Button Abfrage ausführen nicht angezeigt.

10. Optional: OpenTelemetry für Monitoring und Tracing verwenden

Wie im vorherigen Schritt erwähnt, können Sie Messwerte mit dem OpenTelemetry (Otel) SDK implementieren. Die Verwendung von OTel in Architekturen mit mehreren Diensten wird empfohlen. In diesem Schritt wird gezeigt, wie Sie einer Spring Boot-Anwendung OTel-Instrumentierung hinzufügen. In diesem Schritt gehen Sie so vor:

  • Spring Boot-Anwendung mit automatischen Tracing-Funktionen instrumentieren
  • Zählermesswert implementieren, um die Anzahl der erfolgreichen Modellaufrufe zu erfassen
  • Tracing mit Anwendungslogs korrelieren

Die empfohlene Architektur für Dienste auf Produktebene ist die Verwendung des OTel-Collectors zum Erfassen und Aufnehmen aller Observability-Daten aus mehreren Diensten. Der Einfachheit halber wird im Code in diesem Schritt kein Collector verwendet. Stattdessen werden OTel-Exporte verwendet, mit denen Daten direkt in Google Cloud geschrieben werden.

Spring Boot-Anwendung mit OTel-Komponenten und automatischem Tracing einrichten

  1. Kehren Sie in Ihrem Browser zum Fenster (oder Tab) „Cloud Shell“ zurück.
  2. Aktualisieren Sie im Terminal die Datei application.permissions mit zusätzlichen Konfigurationsparametern:
    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
    
    Mit diesen Parametern wird das Exportieren von Beobachtbarkeitsdaten nach Cloud Trace und Cloud Monitoring definiert und das Sampling aller Traces erzwungen.
  3. Fügen Sie der Datei pom.xml die erforderlichen OpenTelemetry-Abhängigkeiten hinzu:
    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"
    
  4. Fügen Sie der Datei pom.xml die OpenTelemetry-BOM hinzu:
    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"
    
  5. Öffnen Sie die Datei DemoApplication.java noch einmal im Cloud Shell-Editor:
    cloudshell edit "${HOME}/codelab-o11y/src/main/java/com/example/demo/DemoApplication.java"
    
  6. Ersetzen Sie den aktuellen Code durch die Version, die einen Leistungsmesswert erhöht. Löschen Sie den Inhalt der Datei, um den Code zu ersetzen, und kopieren Sie dann den folgenden Code in den Editor:
    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);
        }
    }
    
  7. Öffnen Sie die Datei LoggingEventGoogleCloudEncoder.java noch einmal im Cloud Shell-Editor:
    cloudshell edit "${HOME}/codelab-o11y/src/main/java/com/example/demo/LoggingEventGoogleCloudEncoder.java"
    
  8. Ersetzen Sie den aktuellen Code durch die Version, in der den geschriebenen Logs Tracing-Attribute hinzugefügt werden. Wenn Sie die Attribute hinzufügen, können Logs mit den richtigen Trace-Spans korreliert werden. Löschen Sie den Inhalt der Datei, um den Code zu ersetzen, und kopieren Sie dann den folgenden Code in den Editor:
    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";
            }
        }
    }
    

Nach einigen Sekunden werden Ihre Änderungen automatisch in Cloud Shell Editor gespeichert.

Code der GenAI-Anwendung in Cloud Run bereitstellen

  1. Führen Sie im Terminalfenster den Befehl aus, um den Quellcode der Anwendung in Cloud Run bereitzustellen.
    gcloud run deploy codelab-o11y-service \
         --source="${HOME}/codelab-o11y/" \
         --region=us-central1 \
         --allow-unauthenticated
    
    Wenn Sie die folgende Aufforderung sehen, die Sie darüber informiert, dass mit dem Befehl ein neues Repository erstellt wird. Klicken Sie auf Enter.
    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)?
    
    Die Bereitstellung kann einige Minuten dauern. Nach Abschluss der Bereitstellung wird in etwa folgende Ausgabe angezeigt:
    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
    
  2. Kopieren Sie die angezeigte Cloud Run-Dienst-URL in einen separaten Tab oder ein separates Fenster in Ihrem Browser. Alternativ können Sie den folgenden Befehl im Terminal ausführen, um die Dienst-URL auszugeben, und dann bei gedrückter Ctrl auf die angezeigte URL klicken, um sie zu öffnen:
    gcloud run services list \
         --format='value(URL)' \
         --filter='SERVICE:"codelab-o11y-service"'
    
    Wenn die URL geöffnet wird, erhalten Sie möglicherweise einen 500-Fehler oder die folgende Meldung:
    Sorry, this is just a placeholder...
    
    Das bedeutet, dass die Bereitstellung der Dienste nicht abgeschlossen wurde. Warten Sie einige Sekunden und aktualisieren Sie dann die Seite. Am Ende sehen Sie einen Text, der mit Fun Dog Facts beginnt und 10 Fun Facts über Hunde enthält.

Öffnen Sie die Dienst-URL, um Telemetriedaten zu generieren. Aktualisieren Sie die Seite, während Sie den Wert des Parameters ?animal= ändern, um unterschiedliche Ergebnisse zu erhalten.

Anwendungs-Traces ansehen

  1. Klicken Sie auf die Schaltfläche unten, um die Seite „Trace Explorer“ in der Cloud Console zu öffnen:

  2. Wählen Sie einen der letzten Traces aus. Sie sollten 5 oder 6 Spannen sehen, die wie im Screenshot unten aussehen.
    Ansicht des App-Spans im Trace-Explorer
  3. Suchen Sie nach dem Span, der den Aufruf des Event-Handlers (die Methode fun_facts) nachverfolgt. Das ist der letzte Bereich mit dem Namen /.
  4. Wählen Sie im Bereich Trace-Details die Option Logs und Ereignisse aus. Sie sehen Anwendungslogs, die mit diesem bestimmten Span korrelieren. Die Korrelation wird anhand der Trace- und Span-IDs im Trace und im Log erkannt. Sie sollten das Anwendungsprotokoll sehen, in dem der Prompt und die Antwort der Vertex API aufgezeichnet wurden.

Zählermesswert ansehen

  1. Klicken Sie auf die Schaltfläche unten, um die Seite „Metrics Explorer“ in der Cloud Console zu öffnen:

  2. Klicken Sie in der Symbolleiste des Bereichs „Query Builder“ auf die Schaltfläche, deren Name entweder < > MQL oder < > PromQL ist. Die Position der Schaltfläche sehen Sie auf dem Bild unten.
    Position der MQL-Schaltfläche im Metrics Explorer
  3. Prüfen Sie, ob im Ein-/Aus-Button Sprache PromQL ausgewählt ist. Die Sprachschaltfläche befindet sich in derselben Symbolleiste, mit der Sie Ihre Abfrage formatieren können.
  4. Geben Sie Ihre Abfrage in den Editor Abfragen ein:
    sum(rate(workload_googleapis_com:model_call_counter{monitored_resource="generic_task"}[${__interval}]))
    
  5. Klicken Sie auf Abfrage ausführen.Wenn der Ein/Aus-Button Automatisch ausführen aktiviert ist, wird der Button Abfrage ausführen nicht angezeigt.

11. (Optional) Vertrauliche Informationen aus Logs verschleiern

In Schritt 10 haben wir Informationen zur Interaktion der Anwendung mit dem Gemini-Modell protokolliert. Diese Informationen umfassten den Namen des Tieres, den eigentlichen Prompt und die Antwort des Modells. Das Speichern dieser Informationen im Log sollte sicher sein, das gilt jedoch nicht für viele andere Szenarien. Der Prompt kann personenbezogene oder anderweitig vertrauliche Informationen enthalten, die ein Nutzer nicht speichern möchte. Um dieses Problem zu beheben, können Sie die sensiblen Daten, die in Cloud Logging geschrieben werden, verschleiern. Um Codeänderungen zu minimieren, empfehlen wir die folgende Lösung.

  1. Pub/Sub-Thema zum Speichern eingehender Logeinträge erstellen
  2. Erstellen Sie eine Logs-Senke, die aufgenommene Logs an ein Pub/Sub-Thema weiterleitet.
  3. Erstellen Sie eine Dataflow-Pipeline, die Logs ändert, die an ein Pub/Sub-Thema weitergeleitet werden. Gehen Sie dazu so vor:
    1. Logeintrag aus dem Pub/Sub-Thema lesen
    2. Die Nutzlast des Eintrags mit der DLP Inspection API auf vertrauliche Informationen prüfen
    3. Entfernen Sie die vertraulichen Informationen in der Nutzlast mit einer der DLP-Methoden zum Entfernen.
    4. Den verschleierten Logeintrag in Cloud Logging schreiben
  4. Stellen Sie die Pipeline bereit.

12. Optional: Bereinigen

Um das Risiko zu vermeiden, dass für die im Codelab verwendeten Ressourcen und APIs Gebühren anfallen, empfiehlt es sich, nach Abschluss des Codelabs die Ressourcen zu bereinigen. Am einfachsten vermeiden Sie weitere Kosten, wenn Sie das für das Codelab erstellte Projekt löschen.

  1. Führen Sie den Befehl zum Löschen des Projekts im Terminal aus, um das Projekt zu löschen:
    PROJECT_ID=$(gcloud config get-value project)
    gcloud projects delete ${PROJECT_ID} --quiet
    
    Wenn Sie Ihr Cloud-Projekt löschen, wird die Abrechnung für alle in diesem Projekt verwendeten Ressourcen und APIs beendet. Es sollte folgende Meldung angezeigt werden, wobei PROJECT_ID Ihre Projekt-ID ist:
    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.
    
  2. (Optional) Wenn Sie eine Fehlermeldung erhalten, sehen Sie in Schritt 5 nach, welche Projekt-ID Sie während des Labs verwendet haben. Ersetzen Sie den Befehl in der ersten Anleitung damit. Wenn Ihre Projekt-ID beispielsweise lab-example-project lautet, sieht der Befehl so aus:
    gcloud projects delete lab-project-id-example --quiet
    

13. Glückwunsch

In diesem Lab haben Sie eine Anwendung mit generativer KI erstellt, die mit dem Gemini-Modell Vorhersagen trifft. Außerdem wurde die Anwendung mit wichtigen Monitoring- und Logging-Funktionen ausgestattet. Sie haben die Anwendung und Änderungen aus dem Quellcode in Cloud Run bereitgestellt. Anschließend können Sie die Leistung der Anwendung mit Google Cloud Observability-Produkten verfolgen, um die Zuverlässigkeit der Anwendung zu gewährleisten.

Wenn Sie an einer Studie zur Nutzerfreundlichkeit teilnehmen möchten, um die Produkte zu verbessern, mit denen Sie heute gearbeitet haben, registrieren Sie sich hier.

Hier sind einige Optionen, um weiterzulernen: