۱. مقدمه
در این آزمایشگاه کد، یاد میگیرید که چگونه با استفاده از API کوئریدیتا بهترین نتایج را بدست آورید. شما کشف میکنید که چگونه هنگام ارسال درخواستهای زبان طبیعی به پایگاه داده خود، نتایج دقیق و تکرارپذیر ایجاد کنید. برای کمک به شما در دستیابی به این هدف، این راهنما شما را در شش دستورالعمل در چندین فصل راهنمایی میکند و جنبههای مختلف زبان طبیعی به SQL (NL2SQL) و کاربردهای عملی آن را بررسی میکند.
پیشنیازها
- درک اولیه از گوگل کلود و کنسول گوگل کلود
- مهارتهای اولیه کار با رابط خط فرمان و Cloud Shell
آنچه یاد خواهید گرفت
- نحوه استقرار یک کلاستر AlloyDB و نمونه اولیه آن
- نحوه فعال کردن QueryData، توابع هوش مصنوعی و نمایشهای امن پارامتری
- نحوه ایجاد یک مجموعه زمینه QueryData
- نحوه استفاده از قالبها و زمینههای مختلف در API کوئریدیتا
- چگونه میتوان با استفاده از facetها، قالبهای QueryData را انعطافپذیرتر کرد؟
- چگونه ابهام دادهها را با جستجوی مقدار و نمایهسازی سهخطی حل کنیم؟
- نحوه استفاده از توابع هوش مصنوعی برای جستجوی معنایی با قالبها
- نحوه استفاده از نماهای امن پارامتری با API QueryData
آنچه نیاز دارید
- یک حساب کاربری گوگل کلود و پروژه گوگل کلود
- یک مرورگر وب مانند کروم که از کنسول گوگل کلود و کلود شل پشتیبانی میکند
۲. تنظیمات و الزامات
راهاندازی پروژه
- وارد کنسول ابری گوگل شوید. اگر از قبل حساب جیمیل یا گوگل ورکاسپیس ندارید، باید یکی ایجاد کنید .
به جای حساب کاری یا تحصیلی از حساب شخصی استفاده کنید.
- یک پروژه جدید ایجاد کنید یا از یک پروژه موجود دوباره استفاده کنید. برای ایجاد یک پروژه جدید در کنسول Google Cloud، در سربرگ، روی دکمه «انتخاب پروژه» کلیک کنید که یک پنجره بازشو باز میشود.

در پنجره «انتخاب پروژه» روی «پروژه جدید» کلیک کنید تا کادر محاورهای برای پروژه جدید باز شود.

در کادر محاورهای، نام پروژه را وارد کنید و مکان را انتخاب کنید.

- نام پروژه ، نام نمایشی برای شرکتکنندگان این پروژه است. نام پروژه توسط APIهای گوگل استفاده نمیشود و میتوان آن را در هر زمانی تغییر داد.
- شناسه پروژه در تمام پروژههای گوگل کلود منحصر به فرد و غیرقابل تغییر است (پس از تنظیم، دیگر قابل تغییر نیست). کنسول گوگل کلود به طور خودکار یک شناسه منحصر به فرد تولید میکند، اما میتوانید آن را سفارشی کنید. اگر شناسه تولید شده را دوست ندارید، میتوانید یک شناسه تصادفی دیگر ایجاد کنید یا شناسه خودتان را برای بررسی در دسترس بودن آن ارائه دهید. در اکثر آزمایشگاههای کد، باید شناسه پروژه خود را که معمولاً با عبارت PROJECT_ID مشخص میشود، ارجاع دهید.
- برای اطلاع شما، یک مقدار سوم، شماره پروژه ، وجود دارد که برخی از APIها از آن استفاده میکنند. برای کسب اطلاعات بیشتر در مورد هر سه این مقادیر، به مستندات مراجعه کنید.
فعال کردن صورتحساب
یک حساب پرداخت شخصی تنظیم کنید
اگر صورتحساب را با استفاده از اعتبارهای Google Cloud تنظیم کردهاید، میتوانید از این مرحله صرف نظر کنید.
برای تنظیم یک حساب پرداخت شخصی، به اینجا بروید تا پرداخت را در کنسول ابری فعال کنید .
برخی نکات:
- تکمیل این آزمایشگاه باید کمتر از ۵ دلار آمریکا از طریق منابع ابری هزینه داشته باشد.
- شما میتوانید مراحل انتهای این آزمایش را برای حذف منابع دنبال کنید تا از هزینههای بیشتر جلوگیری شود.
- کاربران جدید واجد شرایط استفاده از دوره آزمایشی رایگان ۳۰۰ دلاری هستند.
شروع پوسته ابری
اگرچه میتوان از راه دور و از طریق لپتاپ، گوگل کلود را مدیریت کرد، اما در این آزمایشگاه کد، از گوگل کلود شل ، یک محیط خط فرمان که در فضای ابری اجرا میشود، استفاده خواهید کرد.
از کنسول گوگل کلود ، روی آیکون Cloud Shell در نوار ابزار بالا سمت راست کلیک کنید:

همچنین میتوانید دکمههای G و سپس S را فشار دهید. اگر در کنسول ابری گوگل باشید یا از این لینک استفاده کنید، این توالی، Cloud Shell را فعال میکند.
آمادهسازی و اتصال به محیط فقط چند لحظه طول میکشد. وقتی تمام شد، باید چیزی شبیه به این را ببینید:

این ماشین مجازی با تمام ابزارهای توسعهای که نیاز دارید، مجهز شده است. این ماشین مجازی یک دایرکتوری خانگی پایدار ۵ گیگابایتی ارائه میدهد و روی فضای ابری گوگل اجرا میشود که عملکرد شبکه و احراز هویت را تا حد زیادی بهبود میبخشد. تمام کارهای شما در این آزمایشگاه کد را میتوان در یک مرورگر انجام داد. نیازی به نصب چیزی ندارید.
۳. قبل از شروع
فعال کردن API
برای استفاده از AlloyDB، Compute Engine، سرویسهای شبکه و Agent Platform، APIهای مربوط به آنها را در پروژه Google Cloud خود فعال کنید.
در داخل ترمینال Cloud Shell، مطمئن شوید که شناسه پروژه شما تنظیم شده است:
gcloud config get-value project
این دستور باید شناسه پروژه Google Cloud شما را برگرداند.
متغیر محیطی PROJECT_ID را تنظیم کنید:
PROJECT_ID=$(gcloud config get-value project)
فعال کردن API های مورد نیاز:
gcloud services enable alloydb.googleapis.com \
compute.googleapis.com \
cloudresourcemanager.googleapis.com \
servicenetworking.googleapis.com \
geminidataanalytics.googleapis.com \
cloudaicompanion.googleapis.com \
aiplatform.googleapis.com \
dataplex.googleapis.com
خروجی مورد انتظار:
student@cloudshell:~ (test-project-001-402417)$ gcloud config set project test-project-001-402417
Updated property [core/project].
student@cloudshell:~ (test-project-001-402417)$ PROJECT_ID=$(gcloud config get-value project)
Your active configuration is: [cloudshell-14650]
student@cloudshell:~ (test-project-001-402417)$
student@cloudshell:~ (test-project-001-402417)$ gcloud services enable alloydb.googleapis.com \
compute.googleapis.com \
cloudresourcemanager.googleapis.com \
servicenetworking.googleapis.com \
geminidataanalytics.googleapis.com \
cloudaicompanion.googleapis.com \
aiplatform.googleapis.com \
dataplex.googleapis.com
Operation "operations/acat.p2-4470404856-1f44ebd8-894e-4356-bea7-b84165a57442" finished successfully.
میتوانید درباره هر API فعالشده در مستندات مطالعه کنید.
۴. استقرار AlloyDB
کلاستر AlloyDB و نمونه اولیه آن را ایجاد کنید. میتوانید آن را با استفاده از یک اسکریپت آماده که تمام منابع لازم را مستقر میکند، مستقر کنید یا میتوانید این کار را گام به گام خودتان با دنبال کردن مستندات AlloyDB انجام دهید.
استقرار AlloyDB با استفاده از اسکریپت خودکار
این رویکرد با استفاده از یک اسکریپت خودکار، خوشه AlloyDB را مستقر میکند و جزئیات پیکربندی لازم را برای شروع کار با منابع مستقر ارائه میدهد.
در ترمینال Cloud Shell، دستور زیر را برای کلون کردن اسکریپت استقرار از مخزن اجرا کنید:
REPO_NAME="codelabs"
REPO_URL="https://github.com/GoogleCloudPlatform/$REPO_NAME"
SOURCE_DIR="alloydb-ai-nla"
git clone --no-checkout --filter=blob:none --depth=1 $REPO_URL
cd $REPO_NAME
git sparse-checkout set $SOURCE_DIR
git checkout
cd $SOURCE_DIR
اسکریپت استقرار را اجرا کنید:
./deploy_alloydb.sh
تکمیل اسکریپت پنج تا هفت دقیقه طول میکشد. خروجی، جزئیات استقرار کلاستر شما را نمایش میدهد. لطفاً توجه داشته باشید که رمز عبور شما متفاوت خواهد بود - رمز عبور را برای استفادههای بعدی یادداشت کنید .
... <redacted> ... Creating primary instance: alloydb-aip-01-pr (8 vCPUs for TRIAL cluster) Operation ID: operation-1765988049916-646282264938a-bddce198-9f248715 Creating instance...done. ---------------------------------------- Deployment Process Completed Cluster: alloydb-aip-01 (TRIAL) Instance: alloydb-aip-01-pr Region: us-central1 Initial Password: JBBoDTgixzYwYpkF (if new cluster) ----------------------------------------
کلاستر و نمونه جدید خود را در صفحه AlloyDB Clusters در کنسول Google Cloud مشاهده کنید.

۵. آمادهسازی پایگاه داده
یک پایگاه داده ایجاد کنید، یکپارچهسازی پلتفرم Gemini Enterprise Agent را فعال کنید، اشیاء پایگاه داده را بسازید و دادههای نمونه را اضافه کنید.
مجوزهای لازم را به AlloyDB اعطا کنید
نقشهای IAM مورد نیاز را به عامل سرویس AlloyDB اعطا کنید:
با کلیک روی افزودن (+)، یک برگه جدید Cloud Shell باز کنید.

در تب جدید، دستور زیر را اجرا کنید:
PROJECT_ID=$(gcloud config get-value project)
gcloud projects add-iam-policy-binding $PROJECT_ID \
--member="serviceAccount:service-$(gcloud projects describe $PROJECT_ID --format="value(projectNumber)")@gcp-sa-alloydb.iam.gserviceaccount.com" \
--role="roles/aiplatform.user"
خروجی مورد انتظار کنسول:
student@cloudshell:~ (test-project-001-402417)$ PROJECT_ID=$(gcloud config get-value project) Your active configuration is: [cloudshell-11039] student@cloudshell:~ (test-project-001-402417)$ gcloud projects add-iam-policy-binding $PROJECT_ID \ --member="serviceAccount:service-$(gcloud projects describe $PROJECT_ID --format="value(projectNumber)")@gcp-sa-alloydb.iam.gserviceaccount.com" \ --role="roles/aiplatform.user" Updated IAM policy for project [test-project-001-402417]. bindings: - members: - serviceAccount:service-4470404856@gcp-sa-alloydb.iam.gserviceaccount.com role: roles/aiplatform.user - members: ... etag: BwYIEbe_Z3U= version: 1
فعال کردن API دسترسی به داده
API دسترسی به داده (Data Access API) را در کلاستر AlloyDB خود فعال کنید.
در همان تب ترمینال، دستور زیر را اجرا کنید:
PROJECT_ID=$(gcloud config get-value project)
REGION=us-central1
ADBCLUSTER=alloydb-aip-01
curl -X PATCH \
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
-H "Content-Type: application/json" \
https://alloydb.googleapis.com/v1alpha/projects/$PROJECT_ID/locations/$REGION/clusters/$ADBCLUSTER/instances/$ADBCLUSTER-pr?updateMask=dataApiAccess \
-d '{
"dataApiAccess": "ENABLED",
}'
بهروزرسانی پرچمهای پایگاه داده
قبل از فعال کردن پرچمها در سطح نمونه، صبر کنید تا مرحله API دسترسی به داده تمام شود. مطمئن شوید که وضعیت نمونه شما، همانطور که در تصویر زیر نشان داده شده است، یک علامت سبز نشان میدهد.

برای استفاده از افزونههای هوش مصنوعی و احراز هویت IAM برای ابزارهای عاملگرا، باید پرچمهای پایگاه داده خاصی را در آن نمونه فعال کنید و خود را به عنوان کاربر پایگاه داده اضافه کنید. پرچمهای زیر را فعال کنید:
- alloydb.iam_authentication
- password.enforce_complexity
- google_ml_integration.enable_ai_query_engine
- نمایشهای پارامتری
در همان تب ترمینال، دستورات زیر را اجرا کنید:
PROJECT_ID=$(gcloud config get-value project)
REGION=us-central1
ADBCLUSTER=alloydb-aip-01
gcloud beta alloydb instances update $ADBCLUSTER-pr \
--database-flags password.enforce_complexity=on,alloydb.iam_authentication=on,google_ml_integration.enable_ai_query_engine=on,parameterized_views.enabled=on \
--region=$REGION \
--cluster=$ADBCLUSTER \
--project=$PROJECT_ID \
--update-mode=FORCE_APPLY
یک کاربر AlloyDB IAM برای حساب خود ایجاد کنید:
REGION=us-central1
ADBCLUSTER=alloydb-aip-01
gcloud alloydb users create $(gcloud config get-value account) \
--cluster=$ADBCLUSTER \
--superuser=true \
--region=$REGION \
--type=IAM_BASED
با اجرای دستور exit در ترمینال، تب را ببندید:
exit
اتصال به استودیوی AlloyDB
در فصلهای بعدی، میتوانید تمام دستورات SQL که نیاز به اتصال به پایگاه داده دارند را در AlloyDB Studio اجرا کنید.
برای باز کردن AlloyDB Studio، مراحل زیر را انجام دهید:
- در کنسول Google Cloud، به صفحه Clusters برای AlloyDB for PostgreSQL بروید.
- نمونه اصلی خود را انتخاب کنید تا رابط وب آن باز شود.

- سپس در سمت چپ روی AlloyDB Studio کلیک کنید:

- پایگاه داده
postgresرا انتخاب کنید، IAM Authentication را انتخاب کنید و روی Authenticate کلیک کنید.

این اقدام رابط کاربری AlloyDB Studio را باز میکند.
- برای باز کردن ویرایشگر SQL، تب Untitled Query را انتخاب کنید.

این یک ویرایشگر باز میکند که میتوانید دستورات SQL را در آن اجرا کنید، همانطور که در تصویر زیر نشان داده شده است:

ایجاد پایگاه داده
ایجاد پایگاه داده شروع سریع
در ویرایشگر AlloyDB Studio، دستور زیر را برای ایجاد پایگاه داده اجرا کنید:
CREATE DATABASE quickstart_db
خروجی مورد انتظار:
Statement executed successfully
اتصال به پایگاه دادهی quickstart_db
روی تغییر پایگاه داده/کاربر در AlloyDB Studio کلیک کنید.

از لیست پایگاه داده، quickstart_db را انتخاب کنید، IAM Authentication را انتخاب کنید و احراز هویت را انجام دهید.

این یک اتصال جدید باز میکند که در آن میتوانید با اشیاء پایگاه داده quickstart_db کار کنید.
فعال کردن افزونهها
تمام افزونههای مورد نیاز را بررسی کنید تا مطمئن شوید که در پایگاه داده شما فعال هستند و نسخههای حداقلی صحیحی دارند.
تأیید کنید که تمام افزونههای مورد نیاز در پایگاه داده شما وجود دارند:
SELECT extname, extversion FROM pg_extension WHERE extname IN ('vector', 'google_ml_integration', 'parameterized_views');
خروجی مورد انتظار:
extname | extversion -----------------------+---------------- google_ml_integration | 1.5.9 parameterized_views | 1.0 vector | 0.8.2.google-1
اگر تمام ردیفهای بالا را برنگرداند، به این معنی است که برخی از افزونهها فعال نیستند.
قبل از فعال کردن افزونهها، باید مطمئن شویم که تمام پرچمهای پایگاه داده ، "google_ml_integration.enable_ai_query_engine" و "parameterized_views.enabled" در نمونه فعال شدهاند.
در AlloyDB Studio هنگام اتصال به quickstart_db، دستور زیر را اجرا کنید:
show google_ml_integration.enable_ai_query_engine;
show parameterized_views.enabled;
اگر هر یک از آنها "خاموش" نشان داده میشوند، سعی کنید مرحله "بهروزرسانی پرچمهای پایگاه داده" را تکرار کنید و وضعیت را دوباره با استفاده از دستورات "نمایش..." بررسی کنید.
افزونههای مورد نیاز را فعال کنید.
در AlloyDB Studio هنگام اتصال به quickstart_db، دستور زیر را اجرا کنید:
CREATE EXTENSION IF NOT EXISTS vector;
CREATE EXTENSION IF NOT EXISTS parameterized_views;
نسخههای افزونهها را برای parameterized_views و google_ml بررسی کنید.
در AlloyDB Studio هنگام اتصال به quickstart_db، دستور زیر را اجرا کنید:
SELECT extname, extversion FROM pg_extension WHERE extname IN ('vector', 'google_ml_integration', 'parameterized_views');
خروجی مورد انتظار:
extname | extversion -----------------------+---------------- google_ml_integration | 1.5.9 parameterized_views | 1.0 vector | 0.8.2.google-1
اگر نسخه پایینتر از حد مورد نیاز است، سعی کنید افزونه parameterized_views را بهروزرسانی کنید.
برای parameterized_views این را امتحان کنید:
ALTER EXTENSION parameterized_views UPDATE;
نسخه را دوباره تأیید کنید.
در AlloyDB Studio هنگام اتصال به quickstart_db، دستور زیر را اجرا کنید:
SELECT extname, extversion FROM pg_extension WHERE extname IN ('vector', 'google_ml_integration', 'parameterized_views');
خروجی مورد انتظار:
extname | extversion -----------------------+---------------- google_ml_integration | 1.5.9 parameterized_views | 1.0 vector | 0.8.2.google-1
۶. دادههای نمونه
حالا باید اشیاء را در پایگاه داده ایجاد کرده و دادهها را بارگذاری کنید. شما قصد دارید از یک مجموعه داده فرضی شرکت املاک و مستغلات استفاده کنید. این مجموعه داده شامل دادههای فرضی در مورد فروش املاک و نمایندگان آنها است. دادهها در اسکریپت SQL به نام real_estate_data.sql در مخزن شبیهسازی شده ارائه شدهاند.
ایجاد سطل ذخیرهسازی
از Google SDK (gcloud) برای وارد کردن دادهها از مخزن کلون شده خود به پایگاه داده AlloyDB استفاده کنید. برای این کار باید یک مخزن ذخیرهسازی ابری ایجاد کنید و به حساب سرویس AlloyDB دسترسی بدهید. همچنین، همانطور که در مستندات توضیح داده شده است، میتوانید همیشه این کار را با استفاده از کنسول وب انجام دهید.
در ترمینال Google Cloud Shell دستور زیر را اجرا کنید:
PROJECT_ID=$(gcloud config get-value project)
REGION=us-central1
gcloud storage buckets create gs://$PROJECT_ID-import --project=$PROJECT_ID --location=$REGION
gcloud storage buckets add-iam-policy-binding gs://$PROJECT_ID-import --member="serviceAccount:service-$(gcloud projects describe $PROJECT_ID --format="value(projectNumber)")@gcp-sa-alloydb.iam.gserviceaccount.com" --role=roles/storage.objectViewer
بارگذاری داده
فایل SQL پایگاه داده در پوشه مخزن کلون شده قرار دارد. دستور زیر فرض میکند که شما هنگام کلون کردن مخزن در مرحله قبل هنگام ایجاد خوشه AlloyDB، از دایرکتوری خانگی خود به عنوان نقطه شروع استفاده کردهاید.
فایل dump پایگاه داده را در فضای ذخیرهسازی ابری خود کپی کنید:
REPO_NAME="codelabs"
SOURCE_DIR="alloydb-ai-nla"
cd ~/$REPO_NAME/$SOURCE_DIR
gcloud storage cp ~/$REPO_NAME/$SOURCE_DIR/real_estate_data.sql gs://$PROJECT_ID-import
مجموعه دادهها را به quickstart_db وارد کنید:
PROJECT_ID=$(gcloud config get-value project)
CLUSTER_NAME=alloydb-aip-01
REGION=us-central1
IAM_USER=$(gcloud config get-value account)
gcloud alloydb clusters import $CLUSTER_NAME --region=us-central1 --database=quickstart_db --gcs-uri=gs://$PROJECT_ID-import/real_estate_data.sql --project=$PROJECT_ID --sql --user=$IAM_USER
این دستور، مجموعه دادههای نمونه را در پایگاه داده quickstart_db بارگذاری میکند.
با شمارش رکوردهای جدول real_estate.agents با استفاده از AlloyDB Studio، واردات را تأیید کنید:
SELECT COUNT(*) FROM real_estate.agents;
۷. آمادهسازی هستیشناسی طرحواره
مجموعه زمینه QueryData خود را تنظیم کنید، فرادادههای طرحواره را ارائه دهید و عامل ADK را اجرا کنید.
ایجاد فراداده
متادیتا شامل کامنتهای SQL است که روی جداول و ستونهای پایگاه داده اعمال میشوند. این کامنتها موتور QueryData را هنگام انتخاب اشیاء پایگاه داده راهنمایی میکنند.
اگر طرحواره داده خود را با استفاده از SQL dump ارائه شده وارد کرده باشید، تمام فرادادهها از قبل در طرحواره شما ایجاد شدهاند.
در اینجا نمونهای از قطعه کد فراداده اعمال شده بر روی طرحواره real_estate آورده شده است:
COMMENT ON TABLE real_estate.agents IS 'Stores profile, contact, brokerage affiliation, and active status for individual real estate agents.'; COMMENT ON COLUMN real_estate.agents.agent_id IS 'Primary key uniquely identifying each real estate agent in the database.'; ...
اگر با مجموعه داده خودتان کار میکنید، میتوانید راهنمای مستند شده در مورد نحوه اضافه کردن فراداده برای طرحواره خود را دنبال کنید.
ایجاد زمینه هستیشناسی طرحواره
یک مجموعه زمینه شامل الگوهای پرسوجو، وجهها و جستجوهای مقداری است که به مدل هوش مصنوعی در تولید پرسوجوها کمک میکند. بدون مجموعه زمینه، یک عامل هوش مصنوعی سعی میکند پرسوجو را تنها با استفاده از اطلاعات موجود از طرحواره public و عمدتاً بر اساس نام جداول، ستونها و فرادادهها تولید کند و سعی در استنباط اشیاء مناسب برای پاسخ به یک درخواست پرسوجوی طبیعی دارد.
مجموعه زمینه QueryData یک فایل JSON با قالبهای پرسوجو، وجهها و جستجوی مقادیر است. میتوانید به مثالهای مختلف در مستندات نگاهی بیندازید.
بارگذاری مجموعه زمینه QueryData در کنسول وب
برای بارگذاری یک مجموعه زمینه، AlloyDB Studio را باز کنید و در پنل سمت چپ در پایین، Context sets و سه نقطه را خواهید دید.

روی آن سه نقطه کلیک کنید و گزینه Create context set انتخاب کنید.
در کادر محاورهای باز شده، مقادیر زیر را وارد کنید:
- نام:
sixrecipes - شرح:
Real Estate Query Data - بارگذاری فایل زمینه: آن را خالی نگه دارید
وقتی دکمهی Create را فشار میدهید، اگر برای اولین بار این کار را انجام دهید، ممکن است مقداری طول بکشد تا فضای ذخیرهسازی زمینه راهاندازی شود.
شناسه مجموعه زمینه QueryData را با کلیک مجدد روی سه نقطه سمت راست نام مجموعه زمینه بررسی کنید و Edit context set انتخاب کنید.

شناسه مجموعه زمینه در بالای برگه باز شده در سمت راست ظاهر میشود.

این شناسه را برای مراحل بعدی ذخیره کنید.
عامل هوش مصنوعی را شروع کنید
برای تعامل با backend QueryData جهت تولید و اجرای کوئری، میتوانید از رابط کاربری AlloyDB Studio همانطور که در مستندات توضیح داده شده است، استفاده کنید. اما در این آزمایشگاه از یک عامل هوش مصنوعی به عنوان ابزار اصلی ارتباط با پایگاه داده استفاده خواهید کرد. عاملهای هوش مصنوعی سناریوی واقعگرایانهای برای بارهای کاری آینده هستند و چارچوب Google ADK یک رابط کاربری وب عالی ارائه میدهد که در آن میتوانید تمام مراحل و تعاملات بین مدلها، APIها و برنامهها را مشاهده کنید.
پیکربندی منبع عامل را در Cloud Shell بررسی کنید:
REPO_NAME="codelabs"
SOURCE_DIR="alloydb-ai-nla"
cd ~/$REPO_NAME/$SOURCE_DIR/data_agent
edit agent.py
در فایل میتوانید ببینید که لیست جداول را در طرح خود کجا تعریف میکنیم. در یکی از مراحل آینده به آن باز خواهیم گشت.
# List of database tables included in QueryData API requests
TABLE_IDS = [
"real_estate.municipalities",
"real_estate.cities",
"real_estate.agents",
"real_estate.properties",
"real_estate.schools",
"real_estate.school_to_property",
"real_estate.property_transactions",
"real_estate.secure_offers",
]
و یک روال به نام call_querydata_api برای کار با QueryData API به همراه مجموعهای از ابزارها برای کار با مهارتهای QueryData API وجود دارد.
def call_querydata_api(
prompt: str,
target_project_id: str = project_id,
target_location: str = location,
target_cluster_id: str = cluster_name,
target_instance_id: str = instance_name,
target_database_id: str = database_name,
target_context_set_id: str = context_set_id,
target_table_ids: list[str] = TABLE_IDS,
) -> dict:
"""Calls the Gemini Data Analytics QueryData API to translate natural ...
<Redacted>
...
# ADK File-Based Skill
database_query_skill = load_skill_from_dir(
pathlib.Path(__file__).parent / "skills" / "database-query-skill"
)
skill_toolset = SkillToolset(
skills=[database_query_skill]
)
در اینجا خود عامل ریشه با ابزارهای سریع و در دسترس آمده است.
# Agent configuration
root_agent = Agent(
model=MODEL_ID,
name='root_agent',
description='A helpful assistant for analyst requests.',
instruction=f"""
Answer user questions to the best of your knowledge using provided tools.
Do not try to generate non-existent data but use the grounded data from the database.
When you answer questions about database contents, real estate properties, or sales activity:
1. Refer to database-query-skill for instructions on querying data using QueryData API.
2. Use `call_querydata_api` to submit the natural language prompt to the QueryData API.
CRITICAL: Call `call_querydata_api` EXACTLY ONCE per user request. Do NOT make retries, follow-up calls, or rephrased calls to `call_querydata_api`, even if the result contains zero rows or empty data.
3. Immediately parse the JSON response from that first `call_querydata_api` call.
4. Format your final response to the user containing:
- The generated SQL query (formatted in a Markdown SQL code block).
- The query results formatted as a Markdown table (constructed from `queryResult.columns` and `queryResult.rows`).
- The natural language answer (`naturalLanguageAnswer`).
""",
tools=[call_querydata_api, skill_toolset],
)
برای درک دستورالعملهای سیستم عامل، data_agent/SKILL.md را بررسی کنید:
REPO_NAME="codelabs"
SOURCE_DIR="alloydb-ai-nla"
cd ~/$REPO_NAME/$SOURCE_DIR/data_agent
edit SKILL.md
قبل از شروع به کار agent، باید یک فایل .env با پارامترهایی برای درخواستهای Agent و QueryData API آماده کنید.
شناسه مجموعه زمینه خود را به یک متغیر محیطی صادر کنید:
export QUERYDATA_CONTEXTSET=<context set id from the Create Context Set chapter>
فایل پیکربندی محیط زمان اجرا (.env) خود را در دایرکتوری data_agent ایجاد کنید:
PROJECT_ID=$(gcloud config get-value project)
REGION=us-central1
REPO_NAME="codelabs"
SOURCE_DIR="alloydb-ai-nla"
cd ~/$REPO_NAME/$SOURCE_DIR/data_agent
echo "GOOGLE_GENAI_USE_ENTERPRISE=true" > .env
echo "GOOGLE_CLOUD_PROJECT=$(gcloud config get-value project -q)" >> .env
echo "GOOGLE_CLOUD_LOCATION=global" >> .env
echo "QUERYDATA_CONTEXTSET=$QUERYDATA_CONTEXTSET" >> .env
echo "ALLOYDB_CLUSTER=alloydb-aip-01" >> .env
echo "ALLOYDB_INSTANCE=alloydb-aip-01-pr" >> .env
echo "ALLOYDB_DATABASE=quickstart_db" >> .env
echo "ALLOYDB_LOCATION=$REGION" >> .env
وابستگیها را نصب کنید و سرویس وب عامل را شروع کنید:
cd ~/$REPO_NAME/$SOURCE_DIR/
uv sync
عامل را شروع کنید:
uv run adk web --allow_origins 'regex:https://.*\.cloudshell\.dev'
شما باید خروجی زیر را با نقطه پایانی http://127.0.0.1:8000 ببینید.
INFO: Started server process [83608] INFO: Waiting for application startup. +-----------------------------------------------------------------------------+ | ADK Web Server started | | | | For local testing, access at http://127.0.0.1:8000. | +-----------------------------------------------------------------------------+ INFO: Application startup complete. INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)

برای اجرای رابط کاربری، روی آدرس اینترنتی وب سرور تولید شده (مثلاً http://127.0.0.1:8000) در Cloud Shell کلیک کنید. اگر کار نکرد، در Cloud Shell، روی پیشنمایش وب -> پیشنمایش روی پورت ۸۰۰۰ کلیک کنید تا رابط کاربری باز شود.
مطمئن شوید که data_agent در منوی کشویی بالا سمت چپ انتخاب شده باشد.

تولید و اجرای کوئریها
بیایید کوئری Q1 را اجرا کنیم.
برای ارزیابی عملکرد QueryData پایه بدون قالبها یا جنبههای سفارشی، این پیام زبان طبیعی را در رابط چت اپراتور اجرا کنید:
How many properties are currently for sale in San Diego?
و دکمه فلش را فشار دهید.

وقتی عامل مهارت مناسب را انتخاب کند و از آن مهارت و تابع برای ارسال درخواست به نقطه پایانی API و دریافت کوئری تولید شده و نتایج استفاده کند، گردش کار او آغاز میشود.

و اگر نشانگر ماوس خود را روی مراحل نگه دارید، میتوانید دقیقاً ببینید که آن مراحل چه کاری انجام میدادند. همچنین میتوانید آن و موارد بسیار بیشتری را در پنل سمت چپ هنگام انتخاب یک یا چند مرحله دیگر مشاهده کنید. این میتواند به درک نحوه کار اپراتورها با مهارتها و APIها کمک کند.

ارسال درخواست پیگیری (سوال دوم):
List agents who sold a property for over $1000000.
متوجه خواهید شد که عامل مستقیماً به سراغ مهارت API مربوط به QueryData میرود، زیرا قبلاً مهارتهای موجود را در حافظه نوشته است و نیازی به طی کردن دوباره مرحله کشف ندارد.
SQL تولید شده شبیه به این عبارت است:
SELECT DISTINCT "a"."agent_id", "a"."firstname", "a"."lastname", "a"."email", "a"."brokerage" FROM "real_estate"."agents" AS "a" INNER JOIN "real_estate"."property_transactions" AS "t" ON "a"."agent_id" = "t"."seller_agent_id" WHERE "t"."sale_price" > 1000000 AND "a"."agent_id" IS NOT NULL ORDER BY "a"."lastname" ASC NULLS LAST;
یک پرس و جوی دیگر را امتحان کنید (سوال 3):
What is the average price of a single-family home with a garage in San Diego?
QueryData پرسوجوهای استانداردی با یک مجموعه زمینه خالی تولید میکند، اما وظایف تجاری اغلب به منطق تجاری خاص و رفتار قطعی نیاز دارند.
۸. با تزریق تفسیر، به دقت بالا و ارتباط تجاری دست یابید
تزریق تفسیر به اعلانها تضمین میکند که پرسوجوهای تولید شده با منطق تجاری خاص مطابقت دارند.
شما چنین مثالی را با مشتری که درخواست خرید خانههای یک طبقه در دل مار را دارد، امتحان خواهید کرد. این سوال دو معیار مهم دارد و الگویی رایج برای انتخاب را نشان میدهد.
دستور زبان طبیعی زیر (سوال ۴) را در اپراتور امتحان کنید.
Single level Del Mar houses
موتور یک کوئری عمومی برمیگرداند، اما ممکن است شامل برخی شرایط اضافی مانند is_single_family = TRUE :
SELECT p."property_id", p."address_street", p."price", p."bedrooms", p."bathrooms", p."listing_status", p."is_single_family", p."num_stories", c."city_name" FROM "real_estate"."properties" AS p JOIN "real_estate"."cities" AS c ON p."city_id" = c."city_id" WHERE c."city_name" ILIKE 'Del Mar' AND p."num_stories" = 1 AND p."is_single_family" = TRUE ORDER BY p."property_id" ASC NULLS LAST;
در نتیجه، یک ردیف برگردانده شده دریافت میکنیم:
Natural Language Answer The database contains one single-level, single-family house in Del Mar: Address: 999 Main Ave (Postal Code: 90024) Price: $3,800,000.00 Bedrooms: 4 Bathrooms: 3.5 Listing Status: Active Features: Single-family home (1 story), has a garage, and no condo fees.
یک دستور دیگر را امتحان کنید (سوال ۵):
Del Mar houses close to good schools
این الگوریتم به اندازه کافی هوشمند است که از ستونهای proximity_miles و school_ranking برای مرتبسازی ویژگیها استفاده کند، اما وزن و اهمیت هر معیار را ارزیابی نمیکند.
SELECT "p"."property_id", "p"."address_street", "p"."price", "p"."bedrooms", "p"."bathrooms", "s"."school_name", "s"."school_ranking", "sp"."proximity_miles" FROM "real_estate"."properties" AS "p" INNER JOIN "real_estate"."cities" AS "c" ON "p"."city_id" = "c"."city_id" INNER JOIN "real_estate"."school_to_property" AS "sp" ON "p"."property_id" = "sp"."property_id" INNER JOIN "real_estate"."schools" AS "s" ON "sp"."school_id" = "s"."school_id" WHERE "c"."city_name" = 'Del Mar' AND "sp"."proximity_miles" IS NOT NULL AND "s"."school_ranking" IS NOT NULL ORDER BY "sp"."proximity_miles" ASC NULLS LAST, "s"."school_ranking" ASC NULLS LAST;
تعمیم پرس و جوی نمونه به یک الگو
منطق کسب و کار مستلزم موارد زیر است:
- نزدیکی در فاصله ۲ مایلی
- رتبه مدرسه ۵ یا کمتر
- مرتبسازی وزنی: ۸۰٪ رتبهبندی مدرسه + ۲۰٪ نزدیکی (امتیاز = ۰.۸ * رتبهبندی مدرسه + ۰.۲ * نزدیکی مایل)
فرمول رتبهبندی وزنی به صورت زیر است:
Score = 0.8 * school_ranking + 0.2 * proximity_miles
فایل زمینه sixrecipe_context1_1.json را با استفاده از رابط خط فرمان در Cloud Shell از Cloud Shell دانلود کنید:
cloudshell download ~/codelabs/alloydb-ai-nla/sixrecipe_context1_1.json
یا با استفاده از گزینهی منوی Download از منوی Cloud Shell:

برای تعریف این ساختار استاندارد، فایل sixrecipe_context1_1.json را با استفاده از AlloyDB Studio در مجموعه زمینه sixrecipe خود بارگذاری کنید. روی سه نقطه سمت راست زمینه sixrecipes کلیک کنید و از «ویرایش مجموعه زمینه» برای بارگذاری فایل جدید استفاده کنید. این کار عملاً زمینه خالی قدیمی را با زمینه جدید جایگزین میکند.
این الگو، قوانین صریح الگوی SQL را برای قوانین نزدیکی به مدرسه خوب تعریف میکند:
{
"facets": [],
"templates": [
{
"nl_query": "Riverside houses close to good schools.",
"sql": "SELECT \"p\".\"address_street\", \"p\".\"address_postal_code\", \"s\".\"school_name\", \"stp\".\"proximity_miles\" FROM \"real_estate\".\"properties\" AS \"p\" JOIN \"real_estate\".\"cities\" AS \"c\" ON \"p\".\"city_id\" = \"c\".\"city_id\" JOIN \"real_estate\".\"school_to_property\" AS \"stp\" ON \"p\".\"property_id\" = \"stp\".\"property_id\" JOIN \"real_estate\".\"schools\" AS \"s\" ON \"stp\".\"school_id\" = \"s\".\"school_id\" WHERE \"c\".\"city_name\" = 'Riverside' AND \"s\".\"school_ranking\" <= 5 AND \"stp\".\"proximity_miles\" <= 2 ORDER BY 0.8 * \"s\".\"school_ranking\" + 0.2 * \"stp\".\"proximity_miles\"",
"intent": "Houses in Riverside close to good schools (within 2 miles of schools with a rank of at least 5).",
"manifest": "A given city houses close to good schools.",
"parameterized": {
"parameterized_intent": "Houses in $1 close to good schools (within 2 miles of schools with a rank of at least 5).",
"parameterized_sql": "SELECT \"p\".\"address_street\", \"p\".\"address_postal_code\", \"s\".\"school_name\", \"stp\".\"proximity_miles\" FROM \"real_estate\".\"properties\" AS \"p\" JOIN \"real_estate\".\"cities\" AS \"c\" ON \"p\".\"city_id\" = \"c\".\"city_id\" JOIN \"real_estate\".\"school_to_property\" AS \"stp\" ON \"p\".\"property_id\" = \"stp\".\"property_id\" JOIN \"real_estate\".\"schools\" AS \"s\" ON \"stp\".\"school_id\" = \"s\".\"school_id\" WHERE \"c\".\"city_name\" = $1 AND \"s\".\"school_ranking\" <= 5 AND \"stp\".\"proximity_miles\" <= 2 ORDER BY 0.8 * \"s\".\"school_ranking\" + 0.2 * \"stp\".\"proximity_miles\""
}
}
]
}
دستور را دوباره اجرا کنید:
Del Mar houses close to good schools
اکنون کوئری حاصل با منطق تجاری تعریف شده در الگو مطابقت دارد:
SELECT "p"."address_street", "p"."address_postal_code", "s"."school_name", "stp"."proximity_miles" FROM "real_estate"."properties" AS "p" JOIN "real_estate"."cities" AS "c" ON "p"."city_id" = "c"."city_id" JOIN "real_estate"."school_to_property" AS "stp" ON "p"."property_id" = "stp"."property_id" JOIN "real_estate"."schools" AS "s" ON "stp"."school_id" = "s"."school_id" WHERE "c"."city_name" = 'Del Mar' AND "s"."school_ranking" <= 5 AND "stp"."proximity_miles" <= 2 ORDER BY 0.8 * "s"."school_ranking" + 0.2 * "stp"."proximity_miles"
همراه با دستور SQL تولید شده، intent زیر تولید میشود:
intentExplanation: "Houses in Del Mar close to good schools (within 2 miles of schools with a rank of at least 5)."
همانطور که در اینجا نشان داده شده است، میتوانید هدف را در پنل سمت چپ رابط وب ADK مشاهده کنید:

نتایج دو ویژگی را نشان میدهد که بر اساس امتیاز ما مرتب شدهاند:
Query Results address_street address_postal_code school_name proximity_miles 200 Coast Blvd 92014 Del Mar Heights Elementary 0.50 100 Del Mar Heights Rd 92014 Del Mar Heights Elementary 1.00 Answer Based on the data, here are the properties in Del Mar located within 2 miles of a top-rated school (ranking of 5 or better): 200 Coast Blvd (92014) School: Del Mar Heights Elementary Proximity: 0.50 miles 100 Del Mar Heights Rd (92014) School: Del Mar Heights Elementary Proximity: 1.00 miles
در فصل بعدی، دامنهی این الگو را گسترش خواهید داد.
با دریافت و تفسیر چندین سوال، تفسیر را تزریق کنید
شما میتوانید دامنهی استفاده از الگوی ما را نه تنها برای «نزدیک به مدارس خوب» گسترش دهید، بلکه شرایط دیگری را نیز به مانیفست اضافه کنید تا مثلاً برای «خانه برای خانوادههای دارای فرزند» نیز قابل استفاده باشد.
فایل زمینه بهروزرسانیشده را دانلود کنید:
cloudshell download ~/codelabs/alloydb-ai-nla/sixrecipe_context1_2.json
فایل بهروزرسانیشدهی sixrecipe_context1_2.json را در مجموعهی context خود آپلود کنید.
در فایل مجموعه متن جدید، ما عبارت manifest خود را از "manifest": "A given city houses close to good schools." به manifest: "manifest": "A given city houses close to good schools, or are great for families with kids." . این کار کاربردهای این الگو را برای استفاده در بیش از یک مورد گسترش میدهد.
ارسال این سوال (سوال ۶):
Houses in Waterloo great for families with kids.
عامل از مانیفست الگوی بهروزرسانیشده برای اعمال منطق پرسوجوی استاندارد شما استفاده میکند و همان پرسوجوی فوق را برمیگرداند، با این هدف:
intentExplanation : "Houses in Waterloo close to good schools (within 2 miles of schools with a rank of at least 5)."
۹. از قالبهای چندوجهی برای رسیدن به دقت بالا و در عین حال حفظ انعطافپذیری استفاده کنید
وجهها (facets) شرایط SQL ماژولاری هستند که به صورت پویا با قالبها ترکیب میشوند تا توصیفکنندهها (qualifiers) (مثلاً "خانواده شروعکننده"، "نمای اقیانوس") را بدون ایجاد قالبهای جداگانه برای هر جایگشت، مدیریت کنند.
به جای ایجاد یک الگو برای هر پرسوجو یا شرط، میتوانیم قطعاتی را آماده کنیم که میتوانند روی الگوهای موجود اعمال شوند و ابعاد بیشتری به پرسوجو اضافه کنند.
برای ویژگیهای زیر، یک وجه تعریف کنید:
- خانهای تکخانواری
- وضعیت فهرست فعال
- سه تا چهار اتاق خواب و حداقل دو حمام
- موقعیت مکانی در شهری با نرخ جرم کمتر از ۵۰۰ در هر ۱۰۰۰۰۰ نفر ساکن
فایل زمینه چندوجهی را دانلود کنید:
cloudshell download ~/codelabs/alloydb-ai-nla/sixrecipe_context2_1.json
فایل sixrecipe_context2_1.json را در مجموعه زمینه sixrecipes خود در AlloyDB Studio آپلود کنید تا جنبهها (facets) پیکربندی شوند.
"facets": [
{
"sql_snippet": "real_estate.properties.is_single_family = TRUE AND real_estate.properties.listing_status = 'Active' AND real_estate.properties.bedrooms BETWEEN 3 AND 4 AND real_estate.properties.bathrooms >= 2.0 AND 500 > (SELECT m.crime_rate_per_100k FROM real_estate.cities c JOIN real_estate.municipalities m ON c.municipality_id = m.municipality_id AND c.city_id = real_estate.properties.city_id)",
"intent": "for a starter family (active single-family home listings with 3 to 4 bedrooms, 2+ bathrooms, and a crime rate under 500 per 100,000 residents)",
"manifest": "for a starter family",
"parameterized": {
"parameterized_intent": "for a starter family (active single-family home listings with 3 to 4 bedrooms, 2+ bathrooms, and a crime rate under 500 per 100,000 residents)",
"parameterized_sql_snippet": "real_estate.properties.is_single_family = TRUE AND real_estate.properties.listing_status = 'Active' AND real_estate.properties.bedrooms BETWEEN 3 AND 4 AND real_estate.properties.bathrooms >= 2.0 AND 500 > (SELECT m.crime_rate_per_100k FROM real_estate.cities c JOIN real_estate.municipalities m ON c.municipality_id = m.municipality_id AND c.city_id = real_estate.properties.city_id)"
}
}
]
پرسوجو با استفاده از جستجوی چندوجهی
این کوئری NL (سوال 7) را اجرا کنید:
Del Mar houses close to good schools for a starter family.
موتور، شرایط وجه شما را مستقیماً به پرسوجوی پایه اضافه میکند:
SELECT "p"."address_street", "p"."address_postal_code", "s"."school_name", "stp"."proximity_miles"
FROM "real_estate"."properties" AS "p"
JOIN "real_estate"."cities" AS "c" ON "p"."city_id" = "c"."city_id"
JOIN "real_estate"."school_to_property" AS "stp" ON "p"."property_id" = "stp"."property_id"
JOIN "real_estate"."schools" AS "s" ON "stp"."school_id" = "s"."school_id"
WHERE "c"."city_name" = 'Del Mar'
AND "s"."school_ranking" <= 5
AND "stp"."proximity_miles" <= 2
AND "p"."is_single_family" = TRUE
AND "p"."listing_status" = 'Active'
AND "p"."bedrooms" BETWEEN 3 AND 4
AND "p"."bathrooms" >= 2.0
AND 500 > (
SELECT m.crime_rate_per_100k
FROM real_estate.cities c
JOIN real_estate.municipalities m ON c.municipality_id = m.municipality_id
AND c.city_id = p.city_id
)
ORDER BY 0.8 * "s"."school_ranking" + 0.2 * "stp"."proximity_miles"
و این هم نتایج:
Query Results address_street address_postal_code school_name proximity_miles 200 Coast Blvd 92014 Del Mar Heights Elementary 0.50 Natural Language Answer Based on your criteria, there is an active listing for a single-family house in Del Mar that fits your needs: Address: 200 Coast Blvd, Del Mar, 92014 Nearby School: Del Mar Heights Elementary (ranked within the top 5) Proximity to School: 0.50 miles
اضافه کردن جنبههای بیشتر
اگر بخواهیم بر اساس الگوی نوظهور جدید، یک بُعد دیگر اضافه کنیم - مثلاً یک نمای پنجره برای ملک - چه میشود؟
تطبیق معنایی نمای اقیانوس را در تعریف یک وجه اضافه کنید.
{
"sql_snippet": "((real_estate.properties.description_embedding <=> google_ml.embedding('gemini-embedding-001', 'unobstructed, panoramic, ocean vista, vast Pacific, breathtaking, commanding view, deep blue horizon, massive, sweeping view')::vector) < 0.4)",
"intent": "with ocean view",
"manifest": "with ocean view",
"parameterized": {
"parameterized_intent": "with ocean view",
"parameterized_sql_snippet": "((real_estate.properties.description_embedding <=> google_ml.embedding('gemini-embedding-001', 'unobstructed, panoramic, ocean vista, vast Pacific, breathtaking, commanding view, deep blue horizon, massive, sweeping view')::vector) < 0.4)"
}
مقدار ۰.۴ در تعریف وجهی بالا، آستانهای است که به صورت تجربی کالیبره شده است. فایل زمینه چندوجهی را دانلود کنید:
cloudshell download ~/codelabs/alloydb-ai-nla/sixrecipe_context2_2.json
sixrecipe_context2_2.json را در مجموعه context خود آپلود کنید و این اعلان را اجرا کنید (سوال 8):
Ocean view Del Mar homes near good schools.
خروجی شامل شرایط استاندارد همراه با تطبیق شباهت برداری از طریق google_ml.embedding است:
SELECT "p"."address_street", "p"."address_postal_code", "s"."school_name", "stp"."proximity_miles"
FROM "real_estate"."properties" AS "p"
JOIN "real_estate"."cities" AS "c" ON "p"."city_id" = "c"."city_id"
JOIN "real_estate"."school_to_property" AS "stp" ON "p"."property_id" = "stp"."property_id"
JOIN "real_estate"."schools" AS "s" ON "stp"."school_id" = "s"."school_id"
WHERE "c"."city_name" = 'Del Mar' AND "s"."school_ranking" <= 5 AND "stp"."proximity_miles" <= 2
AND (((p.description_embedding <=> google_ml.embedding('gemini-embedding-001', 'unobstructed, panoramic, ocean vista, vast Pacific, breathtaking, commanding view, deep blue horizon, massive, sweeping view')::vector) <= 0.4))
ORDER BY 0.8 * "s"."school_ranking" + 0.2 * "stp"."proximity_miles";
و این کوئری یک ویژگی را برمیگرداند:
Query Results address_street address_postal_code school_name proximity_miles 100 Del Mar Heights Rd 92014 Del Mar Heights Elementary 1.00 Answer The ocean-view home in Del Mar near a top-ranked school is located at 100 Del Mar Heights Rd (92014). It is situated just 1.00 mile away from Del Mar Heights Elementary, which is one of the area's highly-ranked schools (ranking of 5 or better).
با بررسی توضیحات مربوط به ویژگی در AlloyDB Studio و اجرای کوئری زیر، نتایج را تأیید کنید:
select description from real_estate.properties where address_postal_code='92014' and description is not null;
این توضیحات را با عنوان «منظره دریایی باشکوه» نشان خواهد داد.
Well-located 2-bedroom condo with excellent proximity to coastal shopping and dining. The balcony provides a magnificent marine spectacle against an azure backdrop. Under contract, high monthly HOA fee.
۱۰. ابهامزدایی از دادههای خصوصی شما با استفاده از جستجوهای مقداری
درخواستهای مبهم میتوانند با چندین موجودیت مطابقت داشته باشند، مانند اشتباه گرفتن نام یک مکان با نام یک کسب و کار. جستجوهای مقداری، اصطلاحات را به مفاهیم پایگاه داده نگاشت میکنند تا به حل این ارجاعات کمک کنند.
جستجوی مقدار، ارتباط بین نام ستون به علاوه مقادیر موجود در ستون و یک نوع مفهوم که میتواند برای مثال یک شهر، کشور یا نام باشد را فراهم میکند. و از آنجایی که نه تنها فراداده، بلکه نمونههای نمایندهای از دادهها را در یک ستون نیز فهرستبندی کرده است، میتواند مقداری را که در درخواست زبان طبیعی استفاده شده است با یک نوع مفهوم بالقوه و اینکه چه جدول و ستونی میتواند در SQL حاصل استفاده شود، مرتبط کند.
ابهام در یک پرسش
در زندگی واقعی، به دلیل غلط املایی نامها و مکانهای مختلف، این میتواند حتی دشوارتر باشد. این دستور (سوال ۹) را که حاوی یک غلط املایی و اصطلاح مبهم است، اجرا کنید:
Westwod's sold properties in the last 1 month.
اینجا دو مشکل وجود دارد - نام اشتباه نوشته شده و مشخص نیست که آیا ما در مورد املاک فروخته شده در آن مکان با نامهای مشابه صحبت میکنیم یا در مورد یک آژانس املاک. وقتی کوئری را اجرا میکنیم، کوئری مانند زیر را برمیگرداند.
SELECT "p"."property_id", "p"."address_street", "p"."address_postal_code", "p"."price" AS "listing_price", "p"."bedrooms", "p"."bathrooms", "p"."listing_status", "pt"."sale_date", "pt"."sale_price", "c"."city_name" FROM "real_estate"."properties" AS "p" INNER JOIN "real_estate"."property_transactions" AS "pt" ON "p"."property_id" = "pt"."property_id" INNER JOIN "real_estate"."cities" AS "c" ON "p"."city_id" = "c"."city_id" WHERE ("c"."city_name" ILIKE '%Westwood%' OR "c"."city_name" ILIKE '%Westwod%') AND "pt"."sale_date" >= '2025-09-01'::date AND "pt"."sale_date" <= '2025-09-30'::date ORDER BY "pt"."sale_date" DESC NULLS LAST, "pt"."sale_price" DESC NULLS LAST
نام را اصلاح کرده و فرض را بر این گذاشته که سوال مربوط به موقعیت مکانی ملک بوده و سعی در تطبیق آن با املاک واقع در شهر وستوود دارد.
برای پشتیبانی از مقایسههای رشتهای فازی، افزونهی pg_trgm را در AlloyDB Studio فعال کنید:
CREATE EXTENSION IF NOT EXISTS pg_trgm;
پس از آن میتوانیم از این افزونه برای اضافه کردن جستجوهای مقداری به مجموعه زمینه QueryData خود استفاده کنیم.
در اینجا لیستی از جستجوهای مقداری که میخواهیم استفاده کنیم، آمده است:
"value_searches": [
{
"conceptType": "Municipality name",
"query": "/* Requires extension: pg_trgm */ WITH TrigramMetrics AS (SELECT T.municipality_name AS original_value, (T.municipality_name % $value::text) AS normalized_dist FROM real_estate.municipalities T WHERE T.municipality_name % $value::text) SELECT original_value AS value, 'real_estate.municipalities.municipality_name' AS columns, 'Name of the municipality' AS concept_type, normalized_dist AS distance, ''::text AS context FROM TrigramMetrics",
"description": "Trigram match for municipality name"
},
{
"conceptType": "City name",
"query": "/* Requires extension: pg_trgm */ WITH TrigramMetrics AS (SELECT T.city_name AS original_value, (T.city_name % $value::text) AS normalized_dist FROM real_estate.cities T WHERE T.city_name % $value::text) SELECT original_value AS value, 'real_estate.cities.city_name' AS columns, 'Name of the city' AS concept_type, normalized_dist AS distance, ''::text AS context FROM TrigramMetrics",
"description": "Trigram match for city name"
},
{
"conceptType": "Brokerage name",
"query": "/* Requires extension: pg_trgm */ WITH TrigramMetrics AS (SELECT T.brokerage AS original_value, (T.brokerage % $value::text) AS normalized_dist FROM real_estate.agents T WHERE T.brokerage % $value::text) SELECT original_value AS value, 'real_estate.agents.brokerage' AS columns, 'Name of the brokerage' AS concept_type, normalized_dist AS distance, ''::text AS context FROM TrigramMetrics",
"description": "Trigram match for brokerage name"
}
]
فایل زمینه جستجوی مقدار را دانلود کنید:
cloudshell download ~/codelabs/alloydb-ai-nla/sixrecipe_context3_1.json
فایل sixrecipe_context3_1.json را در مجموعه زمینه QueryData sixrecipes آپلود کرده و آن را ذخیره کنید.
دستور را دوباره اجرا کنید (سوال 9):
Westwod's sold properties in the last 1 month.
این تابع یک پاسخ شفافسازی برگرداند زیرا در جستجوی مقدار، ۳ موجودیت مختلف با مقادیر مشابه پیدا کرد:
The database requires some clarification to provide the exact information you need: The search term 'Westwod' (Westwood) is ambiguous because it can refer to: A municipality name (e.g., the municipality of Westwood) A city name (e.g., the city of Westwood) A brokerage name (e.g., properties sold by agents affiliated with the Westwood brokerage) Could you please clarify which of these you are referring to?
این ردپا به ما سرنخی میدهد که چرا آن مسیر خاص را انتخاب کرده است.

متن کامل اینجاست:
"[NOT_ENOUGH_INFO] The search term 'Westwod' is ambiguous because it can refer to a municipality name, a city name, or a brokerage name. Could you please clarify if you are referring to properties sold within the municipality of Westwood, the city of Westwood, or properties sold by agents affiliated with the Westwood brokerage?"
رفع ابهام از پرسش
اصلاح اعلان ورودی (Q10):
Westwood city location properties sold in September 2025.
و حالا ما کوئری و نتایج را داریم:
Generated SQL SELECT "p"."property_id", "p"."address_street", "p"."address_postal_code", "p"."price", "pt"."sale_date", "pt"."sale_price" FROM "real_estate"."properties" AS "p" INNER JOIN "real_estate"."cities" AS "c" ON "p"."city_id" = "c"."city_id" INNER JOIN "real_estate"."property_transactions" AS "pt" ON "p"."property_id" = "pt"."property_id" WHERE "c"."city_name" = 'Westwood' AND "pt"."sale_date" >= '2025-09-01'::date AND "pt"."sale_date" <= '2025-09-30'::date ORDER BY "pt"."sale_date" ASC NULLS LAST Query Results property_id address_street address_postal_code price sale_date sale_price 32 999 Main St 99999 3800000.00 2025-09-12 1000000.00
۱۱. جستجوی معنایی و توابع هوش مصنوعی
توابع هوش مصنوعی AlloyDB امکان فیلتر معنایی روی دادههای بدون ساختار را فراهم میکنند. از توابعی مانند ai.if و google_ml.embedding مستقیماً در کوئریهای SQL در کنار عملگرهای استاندارد پایگاه داده استفاده کنید.
الگو با عملگرهای ILIKE
به عنوان اولین قدم، فایل زمینه جدید را با عملگرهای ILIKE آپلود کنید.
فایل زمینه قالب ILIKE را دانلود کنید:
cloudshell download ~/codelabs/alloydb-ai-nla/sixrecipe_context4_1.json
فایل sixrecipe_context4_1.json را در مجموعه دادههای خود آپلود کنید تا تطبیق الگوی استاندارد ILIKE برای خانههای «آماده سکونت» ارزیابی شود.
{
"nl_query": "Move-in ready houses",
"sql": "SELECT \"p\".\"address_street\", \"p\".\"address_postal_code\" FROM \"real_estate\".\"properties\" AS \"p\" WHERE \"p\".listing_status = 'Active' AND \"p\".\"description\" IS NOT NULL AND (\"p\".description ILIKE '%turnkey%' OR \"p\".description ILIKE '%move-in%')",
"intent": "Move-in ready houses",
"manifest": "Move-in ready houses",
"parameterized": {
"parameterized_intent": "Move-in ready houses",
"parameterized_sql": "SELECT \"p\".\"address_street\", \"p\".\"address_postal_code\" FROM \"real_estate\".\"properties\" AS \"p\" WHERE \"p\".listing_status = 'Active' AND \"p\".\"description\" IS NOT NULL AND (\"p\".description ILIKE '%turnkey%' OR \"p\".description ILIKE '%move-in%')"
}
}
ارسال این درخواست (سوال 11):
List move-in ready houses.
نتیجه استعلام:
SELECT "p"."address_street", "p"."address_postal_code"
FROM "real_estate"."properties" AS "p"
WHERE "p".listing_status = 'Active'
AND "p"."description" IS NOT NULL
AND ("p".description ILIKE '%turnkey%' OR "p".description ILIKE '%move-in%')
یک رکورد منطبق را برمیگرداند.
Query Results address_street address_postal_code 40 Main St, Unit 8 N2H 2G8
قالب با تابع AI.IF
فایل زمینه قالب AI.IF را دانلود کنید:
cloudshell download ~/codelabs/alloydb-ai-nla/sixrecipe_context4_2.json
فایل sixrecipe_context4_2.json را برای ارزیابی تابع فیلتر معنایی ai.if در مجموعه متن خود آپلود کنید.
{
"nl_query": "List Move-in ready houses",
"sql": "SELECT \"p\".\"address_street\", \"p\".\"address_postal_code\" FROM \"real_estate\".\"properties\" AS \"p\" WHERE \"p\".listing_status = 'Active' AND \"p\".\"description\" IS NOT NULL AND ai.if('Does this description represent a move-in ready house? Description: ' || \"p\".\"description\")",
"intent": "List Move-in ready houses",
"manifest": "List Move-in ready houses",
"parameterized": {
"parameterized_intent": "List Move-in ready houses",
"parameterized_sql": "SELECT \"p\".\"address_street\", \"p\".\"address_postal_code\" FROM \"real_estate\".\"properties\" AS \"p\" WHERE \"p\".listing_status = 'Active' AND \"p\".\"description\" IS NOT NULL AND ai.if('Does this description represent a move-in ready house? Description: ' || \"p\".\"description\")"
}
}
سوال (12) را تکرار کنید:
List move-in ready houses.
SQL تولید شده:
SELECT "p"."address_street", "p"."address_postal_code"
FROM "real_estate"."properties" AS "p"
WHERE "p".listing_status = 'Active'
AND "p"."description" IS NOT NULL
AND ai.if('Does this description represent a move-in ready house? Description: ' || "p"."description")
این به ما همان ویژگی را در نتیجه میدهد:
Query Results Address Street Address Postal Code 40 Main St, Unit 8 N2H 2G8 Natural Language Answer The move-in ready home currently available is located at: Address: 40 Main St, Unit 8 Postal Code: N2H 2G8
وجه با جستجوی برداری
فایل زمینه جستجوی جاسازی را دانلود کنید:
cloudshell download ~/codelabs/alloydb-ai-nla/sixrecipe_context4_3.json
فایل sixrecipe_context4_3.json را در مجموعه متن خود آپلود کنید تا جستجوی برداری معنایی با استفاده از google_ml.embedding ارزیابی شود و خانههایی با لوازم آشپزخانه جدید را جستجو کند.
مجموعه زمینه را با استفاده از فایل sixrecipe_context4_3.json با یک وجه اضافی با استفاده از جستجوی برداری AlloyDB بهروزرسانی کنید.
{
"sql_snippet": "((real_estate.properties.description_embedding <=> google_ml.embedding('gemini-embedding-001', 'Upgraded kitchen appliances')::vector) < 0.4)",
"intent": "with upgraded kitchen appliances",
"manifest": "with upgraded kitchen appliances",
"parameterized": {
"parameterized_intent": "with upgraded kitchen appliances",
"parameterized_sql_snippet": "((real_estate.properties.description_embedding <=> google_ml.embedding('gemini-embedding-001', 'Upgraded kitchen appliances')::vector) < 0.4)"
}
}
مقدار ۰.۴ در تعریف وجه بالا، آستانهای است که به صورت تجربی کالیبره شده است.
این کوئری را اجرا کنید (سوال ۱۳):
List move-in ready houses with upgraded kitchen appliances.
SQL تولید شده:
SELECT "p"."address_street", "p"."address_postal_code" FROM "real_estate"."properties" AS "p" WHERE "p"."listing_status" = 'Active' AND "p"."description" IS NOT NULL AND ai.if('Does this description represent a Move-in ready house? Description: ' || "p"."description") AND ((("p"."description_embedding" <=> google_ml.embedding('gemini-embedding-001', 'Upgraded kitchen appliances')::vector) < 0.4))
در اینجا نتایج جستجو و توصیه زبان طبیعی آمده است:
Query Results Address Postal Code 40 Main St, Unit 8 N2H 2G8 Natural Language Answer The move-in ready house with upgraded kitchen appliances is located at: Address: 40 Main St, Unit 8 Postal Code: N2H 2G8
۱۲. امنیت و حریم خصوصی
هر زمان که رابط برنامهنویسی QueryData کوئریهایی تولید میکند، یک ریسک امنیتی وجود دارد که کوئریهای تولید شده میتوانند دادههای متعلق به سایر کاربران را افشا کنند. نماهای امن پارامتری (PSV) در طول تولید NL2SQL، مرزهای امنیتی سطح ردیف را اعمال میکنند.
ایجاد نمای امن پارامتری
ما یک جدول real_estate.offers داریم که شامل اطلاعاتی در مورد پیشنهادات برای همه معاملات املاک و مستغلات ما است. ما میخواهیم نمایندگان ما فقط معاملات خود را ببینند اما معاملات سایر نمایندگان را نبینند. ما یک PSV با قابلیت فیلتر کردن ردیفها بر اساس agent_id ایجاد میکنیم.
یک نمای امن پارامتری برای جدول پیشنهادات در AlloyDB Studio ایجاد کنید:
CREATE VIEW real_estate.secure_offers
WITH (security_barrier) AS
SELECT offer_id, property_id, buyer_agent_id,
seller_agent_id, offer_amount, offer_date,
offer_status, offer_expiration_date,
contingencies
FROM real_estate.offers
WHERE buyer_agent_id = $@agent_id;
تعریف نمای امنیتی پارامتری را تأیید کنید:
SELECT definition
FROM parameterized_views.all_parameterized_views
WHERE schemaname = 'real_estate' AND viewname = 'secure_offers';
در مورد جدول real_estate.offers چطور؟
محدود کردن دسترسی به دادههای QueryData با استفاده از نماهای امن پارامتری AlloyDB
در فایل agent.py، نمای امنیتی پارامتری real_estate.secure_offers به جای real_estate.offers در TABLE_IDS ثبت شده است:
کد منبع agent.py:
List of database tables included in QueryData API requests
TABLE_IDS = [
"real_estate.municipalities",
"real_estate.cities",
"real_estate.agents",
"real_estate.properties",
"real_estate.schools",
"real_estate.school_to_property",
"real_estate.property_transactions",
"real_estate.secure_offers",
]
و زمینه زمان اجرای جلسه را برای عاملی با agent_id=1 ارسال میکند:
"parameterized_secure_view_parameters": {
"parameters": {
"key": "agent_id",
"value": "1"
}
}
},
در نتیجه، هر درخواست QueryData API آن پارامتر را ارسال میکند و هنگامی که نمای امن در درخواست گنجانده شود، فیلتری اعمال میشود که فقط نتایج مربوط به آن عامل خاص را برمیگرداند.
این کوئری را اجرا کنید (سوال ۱۴):
List the offer id and listing price in 2025 where the offer was within 5% of the final selling price.
SQL تولید شده:
SELECT "o"."offer_id", "p"."price" AS "listing_price"
FROM "real_estate"."secure_offers" AS "o"
INNER JOIN "real_estate"."properties" AS "p" ON "o"."property_id" = "p"."property_id"
INNER JOIN "real_estate"."property_transactions" AS "t" ON "o"."property_id" = "t"."property_id"
WHERE "o"."offer_date" >= '2025-01-01'
AND "o"."offer_date" <= '2025-12-31'
AND "o"."offer_amount" IS NOT NULL
AND "t"."sale_price" IS NOT NULL
AND "p"."price" IS NOT NULL
AND ABS("o"."offer_amount" - "t"."sale_price") <= (0.05 * "t"."sale_price")
ORDER BY "o"."offer_id" ASC NULLS LAST
پرسوجو در نمای (view) نتایج را بر اساس پارامتر جلسه عامل فعال فیلتر میکند، از دادههای رکورد غیرمجاز محافظت میکند و فقط دو رکورد را برمیگرداند.
Query Results Offer ID Listing Price 7 $750,000.00 8 $510,000.00 Natural Language Answer Here are the offers from 2025 where the offer amount was within 5% of the final selling price: Offer ID 7: Listing Price of $750,000.00 Offer ID 8: Listing Price of $510,000.00
اگر کوئری زیر را روی جدول پایه real_estate.offers در AlloyDB Studio اجرا کنید:
SELECT "o"."offer_id", "p"."price" AS "listing_price"
FROM "real_estate"."offers" AS "o"
INNER JOIN "real_estate"."properties" AS "p" ON "o"."property_id" = "p"."property_id"
INNER JOIN "real_estate"."property_transactions" AS "t" ON "o"."property_id" = "t"."property_id"
WHERE "o"."offer_date" >= '2025-01-01'
AND "o"."offer_date" <= '2025-12-31'
AND "o"."offer_amount" IS NOT NULL
AND "t"."sale_price" IS NOT NULL
AND "p"."price" IS NOT NULL
AND ABS("o"."offer_amount" - "t"."sale_price") <= (0.05 * "t"."sale_price")
ORDER BY "o"."offer_id" ASC NULLS LAST
این تابع بیش از دو رکورد را برمیگرداند که دادههای مربوط به همه عاملها را نشان میدهد.
این پایان آزمایش ماست! شما یاد گرفتید که چگونه از API کوئریدیتا، توابع هوش مصنوعی و نماهای امن پارامتری AlloyDB استفاده کنید.
۱۳. محیط را تمیز کنید
وقتی کار آزمایشگاهیتان تمام شد، نمونهها و کلاستر AlloyDB را از بین ببرید.
کلاستر AlloyDB و تمام نمونههای آن را حذف کنید.
خوشه با استفاده از گزینهی force از بین میرود که تمام نمونههای متعلق به خوشه را نیز حذف میکند.
اگر ترمینال شما قطع شد، دوباره متصل شوید و متغیرهای پروژه و محیط را در Cloud Shell تعریف کنید:
gcloud config set project <YOUR_PROJECT_ID>
export REGION=us-central1
export ADBCLUSTER=alloydb-aip-01
export PROJECT_ID=$(gcloud config get-value project)
حذف خوشه:
gcloud alloydb clusters delete $ADBCLUSTER --region=$REGION --force
خروجی مورد انتظار کنسول:
student@cloudshell:~ (test-project-001-402417)$ gcloud alloydb clusters delete $ADBCLUSTER --region=$REGION --force All of the cluster data will be lost when the cluster is deleted. Do you want to continue (Y/n)? Y Operation ID: operation-1697820178429-6082890a0b570-4a72f7e4-4c5df36f Deleting cluster...done.
حذف پشتیبانهای AlloyDB
تمام پشتیبانهای AlloyDB را برای کلاستر حذف کنید:
for i in $(gcloud alloydb backups list \
--filter="CLUSTER_NAME: projects/$PROJECT_ID/locations/$REGION/clusters/$ADBCLUSTER" \
--format="value(name)" \
--sort-by=~createTime) ; do \
gcloud alloydb backups delete $(basename $i) --region $REGION --quiet; done
خروجی مورد انتظار کنسول:
student@cloudshell:~ (test-project-001-402417)$ for i in $(gcloud alloydb backups list --filter="CLUSTER_NAME: projects/$PROJECT_ID/locations/$REGION/clusters/$ADBCLUSTER" --format="value(name)" --sort-by=~createTime) ; do gcloud alloydb backups delete $(basename $i) --region $REGION --quiet; done Operation ID: operation-1697826266108-60829fb7b5258-7f99dc0b-99f3c35f Deleting backup...done.
حذف سطل ذخیرهسازی ابری
برای جلوگیری از هزینههای مداوم ذخیرهسازی، سطل واردات Cloud Storage را حذف کنید:
gcloud storage rm -r gs://${PROJECT_ID}-import
۱۴. تبریک
تبریک میگویم که آزمایشگاه کد را تمام کردید!
آنچه ما پوشش دادهایم
- نحوه استقرار یک کلاستر AlloyDB و نمونه اولیه آن
- نحوه فعال کردن QueryData، توابع هوش مصنوعی و نمایشهای امن پارامتری برای AlloyDB
- نحوه ایجاد یک مجموعه زمینه QueryData
- نحوه استفاده از قالبها و زمینههای مختلف در API کوئریدیتا
- چگونه میتوان با استفاده از facetها، قالبهای QueryData را انعطافپذیرتر کرد؟
- چگونه ابهام دادهها را با جستجوی مقدار و نمایهسازی سهخطی حل کنیم؟
- نحوه استفاده از توابع هوش مصنوعی برای جستجوی معنایی با قالبها
- نحوه استفاده از نماهای امن پارامتری با API QueryData
نظرسنجی
خروجی: