۱. مرور کلی
برنامههای کاربردی هوش مصنوعی نسل بعد مانند هر برنامه دیگری نیاز به مشاهدهپذیری دارند. آیا تکنیکهای مشاهدهپذیری خاصی برای هوش مصنوعی نسل بعد مورد نیاز است؟
در این آزمایشگاه، شما یک برنامه ساده Gen AI ایجاد خواهید کرد. آن را در Cloud Run مستقر خواهید کرد. و آن را با استفاده از خدمات و محصولات رصدپذیری Google Cloud به قابلیتهای ضروری نظارت و ثبت وقایع مجهز خواهید کرد.
آنچه یاد خواهید گرفت
- برنامهای بنویسید که از Vertex AI با ویرایشگر Cloud Shell استفاده کند
- کد برنامه خود را در GitHub ذخیره کنید
- از gcloud CLI برای استقرار کد منبع برنامه خود در Cloud Run استفاده کنید
- قابلیتهای نظارت و ثبت وقایع را به برنامه Gen AI خود اضافه کنید
- استفاده از معیارهای مبتنی بر لاگ
- پیادهسازی ثبت وقایع و نظارت با Open Telemetry SDK
- کسب بینش در مورد مدیریت مسئولانه دادههای هوش مصنوعی
۲. پیشنیازها
اگر از قبل حساب گوگل ندارید، باید یک حساب جدید ایجاد کنید .
۳. راهاندازی پروژه
- با حساب گوگل خود وارد کنسول ابری گوگل شوید.
- یک پروژه جدید ایجاد کنید یا از یک پروژه موجود دوباره استفاده کنید. شناسه پروژهای را که ایجاد یا انتخاب کردهاید، یادداشت کنید.
- فعال کردن صورتحساب برای پروژه.
- تکمیل این آزمایشگاه باید کمتر از ۵ دلار در هزینههای صدور صورتحساب هزینه داشته باشد.
- شما میتوانید مراحل انتهای این آزمایش را برای حذف منابع دنبال کنید تا از هزینههای بیشتر جلوگیری شود.
- کاربران جدید واجد شرایط استفاده از دوره آزمایشی رایگان ۳۰۰ دلاری هستند.
- تأیید کنید که پرداخت در پروژههای من در پرداخت ابری فعال شده است
- اگر در ستون
Billing accountدر پروژه جدید شما نوشته شده باشدBilling is disabled:- روی سه نقطه در ستون
Actionsکلیک کنید - روی تغییر صورتحساب کلیک کنید
- حساب پرداختی که میخواهید استفاده کنید را انتخاب کنید
- روی سه نقطه در ستون
- اگر در یک رویداد زنده شرکت میکنید، احتمالاً نام حساب کاربری ، حساب پرداخت آزمایشی پلتفرم ابری گوگل خواهد بود.
- اگر در ستون
۴. ویرایشگر Cloud Shell را آماده کنید
- به ویرایشگر Cloud Shell بروید. اگر با پیام زیر مواجه شدید که از شما میخواهد به cloud shell اجازه دهید با اطلاعات کاربری شما gcloud را فراخوانی کند، برای ادامه روی Authorize کلیک کنید.

- پنجره ترمینال را باز کنید
- روی منوی همبرگری کلیک کنید

- روی ترمینال کلیک کنید
- روی ترمینال جدید کلیک کنید

- روی منوی همبرگری کلیک کنید
- در ترمینال، شناسه پروژه خود را پیکربندی کنید:
به جایgcloud config set project [PROJECT_ID][PROJECT_ID]، شناسه پروژه خود را قرار دهید. برای مثال، اگر شناسه پروژه شماlab-example-projectباشد، دستور به صورت زیر خواهد بود: اگر با پیام زیر مواجه شدید که میگوید gcloud درخواست اعتبارنامه شما را برای GCPI API دارد، برای ادامه روی تأیید (Authorize) کلیک کنید.gcloud config set project lab-project-id-example

در صورت اجرای موفقیتآمیز، باید پیام زیر را مشاهده کنید: اگر یکUpdated property [core/project].
WARNINGمشاهده کردید و از شما پرسیده شدDo you want to continue (Y/N)?احتمالاً شناسه پروژه را اشتباه وارد کردهاید.Nرا فشار دهید،Enterرا بزنید و پس از یافتن شناسه پروژه صحیح، دوباره سعی کنید دستورgcloud config set projectاجرا کنید. - (اختیاری) اگر در یافتن شناسه پروژه مشکل دارید، دستور زیر را اجرا کنید تا شناسه پروژه همه پروژههای خود را که بر اساس زمان ایجاد به ترتیب نزولی مرتب شدهاند، مشاهده کنید:
gcloud projects list \ --format='value(projectId,createTime)' \ --sort-by=~createTime
۵. فعال کردن APIهای گوگل
در ترمینال، APIهای گوگل مورد نیاز برای این آزمایشگاه را فعال کنید:
gcloud services enable \
run.googleapis.com \
cloudbuild.googleapis.com \
aiplatform.googleapis.com \
logging.googleapis.com \
monitoring.googleapis.com \
cloudtrace.googleapis.com
تکمیل این دستور مدتی طول میکشد. در نهایت، پیامی مشابه این نمایش داده میشود:
Operation "operations/acf.p2-73d90d00-47ee-447a-b600" finished successfully.
اگر پیام خطایی با ERROR: (gcloud.services.enable) HttpError accessing دریافت کردید و حاوی جزئیات خطایی مانند زیر بود، دستور را پس از ۱-۲ دقیقه تأخیر دوباره امتحان کنید.
"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",
...
}
۶. یک برنامه Gen AI ایجاد کنید
در این مرحله شما یک کد برای برنامه ساده مبتنی بر درخواست خواهید نوشت که از مدل Gemini برای نمایش 10 حقیقت جالب در مورد حیوان مورد نظر شما استفاده میکند. برای ایجاد کد برنامه، مراحل زیر را دنبال کنید.
- در ترمینال، دایرکتوری
codelab-o11yرا ایجاد کنید:mkdir "${HOME}/codelab-o11y" - دایرکتوری فعلی را به
codelab-o11yتغییر دهید:cd "${HOME}/codelab-o11y" - کد بوتاسترپ برنامه جاوا را با استفاده از Spring Framework Starter دانلود کنید:
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 - کد بوتاسترپ را از حالت آرشیو خارج کرده و در پوشه فعلی قرار دهید:
unzip java-starter.zip - و فایل آرشیو را از پوشه حذف کنید:
rm java-starter.zip - فایل
project.tomlرا برای تعریف نسخه Java Runtime که هنگام استقرار کد در Cloud Run استفاده میشود، ایجاد کنید:cat > "${HOME}/codelab-o11y/project.toml" << EOF [[build.env]] name = "GOOGLE_RUNTIME_VERSION" value = "17" EOF - وابستگیهای Google Cloud SDK را به فایل
pom.xmlاضافه کنید:- بسته 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" - بسته هوش مصنوعی گوگل کلود ورتکس را اضافه کنید:
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"
- بسته Google Cloud Core را اضافه کنید:
- فایل
DemoApplication.javaرا در ویرایشگر Cloud Shell باز کنید: اکنون باید یک کد منبعِ Scaffold شده از فایلcloudshell edit "${HOME}/codelab-o11y/src/main/java/com/example/demo/DemoApplication.java"DemoApplication.javaدر پنجره ویرایشگر بالای ترمینال ظاهر شود. کد منبع فایل مشابه کد زیر خواهد بود: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); } } - کد موجود در ویرایشگر را با نسخه نشان داده شده در زیر جایگزین کنید. برای جایگزینی کد، محتوای فایل را حذف کرده و سپس کد زیر را در ویرایشگر کپی کنید:
پس از چند ثانیه، ویرایشگر Cloud Shell کد شما را به طور خودکار ذخیره میکند.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); } }
کد برنامه Gen AI را در Cloud Run مستقر کنید
- در پنجره ترمینال، دستور زیر را اجرا کنید تا کد منبع برنامه در Cloud Run مستقر شود.
اگر پیامی مانند زیر مشاهده کردید که به شما اطلاع میدهد دستور یک مخزن جدید ایجاد خواهد کرد، رویgcloud run deploy codelab-o11y-service \ --source="${HOME}/codelab-o11y/" \ --region=us-central1 \ --allow-unauthenticatedEnterکلیک کنید. فرآیند استقرار ممکن است تا چند دقیقه طول بکشد. پس از اتمام فرآیند استقرار، خروجی مانند زیر را مشاهده خواهید کرد: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
- آدرس اینترنتی (URL) سرویس Cloud Run نمایش داده شده را در یک تب یا پنجره جداگانه در مرورگر خود کپی کنید. روش دیگر، اجرای دستور زیر در ترمینال برای چاپ آدرس اینترنتی سرویس و کلیک بر روی آدرس اینترنتی نشان داده شده در حالی که کلید Ctrl را نگه داشتهاید تا آدرس اینترنتی باز شود:
وقتی URL باز میشود، ممکن است خطای ۵۰۰ دریافت کنید یا پیام زیر را ببینید:gcloud run services list \ --format='value(URL)' \ --filter='SERVICE:"codelab-o11y-service"' این یعنی سرویسها هنوز استقرار خود را به پایان نرسانده اند. چند لحظه صبر کنید و صفحه را رفرش کنید. در پایان متنی را خواهید دید که با «دانستنیهای جالب درباره سگها» شروع میشود و شامل ۱۰ حقیقت جالب درباره سگها است.Sorry, this is just a placeholder...
سعی کنید با برنامه تعامل داشته باشید تا حقایق جالبی در مورد حیوانات مختلف به دست آورید. برای انجام این کار، پارامتر animal را به URL اضافه کنید، مانند ?animal=[ANIMAL] که در آن [ANIMAL] نام یک حیوان است. به عنوان مثال، برای دریافت 10 حقیقت جالب در مورد گربهها، ? ?animal=cat یا برای دریافت 10 حقیقت جالب در مورد لاکپشتهای ?animal=sea turtle را اضافه کنید.
۷. فراخوانیهای API مربوط به Vertex خود را بررسی کنید
حسابرسی فراخوانیهای API گوگل، پاسخهایی به سوالاتی مانند «چه کسی، کجا و چه زمانی یک API خاص را فراخوانی میکند؟» ارائه میدهد. حسابرسی هنگام عیبیابی برنامه، بررسی مصرف منابع یا انجام تجزیه و تحلیلهای قانونی نرمافزار اهمیت دارد.
گزارشهای حسابرسی به شما امکان میدهند فعالیتهای مدیریتی و سیستمی را ردیابی کنید و همچنین فراخوانیهای مربوط به عملیات API «خواندن داده» و «نوشتن داده» را ثبت کنید. برای حسابرسی درخواستهای Vertex AI برای تولید محتوا، باید گزارشهای حسابرسی «خواندن داده» را در کنسول Cloud فعال کنید .
- برای باز کردن صفحه گزارشهای حسابرسی در کنسول ابری، روی دکمه زیر کلیک کنید
- مطمئن شوید که پروژهای که برای این آزمایشگاه ایجاد کردهاید، در صفحه انتخاب شده باشد. پروژه انتخاب شده در گوشه سمت چپ بالای صفحه، درست از منوی همبرگری نشان داده میشود:

در صورت لزوم، پروژه صحیح را از combobox انتخاب کنید. - در جدول پیکربندی گزارشهای حسابرسی دسترسی به دادهها ، در ستون سرویس، سرویس
Vertex AI APIرا پیدا کنید و با انتخاب کادر انتخاب واقع در سمت چپ نام سرویس، آن را انتخاب کنید.
- در پنل اطلاعات سمت راست، نوع حسابرسی «خواندن دادهها» را انتخاب کنید.

- روی ذخیره کلیک کنید.
برای ایجاد گزارشهای حسابرسی، آدرس اینترنتی سرویس را باز کنید. صفحه را رفرش کنید و در عین حال مقدار پارامتر ?animal= را تغییر دهید تا نتایج متفاوتی دریافت کنید.
بررسی گزارشهای حسابرسی
- برای باز کردن صفحه Logs Explorer در کنسول Cloud، روی دکمه زیر کلیک کنید:
- فیلتر زیر را در کادر Query قرار دهید.
پنجرهی کوئری (Query pane) یک ویرایشگر است که در بالای صفحهی Logs Explorer قرار دارد:LOG_ID("cloudaudit.googleapis.com%2Fdata_access") AND protoPayload.serviceName="aiplatform.googleapis.com"
- روی اجرای پرسوجو کلیک کنید.
- یکی از ورودیهای گزارش حسابرسی را انتخاب کنید و فیلدها را برای بررسی اطلاعات ثبتشده در گزارش گسترش دهید.
شما میتوانید جزئیات مربوط به فراخوانی API ورتکس، شامل متد و مدلی که استفاده شده است را مشاهده کنید. همچنین میتوانید هویت فراخوانیکننده و مجوزهای مجاز برای فراخوانی را مشاهده کنید.
۸. تعاملات با Gen AI را ثبت کنید
شما پارامترهای درخواست API یا دادههای پاسخ را در گزارشهای حسابرسی پیدا نمیکنید. با این حال، این اطلاعات میتواند برای عیبیابی برنامه و تجزیه و تحلیل گردش کار مهم باشد. در این مرحله، ما این شکاف را با اضافه کردن گزارشگیری از برنامه پر میکنیم.
پیادهسازی از Logback با Spring Boot برای چاپ لاگهای برنامه در خروجی استاندارد استفاده میکند. این روش دارای قابلیت Cloud Run برای ثبت اطلاعات چاپ شده در خروجی استاندارد و ارسال خودکار آن به Cloud Logging است. برای ثبت اطلاعات به عنوان دادههای ساختاریافته، لاگهای چاپ شده باید بر اساس آن قالببندی شوند. برای افزودن قابلیتهای لاگ ساختاریافته به برنامه، دستورالعملهای زیر را دنبال کنید.
- به پنجره (یا برگه) «پوسته ابری» در مرورگر خود برگردید.
- یک فایل جدید
LoggingEventGoogleCloudEncoder.javaدر ویرایشگر Cloud Shell ایجاد و باز کنید:cloudshell edit "${HOME}/codelab-o11y/src/main/java/com/example/demo/LoggingEventGoogleCloudEncoder.java" - کد زیر را برای پیادهسازی رمزگذار Logback که لاگ را به صورت رشتهای JSON و با پیروی از فرمت لاگ ساختاریافته 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"; } } } - یک فایل جدید
logback.xmlدر ویرایشگر Cloudoud Shell ایجاد و باز کنید:cloudshell edit "${HOME}/codelab-o11y/src/main/resources/logback.xml" - برای پیکربندی Logback جهت استفاده از رمزگذار با پیوست Logback که گزارشها را در خروجی استاندارد چاپ میکند، 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> - فایل
DemoApplication.javaرا در ویرایشگر Cloud Shell دوباره باز کنید:cloudshell edit "${HOME}/codelab-o11y/src/main/java/com/example/demo/DemoApplication.java" - کد موجود در ویرایشگر را با نسخه نشان داده شده در زیر جایگزین کنید تا درخواست و پاسخ Gen AI را ثبت کنید. برای جایگزینی کد، محتوای فایل را حذف کرده و سپس کد زیر را در ویرایشگر کپی کنید:
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); } }
پس از چند ثانیه، ویرایشگر Cloud Shell تغییرات شما را به طور خودکار ذخیره میکند.
کد برنامه Gen AI را در Cloud Run مستقر کنید
- در پنجره ترمینال، دستور زیر را اجرا کنید تا کد منبع برنامه در Cloud Run مستقر شود.
اگر پیامی مانند زیر مشاهده کردید که به شما اطلاع میدهد دستور یک مخزن جدید ایجاد خواهد کرد، رویgcloud run deploy codelab-o11y-service \ --source="${HOME}/codelab-o11y/" \ --region=us-central1 \ --allow-unauthenticatedEnterکلیک کنید. فرآیند استقرار ممکن است تا چند دقیقه طول بکشد. پس از اتمام فرآیند استقرار، خروجی مانند زیر را مشاهده خواهید کرد: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
- آدرس اینترنتی (URL) سرویس Cloud Run نمایش داده شده را در یک تب یا پنجره جداگانه در مرورگر خود کپی کنید. روش دیگر، اجرای دستور زیر در ترمینال برای چاپ آدرس اینترنتی سرویس و کلیک بر روی آدرس اینترنتی نشان داده شده در حالی که کلید Ctrl را نگه داشتهاید تا آدرس اینترنتی باز شود:
وقتی URL باز میشود، ممکن است خطای ۵۰۰ دریافت کنید یا پیام زیر را ببینید:gcloud run services list \ --format='value(URL)' \ --filter='SERVICE:"codelab-o11y-service"' این یعنی سرویسها هنوز استقرار خود را به پایان نرسانده اند. چند لحظه صبر کنید و صفحه را رفرش کنید. در پایان متنی را خواهید دید که با «دانستنیهای جالب درباره سگها» شروع میشود و شامل ۱۰ حقیقت جالب درباره سگها است.Sorry, this is just a placeholder...
برای تولید گزارشهای برنامه، URL سرویس را باز کنید. صفحه را رفرش کنید و در عین حال مقدار پارامتر ?animal= را تغییر دهید تا نتایج متفاوتی دریافت کنید.
برای مشاهده لاگهای برنامه، مراحل زیر را انجام دهید:
- برای باز کردن صفحه کاوشگر گزارشها در کنسول ابری، روی دکمه زیر کلیک کنید:
- فیلتر زیر را در کادر Query (شماره ۲ در رابط Log explorer ) قرار دهید:
LOG_ID("run.googleapis.com%2Fstdout") AND severity=DEBUG - روی اجرای پرسوجو کلیک کنید.
نتیجهی پرسوجو، گزارشهایی با پاسخ سریع و هوش مصنوعی Vertex شامل رتبهبندیهای ایمنی را نشان میدهد.
۹. تعاملات با هوش مصنوعی نسل جدید را بشمارید
Cloud Run معیارهای مدیریتشدهای را مینویسد که میتوانند برای نظارت بر سرویسهای مستقر استفاده شوند. معیارهای نظارت مدیریتشده توسط کاربر، کنترل بیشتری بر دادهها و فرکانس بهروزرسانی معیار ارائه میدهند. برای پیادهسازی چنین معیاری، نیاز به نوشتن کدی است که دادهها را جمعآوری کرده و در Cloud Monitoring مینویسد. برای نحوه پیادهسازی آن با استفاده از OpenTelemetry SDK، به مرحله بعدی (اختیاری) مراجعه کنید.
این مرحله جایگزینی برای پیادهسازی معیار کاربر در کد - معیارهای مبتنی بر گزارش - را نشان میدهد. معیارهای مبتنی بر گزارش به شما امکان میدهند معیارهای نظارتی را از ورودیهای گزارش که برنامه شما در Cloud Logging مینویسد، ایجاد کنید. ما از گزارشهای برنامه که در مرحله قبل پیادهسازی کردیم، برای تعریف یک معیار مبتنی بر گزارش از نوع شمارنده استفاده خواهیم کرد. این معیار تعداد تماسهای موفق با Vertex API را شمارش میکند.
- به پنجرهی کاوشگر لاگها که در مرحلهی قبل استفاده کردیم، نگاه کنید. در زیر پنل کوئری، منوی کشویی Actions را پیدا کرده و روی آن کلیک کنید تا باز شود. برای یافتن این منو، به تصویر زیر مراجعه کنید:

- در منوی باز شده، گزینه « ایجاد معیار» را انتخاب کنید تا پنل «ایجاد معیار مبتنی بر گزارش» باز شود.
- برای پیکربندی یک معیار شمارنده جدید در پنل ایجاد معیار مبتنی بر گزارش ، این مراحل را دنبال کنید:
- نوع متریک را تنظیم کنید: شمارنده را انتخاب کنید.
- فیلدهای زیر را در بخش جزئیات تنظیم کنید:
- نام معیار ثبت وقایع : نام را روی
model_interaction_countتنظیم کنید. برخی محدودیتهای نامگذاری اعمال میشود؛ برای جزئیات بیشتر به بخش «عیبیابی محدودیتهای نامگذاری» مراجعه کنید. - توضیحات : توضیحی برای معیار وارد کنید. به عنوان مثال،
Number of log entries capturing successful call to model inference. - واحدها : این قسمت را خالی بگذارید یا رقم
1را وارد کنید.
- نام معیار ثبت وقایع : نام را روی
- مقادیر را در بخش انتخاب فیلتر رها کنید. توجه داشته باشید که فیلد فیلتر ساخت همان فیلتری را دارد که برای دیدن گزارشهای برنامه استفاده کردیم.
- (اختیاری) برچسبی اضافه کنید که به شمارش تعداد صداهای هر حیوان کمک کند. توجه: این برچسب پتانسیل افزایش شدید کاردینالیتی معیار را دارد و برای استفاده در تولید توصیه نمیشود:
- روی افزودن برچسب کلیک کنید.
- فیلدهای زیر را در بخش برچسبها تنظیم کنید:
- نام برچسب : نام را روی
animalتنظیم کنید. - توضیحات : توضیحات برچسب را وارد کنید. برای مثال،
Animal parameter. - نوع برچسب :
STRINGرا انتخاب کنید. - نام فیلد : نوع
jsonPayload.animalرا وارد کنید. - عبارت منظم : آن را خالی بگذارید.
- نام برچسب : نام را روی
- کلیک کنید انجام شد
- برای ایجاد معیار، روی «ایجاد معیار» کلیک کنید.
همچنین میتوانید با استفاده از دستور gcloud logging metrics create CLI در gcloud یا با استفاده از google_logging_metric Terraform resource ، یک معیار مبتنی بر گزارش از صفحه معیارهای مبتنی بر گزارش ایجاد کنید.
برای تولید دادههای معیار، URL سرویس را باز کنید. برای برقراری چندین فراخوانی به مدل، صفحه باز شده را چندین بار رفرش کنید. مانند قبل، سعی کنید از حیوانات مختلف در پارامتر استفاده کنید.
برای جستجوی دادههای متریک مبتنی بر لاگ، عبارت PromQL را وارد کنید. برای وارد کردن یک عبارت PromQL، مراحل زیر را انجام دهید:
- برای باز کردن صفحه مرورگر معیارها در کنسول ابری، روی دکمه زیر کلیک کنید:
- در نوار ابزار پنل query-builder، دکمهای که نام آن < > MQL یا < > PromQL است را انتخاب کنید. برای مشاهده محل دکمه، به تصویر زیر مراجعه کنید.

- مطمئن شوید که PromQL در قسمت زبان (Language) انتخاب شده باشد. این قسمت در همان نوار ابزاری قرار دارد که به شما امکان قالببندی کوئری (query) را میدهد.
- پرسوجوی خود را در ویرایشگر پرسوجوها وارد کنید:
برای اطلاعات بیشتر در مورد استفاده از PromQL، به PromQL در Cloud Monitoring مراجعه کنید.sum(rate(logging_googleapis_com:user_model_interaction_count{monitored_resource="cloud_run_revision"}[${__interval}])) - روی اجرای پرسوجو کلیک کنید. نمودار خطی مشابه این تصویر را مشاهده خواهید کرد:

توجه داشته باشید که وقتی گزینهی اجرای خودکار فعال است، دکمهی اجرای پرسوجو نمایش داده نمیشود.
۱۰. (اختیاری) استفاده از Open Telemetry برای نظارت و ردیابی
همانطور که در مرحله قبل ذکر شد، میتوان معیارها را با استفاده از OpenTelemetry (Otel) SDK پیادهسازی کرد. استفاده از OTel در معماریهای چند سرویسه یک روش توصیه شده است. این مرحله افزودن ابزار دقیق OTel به یک برنامه Spring Boot را نشان میدهد. در این مرحله موارد زیر را انجام خواهید داد:
- ابزار دقیق برنامه Spring Boot با قابلیت ردیابی خودکار
- پیادهسازی یک معیار شمارنده برای نظارت بر تعدادی از فراخوانیهای موفق مدل
- مرتبط کردن ردیابی با لاگهای برنامه
معماری پیشنهادی برای سرویسهای سطح محصول، استفاده از OTel collector برای جمعآوری و دریافت تمام دادههای مشاهدهپذیری از چندین سرویس است. کد موجود در این مرحله به دلیل سادگی از collector استفاده نمیکند. در عوض از OTel exportها استفاده میکند که دادهها را مستقیماً در Google Cloud مینویسند.
راهاندازی برنامه Spring Boot با کامپوننتهای OTel و ردیابی خودکار
- به پنجره (یا برگه) «پوسته ابری» در مرورگر خود برگردید.
- در ترمینال، فایل
application.permissionsرا با پارامترهای پیکربندی اضافی بهروزرسانی کنید: این پارامترها، دادههای مشاهدهپذیری خروجی را به Cloud Trace و Cloud Monitoring تعریف میکنند و نمونهبرداری از همه ردپاها را الزامی میکنند.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 - وابستگیهای مورد نیاز OpenTelemetry را به فایل
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" - OpenTelemetry BOM را به فایل
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" - فایل
DemoApplication.javaرا در ویرایشگر Cloud Shell دوباره باز کنید:cloudshell edit "${HOME}/codelab-o11y/src/main/java/com/example/demo/DemoApplication.java" - کد فعلی را با نسخهای که یک معیار عملکرد را افزایش میدهد جایگزین کنید. برای جایگزینی کد، محتوای فایل را حذف کنید و سپس کد زیر را در ویرایشگر کپی کنید:
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); } } - فایل
LoggingEventGoogleCloudEncoder.javaرا در ویرایشگر Cloud Shell دوباره باز کنید:cloudshell edit "${HOME}/codelab-o11y/src/main/java/com/example/demo/LoggingEventGoogleCloudEncoder.java" - کد فعلی را با نسخهای که ویژگیهای ردیابی را به لاگهای نوشته شده اضافه میکند، جایگزین کنید. افزودن این ویژگیها باعث میشود لاگها با محدودههای ردیابی صحیح مرتبط شوند. برای جایگزینی کد، محتوای فایل را حذف کرده و سپس کد زیر را در ویرایشگر کپی کنید:
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"; } } }
پس از چند ثانیه، ویرایشگر Cloud Shell تغییرات شما را به طور خودکار ذخیره میکند.
کد برنامه Gen AI را در Cloud Run مستقر کنید
- در پنجره ترمینال، دستور زیر را اجرا کنید تا کد منبع برنامه در Cloud Run مستقر شود.
اگر پیامی مانند زیر مشاهده کردید که به شما اطلاع میدهد دستور یک مخزن جدید ایجاد خواهد کرد، رویgcloud run deploy codelab-o11y-service \ --source="${HOME}/codelab-o11y/" \ --region=us-central1 \ --allow-unauthenticatedEnterکلیک کنید. فرآیند استقرار ممکن است تا چند دقیقه طول بکشد. پس از اتمام فرآیند استقرار، خروجی مانند زیر را مشاهده خواهید کرد: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
- آدرس اینترنتی (URL) سرویس Cloud Run نمایش داده شده را در یک تب یا پنجره جداگانه در مرورگر خود کپی کنید. روش دیگر، اجرای دستور زیر در ترمینال برای چاپ آدرس اینترنتی سرویس و کلیک بر روی آدرس اینترنتی نشان داده شده در حالی که کلید Ctrl را نگه داشتهاید تا آدرس اینترنتی باز شود:
وقتی URL باز میشود، ممکن است خطای ۵۰۰ دریافت کنید یا پیام زیر را ببینید:gcloud run services list \ --format='value(URL)' \ --filter='SERVICE:"codelab-o11y-service"' این یعنی سرویسها هنوز استقرار خود را به پایان نرسانده اند. چند لحظه صبر کنید و صفحه را رفرش کنید. در پایان متنی را خواهید دید که با «دانستنیهای جالب درباره سگها» شروع میشود و شامل ۱۰ حقیقت جالب درباره سگها است.Sorry, this is just a placeholder...
برای تولید دادههای تلهمتری، URL سرویس را باز کنید. صفحه را رفرش کنید و در عین حال مقدار پارامتر ?animal= را تغییر دهید تا نتایج متفاوتی دریافت کنید.
کاوش ردپاهای برنامه
- برای باز کردن صفحه Trace explorer در کنسول Cloud، روی دکمه زیر کلیک کنید:
- یکی از جدیدترین ردپاها را انتخاب کنید. قرار است ۵ یا ۶ دهانه مانند تصویر زیر ببینید.

- دهانهای را پیدا کنید که فراخوانی را تا کنترلکننده رویداد (متد
fun_facts) ردیابی میکند. این آخرین دهانه با نام/خواهد بود. - در پنل جزئیات ردیابی، Logs & events را انتخاب کنید. گزارشهای برنامهای را خواهید دید که با این span خاص مرتبط هستند. این ارتباط با استفاده از شناسههای trace و span در trace و log شناسایی میشود. قرار است گزارش برنامهای که prompt را نوشته و پاسخ Vertex API را ببینید.
متریک شمارنده را بررسی کنید
- برای باز کردن صفحه مرورگر معیارها در کنسول ابری، روی دکمه زیر کلیک کنید:
- در نوار ابزار پنل query-builder، دکمهای که نام آن < > MQL یا < > PromQL است را انتخاب کنید. برای مشاهده محل دکمه، به تصویر زیر مراجعه کنید.

- مطمئن شوید که PromQL در قسمت زبان (Language) انتخاب شده باشد. این قسمت در همان نوار ابزاری قرار دارد که به شما امکان قالببندی کوئری (query) را میدهد.
- پرسوجوی خود را در ویرایشگر پرسوجوها وارد کنید:
sum(rate(workload_googleapis_com:model_call_counter{monitored_resource="generic_task"}[${__interval}])) - روی اجرای پرسوجو کلیک کنید. وقتی گزینهی اجرای خودکار فعال باشد، دکمهی اجرای پرسوجو نمایش داده نمیشود.
۱۱. (اختیاری) اطلاعات حساس مبهمسازیشده از لاگها
در مرحله 10، اطلاعات مربوط به تعامل برنامه با مدل Gemini را ثبت کردیم. این اطلاعات شامل نام حیوان، اعلان واقعی و پاسخ مدل بود. اگرچه ذخیره این اطلاعات در گزارش باید ایمن باشد، اما برای بسیاری از سناریوهای دیگر لزوماً صحیح نیست. اعلان ممکن است شامل برخی اطلاعات شخصی یا حساس باشد که کاربر نمیخواهد ذخیره شود. برای رفع این مشکل، میتوانید دادههای حساسی را که در Cloud Logging نوشته میشوند، مبهمسازی کنید. برای به حداقل رساندن تغییرات کد، راه حل زیر توصیه میشود.
- یک تاپیک PubSub برای ذخیره ورودیهای لاگ ایجاد کنید
- یک مخزن لاگ ایجاد کنید که لاگهای دریافتشده را به تاپیک PubSub هدایت کند.
- یک خط لوله Dataflow ایجاد کنید که گزارشهای هدایتشده به موضوع PubSub را با دنبال کردن مراحل زیر تغییر دهد:
- خواندن یک ورودی لاگ از مبحث PubSub
- با استفاده از API بازرسی DLP، اطلاعات حساس مربوط به payload ورودی را بررسی کنید.
- اطلاعات حساس موجود در پیلود را با استفاده از یکی از روشهای ویرایش DLP ویرایش کنید.
- ورودی لاگ مبهمسازیشده را در Cloud Logging بنویسید
- خط لوله را مستقر کنید
۱۲. (اختیاری) تمیز کردن
برای جلوگیری از خطر متحمل شدن هزینههای مربوط به منابع و APIهای مورد استفاده در آزمایشگاه کد، توصیه میشود پس از اتمام آزمایشگاه، آن را پاکسازی کنید. سادهترین راه برای حذف هزینهها، حذف پروژهای است که برای آزمایشگاه کد ایجاد کردهاید.
- برای حذف پروژه، دستور delete project را در ترمینال اجرا کنید:
حذف پروژه ابری شما، پرداخت هزینه برای تمام منابع و APIهای استفاده شده در آن پروژه را متوقف میکند. باید این پیام را ببینید که در آنPROJECT_ID=$(gcloud config get-value project) gcloud projects delete ${PROJECT_ID} --quietPROJECT_IDشناسه پروژه شما خواهد بود: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. - (اختیاری) اگر با خطایی مواجه شدید، برای یافتن شناسه پروژهای که در طول آزمایش استفاده کردهاید، به مرحله ۵ مراجعه کنید. آن را با دستور موجود در دستورالعمل اول جایگزین کنید. برای مثال، اگر شناسه پروژه شما
lab-example-projectباشد، دستور به صورت زیر خواهد بود:gcloud projects delete lab-project-id-example --quiet
۱۳. تبریک
در این آزمایشگاه، شما یک برنامه Gen AI ایجاد کردید که از مدل Gemini برای پیشبینی استفاده میکند. و برنامه را با قابلیتهای ضروری نظارت و ثبت وقایع تجهیز کردید. برنامه و تغییرات آن را از کد منبع به Cloud Run منتقل کردید. سپس از محصولات Google Cloud Observability برای ردیابی عملکرد برنامه استفاده کردید تا از قابلیت اطمینان برنامه اطمینان حاصل کنید.
اگر علاقهمند به شرکت در یک مطالعه تحقیقاتی تجربه کاربری (UX) برای بهبود محصولاتی که امروز با آنها کار کردهاید هستید، اینجا ثبت نام کنید .
در اینجا چند گزینه برای ادامه تحصیل شما وجود دارد:
- Codelab نحوه استقرار برنامه چت مبتنی بر Gemini در Cloud Run
- Codelab نحوه استفاده از فراخوانی تابع Gemini با Cloud Run
- نحوه استفاده از API هوش ویدیویی Cloud Run Jobs برای پردازش صحنه به صحنه یک ویدیو
- کارگاه آموزشی بر اساس تقاضا ، موتور کوبرنتیز گوگل (Google Kubernetes Engine) به صورت آنبورد
- درباره پیکربندی شمارنده و معیارهای توزیع با استفاده از گزارشهای برنامه بیشتر بدانید
- نوشتن معیارهای OTLP با استفاده از یک محفظه کناری OpenTelemetry
- اشاره به استفاده از Open Telemetry در Google Cloud