1. Giriş
Bu codelab'de QueryData API'yi kullanarak en iyi sonuçları nasıl alacağınızı öğreneceksiniz. Veritabanınıza doğal dil istekleri gönderirken doğru ve tekrarlanabilir sonuçlar elde etmeyi öğrenirsiniz. Bu hedefe ulaşmanıza yardımcı olmak için rehberde, doğal dilden SQL'e (NL2SQL) dönüştürmenin farklı yönlerini ve pratik uygulamalarını ele alan altı tarif, çeşitli bölümler halinde açıklanıyor.
Ön koşullar
- Google Cloud ve Google Cloud Console hakkında temel bilgiler
- Komut satırı arayüzü ve Cloud Shell ile ilgili temel beceriler
Neler öğreneceksiniz?
- AlloyDB kümesi ve birincil örnek dağıtma
- QueryData, yapay zeka işlevleri ve parametreli güvenli görünümler nasıl etkinleştirilir?
- QueryData bağlam kümesi oluşturma
- QueryData API'de farklı şablonları ve bağlamları kullanma
- Fasetleri kullanarak QueryData şablonlarını daha esnek hale getirme
- Değer araması ve üçlü gram dizine ekleme ile veri belirsizliğini çözme
- Şablonlarla semantik arama için yapay zeka işlevlerini kullanma
- QueryData API ile parametre haline getirilmiş güvenli görünümler nasıl kullanılır?
İhtiyacınız olanlar
- Google Cloud hesabı ve Google Cloud projesi
- Google Cloud Console ve Cloud Shell'i destekleyen Chrome gibi bir web tarayıcısı
2. Kurulum ve Gereksinimler
Proje Ayarları
- Google Cloud Console'da oturum açın. Gmail veya Google Workspace hesabınız yoksa hesap oluşturmanız gerekir.
İş veya okul hesabı yerine kişisel hesap kullanıyorsanız.
- Yeni bir proje oluşturun veya mevcut bir projeyi yeniden kullanın. Google Cloud Console'da yeni bir proje oluşturmak için başlıkta bir pop-up pencere açacak olan Proje seç düğmesini tıklayın.

Proje seçin penceresinde Yeni Proje'yi tıklayın. Yeni proje için bir iletişim kutusu açılır.

İletişim kutusunda bir proje adı girin ve konumu seçin.

- Proje adı, bu projenin katılımcıları için görünen addır. Proje adı, Google API'leri tarafından kullanılmaz ve istediğiniz zaman değiştirilebilir.
- Proje kimliği, tüm Google Cloud projelerinde benzersizdir ve sabittir (ayarlandıktan sonra değiştirilemez). Google Cloud Console, otomatik olarak benzersiz bir kimlik oluşturur ancak bu kimliği özelleştirebilirsiniz. Oluşturulan kimliği beğenmediyseniz başka bir rastgele kimlik oluşturabilir veya kendi kimliğinizi girerek kullanılabilirliğini kontrol edebilirsiniz. Çoğu codelab'de, genellikle PROJECT_ID yer tutucusuyla tanımlanan proje kimliğinize başvurmanız gerekir.
- Bazı API'lerin kullandığı üçüncü bir değer olan Proje Numarası da vardır. Bu üç değer hakkında daha fazla bilgiyi belgelerde bulabilirsiniz.
Faturalandırmayı Etkinleştir
Kişisel faturalandırma hesabı oluşturma
Faturalandırmayı Google Cloud kredilerini kullanarak ayarladıysanız bu adımı atlayabilirsiniz.
Kişisel faturalandırma hesabı oluşturmak için Cloud Console'da faturalandırmayı etkinleştirmek üzere buraya gidin.
Bazı notlar:
- Bu laboratuvarı tamamlamak için 5 ABD dolarından daha az tutarda bulut kaynağı kullanmanız gerekir.
- Daha fazla ücret alınmaması için bu laboratuvarın sonundaki adımları uygulayarak kaynakları silebilirsiniz.
- Yeni kullanıcılar 300 ABD doları değerinde ücretsiz deneme sürümünden yararlanabilir.
Cloud Shell'i Başlatma
Google Cloud, dizüstü bilgisayarınızdan uzaktan çalıştırılabilir ancak bu codelab'de Cloud'da çalışan bir komut satırı ortamı olan Google Cloud Shell'i kullanacaksınız.
Google Cloud Console'da sağ üstteki araç çubuğunda Cloud Shell simgesini tıklayın:

Alternatif olarak G ve ardından S tuşuna basabilirsiniz. Bu sıra, Google Cloud Console'da bulunuyorsanız veya bu bağlantıyı kullanıyorsanız Cloud Shell'i etkinleştirir.
Ortamın temel hazırlığı ve bağlantı kurulması yalnızca birkaç dakikanızı alır. İşlem tamamlandığında aşağıdakine benzer bir sonuç görürsünüz:

Bu sanal makine, ihtiyaç duyacağınız tüm geliştirme araçlarıyla birlikte gelir. 5 GB boyutunda kalıcı bir ana dizin sunar ve Google Cloud üzerinde çalışır. Bu sayede ağ performansı ve kimlik doğrulama önemli ölçüde güçlenir. Bu codelab'deki tüm çalışmalarınızı tarayıcıda yapabilirsiniz. Herhangi bir şey yüklemeniz gerekmez.
3. Başlamadan önce
API'yi Etkinleştir
AlloyDB, Compute Engine, ağ hizmetleri ve Agent Platform'u kullanmak için Google Cloud projenizde ilgili API'leri etkinleştirin.
Cloud Shell terminalinde proje kimliğinizin ayarlandığından emin olun:
gcloud config get-value project
Komut, Google Cloud proje kimliğinizi döndürmelidir.
PROJECT_ID ortam değişkenini ayarlayın:
PROJECT_ID=$(gcloud config get-value project)
Gerekli API'leri etkinleştirin:
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
Beklenen çıktı:
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.
Etkinleştirilen her API hakkında bilgiyi dokümanlarda bulabilirsiniz.
4. AlloyDB'yi dağıtma
AlloyDB kümesi ve birincil örnek oluşturun. Gerekli tüm kaynakları dağıtacak şekilde hazırlanmış bir komut dosyası kullanarak dağıtabilir veya AlloyDB dokümanlarını inceleyerek adım adım kendiniz yapabilirsiniz.
Otomatik komut dosyası kullanarak AlloyDB'yi dağıtma
Bu yaklaşımda, AlloyDB kümesini dağıtmak için otomatik bir komut dosyası kullanılır ve dağıtılan kaynaklarla çalışmaya başlamak için gerekli yapılandırma ayrıntıları sağlanır.
Cloud Shell terminalinde, dağıtım komut dosyasını depodan klonlamak için komutu çalıştırın:
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
Dağıtım komut dosyasını çalıştırın:
./deploy_alloydb.sh
Komut dosyasının tamamlanması beş ila yedi dakika sürer. Çıkışta küme dağıtım ayrıntılarınız gösterilir. Şifrenizin farklı olacağını lütfen unutmayın. Şifreyi ileride kullanmak üzere kaydedin.
... <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) ----------------------------------------
Google Cloud Console'daki AlloyDB kümeleri sayfasında yeni kümenizi ve örneğinizi görüntüleyin.

5. Veritabanını Hazırlama
Veritabanı oluşturma, Gemini Enterprise Agent Platform entegrasyonunu etkinleştirme, veritabanı nesneleri oluşturma ve örnek veriler ekleme.
AlloyDB'ye Gerekli İzinleri Verme
AlloyDB hizmet aracısına gerekli IAM rollerini verin:
Ekle (+) seçeneğini tıklayarak yeni bir Cloud Shell sekmesi açın.

Yeni sekmede şu komutu çalıştırın:
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"
Beklenen konsol çıkışı:
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
Data Access API'yi etkinleştirme
AlloyDB kümenizde Data Access API'yi etkinleştirin.
Aynı terminal sekmesinde aşağıdaki komutu çalıştırın:
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",
}'
Veritabanı İşaretlerini Güncelleme
Örnek düzeyinde işaretleri etkinleştirmeden önce Veri Erişim API'si adımının tamamlanmasını bekleyin. Aşağıdaki resimde gösterildiği gibi, örneğinizin durumunda yeşil bir onay işareti göründüğünden emin olun.

Yapay zeka uzantılarını ve IAM kimlik doğrulamasını kullanmak için örnekte belirli veritabanı işaretlerini etkinleştirmeniz ve kendinizi veritabanı kullanıcısı olarak eklemeniz gerekir. Aşağıdaki işaretleri etkinleştirin:
- alloydb.iam_authentication
- password.enforce_complexity
- google_ml_integration.enable_ai_query_engine
- parameterized_views
Aynı terminal sekmesinde aşağıdaki komutları çalıştırın:
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
Hesabınız için bir AlloyDB IAM kullanıcısı oluşturun:
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
Terminalde exit komutunu çalıştırarak sekmeyi kapatın:
exit
AlloyDB Studio'ya bağlanma
Aşağıdaki bölümlerde, AlloyDB Studio'da veritabanı bağlantısı gerektiren tüm SQL komutlarını çalıştırabilirsiniz.
AlloyDB Studio'yu açmak için aşağıdaki adımları uygulayın:
- Google Cloud Console'da PostgreSQL için AlloyDB'nin Kümeler sayfasına gidin.
- Web arayüzünü açmak için birincil örneğinizi seçin.

- Ardından sol tarafta AlloyDB Studio'yu tıklayın:

postgresveritabanını seçin, IAM kimlik doğrulamasını tercih edin ve Kimlik Doğrula'yı tıklayın.

Bu işlem, AlloyDB Studio arayüzünü açar.
- SQL düzenleyiciyi açmak için Untitled Query (Adsız Sorgu) sekmesini seçin.

Bu işlemle, aşağıdaki resimde gösterildiği gibi SQL komutlarını çalıştırabileceğiniz bir düzenleyici açılır:

Veritabanı Oluşturma
Hızlı başlangıç veritabanını oluşturma
Veritabanını oluşturmak için AlloyDB Studio düzenleyicisinde aşağıdaki komutu çalıştırın:
CREATE DATABASE quickstart_db
Beklenen çıktı:
Statement executed successfully
quickstart_db'ye bağlanma
AlloyDB Studio'da Veritabanını/kullanıcıyı değiştir'i tıklayın.

Veritabanı listesinden quickstart_db'yi seçin, IAM kimlik doğrulamasını seçin ve kimliğinizi doğrulayın.

quickstart_db veritabanındaki nesnelerle çalışabileceğiniz yeni bir bağlantı açılır.
Uzantıları etkinleştirme
Veritabanınızda etkinleştirildiklerini ve doğru minimum sürümlere sahip olduklarını doğrulamak için gerekli tüm uzantıları kontrol edin.
Gerekli tüm uzantıların veritabanınızda bulunduğunu doğrulayın:
SELECT extname, extversion FROM pg_extension WHERE extname IN ('vector', 'google_ml_integration', 'parameterized_views');
Beklenen çıktı:
extname | extversion -----------------------+---------------- google_ml_integration | 1.5.9 parameterized_views | 1.0 vector | 0.8.2.google-1
Yukarıdaki satırların tümü döndürülmüyorsa uzantıların bazıları etkinleştirilmemiştir.
Uzantıları etkinleştirmeden önce, örnekte tüm veritabanı işaretlerinin ,"google_ml_integration.enable_ai_query_engine" ve "parameterized_views.enabled" etkinleştirildiğinden emin olmamız gerekir.
AlloyDB Studio'da quickstart_db'ye bağlıyken şunu çalıştırın:
show google_ml_integration.enable_ai_query_engine;
show parameterized_views.enabled;
Bunlardan herhangi biri "kapalı" olarak gösteriliyorsa "Veritabanı İşaretlerini Güncelle" adımını tekrarlamayı deneyin ve durumu tekrar "show..." komutlarını kullanarak kontrol edin.
Gerekli uzantıları etkinleştirin.
AlloyDB Studio'da quickstart_db'ye bağlıyken şunu çalıştırın:
CREATE EXTENSION IF NOT EXISTS vector;
CREATE EXTENSION IF NOT EXISTS parameterized_views;
parameterized_views ve google_ml uzantılarının sürümlerini kontrol edin.
AlloyDB Studio'da quickstart_db'ye bağlıyken şunu çalıştırın:
SELECT extname, extversion FROM pg_extension WHERE extname IN ('vector', 'google_ml_integration', 'parameterized_views');
Beklenen çıktı:
extname | extversion -----------------------+---------------- google_ml_integration | 1.5.9 parameterized_views | 1.0 vector | 0.8.2.google-1
Sürüm gerekenden düşükse parameterized_views uzantısını güncellemeyi deneyin.
parameterized_views için şunu deneyin:
ALTER EXTENSION parameterized_views UPDATE;
Sürümü tekrar doğrulayın.
AlloyDB Studio'da quickstart_db'ye bağlıyken şunu çalıştırın:
SELECT extname, extversion FROM pg_extension WHERE extname IN ('vector', 'google_ml_integration', 'parameterized_views');
Beklenen çıktı:
extname | extversion -----------------------+---------------- google_ml_integration | 1.5.9 parameterized_views | 1.0 vector | 0.8.2.google-1
6. Örnek Veriler
Şimdi veritabanında nesneler oluşturmanız ve verileri yüklemeniz gerekiyor. Kurgusal bir emlak şirketi veri kümesi kullanacaksınız. Mülk satışları ve acenteler hakkında kurgusal veriler içerir. Veriler, klonlanmış depodaki SQL komut dosyasında real_estate_data.sql sağlanmıştır.
Depolama paketi oluşturma
Klonlanmış deponuzdaki verileri AlloyDB veritabanına aktarmak için Google SDK'sını (gcloud) kullanın. Bunun için bir Cloud Storage paketi oluşturmanız ve AlloyDB hizmet hesabına erişim izni vermeniz gerekir. Alternatif olarak, dokümanlarda açıklandığı gibi web konsolunu kullanarak da yapmayı deneyebilirsiniz.
Google Cloud Shell terminalinde şunu çalıştırın:
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
Verileri Yükle
Veritabanı SQL dökümü, klonlanmış depo klasöründe bulunur. Aşağıdaki komutta, AlloyDB kümesini oluştururken önceki adımda depoyu klonladığınızda başlangıç noktası olarak ana dizininizi kullandığınız varsayılır.
Veritabanı dökümü dosyasını Cloud Storage paketinize kopyalayın:
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
Veri kümesini quickstart_db'ye aktarın:
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
Komut, örnek veri kümesini quickstart_db veritabanına yükler.
AlloyDB Studio'yu kullanarak real_estate.agents tablosundaki kayıtları sayarak içe aktarma işlemini doğrulayın:
SELECT COUNT(*) FROM real_estate.agents;
7. Şema Ontolojisini Hazırlama
QueryData bağlam kümenizi ayarlayın, şema meta verilerini sağlayın ve ADK aracısını çalıştırın.
Meta Veri Oluşturma
Meta veriler, veritabanı tablolarına ve sütunlarına uygulanan SQL yorumlarından oluşur. Bu yorumlar, veritabanı nesneleri seçilirken QueryData motoruna yol gösterir.
Veri şemanızı sağlanan SQL dökümünü kullanarak içe aktardıysanız tüm meta veriler şemanızda zaten oluşturulmuştur.
real_estate şemasına uygulanan meta verilerin örnek snippet'ini aşağıda bulabilirsiniz:
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.'; ...
Kendi veri kümenizle çalışıyorsanız şemanızın meta verilerini ekleme hakkında belgelenmiş kılavuzu inceleyebilirsiniz.
Şema Ontolojisi Bağlamı Oluşturma
Bağlam kümesi, yapay zeka modelinin sorgu oluşturmasına yardımcı olan sorgu şablonları, yönler ve değer aramaları içerir. Bağlam ayarlanmadığında yapay zeka ajanı, öncelikle tablo adlarına, sütunlara ve meta verilere dayalı olarak public şemasındaki yalnızca mevcut bilgileri kullanarak bir sorgu oluşturmaya çalışır. Doğal bir sorgu isteğini yanıtlamak için doğru nesneleri tahmin etmeye çalışır.
QueryData bağlam kümesi, sorgu şablonları, yönler ve değer aramaları içeren bir JSON dosyasıdır. Belgelerdeki farklı örneklere göz atabilirsiniz.
Web Console'da QueryData Context Set'i yükleme
Bağlam kümesi yüklemek için AlloyDB Studio'yu açın. Sol panelin en altında Context sets ve üç nokta görürsünüz.

Üç noktayı tıklayıp Create context set simgesini seçin.
Açılan iletişim kutusuna aşağıdaki değerleri girin:
- Ad:
sixrecipes - Açıklama:
Real Estate Query Data - Bağlam dosyası yükleme: Boş bırakın
Create düğmesine bastığınızda, bağlam depolama alanının ilk kez başlatılması biraz zaman alabilir.
Bağlam kümesi adının sağındaki üç noktayı tekrar tıklayıp Edit context set seçeneğini belirleyerek QueryData bağlam kümesi kimliğini kontrol edin.

Bağlam grubu kimliği, sağ tarafta açılan sekmenin üst kısmında görünür.

Bu kimliği sonraki adımlarda kullanmak üzere kaydedin.
Yapay Zeka Aracını Başlatma
Sorgu oluşturmak ve yürütmek için QueryData arka ucuyla etkileşim kurmak üzere belgelerde açıklandığı şekilde AlloyDB Studio arayüzünü kullanabilirsiniz. Ancak bu laboratuvarda, veritabanıyla iletişim kurmak için ana araç olarak bir yapay zeka aracısı kullanacaksınız. Yapay zeka aracıları, gelecekteki iş yükleri için daha gerçekçi bir senaryodur ve Google ADK çerçevesi, modeller, API'ler ve uygulamalar arasındaki tüm adımları ve etkileşimleri görebileceğiniz harika bir web arayüzü sunar.
Cloud Shell'de aracı kaynak yapılandırmasını inceleyin:
REPO_NAME="codelabs"
SOURCE_DIR="alloydb-ai-nla"
cd ~/$REPO_NAME/$SOURCE_DIR/data_agent
edit agent.py
Dosyada, şemamızdaki tablo listesini nerede tanımladığımızı görebilirsiniz. Bu konuya sonraki adımlardan birinde tekrar değineceğiz.
# 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",
]
Ayrıca, QueryData API ile çalışmak için bir prosedür call_querydata_api ve QueryData API becerileriyle çalışmak için bir araç seti vardır.
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]
)
İstem ve kullanılabilir araçlarla birlikte kök aracı aşağıda verilmiştir.
# 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],
)
Temsilcinin sistem talimatlarını anlamak için data_agent/SKILL.md dosyasını inceleyin:
REPO_NAME="codelabs"
SOURCE_DIR="alloydb-ai-nla"
cd ~/$REPO_NAME/$SOURCE_DIR/data_agent
edit SKILL.md
Ajanı başlatmadan önce, Ajan ve QueryData API istekleri için parametrelerin bulunduğu bir .env dosyası hazırlamanız gerekir.
Bağlam kümesi kimliğinizi bir ortam değişkenine aktarın:
export QUERYDATA_CONTEXTSET=<context set id from the Create Context Set chapter>
data_agent dizininde çalışma zamanı ortamı yapılandırma dosyanızı (.env) oluşturun:
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
Bağımlılıkları yükleyin ve aracı web hizmetini başlatın:
cd ~/$REPO_NAME/$SOURCE_DIR/
uv sync
Aracıyı başlatın:
uv run adk web --allow_origins 'regex:https://.*\.cloudshell\.dev'
http://127.0.0.1:8000 uç noktasıyla aşağıdaki gibi bir çıkış görürsünüz .
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)

Aracı arayüzünü başlatmak için Cloud Shell'de oluşturulan web sunucusu URL'sini (ör. http://127.0.0.1:8000) tıklayın. Çalışmazsa aracı arayüzünü açmak için Cloud Shell'de Web Önizlemesi -> 8000 bağlantı noktasında önizle'yi tıklayın.
Sol üstteki açılır listede data_agent simgesinin seçili olduğunu doğrulayın.

Sorgu oluşturma ve çalıştırma
Q1 sorgusunu çalıştırmamıza izin verin.
Temel QueryData performansını özel şablonlar veya yönler olmadan değerlendirmek için bu doğal dil istemini aracı sohbet arayüzünde çalıştırın:
How many properties are currently for sale in San Diego?
Ok düğmesine basın.

Uygun beceriyi seçip bu beceriyi ve işlevi kullanarak isteği API uç noktasına göndermek, oluşturulan sorguyu ve sonuçları geri almak için aracı iş akışını başlatır.

Fare imlecinizi adımların üzerine getirerek bu adımların tam olarak ne yaptığını görebilirsiniz. Ayrıca, bir adımı seçtiğinizde sol panelde bu ve daha birçok bilgiyi görebilirsiniz. Temsilcilerin beceriler ve API'lerle nasıl çalıştığını anlamanıza yardımcı olabilir.

Ek sorgu gönderme (S2):
List agents who sold a property for over $1000000.
Aracı, kullanılabilir becerileri belleğe zaten yazdığı ve tekrar keşif aşamasından geçmesi gerekmediği için doğrudan QueryData API becerisine gider.
Oluşturulan SQL, şu ifadeye benzer:
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;
Başka bir sorgu deneyin (S3):
What is the average price of a single-family home with a garage in San Diego?
QueryData, boş bir bağlam kümesiyle standart sorgular oluşturur ancak işletme görevleri genellikle belirli bir işletme mantığı ve deterministik davranış gerektirir.
8. Yorum ekleyerek yüksek doğruluk ve işletme alaka düzeyi elde etme
Yorumu istemlere yerleştirmek, oluşturulan sorguların belirli bir iş mantığıyla eşleşmesini sağlar.
Del Mar'da tek katlı evler isteyen bir müşterinin örneğini deneyeceksiniz. Soruda iki önemli metrik var ve seçim için sıkça kullanılan bir kalıbı temsil ediyor.
Ajanla aşağıdaki doğal dil istemini (S4) deneyin.
Single level Del Mar houses
Motor, genel bir sorgu döndürür ancak is_single_family = TRUE gibi bazı ek koşullar içerebilir:
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;
Sonuç olarak döndürülen bir satır elde ederiz:
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.
Başka bir istemi test edin (S5):
Del Mar houses close to good schools
Özellikleri sıralamak için proximity_miles ve school_ranking sütunlarını kullanacak kadar akıllı olsa da her metriğin ağırlığını ve önemini değerlendirmez.
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;
Örnek sorguyu şablona dönüştürme
İş mantığı için gerekenler:
- 2 mil içinde yakınlık
- 5 veya daha düşük okul sıralaması
- Ağırlıklı sıralama: %80 okul sıralaması +% 20 yakınlık (Puan = 0,8 * okul_sıralaması + 0,2 * yakınlık_mesafesi)
Ağırlıklı sıralama formülü şu şekildedir:
Score = 0.8 * school_ranking + 0.2 * proximity_miles
Cloud Shell'deki komut satırı arayüzünü kullanarak Cloud Shell'den sixrecipe_context1_1.json bağlam dosyasını indirin:
cloudshell download ~/codelabs/alloydb-ai-nla/sixrecipe_context1_1.json
Alternatif olarak, Cloud Shell menüsündeki Download menü öğesini kullanabilirsiniz:

Bu standart yapıyı tanımlamak için AlloyDB Studio'yu kullanarak sixrecipe_context1_1.json dosyasını sixrecipe bağlam kümenize yükleyin. sixrecipes bağlamının sağındaki üç noktayı tıklayın ve yeni dosyayı yüklemek için "Bağlam kümesini düzenle"yi kullanın. Bu işlem, eski boş bağlamı yeni bağlamla etkili bir şekilde değiştirir.
Şablon, iyi okul yakınlığı kuralları için açık SQL şablonu kurallarını tanımlar:
{
"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\""
}
}
]
}
İstemi yeniden çalıştırın:
Del Mar houses close to good schools
Sonuçta elde edilen sorgu artık şablonda tanımlanan iş mantığıyla eşleşiyor:
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"
Oluşturulan SQL ifadesiyle birlikte aşağıdaki amaç da oluşturulur:
intentExplanation: "Houses in Del Mar close to good schools (within 2 miles of schools with a rank of at least 5)."
Amacı, ADK web arayüzünün sol bölmesinde aşağıdaki gibi görebilirsiniz:

Sonuçlarda, puanımıza göre sıralanmış iki mülk gösteriliyor:
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
Bir sonraki bölümde, şablonun kapsamını genişleteceksiniz.
Birden fazla soruyu yakalayıp yorumlayarak yorumlama ekleme
Şablonumuzun kapsamını genişleterek yalnızca "iyi okullara yakın" için değil, aynı zamanda manifeste başka koşullar ekleyerek örneğin "çocuklu aileler için evler" için de kullanılmasını sağlayabilirsiniz.
Güncellenen bağlam dosyasını indirin:
cloudshell download ~/codelabs/alloydb-ai-nla/sixrecipe_context1_2.json
Güncellenen sixrecipe_context1_2.json dosyasını bağlam kümenize yükleyin.
Yeni bağlam kümesi dosyasında, manifestimizi "manifest": "A given city houses close to good schools." yerine "manifest": "A given city houses close to good schools, or are great for families with kids." manifestiyle değiştiriyoruz. Bu şablonun yalnızca bir durum için değil, daha fazla durumda kullanılabilmesini sağlar.
Bu sorguyu gönderin (S6):
Houses in Waterloo great for families with kids.
Aracı, standartlaştırılmış sorgu mantığınızı uygulamak için güncellenmiş şablon manifestini kullanır. Bu mantık, yukarıdakiyle aynı sorguyu şu amaçlarla döndürür:
intentExplanation : "Houses in Waterloo close to good schools (within 2 miles of schools with a rank of at least 5)."
9. Esnekliği korurken yüksek doğruluk elde etmek için Faceted Templates'i kullanma
Fasetler, her permütasyon için ayrı şablonlar oluşturmadan niteleyicileri (ör. "başlangıç seviyesi aile", "deniz manzarası") işlemek üzere şablonlarla dinamik olarak birleştirilen modüler SQL koşullarıdır.
Her sorgu veya koşul için şablon oluşturmak yerine, sorguya daha fazla boyut ekleyerek mevcut şablonlara uygulanabilecek parçalar hazırlayabiliriz.
Aşağıdaki özelliklere sahip mülkler için bir yön tanımlayın:
- Müstakil ev
- Etkin bir listeleme durumu
- Üç veya dört yatak odası ve en az iki banyo
- 100.000 sakine düşen suç oranı 500'ün altında olan bir belediyedeki konum
Fasetli bağlam dosyasını indirin:
cloudshell download ~/codelabs/alloydb-ai-nla/sixrecipe_context2_1.json
Facet'leri yapılandırmak için sixrecipe_context2_1.json dosyasını AlloyDB Studio'daki sixrecipes bağlam kümenize yükleyin.
"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)"
}
}
]
Özelliklere göre aramayı kullanarak sorgu oluşturma
Şu doğal dil sorgusunu (Q7) çalıştırın:
Del Mar houses close to good schools for a starter family.
Motor, yön koşullarınızı doğrudan temel sorguya ekler:
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"
Sonuçlar:
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
Daha fazla yön ekleme
Yeni ortaya çıkan düzene göre bir boyut daha eklemek istersek ne olur? Örneğin, mülk için pencere görünümü.
Bir yön tanımına deniz manzarası anlamsal eşleşmesi ekleyin.
{
"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)"
}
Yukarıdaki yön tanımında yer alan 0,4 değeri, deneysel olarak kalibre edilmiş bir eşiktir. Çok yönlü bağlam dosyasını indirin:
cloudshell download ~/codelabs/alloydb-ai-nla/sixrecipe_context2_2.json
Bağlam kümenize sixrecipe_context2_2.json yükleyin ve şu istemi (S8) çalıştırın:
Ocean view Del Mar homes near good schools.
Çıkış, google_ml.embedding aracılığıyla vektör benzerliği eşleştirme ile birleştirilmiş standart koşulları içerir:
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";
Sorgu bir mülk döndürür:
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'da mülkün açıklamasını kontrol ederek ve aşağıdaki sorguyu çalıştırarak sonuçları doğrulayın:
select description from real_estate.properties where address_postal_code='92014' and description is not null;
Açıklamada "muhteşem deniz manzarası" ifadesi yer alır.
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.
10. Değer aramalarını kullanarak özel verilerinizin anlam belirsizliğini giderme
Belirsiz istekler, birden fazla öğeyle eşleşebilir. Örneğin, konum adı ile işletme adı karıştırılabilir. Değer aramaları, bu referansların çözülmesine yardımcı olmak için arama terimlerini veritabanı kavramlarıyla eşler.
Değer araması, sütun adı ile sütundaki değerler arasında, örneğin şehir, ülke veya ad olabilecek bir kavram türüyle ilişkiler sağlar. Ayrıca, yalnızca meta verileri değil, bir sütundaki verilerin temsili örneklerini de dizine eklediğinden, doğal dil isteğinde kullanılan bir değeri olası bir kavram türüyle ve sonuçtaki SQL'de hangi tablo ve sütunun kullanılabileceğiyle ilişkilendirebilir.
Sorgudaki belirsizlik
Gerçek hayatta farklı adların ve konumların yanlış yazılması nedeniyle bu durum daha da zor olabilir. Yazım hatası ve belirsiz terim içeren bu istemi (S9) çalıştırın:
Westwod's sold properties in the last 1 month.
Burada iki sorun var: Ad yanlış yazılmış ve benzer adlara sahip yerlerde satılan mülklerden mi yoksa bir emlak acentesinden mi bahsedildiği net değil. Sorguyu çalıştırdığımızda aşağıdaki gibi bir sorgu döndürülür.
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
Adı düzeltmiş ve sorunun, Westwood şehrindeki mülklerle eşleşmeye çalışan mülklerin konumuyla ilgili olduğunu varsaymıştır.
Yaklaşık dize karşılaştırmalarını desteklemek için AlloyDB Studio'da pg_trgm uzantısını etkinleştirin:
CREATE EXTENSION IF NOT EXISTS pg_trgm;
Ardından, uzantıyı kullanarak QueryData bağlam kümemize değer aramaları ekleyebiliriz.
Kullanmak istediğimiz değer aramalarının listesini aşağıda bulabilirsiniz:
"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"
}
]
Değer arama bağlamı dosyasını indirin:
cloudshell download ~/codelabs/alloydb-ai-nla/sixrecipe_context3_1.json
sixrecipe_context3_1.json dosyasını QueryData sixrecipes bağlam kümesine yükleyin ve kaydedin.
İstemi yeniden çalıştırın (S9):
Westwod's sold properties in the last 1 month.
Değer aramasında benzer değerlere sahip 3 farklı öğe bulduğu için açıklama yanıtı döndürdü:
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?
İz, neden bu yolu seçtiği konusunda bize bir ipucu veriyor.

Tam metin:
"[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?"
Sorgudaki belirsizliği giderme
Giriş istemini hassaslaştırın (S10):
Westwood city location properties sold in September 2025.
Şimdi sorgu ve sonuçlar elimizde:
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
11. Semantik Arama ve Yapay Zeka İşlevleri
AlloyDB AI işlevleri, yapılandırılmamış veriler üzerinde anlamsal filtreleme yapılmasını sağlar. Standart veritabanı operatörlerinin yanı sıra doğrudan SQL sorgularında ai.if ve google_ml.embedding gibi işlevleri kullanın.
ILIKE operatörlerini içeren şablon
İlk adım olarak, ILIKE operatörleriyle yeni bağlam dosyasını yükleyin.
ILIKE şablon bağlam dosyasını indirin:
cloudshell download ~/codelabs/alloydb-ai-nla/sixrecipe_context4_1.json
"Taşınmaya hazır" evler için standart ILIKE kalıp eşleştirme özelliğini değerlendirmek üzere sixrecipe_context4_1.json dosyasını bağlam kümenize yükleyin.
{
"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%')"
}
}
Bu sorguyu (S11) gönderin:
List move-in ready houses.
Sonuçtaki sorgu:
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%')
Eşleşen bir kayıt döndürür.
Query Results address_street address_postal_code 40 Main St, Unit 8 N2H 2G8
AI.IF işlevinin bulunduğu şablon
AI.IF şablon bağlam dosyasını indirin:
cloudshell download ~/codelabs/alloydb-ai-nla/sixrecipe_context4_2.json
ai.if semantik filtreleme işlevini değerlendirmek için sixrecipe_context4_2.json dosyasını bağlam kümenize yükleyin.
{
"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\")"
}
}
İstemi tekrarla (S12):
List move-in ready houses.
Oluşturulan 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")
Bu, sonuçta aynı özelliği verir:
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
Vektör aramasıyla yönlendirme
Yerleştirme arama bağlamı dosyasını indirin:
cloudshell download ~/codelabs/alloydb-ai-nla/sixrecipe_context4_3.json
google_ml.embedding kullanarak semantik vektör aramasını değerlendirmek ve yeni mutfak aletleriyle ev aramak için sixrecipe_context4_3.json dosyasını bağlam kümenize yükleyin.
AlloyDB vektör arama ile ek bir yön içeren sixrecipe_context4_3.json dosyasını kullanarak bağlam kümesini güncelleyin.
{
"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)"
}
}
Yukarıdaki yön tanımında yer alan 0,4 değeri, deneysel olarak kalibre edilmiş bir eşiktir.
Bu sorguyu (S13) çalıştırın:
List move-in ready houses with upgraded kitchen appliances.
Oluşturulan 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))
Sorgu sonuçları ve doğal dil önerisi:
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
12. Güvenlik ve Gizlilik
QueryData API her sorgu oluşturduğunda, oluşturulan sorguların diğer kullanıcılara ait verileri açığa çıkarma riski vardır. Parametrelendirilmiş Güvenli Görünümler (PSV'ler), NL2SQL oluşturma sırasında satır düzeyinde güvenlik sınırlarını zorunlu kılar.
Parametreli Güvenli Görünüm Oluşturma
Tüm emlak anlaşmalarımızla ilgili teklif bilgilerini içeren bir real_estate.offers tablomuz var. Aracılarımızın yalnızca kendi anlaşmalarını görmesini, diğer aracılarla ilgili anlaşmaları görmemesini istiyoruz. Satırları agent_id'ye göre filtreleme özelliğine sahip bir PSV oluştururuz.
AlloyDB Studio'da teklifler tablosu için parametreli güvenli görünüm oluşturma:
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;
Parametreli güvenlik görünümü tanımını doğrulayın:
SELECT definition
FROM parameterized_views.all_parameterized_views
WHERE schemaname = 'real_estate' AND viewname = 'secure_offers';
Peki ya real_estate.offers tablosu?
AlloyDB parametreli güvenli görünümlerini kullanarak QueryData veri erişimini sınırlama
agent.py dosyasında, parametrelendirilmiş güvenlik görünümü real_estate.secure_offers, real_estate.offers yerine TABLE_IDS'ye kaydedilir:
agent.py kaynak kodu:
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",
]
Ayrıca, agent_id=1 olan bir aracı için oturum çalışma zamanı bağlamını iletir:
"parameterized_secure_view_parameters": {
"parameters": {
"key": "agent_id",
"value": "1"
}
}
},
Sonuç olarak, her QueryData API isteği bu parametreyi iletir ve güvenli görünüm isteğe dahil edildiğinde yalnızca söz konusu temsilciye ait sonuçları döndüren filtreleme uygulanır.
Bu sorguyu (S14) çalıştırın:
List the offer id and listing price in 2025 where the offer was within 5% of the final selling price.
Oluşturulan 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
Görünüm sorgulandığında sonuçlar etkin aracı oturumu parametresine göre filtrelenir. Bu sayede yetkisiz kayıt verileri korunur ve yalnızca iki kayıt döndürülür.
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
AlloyDB Studio'daki temel real_estate.offers tablosunda aşağıdaki sorguyu çalıştırırsanız:
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
Tüm temsilcilerin verilerini göstererek ikiden fazla kayıt döndürür.
Laboratuvarımızın sonuna geldik. QueryData API'yi, AI işlevlerini ve AlloyDB Parametreli Güvenli Görünümleri kullanmayı öğrendiniz.
13. Ortamı temizleme
Laboratuvarı tamamladığınızda AlloyDB örneklerini ve kümeyi yok edin.
AlloyDB kümesini ve tüm örnekleri silme
Küme, force seçeneğiyle yok edilir. Bu seçenek, kümeye ait tüm örnekleri de siler.
Terminalinizin bağlantısı kesildiyse tekrar bağlanın ve Cloud Shell'de proje ile ortam değişkenlerini tanımlayın:
gcloud config set project <YOUR_PROJECT_ID>
export REGION=us-central1
export ADBCLUSTER=alloydb-aip-01
export PROJECT_ID=$(gcloud config get-value project)
Kümeyi silme:
gcloud alloydb clusters delete $ADBCLUSTER --region=$REGION --force
Beklenen konsol çıkışı:
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 yedeklerini silme
Kümenin tüm AlloyDB yedeklerini silin:
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
Beklenen konsol çıkışı:
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 paketini silme
Devam eden depolama ücretlerini önlemek için Cloud Storage içe aktarma paketini silin:
gcloud storage rm -r gs://${PROJECT_ID}-import
14. Tebrikler
Codelab'i tamamladığınız için tebrikler.
İşlediğimiz konular
- AlloyDB kümesi ve birincil örnek dağıtma
- AlloyDB için QueryData, yapay zeka işlevleri ve parametrelendirilmiş güvenli görünümleri etkinleştirme
- QueryData bağlam kümesi oluşturma
- QueryData API'de farklı şablonları ve bağlamları kullanma
- Fasetleri kullanarak QueryData şablonlarını daha esnek hale getirme
- Değer araması ve üçlü gram dizine ekleme ile veri belirsizliğini çözme
- Şablonlarla semantik arama için yapay zeka işlevlerini kullanma
- QueryData API ile parametreli güvenli görünümler nasıl kullanılır?
Anket
Çıkış: