۱. مرور کلی
برنامههای کاربردی هوش مصنوعی نسل بعد مانند هر برنامه دیگری نیاز به مشاهدهپذیری دارند. آیا تکنیکهای مشاهدهپذیری خاصی برای هوش مصنوعی نسل بعد مورد نیاز است؟
در این آزمایشگاه، شما یک برنامه ساده 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 Go ایجاد کنید
در این مرحله شما یک کد برای برنامه ساده مبتنی بر درخواست خواهید نوشت که از مدل Gemini برای نمایش 10 حقیقت جالب در مورد حیوان مورد نظر شما استفاده میکند. برای ایجاد کد برنامه، مراحل زیر را دنبال کنید.
- در ترمینال، دایرکتوری
codelab-o11yرا ایجاد کنید:mkdir ~/codelab-o11y - دایرکتوری فعلی را به
codelab-o11yتغییر دهید:cd ~/codelab-o11y - ماژولهای Go را مقداردهی اولیه کنید:
go mod init codelab - نصب Vertex AI SDK برای Go:
go get cloud.google.com/go/vertexai/genai - برای دریافت شناسه پروژه فعلی، کتابخانه Metadata را برای Go نصب کنید:
go get cloud.google.com/go/compute/metadata - یک فایل
setup.goایجاد کنید و آن را در ویرایشگر Cloud Shell باز کنید: این فایل برای میزبانی کد مقداردهی اولیه استفاده خواهد شد. یک فایل خالی جدید با نامcloudshell edit setup.gosetup.goدر پنجره ویرایشگر ظاهر میشود. - کد زیر را کپی کرده و در فایل
setup.goباز شده جایگذاری کنید:package main import ( "context" "os" "cloud.google.com/go/compute/metadata" ) func projectID(ctx context.Context) (string, error) { var projectID = os.Getenv("GOOGLE_CLOUD_PROJECT") if projectID == "" { return metadata.ProjectIDWithContext(ctx) } return projectID, nil } - به پنجره ترمینال برگردید و دستور زیر را برای ایجاد و باز کردن فایل
main.goدر ویرایشگر Cloud Shell اجرا کنید: اکنون باید یک فایل خالی در پنجره ویرایشگر بالای ترمینال ظاهر شود. صفحه شما مشابه تصویر زیر خواهد بود:cloudshell edit main.go
- کد زیر را کپی کرده و در فایل
main.goباز شده قرار دهید: پس از چند ثانیه، ویرایشگر Cloud Shell کد شما را به طور خودکار ذخیره میکند.package main import ( "context" "fmt" "net/http" "os" "cloud.google.com/go/vertexai/genai" ) var model *genai.GenerativeModel func main() { ctx := context.Background() projectID, err := projectID(ctx) if err != nil { return } var client *genai.Client client, err = genai.NewClient(ctx, projectID, "us-central1") if err != nil { return } defer client.Close() model = client.GenerativeModel("gemini-1.5-flash-001") http.HandleFunc("/", Handler) port := os.Getenv("PORT") if port == "" { port = "8080" } if err := http.ListenAndServe(":"+port, nil); err != nil { return } } func Handler(w http.ResponseWriter, r *http.Request) { animal := r.URL.Query().Get("animal") if animal == "" { animal = "dog" } prompt := fmt.Sprintf("Give me 10 fun facts about %s. Return the results as HTML without markdown backticks.", animal) resp, err := model.GenerateContent(r.Context(), genai.Text(prompt)) if err != nil { w.WriteHeader(http.StatusTooManyRequests) return } if len(resp.Candidates) > 0 && len(resp.Candidates[0].Content.Parts) > 0 { htmlContent := resp.Candidates[0].Content.Parts[0] w.Header().Set("Content-Type", "text/html; charset=utf-8") fmt.Fprint(w, htmlContent) } }
کد برنامه 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 یا دادههای پاسخ را در گزارشهای حسابرسی پیدا نمیکنید. با این حال، این اطلاعات میتواند برای عیبیابی برنامه و تحلیل گردش کار مهم باشد. در این مرحله، ما این شکاف را با اضافه کردن گزارشگیری برنامه پر میکنیم. گزارشگیری از بسته استاندارد Go log/slog برای نوشتن گزارشهای ساختاریافته استفاده میکند. بسته log/slog نمیداند که گزارشها را در Google Cloud بنویسد. از نوشتن در خروجی استاندارد پشتیبانی میکند. با این حال، Cloud Run قابلیت ثبت اطلاعات چاپ شده در خروجی استاندارد و ارسال خودکار آن به Cloud Logging را دارد. برای ثبت صحیح گزارشهای ساختاریافته، گزارش چاپ شده باید بر اساس آن قالببندی شود. دستورالعملهای زیر را برای افزودن قابلیتهای گزارشگیری ساختاریافته به برنامه Go خود دنبال کنید.
- به پنجره (یا برگه) «پوسته ابری» در مرورگر خود برگردید.
- در ترمینال،
setup.goدوباره باز کنید:cloudshell edit ~/codelab-o11y/setup.go - کد را با نسخهای که ثبت وقایع را تنظیم میکند جایگزین کنید. برای جایگزینی کد، محتوای فایل را حذف کنید و سپس کد زیر را کپی کرده و در ویرایشگر قرار دهید:
package main import ( "context" "os" "log/slog" "cloud.google.com/go/compute/metadata" ) func projectID(ctx context.Context) (string, error) { var projectID = os.Getenv("GOOGLE_CLOUD_PROJECT") if projectID == "" { return metadata.ProjectIDWithContext(ctx) } return projectID, nil } func setupLogging() { opts := &slog.HandlerOptions{ Level: slog.LevelDebug, ReplaceAttr: func(group []string, a slog.Attr) slog.Attr { switch a.Key { case slog.LevelKey: a.Key = "severity" if level := a.Value.Any().(slog.Level); level == slog.LevelWarn { a.Value = slog.StringValue("WARNING") } case slog.MessageKey: a.Key = "message" case slog.TimeKey: a.Key = "timestamp" } return a }, } jsonHandler := slog.NewJSONHandler(os.Stdout, opts) slog.SetDefault(slog.New(jsonHandler)) } - به ترمینال برگردید و
main.goدوباره باز کنید:cloudshell edit ~/codelab-o11y/main.go - کد برنامه را با نسخهای که تعامل با مدل را ثبت میکند، جایگزین کنید. برای جایگزینی کد، محتوای فایل را حذف کنید و سپس کد زیر را کپی کرده و در ویرایشگر قرار دهید:
package main import ( "context" "fmt" "net/http" "os" "encoding/json" "log/slog" "cloud.google.com/go/vertexai/genai" ) var model *genai.GenerativeModel func main() { ctx := context.Background() projectID, err := projectID(ctx) if err != nil { return } setupLogging() var client *genai.Client client, err = genai.NewClient(ctx, projectID, "us-central1") if err != nil { slog.ErrorContext(ctx, "Failed to marshal response to JSON", slog.Any("error", err)) os.Exit(1) } defer client.Close() model = client.GenerativeModel("gemini-1.5-flash-001") http.HandleFunc("/", Handler) port := os.Getenv("PORT") if port == "" { port = "8080" } if err := http.ListenAndServe(":"+port, nil); err != nil { slog.ErrorContext(ctx, "Failed to start the server", slog.Any("error", err)) os.Exit(1) } } func Handler(w http.ResponseWriter, r *http.Request) { animal := r.URL.Query().Get("animal") if animal == "" { animal = "dog" } prompt := fmt.Sprintf("Give me 10 fun facts about %s. Return the results as HTML without markdown backticks.", animal) resp, err := model.GenerateContent(r.Context(), genai.Text(prompt)) if err != nil { w.WriteHeader(http.StatusTooManyRequests) return } jsonBytes, err := json.Marshal(resp) if err != nil { slog.Error("Failed to marshal response to JSON", slog.Any("error", err)) } else { slog.DebugContext(r.Context(), "content is generated", slog.String("animal", animal), slog.String("prompt", prompt), slog.String("response", string(jsonBytes))) } if len(resp.Candidates) > 0 && len(resp.Candidates[0].Content.Parts) > 0 { htmlContent := resp.Candidates[0].Content.Parts[0] w.Header().Set("Content-Type", "text/html; charset=utf-8") fmt.Fprint(w, htmlContent) } }
ثبت وقایع (logging) به گونهای پیکربندی شده است که وقایع را در خروجی استاندارد ( stdout چاپ کند، جایی که توسط عامل ثبت وقایع Cloud Run جمعآوری شده و به صورت غیرهمزمان به Cloud Logging وارد میشود. تابع main() برای تنظیم گزارش ساختاریافته استاندارد Go اصلاح شده است تا از طرح JSON که از دستورالعملهای قالببندی ساختاریافته پیروی میکند، استفاده کند. تمام دستورات return آن با کدی جایگزین میشوند که گزارشهای خطا را قبل از خروج مینویسد. تابع Handler() برای نوشتن گزارش ساختاریافته هنگام دریافت پاسخ از فراخوانی API هوش مصنوعی Vertex تجهیز شده است. این گزارش، پارامتر animal درخواست و اعلان و پاسخ مدل را ثبت میکند.
پس از چند ثانیه، ویرایشگر 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 برای پشتیبانی از ردیابی و نظارت بر برنامه
- پر کردن پیکربندی Otel با ابرداده منابع محیط Cloud Run
- کاربرد فلاسک ابزار دقیق با قابلیت ردیابی خودکار
- پیادهسازی یک معیار شمارنده برای نظارت بر تعدادی از فراخوانیهای موفق مدل
- مرتبط کردن ردیابی با لاگهای برنامه
معماری پیشنهادی برای سرویسهای سطح محصول، استفاده از OTel collector برای جمعآوری و دریافت تمام دادههای مشاهدهپذیری برای یک یا چند سرویس است. کد موجود در این مرحله به دلیل سادگی از collector استفاده نمیکند. در عوض از OTel exportها استفاده میکند که دادهها را مستقیماً در Google Cloud مینویسند.
راهاندازی اجزای Otel برای ردیابی و نظارت بر معیارها
- به پنجره (یا برگه) «پوسته ابری» در مرورگر خود برگردید.
- در ترمینال،
setup.goدوباره باز کنید:cloudshell edit ~/codelab-o11y/setup.go - کد را با نسخهای که ردیابی و جمعآوری متریک OpenTelemetry را مقداردهی اولیه میکند، جایگزین کنید. برای جایگزینی کد، محتوای فایل را حذف کنید و سپس کد زیر را کپی کرده و در ویرایشگر قرار دهید:
package main import ( "context" "errors" "fmt" "net/http" "os" "log/slog" "go.opentelemetry.io/contrib/detectors/gcp" "go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp" "go.opentelemetry.io/contrib/propagators/autoprop" "go.opentelemetry.io/otel" sdkmetric "go.opentelemetry.io/otel/sdk/metric" "go.opentelemetry.io/otel/sdk/resource" sdktrace "go.opentelemetry.io/otel/sdk/trace" semconv "go.opentelemetry.io/otel/semconv/v1.27.0" "go.opentelemetry.io/otel/trace" cloudmetric "github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric" cloudtrace "github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/trace" "cloud.google.com/go/compute/metadata" ) var ( projID string ) func projectID(ctx context.Context) (string, error) { var projectID = os.Getenv("GOOGLE_CLOUD_PROJECT") if projectID == "" { return metadata.ProjectIDWithContext(ctx) } return projectID, nil } func setupLogging() { opts := &slog.HandlerOptions{ Level: slog.LevelDebug, ReplaceAttr: func(group []string, a slog.Attr) slog.Attr { switch a.Key { case slog.LevelKey: a.Key = "severity" if level := a.Value.Any().(slog.Level); level == slog.LevelWarn { a.Value = slog.StringValue("WARNING") } case slog.MessageKey: a.Key = "message" case slog.TimeKey: a.Key = "timestamp" } return a }, } jsonHandler := slog.NewJSONHandler(os.Stdout, opts) instrumentedHandler := handlerWithSpanContext(jsonHandler) slog.SetDefault(slog.New(instrumentedHandler)) } type spanContextLogHandler struct { slog.Handler } func handlerWithSpanContext(handler slog.Handler) *spanContextLogHandler { return &spanContextLogHandler{Handler: handler} } func (t *spanContextLogHandler) Handle(ctx context.Context, record slog.Record) error { if s := trace.SpanContextFromContext(ctx); s.IsValid() { trace := fmt.Sprintf("projects/%s/traces/%s", projID, s.TraceID()) record.AddAttrs( slog.Any("logging.googleapis.com/trace", trace), ) record.AddAttrs( slog.Any("logging.googleapis.com/spanId", s.SpanID()), ) record.AddAttrs( slog.Bool("logging.googleapis.com/trace_sampled", s.TraceFlags().IsSampled()), ) } return t.Handler.Handle(ctx, record) } func setupTelemetry(ctx context.Context) (shutdown func(context.Context) error, err error) { var shutdownFuncs []func(context.Context) error shutdown = func(ctx context.Context) error { var err error for _, fn := range shutdownFuncs { err = errors.Join(err, fn(ctx)) } shutdownFuncs = nil return err } projID, err = projectID(ctx) if err != nil { err = errors.Join(err, shutdown(ctx)) return } res, err2 := resource.New( ctx, resource.WithDetectors(gcp.NewDetector()), resource.WithTelemetrySDK(), resource.WithAttributes(semconv.ServiceNameKey.String(os.Getenv("K_SERVICE"))), ) if err2 != nil { err = errors.Join(err2, shutdown(ctx)) return } otel.SetTextMapPropagator(autoprop.NewTextMapPropagator()) texporter, err2 := cloudtrace.New(cloudtrace.WithProjectID(projID)) if err2 != nil { err = errors.Join(err2, shutdown(ctx)) return } tp := sdktrace.NewTracerProvider( sdktrace.WithSampler(sdktrace.AlwaysSample()), sdktrace.WithResource(res), sdktrace.WithBatcher(texporter)) shutdownFuncs = append(shutdownFuncs, tp.Shutdown) otel.SetTracerProvider(tp) mexporter, err2 := cloudmetric.New(cloudmetric.WithProjectID(projID)) if err2 != nil { err = errors.Join(err2, shutdown(ctx)) return } mp := sdkmetric.NewMeterProvider( sdkmetric.WithReader(sdkmetric.NewPeriodicReader(mexporter)), sdkmetric.WithResource(res), ) shutdownFuncs = append(shutdownFuncs, mp.Shutdown) otel.SetMeterProvider(mp) return shutdown, nil } func registerHttpHandler(route string, handleFn http.HandlerFunc) { instrumentedHandler := otelhttp.NewHandler(otelhttp.WithRouteTag(route, handleFn), route) http.Handle(route, instrumentedHandler) } - به ترمینال برگردید و دستور زیر را برای بهروزرسانی تعاریف ماژول Go در فایل
go.modاجرا کنید:go mod tidy - به ترمینال برگردید و
main.goدوباره باز کنید:cloudshell edit ~/codelab-o11y/main.go - کد فعلی را با نسخهای که ردیابی HTTP را ابزاربندی میکند و معیار عملکرد را مینویسد، جایگزین کنید. برای جایگزینی کد، محتوای فایل را حذف کنید و سپس کد زیر را کپی کرده و در ویرایشگر قرار دهید:
package main import ( "context" "errors" "fmt" "net/http" "os" "encoding/json" "log/slog" "cloud.google.com/go/vertexai/genai" "go.opentelemetry.io/otel" "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/metric" ) var model *genai.GenerativeModel var counter metric.Int64Counter const scopeName = "genai-o11y/go/workshop/example" func main() { ctx := context.Background() projectID, err := projectID(ctx) if err != nil { return } setupLogging() shutdown, err := setupTelemetry(ctx) if err != nil { slog.ErrorContext(ctx, "error setting up OpenTelemetry", slog.Any("error", err)) os.Exit(1) } meter := otel.Meter(scopeName) counter, err = meter.Int64Counter("model_call_counter") if err != nil { slog.ErrorContext(ctx, "error setting up OpenTelemetry", slog.Any("error", err)) os.Exit(1) } var client *genai.Client client, err = genai.NewClient(ctx, projectID, "us-central1") if err != nil { slog.ErrorContext(ctx, "Failed to marshal response to JSON", slog.Any("error", err)) os.Exit(1) } defer client.Close() model = client.GenerativeModel("gemini-1.5-flash-001") registerHttpHandler("/", Handler) port := os.Getenv("PORT") if port == "" { port = "8080" } if err = errors.Join(http.ListenAndServe(":"+port, nil), shutdown(ctx)); err != nil { slog.ErrorContext(ctx, "Failed to start the server", slog.Any("error", err)) os.Exit(1) } } func Handler(w http.ResponseWriter, r *http.Request) { animal := r.URL.Query().Get("animal") if animal == "" { animal = "dog" } prompt := fmt.Sprintf("Give me 10 fun facts about %s. Return the results as HTML without markdown backticks.", animal) resp, err := model.GenerateContent(r.Context(), genai.Text(prompt)) if err != nil { w.WriteHeader(http.StatusTooManyRequests) return } jsonBytes, err := json.Marshal(resp) if err != nil { slog.ErrorContext(r.Context(), "Failed to marshal response to JSON", slog.Any("error", err)) } else { slog.DebugContext(r.Context(), "content is generated", slog.String("animal", animal), slog.String("prompt", prompt), slog.String("response", string(jsonBytes))) } if len(resp.Candidates) > 0 && len(resp.Candidates[0].Content.Parts) > 0 { clabels := []attribute.KeyValue{attribute.Key("animal").String(animal)} counter.Add(r.Context(), 1, metric.WithAttributes(clabels...)) htmlContent := resp.Candidates[0].Content.Parts[0] w.Header().Set("Content-Type", "text/html; charset=utf-8") fmt.Fprint(w, htmlContent) } }
این برنامه اکنون از OpenTelemetry SDK برای تجهیز اجرای کد با ردیابی و پیادهسازی شمارش تعداد اجرای موفق به عنوان یک معیار استفاده میکند. متد main() برای تنظیم صادرکنندگان OpenTelemetry برای ردیابیها و معیارها جهت نوشتن مستقیم در Google Cloud Tracing and Monitoring اصلاح شده است. همچنین پیکربندیهای اضافی را برای پر کردن ردیابیها و معیارهای جمعآوریشده با فرادادههای مربوط به محیط Cloud Run انجام میدهد. تابع Handler() بهروزرسانی میشود تا هر بار که فراخوانی Vertex AI API نتایج معتبر را برمیگرداند، شمارنده معیار را افزایش دهد.
پس از چند ثانیه، ویرایشگر 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