Các kỹ thuật quan sát thực tế cho ứng dụng AI tạo sinh trong Java

1. Tổng quan

Các ứng dụng AI tạo sinh cũng cần có khả năng quan sát như mọi ứng dụng khác. Có kỹ thuật quan sát đặc biệt nào cần thiết cho AI tạo sinh không?

Trong lớp học lập trình này, bạn sẽ tạo một ứng dụng AI tạo sinh đơn giản. Triển khai ứng dụng đó lên Cloud Run. Đồng thời, hãy đo lường ứng dụng bằng các tính năng giám sát và ghi nhật ký thiết yếu bằng các dịch vụ và sản phẩm khả năng quan sát của Google Cloud.

Kiến thức bạn sẽ học được

  • Viết một ứng dụng sử dụng Vertex AI bằng Trình chỉnh sửa Cloud Shell
  • Lưu trữ mã ứng dụng trong GitHub
  • Sử dụng gcloud CLI để triển khai mã nguồn của ứng dụng lên Cloud Run
  • Thêm chức năng giám sát và ghi nhật ký vào ứng dụng AI tạo sinh
  • Sử dụng các chỉ số dựa trên nhật ký
  • Triển khai tính năng ghi nhật ký và giám sát bằng SDK Open Telemetry
  • Nhận thông tin chi tiết về cách xử lý dữ liệu AI có trách nhiệm

2. Điều kiện tiên quyết

Nếu chưa có Tài khoản Google, bạn phải tạo một tài khoản mới.

3. Thiết lập dự án

  1. Đăng nhập vào Google Cloud Console bằng Tài khoản Google của bạn.
  2. Tạo dự án mới hoặc chọn sử dụng lại một dự án hiện có. Ghi lại mã dự án của dự án bạn vừa tạo hoặc chọn.
  3. Bật tính năng thanh toán cho dự án.
    • Chi phí thanh toán để hoàn thành lớp học này sẽ dưới 5 USD.
    • Bạn có thể làm theo các bước ở cuối lớp học này để xoá tài nguyên nhằm tránh bị tính thêm phí.
    • Người dùng mới đủ điều kiện dùng thử miễn phí 300 USD.
  4. Xác nhận rằng bạn đã bật tính năng thanh toán trong phần Dự án của tôi trong Cloud Billing
    • Nếu dự án mới của bạn có nội dung Billing is disabled trong cột Billing account:
      1. Nhấp vào biểu tượng ba dấu chấm trong cột Actions
      2. Nhấp vào Thay đổi thông tin thanh toán
      3. Chọn tài khoản thanh toán mà bạn muốn sử dụng
    • Nếu bạn đang tham dự một sự kiện trực tiếp, tài khoản đó có thể có tên là Tài khoản thanh toán dùng thử Google Cloud Platform

4. Chuẩn bị Trình chỉnh sửa Cloud Shell

  1. Chuyển đến Trình chỉnh sửa Cloud Shell. Nếu bạn thấy thông báo sau yêu cầu uỷ quyền cho màn hình shell trên đám mây gọi gcloud bằng thông tin xác thực của bạn, hãy nhấp vào Uỷ quyền để tiếp tục.
    Nhấp để uỷ quyền cho Cloud Shell
  2. Mở cửa sổ dòng lệnh
    1. Nhấp vào trình đơn có biểu tượng ba dấu gạch ngang Biểu tượng trình đơn có ba đường kẻ
    2. Nhấp vào Terminal (Thiết bị đầu cuối)
    3. Nhấp vào New Terminal
      Mở cửa sổ dòng lệnh mới trong Trình chỉnh sửa Cloud Shell (Thiết bị đầu cuối mới)
  3. Trong thiết bị đầu cuối, hãy định cấu hình mã dự án:
    gcloud config set project [PROJECT_ID]
    
    Thay thế [PROJECT_ID] bằng mã dự án của bạn. Ví dụ: nếu mã dự án của bạn là lab-example-project, thì lệnh sẽ là:
    gcloud config set project lab-project-id-example
    
    Nếu bạn thấy thông báo sau đây cho biết gcloud yêu cầu thông tin xác thực của bạn cho API GCPI, hãy nhấp vào Uỷ quyền để tiếp tục.
    Nhấp để uỷ quyền cho Cloud Shell
    Khi thực thi thành công, bạn sẽ thấy thông báo sau:
    Updated property [core/project].
    
    Nếu bạn thấy WARNING và được hỏi Do you want to continue (Y/N)?, thì có thể bạn đã nhập không chính xác mã dự án. Nhấn N, nhấn Enter rồi thử chạy lại lệnh gcloud config set project sau khi bạn tìm thấy mã dự án chính xác.
  4. (Không bắt buộc) Nếu bạn gặp sự cố khi tìm mã dự án, hãy chạy lệnh sau để xem mã dự án của tất cả dự án được sắp xếp theo thời gian tạo theo thứ tự giảm dần:
    gcloud projects list \
         --format='value(projectId,createTime)' \
         --sort-by=~createTime
    

5. Bật API của Google

Trong dòng lệnh, hãy bật các API Google bắt buộc cho lớp học này:

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

Lệnh này sẽ mất chút thời gian để hoàn tất. Cuối cùng, ứng dụng sẽ tạo ra một thông báo thành công tương tự như sau:

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

Nếu bạn nhận được thông báo lỗi bắt đầu bằng ERROR: (gcloud.services.enable) HttpError accessing và chứa thông tin chi tiết về lỗi như bên dưới, hãy thử lại lệnh sau khi chờ 1-2 phút.

"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. Tạo ứng dụng AI tạo sinh

Trong bước này, bạn sẽ viết mã của một ứng dụng đơn giản dựa trên yêu cầu sử dụng mô hình Gemini để hiển thị 10 thông tin thú vị về một loài động vật mà bạn chọn. Hãy làm theo các bước sau để tạo mã ứng dụng.

  1. Trong dòng lệnh, hãy tạo thư mục codelab-o11y:
    mkdir "${HOME}/codelab-o11y"
    
  2. Thay đổi thư mục hiện tại thành codelab-o11y:
    cd "${HOME}/codelab-o11y"
    
  3. Tải mã khởi động của ứng dụng Java xuống bằng trình khởi động khung 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
    
  4. Giải nén mã khởi động vào thư mục hiện tại:
    unzip java-starter.zip
    
  5. Và xoá tệp lưu trữ khỏi thư mục:
    rm java-starter.zip
    
  6. Tạo tệp project.toml để xác định phiên bản Java Runtime sẽ dùng khi triển khai mã cho Cloud Run:
    cat > "${HOME}/codelab-o11y/project.toml" << EOF
    [[build.env]]
        name = "GOOGLE_RUNTIME_VERSION"
        value = "17"
    EOF
    
  7. Thêm các phần phụ thuộc Google Cloud SDK vào tệp pom.xml:
    1. Thêm gói 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"
      
    2. Thêm gói 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"
      
  8. Mở tệp DemoApplication.java trong Trình chỉnh sửa Cloud Shell:
    cloudshell edit "${HOME}/codelab-o11y/src/main/java/com/example/demo/DemoApplication.java"
    
    Mã nguồn được tạo sẵn của tệp DemoApplication.java sẽ xuất hiện trong cửa sổ trình soạn thảo phía trên thiết bị đầu cuối. Mã nguồn của tệp sẽ tương tự như sau:
    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. Thay thế mã trong trình chỉnh sửa bằng phiên bản hiển thị bên dưới. Để thay thế mã, hãy xoá nội dung của tệp rồi sao chép mã dưới đây vào trình chỉnh sửa:
    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);
        }
    }
    
    Sau vài giây, Trình chỉnh sửa Cloud Shell sẽ tự động lưu mã của bạn.

Triển khai mã của ứng dụng Gen AI cho Cloud Run

  1. Trong cửa sổ dòng lệnh, hãy chạy lệnh để triển khai mã nguồn của ứng dụng lên Cloud Run.
    gcloud run deploy codelab-o11y-service \
         --source="${HOME}/codelab-o11y/" \
         --region=us-central1 \
         --allow-unauthenticated
    
    Nếu bạn thấy lời nhắc như bên dưới, thông báo cho bạn rằng lệnh này sẽ tạo một kho lưu trữ mới. Nhấp vào 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)?
    
    Quá trình triển khai có thể mất vài phút. Sau khi quá trình triển khai hoàn tất, bạn sẽ thấy kết quả như sau:
    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. Sao chép URL dịch vụ Cloud Run hiển thị vào một thẻ hoặc cửa sổ riêng trong trình duyệt. Ngoài ra, hãy chạy lệnh sau trong cửa sổ dòng lệnh để in URL dịch vụ và nhấp vào URL hiển thị trong khi giữ phím Ctrl để mở URL:
    gcloud run services list \
         --format='value(URL)' \
         --filter='SERVICE:"codelab-o11y-service"'
    
    Khi mở URL, bạn có thể gặp lỗi 500 hoặc thấy thông báo:
    Sorry, this is just a placeholder...
    
    Điều này có nghĩa là các dịch vụ chưa hoàn tất quá trình triển khai. Đợi vài phút rồi làm mới trang. Ở cuối, bạn sẽ thấy một văn bản bắt đầu bằng Thông tin thú vị về chó và chứa 10 thông tin thú vị về chó.

Hãy thử tương tác với ứng dụng để biết các thông tin thú vị về nhiều loài động vật. Để thực hiện việc này, hãy thêm tham số animal vào URL, chẳng hạn như ?animal=[ANIMAL], trong đó [ANIMAL] là tên một con vật. Ví dụ: nối ?animal=cat để nhận 10 sự thật thú vị về mèo hoặc ?animal=sea turtle để nhận 10 sự thật thú vị về rùa biển.

7. Kiểm tra các lệnh gọi API Vertex

Việc kiểm tra các lệnh gọi API của Google sẽ giúp trả lời các câu hỏi như "Ai gọi một API cụ thể, ở đâu và khi nào?". Việc kiểm tra rất quan trọng khi bạn khắc phục sự cố ứng dụng, điều tra mức sử dụng tài nguyên hoặc thực hiện phân tích pháp y phần mềm.

Nhật ký kiểm tra cho phép bạn theo dõi các hoạt động quản trị và hệ thống, cũng như ghi lại các lệnh gọi đến các thao tác API "đọc dữ liệu" và "ghi dữ liệu". Để kiểm tra các yêu cầu của Vertex AI nhằm tạo nội dung, bạn phải bật nhật ký kiểm tra "Đọc dữ liệu" trong Cloud Console.

  1. Nhấp vào nút bên dưới để mở trang Nhật ký kiểm tra trong Cloud Console

  2. Đảm bảo rằng trang này đã chọn dự án mà bạn đã tạo cho lớp học này. Dự án đã chọn sẽ xuất hiện ở góc trên cùng bên trái của trang ngay từ trình đơn bánh hamburger:
    Trình đơn thả xuống về dự án trên Google Cloud Console
    Nếu cần, hãy chọn đúng dự án trong hộp kết hợp.
  3. Trong bảng Cấu hình nhật ký kiểm tra quyền truy cập dữ liệu, trong cột Dịch vụ, hãy tìm dịch vụ Vertex AI API rồi chọn dịch vụ đó bằng cách chọn hộp đánh dấu ở bên trái tên dịch vụ.
    Chọn Vertex AI API
  4. Trong bảng thông tin ở bên phải, hãy chọn loại kiểm tra "Đọc dữ liệu".
    Kiểm tra nhật ký Đọc dữ liệu
  5. Nhấp vào Lưu.

Để tạo nhật ký kiểm tra, hãy mở URL của dịch vụ. Làm mới trang trong khi thay đổi giá trị của thông số ?animal= để nhận được kết quả khác.

Khám phá nhật ký kiểm tra

  1. Nhấp vào nút bên dưới để mở trang Trình khám phá nhật ký trong Cloud Console:

  2. Dán bộ lọc sau vào ngăn Truy vấn.
    LOG_ID("cloudaudit.googleapis.com%2Fdata_access") AND
    protoPayload.serviceName="aiplatform.googleapis.com"
    
    Ngăn Truy vấn là một trình chỉnh sửa nằm ở gần đầu trang Trình khám phá nhật ký:
    Truy vấn nhật ký kiểm tra
  3. Nhấp vào Run query (Chạy truy vấn).
  4. Chọn một trong các mục nhập nhật ký kiểm tra rồi mở rộng các trường để kiểm tra thông tin được ghi lại trong nhật ký.
    Bạn có thể xem thông tin chi tiết về lệnh gọi API Vertex, bao gồm cả phương thức và mô hình đã sử dụng. Bạn cũng có thể xem danh tính của phương thức gọi và những quyền đã cho phép lệnh gọi.

8. Ghi lại các hoạt động tương tác với AI tạo sinh

Bạn không tìm thấy thông số yêu cầu API hoặc dữ liệu phản hồi trong nhật ký kiểm tra. Tuy nhiên, thông tin này có thể quan trọng để khắc phục sự cố ứng dụng và phân tích quy trình công việc. Trong bước này, chúng ta sẽ lấp đầy khoảng trống này bằng cách thêm tính năng ghi nhật ký ứng dụng.

Quá trình triển khai sử dụng Logback với Spring Boot để in nhật ký ứng dụng vào đầu ra tiêu chuẩn. Phương thức này có khả năng ghi lại thông tin được in ra đầu ra chuẩn và tự động nhập thông tin đó vào Cloud Logging. Để ghi lại thông tin dưới dạng dữ liệu có cấu trúc, bạn phải định dạng nhật ký in cho phù hợp. Hãy làm theo hướng dẫn bên dưới để thêm các tính năng ghi nhật ký có cấu trúc vào ứng dụng.

  1. Quay lại cửa sổ (hoặc thẻ) "Cloud Shell" trong trình duyệt.
  2. Tạo và mở tệp mới LoggingEventGoogleCloudEncoder.java trong Trình chỉnh sửa Clooud Shell:
    cloudshell edit "${HOME}/codelab-o11y/src/main/java/com/example/demo/LoggingEventGoogleCloudEncoder.java"
    
  3. Sao chép và dán mã sau để triển khai bộ mã hoá Logback giúp mã hoá nhật ký dưới dạng JSON chuỗi theo định dạng nhật ký có cấu trúc của 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";
            }
        }
    }
    
  4. Tạo và mở tệp mới logback.xml trong Trình chỉnh sửa Clooud Shell:
    cloudshell edit "${HOME}/codelab-o11y/src/main/resources/logback.xml"
    
  5. Sao chép và dán tệp XML sau đây để định cấu hình Logback nhằm sử dụng bộ mã hoá với trình bổ trợ Logback in nhật ký vào đầu ra chuẩn:
    <?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. Mở lại tệp DemoApplication.java trong Trình chỉnh sửa Cloud Shell:
    cloudshell edit "${HOME}/codelab-o11y/src/main/java/com/example/demo/DemoApplication.java"
    
  7. Thay thế mã trong trình chỉnh sửa bằng phiên bản hiển thị bên dưới để ghi lại yêu cầu và phản hồi của Gen AI. Để thay thế mã, hãy xoá nội dung của tệp rồi sao chép mã dưới đây vào trình chỉnh sửa:
    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);
        }
    }
    

Sau vài giây, Trình chỉnh sửa Cloud Shell sẽ tự động lưu các thay đổi của bạn.

Triển khai mã của ứng dụng Gen AI cho Cloud Run

  1. Trong cửa sổ dòng lệnh, hãy chạy lệnh để triển khai mã nguồn của ứng dụng lên Cloud Run.
    gcloud run deploy codelab-o11y-service \
         --source="${HOME}/codelab-o11y/" \
         --region=us-central1 \
         --allow-unauthenticated
    
    Nếu bạn thấy lời nhắc như bên dưới, thông báo cho bạn rằng lệnh này sẽ tạo một kho lưu trữ mới. Nhấp vào 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)?
    
    Quá trình triển khai có thể mất vài phút. Sau khi quá trình triển khai hoàn tất, bạn sẽ thấy kết quả như sau:
    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. Sao chép URL dịch vụ Cloud Run hiển thị vào một thẻ hoặc cửa sổ riêng trong trình duyệt. Ngoài ra, hãy chạy lệnh sau trong cửa sổ dòng lệnh để in URL dịch vụ và nhấp vào URL hiển thị trong khi giữ phím Ctrl để mở URL:
    gcloud run services list \
         --format='value(URL)' \
         --filter='SERVICE:"codelab-o11y-service"'
    
    Khi mở URL, bạn có thể gặp lỗi 500 hoặc thấy thông báo:
    Sorry, this is just a placeholder...
    
    Điều này có nghĩa là các dịch vụ chưa hoàn tất quá trình triển khai. Đợi vài phút rồi làm mới trang. Ở cuối, bạn sẽ thấy một văn bản bắt đầu bằng Thông tin thú vị về chó và chứa 10 thông tin thú vị về chó.

Để tạo nhật ký ứng dụng, hãy mở URL dịch vụ. Làm mới trang trong khi thay đổi giá trị của thông số ?animal= để nhận được kết quả khác.
Để xem nhật ký ứng dụng, hãy làm như sau:

  1. Nhấp vào nút bên dưới để mở trang Trình khám phá nhật ký trong Cloud Console:

  2. Dán bộ lọc sau vào ngăn Truy vấn (#2 trong giao diện Trình khám phá nhật ký):
    LOG_ID("run.googleapis.com%2Fstdout") AND
    severity=DEBUG
    
  3. Nhấp vào Run query (Chạy truy vấn).

Kết quả của truy vấn cho thấy nhật ký có câu lệnh và phản hồi của Vertex AI, bao gồm cả điểm xếp hạng an toàn.

9. Đếm lượt tương tác với AI tạo sinh

Cloud Run ghi các chỉ số được quản lý có thể dùng để theo dõi các dịch vụ đã triển khai. Chỉ số giám sát do người dùng quản lý giúp bạn kiểm soát tốt hơn dữ liệu và tần suất cập nhật chỉ số. Để triển khai chỉ số như vậy, bạn cần viết mã thu thập dữ liệu và ghi dữ liệu đó vào Cloud Monitoring. Hãy xem bước tiếp theo (không bắt buộc) để biết cách triển khai tính năng này bằng SDK OpenTelemetry.

Bước này cho thấy giải pháp thay thế để triển khai chỉ số người dùng trong mã – chỉ số dựa trên nhật ký. Các chỉ số dựa trên nhật ký cho phép bạn tạo các chỉ số giám sát từ các mục nhập nhật ký mà ứng dụng của bạn ghi vào Cloud Logging. Chúng ta sẽ sử dụng nhật ký ứng dụng mà chúng ta đã triển khai ở bước trước để xác định chỉ số dựa trên nhật ký của trình đếm loại. Chỉ số này sẽ tính số lệnh gọi thành công đến Vertex API.

  1. Hãy xem cửa sổ của Trình khám phá nhật ký mà chúng ta đã sử dụng ở bước trước. Trong ngăn Truy vấn, hãy tìm trình đơn thả xuống Thao tác rồi nhấp vào trình đơn đó để mở. Hãy xem ảnh chụp màn hình bên dưới để tìm trình đơn:
    Thanh công cụ kết quả truy vấn có trình đơn thả xuống Hành động
  2. Trong trình đơn đã mở, hãy chọn Tạo chỉ số để mở bảng điều khiển Tạo chỉ số dựa trên nhật ký.
  3. Hãy làm theo các bước sau để định cấu hình chỉ số bộ đếm mới trong bảng điều khiển Tạo chỉ số dựa trên nhật ký:
    1. Đặt Loại chỉ số: Chọn Bộ đếm.
    2. Thiết lập các trường sau trong mục Chi tiết:
      • Tên chỉ số nhật ký: Đặt tên là model_interaction_count. Có một số quy định hạn chế về việc đặt tên; Hãy xem phần Khắc phục sự cố về quy định hạn chế về việc đặt tên để biết thông tin chi tiết.
      • Nội dung mô tả: Nhập nội dung mô tả cho chỉ số. Ví dụ: Number of log entries capturing successful call to model inference.
      • Đơn vị: Để trống hoặc chèn chữ số 1.
    3. Để nguyên các giá trị trong mục Lựa chọn bộ lọc. Xin lưu ý rằng trường Build filter (Bộ lọc bản dựng) có cùng bộ lọc mà chúng ta đã sử dụng để xem nhật ký ứng dụng.
    4. (Không bắt buộc) Thêm nhãn giúp đếm số lượng cuộc gọi cho mỗi con vật. LƯU Ý: nhãn này có khả năng làm tăng đáng kể số lượng giá trị riêng biệt của chỉ số và bạn không nên sử dụng nhãn này trong phiên bản chính thức:
      1. Nhấp vào Thêm nhãn.
      2. Đặt các trường sau trong phần Nhãn:
        • Tên nhãn: Đặt tên là animal.
        • Nội dung mô tả: Nhập nội dung mô tả về nhãn. Ví dụ: Animal parameter.
        • Loại nhãn: Chọn STRING.
        • Tên trường: Nhập jsonPayload.animal.
        • Biểu thức chính quy: Để trống.
      3. Nhấp vào Xong
    5. Nhấp vào Tạo chỉ số để tạo chỉ số.

Bạn cũng có thể tạo chỉ số dựa trên nhật ký trên trang Chỉ số dựa trên nhật ký bằng cách sử dụng lệnh CLI gcloud logging metrics create hoặc tài nguyên Terraform google_logging_metric.

Để tạo dữ liệu chỉ số, hãy mở URL của dịch vụ. Làm mới trang đã mở nhiều lần để thực hiện nhiều lệnh gọi đến mô hình. Giống như trước, hãy thử sử dụng các loài động vật khác nhau trong tham số.

Nhập truy vấn PromQL để tìm dữ liệu chỉ số dựa trên nhật ký. Để nhập truy vấn PromQL, hãy làm như sau:

  1. Nhấp vào nút bên dưới để mở trang Trình khám phá chỉ số trong Cloud Console:

  2. Trong thanh công cụ của ngăn trình tạo truy vấn, hãy chọn nút có tên là < > MQL hoặc < > PromQL. Xem hình ảnh bên dưới để biết vị trí của nút.
    Vị trí của nút MQL trong Trình khám phá chỉ số
  3. Xác minh rằng bạn đã chọn PromQL trong nút bật/tắt Language (Ngôn ngữ). Nút bật/tắt ngôn ngữ nằm trong cùng một thanh công cụ cho phép bạn định dạng truy vấn.
  4. Nhập truy vấn của bạn vào trình chỉnh sửa Truy vấn:
    sum(rate(logging_googleapis_com:user_model_interaction_count{monitored_resource="cloud_run_revision"}[${__interval}]))
    
    Để biết thêm thông tin về cách sử dụng PromQL, hãy xem bài viết PromQL trong Cloud Monitoring.
  5. Nhấp vào Run Query (Chạy truy vấn). Bạn sẽ thấy một biểu đồ đường tương tự như ảnh chụp màn hình sau:
    Hiển thị các chỉ số được truy vấn

    Lưu ý rằng khi bạn bật nút bật/tắt Tự động chạy, nút Chạy truy vấn sẽ không xuất hiện.

10. (Không bắt buộc) Sử dụng Open Telemetry để giám sát và theo dõi

Như đã đề cập ở bước trước, bạn có thể triển khai các chỉ số bằng cách sử dụng SDK OpenTelemetry (Otel). Bạn nên sử dụng OTel trên các cấu trúc đa dịch vụ. Bước này minh hoạ cách thêm khả năng đo lường OTel vào ứng dụng Spring Boot. Trong bước này, bạn sẽ thực hiện những việc sau:

  • Đo lường ứng dụng Spring Boot bằng các tính năng theo dõi tự động
  • Triển khai chỉ số bộ đếm để theo dõi số lượng lệnh gọi mô hình thành công
  • Liên kết tính năng theo dõi với nhật ký ứng dụng

Kiến trúc được đề xuất cho các dịch vụ cấp sản phẩm là sử dụng Trình thu thập Otel để thu thập và nhập tất cả dữ liệu khả năng quan sát từ nhiều dịch vụ. Để đơn giản, mã trong bước này không sử dụng trình thu thập. Thay vào đó, công cụ này sử dụng các tệp xuất OTel để ghi dữ liệu trực tiếp vào Google Cloud.

Thiết lập ứng dụng Spring Boot bằng các thành phần OTel và tính năng theo dõi tự động

  1. Quay lại cửa sổ (hoặc thẻ) "Cloud Shell" trong trình duyệt.
  2. Trong dòng lệnh, hãy cập nhật tệp application.permissions bằng các tham số cấu hình bổ sung:
    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
    
    Các thông số này xác định việc xuất dữ liệu khả năng quan sát sang Cloud Trace và Cloud Monitoring, đồng thời thực thi việc lấy mẫu tất cả dấu vết.
  3. Thêm các phần phụ thuộc OpenTelemetry bắt buộc vào tệp pom.xml:
    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. Thêm BOM OpenTelemetry vào tệp 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"
    
  5. Mở lại tệp DemoApplication.java trong Trình chỉnh sửa Cloud Shell:
    cloudshell edit "${HOME}/codelab-o11y/src/main/java/com/example/demo/DemoApplication.java"
    
  6. Thay thế mã hiện tại bằng phiên bản làm tăng một chỉ số hiệu suất. Để thay thế mã, hãy xoá nội dung của tệp rồi sao chép mã dưới đây vào trình chỉnh sửa:
    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. Mở lại tệp LoggingEventGoogleCloudEncoder.java trong Trình chỉnh sửa Cloud Shell:
    cloudshell edit "${HOME}/codelab-o11y/src/main/java/com/example/demo/LoggingEventGoogleCloudEncoder.java"
    
  8. Thay thế mã hiện tại bằng phiên bản thêm các thuộc tính theo dõi vào nhật ký đã ghi. Việc thêm các thuộc tính này cho phép liên kết nhật ký với các span theo dõi chính xác. Để thay thế mã, hãy xoá nội dung của tệp rồi sao chép mã dưới đây vào trình chỉnh sửa:
    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";
            }
        }
    }
    

Sau vài giây, Trình chỉnh sửa Cloud Shell sẽ tự động lưu các thay đổi của bạn.

Triển khai mã của ứng dụng Gen AI cho Cloud Run

  1. Trong cửa sổ dòng lệnh, hãy chạy lệnh để triển khai mã nguồn của ứng dụng lên Cloud Run.
    gcloud run deploy codelab-o11y-service \
         --source="${HOME}/codelab-o11y/" \
         --region=us-central1 \
         --allow-unauthenticated
    
    Nếu bạn thấy lời nhắc như bên dưới, thông báo cho bạn rằng lệnh này sẽ tạo một kho lưu trữ mới. Nhấp vào 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)?
    
    Quá trình triển khai có thể mất vài phút. Sau khi quá trình triển khai hoàn tất, bạn sẽ thấy kết quả như sau:
    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. Sao chép URL dịch vụ Cloud Run hiển thị vào một thẻ hoặc cửa sổ riêng trong trình duyệt. Ngoài ra, hãy chạy lệnh sau trong cửa sổ dòng lệnh để in URL dịch vụ và nhấp vào URL hiển thị trong khi giữ phím Ctrl để mở URL:
    gcloud run services list \
         --format='value(URL)' \
         --filter='SERVICE:"codelab-o11y-service"'
    
    Khi mở URL, bạn có thể gặp lỗi 500 hoặc thấy thông báo:
    Sorry, this is just a placeholder...
    
    Điều này có nghĩa là các dịch vụ chưa hoàn tất quá trình triển khai. Đợi vài phút rồi làm mới trang. Ở cuối, bạn sẽ thấy một văn bản bắt đầu bằng Thông tin thú vị về chó và chứa 10 thông tin thú vị về chó.

Để tạo dữ liệu đo từ xa, hãy mở URL của dịch vụ. Làm mới trang trong khi thay đổi giá trị của thông số ?animal= để nhận được kết quả khác.

Khám phá dấu vết ứng dụng

  1. Nhấp vào nút bên dưới để mở trang Trình khám phá dấu vết trong Cloud Console:

  2. Chọn một trong các dấu vết gần đây nhất. Bạn sẽ thấy 5 hoặc 6 span giống như trong ảnh chụp màn hình bên dưới.
    Chế độ xem span ứng dụng trong Trình khám phá dấu vết
  3. Tìm span theo dõi lệnh gọi đến trình xử lý sự kiện (phương thức fun_facts). Đây sẽ là span cuối cùng có tên /.
  4. Trong ngăn Trace details (Thông tin chi tiết về dấu vết), hãy chọn Logs & events (Nhật ký và sự kiện). Bạn sẽ thấy nhật ký ứng dụng tương quan với khoảng thời gian cụ thể này. Mối tương quan được phát hiện bằng cách sử dụng mã theo dõi và mã span trong dấu vết và trong nhật ký. Bạn sẽ thấy nhật ký ứng dụng đã ghi lời nhắc và phản hồi của Vertex API.

Khám phá chỉ số bộ đếm

  1. Nhấp vào nút bên dưới để mở trang Trình khám phá chỉ số trong Cloud Console:

  2. Trong thanh công cụ của ngăn trình tạo truy vấn, hãy chọn nút có tên là < > MQL hoặc < > PromQL. Xem hình ảnh bên dưới để biết vị trí của nút.
    Vị trí của nút MQL trong Trình khám phá chỉ số
  3. Xác minh rằng bạn đã chọn PromQL trong nút bật/tắt Language (Ngôn ngữ). Nút bật/tắt ngôn ngữ nằm trong cùng một thanh công cụ cho phép bạn định dạng truy vấn.
  4. Nhập truy vấn của bạn vào trình chỉnh sửa Truy vấn:
    sum(rate(workload_googleapis_com:model_call_counter{monitored_resource="generic_task"}[${__interval}]))
    
  5. Nhấp vào Run Query (Chạy truy vấn). Khi bạn bật nút chuyển Auto-run (Tự động chạy), nút Run Query (Chạy truy vấn) sẽ không xuất hiện.

11. (Không bắt buộc) Thông tin nhạy cảm đã làm rối mã nguồn trong nhật ký

Ở Bước 10, chúng ta đã ghi lại thông tin về hoạt động tương tác của ứng dụng với mô hình Gemini. Thông tin này bao gồm tên của động vật, câu lệnh thực tế và câu trả lời của mô hình. Mặc dù việc lưu trữ thông tin này trong nhật ký là an toàn, nhưng không nhất thiết phải đúng trong nhiều trường hợp khác. Lời nhắc có thể bao gồm một số thông tin cá nhân hoặc thông tin nhạy cảm khác mà người dùng không muốn lưu trữ. Để giải quyết vấn đề này, bạn có thể làm rối dữ liệu nhạy cảm được ghi vào Cloud Logging. Để giảm thiểu việc sửa đổi mã, bạn nên sử dụng giải pháp sau.

  1. Tạo một chủ đề Pub/Sub để lưu trữ các mục nhập nhật ký đến
  2. Tạo một vùng chứa nhật ký chuyển hướng nhật ký đã nhập vào chủ đề PubSub.
  3. Tạo quy trình Dataflow (Luồng dữ liệu) sửa đổi nhật ký được chuyển hướng đến chủ đề PubSub theo các bước sau:
    1. Đọc một mục nhập nhật ký từ chủ đề PubSub
    2. Kiểm tra trọng tải của mục nhập để tìm thông tin nhạy cảm bằng API kiểm tra DLP
    3. Xoá thông tin nhạy cảm trong tải trọng bằng một trong các phương thức loại bỏ của DLP
    4. Ghi mục nhập nhật ký đã làm rối mã nguồn vào Cloud Logging
  4. Triển khai quy trình

12. (Không bắt buộc) Dọn dẹp

Để tránh rủi ro phải trả phí cho các tài nguyên và API dùng trong lớp học lập trình, bạn nên dọn dẹp sau khi hoàn tất lớp học. Cách dễ nhất để loại bỏ tính năng thanh toán là xoá dự án mà bạn đã tạo cho lớp học lập trình này.

  1. Để xoá dự án, hãy chạy lệnh xoá dự án trong dòng lệnh:
    PROJECT_ID=$(gcloud config get-value project)
    gcloud projects delete ${PROJECT_ID} --quiet
    
    Việc xoá dự án trên Google Cloud sẽ dừng tính phí cho tất cả tài nguyên và API được sử dụng trong dự án đó. Bạn sẽ thấy thông báo này, trong đó PROJECT_ID là mã dự án của bạn:
    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. (Không bắt buộc) Nếu bạn gặp lỗi, hãy tham khảo Bước 5 để tìm mã dự án mà bạn đã sử dụng trong lớp học này. Thay thế giá trị này cho lệnh trong hướng dẫn đầu tiên. Ví dụ: nếu mã dự án của bạn là lab-example-project, thì lệnh sẽ là:
    gcloud projects delete lab-project-id-example --quiet
    

13. Xin chúc mừng

Trong lớp học này, bạn đã tạo một ứng dụng AI tạo sinh sử dụng mô hình Gemini để đưa ra dự đoán. Đồng thời, đo lường ứng dụng bằng các chức năng giám sát và ghi nhật ký thiết yếu. Bạn đã triển khai ứng dụng và các thay đổi từ mã nguồn sang Cloud Run. Sau đó, bạn có thể sử dụng các sản phẩm Google Cloud Observability để theo dõi hiệu suất của ứng dụng, nhờ đó có thể đảm bảo độ tin cậy của ứng dụng.

Nếu bạn muốn tham gia một nghiên cứu về trải nghiệm người dùng (UX) để cải thiện các sản phẩm mà bạn đã sử dụng hôm nay, hãy đăng ký tại đây.

Dưới đây là một số cách để bạn tiếp tục học tập: