1. Giriş
Bu uygulamalı oturumda, temel ve durumsuz chatbot'ların ötesine geçerek akıllı bir kafe konsiyerji oluşturacaksınız. Bu konsiyerj, Gemini tarafından desteklenen ve samimi bir barista gibi davranan bir yapay zeka aracısıdır. Oturum durumunda izlenen kahve siparişlerini alır, kullanıcı kapsamlı durumdaki uzun vadeli beslenme tercihlerini hatırlar ve her şeyi Cloud SQL PostgreSQL veritabanında kalıcı hale getirir. Uygulamayı yeniden başlattıktan ve yeni bir görüşme başlattıktan sonra bile, temsilciniz laktoz intoleransınız olduğunu hatırlar.
Oluşturacağımız sistem mimarisi

Ön koşullar
- Deneme faturalandırma hesabına sahip bir Google Cloud hesabı
- Python hakkında temel bilgi
- ADK, yapay zeka aracıları veya Cloud SQL ile ilgili deneyim gerekmez.
Neler öğreneceksiniz?
- Google'ın Agent Development Kit'ini (ADK) kullanarak özel araçlarla yapay zeka temsilcisi oluşturma
- Oturum durumunu
ToolContextaracılığıyla okuyan ve yazan araçları tanımlayın. - Oturum kapsamlı durum ile kullanıcı kapsamlı durumu (
user:öneki) ayırt etme - Cloud SQL PostgreSQL örneği sağlama ve Cloud Shell'den bu örneğe bağlanma
adk webkomutunu kullandığınızda varsayılan olan yerel depolama alanından, özel veritabanı ile kalıcı depolama içinDatabaseSessionService'ye geçiş yapın.- Aracı belleğinin, uygulama yeniden başlatıldığında ve ayrı sohbet oturumlarında kalıcı olduğunu doğrulayın.
Gerekenler
- Çalışır durumda bir bilgisayar ve güvenilir bir internet bağlantısı.
- Google Cloud Console'a erişmek için Chrome gibi bir tarayıcı
- Meraklı bir zihin ve öğrenme isteği
2. Ortamınızı ayarlama
Bu adımda Cloud Shell ortamınız hazırlanır ve Google Cloud projeniz yapılandırılır.
Cloud Shell'i açma
Tarayıcınızda Cloud Shell'i açın. Cloud Shell, bu codelab için ihtiyacınız olan tüm araçların bulunduğu önceden yapılandırılmış bir ortam sağlar. İstendiğinde Yetkilendir'i tıklayın.
Arayüzünüz aşağıdaki gibi görünmelidir.

Bu, ana arayüzümüz olacak. Üstte IDE, altta terminal yer alacak.
Çalışma dizininizi ayarlama
Çalışma dizininizi oluşturun. Bu codelab'de yazdığınız tüm kodlar, referans deposundan ayrı olarak burada bulunur:
# Create your working directory
mkdir -p ~/build-agent-adk-cloudsql
# Change cloudshell workspace and working directory into previously created dir
cloudshell workspace ~/build-agent-adk-cloudsql && cd ~/build-agent-adk-cloudsql
Terminalinizi oluşturmak için Görünüm -> Terminal'i bulun.

Google Cloud projenizi ve ilk ortam değişkenlerinizi ayarlama
Proje kurulum komut dosyasını çalışma dizininize indirin:
curl -sL https://raw.githubusercontent.com/alphinside/cloud-trial-project-setup/main/setup_verify_trial_project.sh -o setup_verify_trial_project.sh
Komut dosyasını çalıştırın. Deneme faturalandırma hesabınızı doğrular, yeni bir proje oluşturur (veya mevcut bir projeyi doğrular), proje kimliğinizi geçerli dizindeki bir .env dosyasına kaydeder ve terminalde etkin projeyi ayarlar.
bash setup_verify_trial_project.sh && source .env
Bu komutu çalıştırdığınızda önerilen proje kimliği adı istenir. Devam etmek için Enter tuşuna basabilirsiniz.

Bir süre bekledikten sonra konsolunuzda bu çıktıyı görürseniz bir sonraki adıma geçebilirsiniz. 
Çalıştırılan komut dosyası aşağıdaki adımları uygular:
- Etkin bir deneme faturalandırma hesabınız olduğunu doğrulayın.
.enviçinde mevcut bir proje olup olmadığını kontrol edin (varsa)- Yeni bir proje oluşturun veya mevcut projeyi yeniden kullanın
- Deneme faturalandırma hesabını projenize bağlama
- Proje kimliğini .env dosyasına kaydedin.
- Projeyi etkin gcloud projesi olarak ayarlayın
Cloud Shell terminal isteminde çalışma dizininizin yanındaki sarı metni kontrol ederek projenin doğru şekilde ayarlandığını doğrulayın. Proje kimliğiniz gösterilmelidir.

Gerekli API'leri etkinleştirme
Bu codelab için gereken Google Cloud API'lerini etkinleştirin:
gcloud services enable \
aiplatform.googleapis.com \
sqladmin.googleapis.com \
compute.googleapis.com
- Vertex AI API (
aiplatform.googleapis.com): Temsilciniz, Vertex AI aracılığıyla Gemini modellerini kullanır. - Cloud SQL Admin API (
sqladmin.googleapis.com): Kalıcı depolama için bir PostgreSQL örneği sağlarsınız ve yönetirsiniz. - Compute Engine API (
compute.googleapis.com): Cloud SQL örnekleri oluşturmak için gereklidir.
Gemini ve Cloud ürünlerinin bölgesini yapılandırma
Devam etmeden önce, etkileşimde bulunduğumuz ürün için gerekli konum/bölge yapılandırmasını da ayarlayalım. .env dosyamıza aşağıdaki yapılandırmayı ekleyin.
# This is for our Gemini endpoint
echo "GOOGLE_CLOUD_LOCATION=global" >> .env
# This is for our other Cloud products
echo "REGION=us-central1" >> .env
source .env
Bir sonraki adıma geçelim.
3. Cloud SQL'i ayarlama
Bu adımda bir Cloud SQL PostgreSQL örneği sağlanır ve aracınız bellek içi depolamadan veritabanı destekli depolamaya geçirilir. Örnek oluşturma işlemi birkaç dakika sürer. Bu nedenle, önce bu işlemi başlatın. İşlem tamamlanana kadar bir sonraki konuyla ilgili tartışmamıza devam edebiliriz.
Örnek oluşturma işlemini başlatma
Veritabanı şifresini .env dosyanıza ekleyin ve dosyayı yeniden yükleyin. Şifre olarak cafe-agent-pwd-2025 değerini kullanacağız.
echo "DB_PASSWORD=cafe-agent-pwd-2025" >> .env
source .env
Cloud SQL PostgreSQL örneği oluşturmak için bu komutu çalıştırın. Bu işlemin tamamlanması birkaç dakika sürer. İşlemi çalışır durumda bırakıp sonraki bölüme geçin.
gcloud sql instances create cafe-concierge-db \
--database-version=POSTGRES_17 \
--edition=ENTERPRISE \
--region=${REGION} \
--availability-type=ZONAL \
--project=${GOOGLE_CLOUD_PROJECT} \
--tier=db-f1-micro \
--root-password=${DB_PASSWORD} \
--quiet &
Yukarıdaki komutla ilgili birkaç not:
db-f1-micro, bu kod laboratuvarı için yeterli olan en küçük (ve en ucuz) Cloud SQL katmanıdır.--root-password, varsayılan postgres kullanıcısının şifresini ayarlar.- Komuttaki
&soneki, komutu arka planda çalıştırır. Böylece çalışmaya devam edebilirsiniz.
İşlem arka planda çalıştırılır ancak konsol çıkışı zaman zaman mevcut terminalde gösterilir. Daha iyi odaklanabilmek için Cloud Shell'de yeni bir terminal sekmesi açalım (artı simgesini tıklayın).

Çalışma dizininize tekrar gidin ve önceki kurulum komut dosyasını kullanarak projeyi etkinleştirin.
cd ~/build-agent-adk-cloudsql
bash setup_verify_trial_project.sh && source .env
Ardından, bir sonraki bölüme geçelim.
4. Cafe Concierge aracısını oluşturma
Bu adımda ADK aracınızın proje yapısı oluşturulur ve menü aracı içeren temel bir Cafe Concierge tanımlanır.
Python projesini başlatma
Bu codelab'de, sanal ortamları ve bağımlılıkları tek bir araçta işleyen hızlı bir Python paket yöneticisi olan uv kullanılır. Cloud Shell'e önceden yüklenmiştir.
Python projesi başlatın ve ADK'yı bağımlılık olarak ekleyin:
uv init
uv add google-adk==1.25.0 asyncpg
uv init, pyproject.toml ve sanal ortam oluşturur. uv add komutu, bağımlılığı yükler ve pyproject.toml dosyasına kaydeder.
Aracı proje yapısını başlatma
ADK, belirli bir klasör düzeni bekler: __init__.py, agent.py ve ayrıca temsilci dizininde .env içeren, temsilcinizin adını taşıyan bir dizin
ADK, bu işlemi hızlı bir şekilde yapmanıza yardımcı olacak yerleşik bir komuta sahiptir. Aşağıdaki komutu çalıştırın.
uv run adk create cafe_concierge \
--model gemini-2.5-flash \
--project ${GOOGLE_CLOUD_PROJECT} \
--region ${GOOGLE_CLOUD_LOCATION}
Bu komut, beyin olarak gemini-2.5-flash ile bir aracı yapısı oluşturur. Dizininiz artık şu şekilde görünmelidir:
build-agent-adk-cloudsql/ ├── cafe_concierge/ │ ├── __init__.py │ ├── agent.py │ └── .env ├── pyproject.toml ├── .env ├── .venv/ └── ...
Temsilciyi yazma
Cloud Shell Düzenleyici'de cafe_concierge/agent.py dosyasını açın.
cloudshell edit cafe_concierge/agent.py
ve dosyayı aşağıdaki kodla üzerine yazın.
# cafe_concierge/agent.py
from google.adk.agents import LlmAgent
from google.adk.tools import ToolContext
CAFE_MENU = {
"espresso": {
"price": 3.50,
"description": "Rich and bold single shot",
"tags": ["vegan", "dairy-free", "gluten-free"],
},
"latte": {
"price": 5.00,
"description": "Espresso with steamed milk",
"tags": ["gluten-free"],
},
"oat milk latte": {
"price": 5.50,
"description": "Espresso with steamed oat milk",
"tags": ["vegan", "dairy-free", "gluten-free"],
},
"cappuccino": {
"price": 4.50,
"description": "Espresso with equal parts steamed milk and foam",
"tags": ["gluten-free"],
},
"cold brew": {
"price": 4.00,
"description": "Slow-steeped for 12 hours, served over ice",
"tags": ["vegan", "dairy-free", "gluten-free"],
},
"matcha latte": {
"price": 5.50,
"description": "Ceremonial grade matcha with steamed milk",
"tags": ["gluten-free"],
},
"croissant": {
"price": 3.00,
"description": "Buttery, flaky French pastry",
"tags": [],
},
"banana bread": {
"price": 3.50,
"description": "Homemade with walnuts",
"tags": ["vegan"],
},
}
def get_menu() -> dict:
"""Returns the full cafe menu with prices, descriptions, and dietary tags.
Use this tool when the customer asks what's available, wants to see
the menu, or asks about specific items.
"""
return CAFE_MENU
root_agent = LlmAgent(
name="cafe_concierge",
model="gemini-2.5-flash",
instruction="""You are a friendly and knowledgeable barista at "The Cloud Cafe".
Your job:
- Help customers browse the menu and answer questions about items.
- Take coffee and food orders.
- Remember and respect dietary preferences.
Be conversational, warm, and concise. If a customer mentions a dietary
restriction, acknowledge it and suggest suitable options from the menu.
""",
tools=[get_menu],
)
Bu, bir araç içeren temel bir aracı tanımlar: get_menu(). Ajan, menüyle ilgili soruları yanıtlayabilir ancak henüz siparişleri takip edemez veya tercihleri hatırlayamaz.
Aracının çalıştığını doğrulama
ADK geliştirme kullanıcı arayüzünü çalışma dizininizden başlatın:
cd ~/build-agent-adk-cloudsql
uv run adk web
Cloud Shell'in web önizleme özelliğini kullanarak terminalde gösterilen URL'yi (genellikle http://localhost:8000) açın. Sol üst köşedeki aracı açılır listesinden cafe_concierge simgesini seçin.
Sohbet çubuğuna aşağıdaki metni yazın ve temsilcinin menü öğeleri ve fiyatlarla yanıt verdiğini doğrulayın.
What's on the menu?

Devam etmeden önce Ctrl+C tuşlarına basarak geliştirici kullanıcı arayüzünü durdurun.
5. Durumlu Sipariş Yönetimi'ni ekleme
Ajan menüyü gösterebilir ancak sipariş alamaz veya tercihleri hatırlayamaz. Bu adımda, bir görüşmedeki siparişleri izlemek ve görüşmelerdeki beslenme tercihlerini depolamak için ADK'nın durum sistemini kullanan dört araç eklenir.
Oturum etkinliklerini ve durumunu anlama
Her ADK görüşmesi bir Session nesnesinde yer alır. Oturumda iki farklı şey izlenir: Etkinlikler ve durum. Aradaki farkı anlamak, doğru şeyleri doğru şekilde hatırlayan aracıları oluşturmak için önemlidir.
Etkinlikler, bir sohbette olan her şeyin kronolojik günlüğüdür. Her kullanıcı mesajı, her aracı yanıtı, her araç çağrısı ve dönüş değeri bir Event olarak kaydedilir ve oturumun etkinlikler listesine eklenir. Etkinlikler sabittir: Kaydedildikten sonra asla değişmezler. Etkinlikleri bir görüşmenin tam transkripti olarak düşünebilirsiniz.
Durum, temsilcinin bir görüşme sırasında okuduğu ve yazdığı bir anahtar/değer not defteridir. Etkinliklerin aksine durum değiştirilebilir. Değerler, görüşme geliştikçe değişir. Durum, aracının işlem yapmak için ihtiyaç duyduğu yapılandırılmış verileri (mevcut sipariş, müşterinin tercihleri, devam eden toplam) depoladığı yerdir. Durumu, temsilcinin transkriptin yanında tuttuğu yapışkan notlar olarak düşünebilirsiniz.
Bu iki kavram arasındaki ilişki şu şekildedir:

Araçlar, durumu ToolContext aracılığıyla okur ve yazar. ToolContext, ADK'nın parametre olarak bildiren tüm araç işlevlerine otomatik olarak yerleştirdiği bir nesnedir. Bu profili kendiniz oluşturmazsınız. tool_context.state aracılığıyla bir araç, oturumun durum not defterini okuyup yazabilir. ADK, işlev imzasını inceler: ToolContext türündeki parametreler yerleştirilir, diğer tüm parametreler ise LLM tarafından sohbete göre doldurulur.
Bir araç tool_context.state konumuna yazdığında ADK, bu değişikliği etkinlik içinde state_delta olarak kaydeder. SessionService daha sonra farkı oturumun mevcut durumuna uygular. Bu, durum değişikliklerinin her zaman bunları tetikleyen etkinliğe kadar izlenebileceği anlamına gelir. Bu durum, callback_context gibi diğer bağlam biçimleri için de geçerlidir.
Eyalet öneklerini anlama
Durum anahtarları, kapsamlarını kontrol etmek için önekler kullanır:
Ön ek | Kapsam | Yeniden başlatma işleminden sonra çalışmaya devam eder mi? (DB ile) |
(yok) | Yalnızca geçerli oturum | Evet |
| Bu kullanıcının tüm oturumları | Evet |
| Tüm oturumlar, tüm kullanıcılar | Evet |
| Yalnızca geçerli çağırma | Hayır |
Bu codelab'de bu öneklerden ikisini kullanacaksınız: oturum kapsamlı veriler için öneksiz anahtarlar (yalnızca bu görüşmeyle alakalı olan mevcut sipariş) ve kullanıcı kapsamlı veriler için user: anahtarları (bu kullanıcının tüm görüşmelerinde geçerli olan beslenme tercihleri).
Durumlu araçları ekleme
Cloud Shell Düzenleyici'de cafe_concierge/agent.py dosyasını açın.
cloudshell edit cafe_concierge/agent.py
Ardından, aşağıdaki dört işlevi root_agent tanımının üzerine ekleyin:
# cafe_concierge/agent.py (add below get_menu, above root_agent)
def place_order(tool_context: ToolContext, items: list[str]) -> dict:
"""Places an order for the specified menu items.
Use this tool when the customer confirms they want to order something.
Args:
tool_context: Provided automatically by ADK.
items: A list of menu item names the customer wants to order.
"""
valid_items = []
invalid_items = []
total = 0.0
for item in items:
item_lower = item.lower()
if item_lower in CAFE_MENU:
valid_items.append(item_lower)
total += CAFE_MENU[item_lower]["price"]
else:
invalid_items.append(item)
if not valid_items:
return {"error": f"None of these items are on our menu: {invalid_items}"}
order = {"items": valid_items, "total": round(total, 2)}
tool_context.state["current_order"] = order
result = {"order": order}
if invalid_items:
result["warning"] = f"These items are not on our menu: {invalid_items}"
return result
def get_order_summary(tool_context: ToolContext) -> dict:
"""Returns the current order summary for this session.
Use this tool when the customer asks about their current order,
wants to review what they ordered, or asks for the total.
Args:
tool_context: Provided automatically by ADK.
"""
order = tool_context.state.get("current_order")
if order:
return {"order": order}
return {"message": "No order has been placed yet in this session."}
def set_dietary_preference(tool_context: ToolContext, preference: str) -> dict:
"""Saves a dietary preference that persists across all conversations.
Use this tool when the customer mentions a dietary restriction or
preference (e.g., "I'm vegan", "I'm lactose intolerant",
"I have a nut allergy").
Args:
tool_context: Provided automatically by ADK.
preference: The dietary preference to save (e.g., "vegan",
"lactose intolerant", "nut allergy").
"""
existing = tool_context.state.get("user:dietary_preferences", [])
if not isinstance(existing, list):
existing = []
preference_lower = preference.lower().strip()
if preference_lower not in existing:
existing.append(preference_lower)
tool_context.state["user:dietary_preferences"] = existing
return {
"saved": preference_lower,
"all_preferences": existing,
}
def get_dietary_preferences(tool_context: ToolContext) -> dict:
"""Retrieves the customer's saved dietary preferences.
Use this tool when you need to check the customer's dietary
restrictions before making recommendations.
Args:
tool_context: Provided automatically by ADK.
"""
preferences = tool_context.state.get("user:dietary_preferences", [])
if preferences:
return {"preferences": preferences}
return {"message": "No dietary preferences saved yet."}
Dikkat edilmesi gereken iki nokta:
place_orderveget_order_summary, önek içermeyen anahtarlar (current_order) kullanır. Bu durum, mevcut oturumla ilişkilidir. Yeni bir görüşme boş bir siparişle başlar.set_dietary_preferenceveget_dietary_preferences,user:önekini (user:dietary_preferences) kullanır. Bu durum, aynı kullanıcının tüm oturumlarında paylaşılır.
Temsilciyi yeni araçlar ve talimatlarla güncelleme
Dosyanın en altındaki mevcut root_agent tanımını şu tanımla değiştirin:
# cafe_concierge/agent.py (replace the existing root_agent)
root_agent = LlmAgent(
name="cafe_concierge",
model="gemini-2.5-flash",
instruction="""You are a friendly and knowledgeable barista at "The Cloud Cafe".
Your job:
- Help customers browse the menu and answer questions about items.
- Take coffee and food orders.
- Remember and respect dietary preferences.
The customer's saved dietary preferences are: {user:dietary_preferences?}
IMPORTANT RULES:
- When a customer mentions a dietary restriction, ALWAYS save it using the
set_dietary_preference tool before doing anything else.
- Before recommending items, check the customer's dietary preferences. If they
have preferences saved, only recommend items compatible with those
restrictions. Check the menu item tags to determine compatibility.
- When placing an order, confirm the items and total with the customer.
Be conversational, warm, and concise.
""",
tools=[
get_menu,
place_order,
get_order_summary,
set_dietary_preference,
get_dietary_preferences,
],
)
Talimatta, bu müşterinin kayıtlı tercihlerini doğrudan isteme yerleştirmek için durum yerleştirme şablonu {user:dietary_preferences?} kullanılır.
Dosyanın tamamını doğrulama
cafe_concierge/agent.py hesabınızda artık şunlar olmalıdır:
CAFE_MENUsözlüğü- Beş araç işlevi:
get_menu,place_order,get_order_summary,set_dietary_preference,get_dietary_preferences - Beş aracın tümüyle
root_agenttanımı
6. ADK Geliştirici Kullanıcı Arayüzü ile Aracı Test Etme
Bu adımda, temsilci çalıştırılır ve tüm durum bilgisi olan özellikler (sıralama, tercih izleme ve oturumlar arası bellek (aynı işlem içinde)) kullanılır. Ayrıca ADK'nın görüşmeyi dahili olarak nasıl izlediğini görmek için Etkinlikler ve Durum panellerini inceleyeceksiniz.
Geliştirici kullanıcı arayüzünü başlatma
cd ~/build-agent-adk-cloudsql
uv run adk web
8000 numaralı bağlantı noktasında Web Önizlemesi'ni açın ve açılır listeden cafe_concierge simgesini seçin.
1. görüşme: Sipariş verme ve tercihleri ayarlama
Aşağıdaki istemleri sırayla deneyin:
What's on the menu?
I'm lactose intolerant
What would you recommend?
I'll have an oat milk latte and a banana bread
What's my order?
Oturum etkinliklerini inceleme
Etkinliğin tamamı yakalanır ve web kullanıcı arayüzünde gösterilir. Sohbet kutusunda yalnızca isteminiz ve yanıtınızın değil, tool_call ve tool_response'nin de yer aldığını görürsünüz.

Etkinliklerin listesini sırayla görürsünüz. Her etkinliğin bir yazarı (etkinliği oluşturan kişi) ve bir türü (ne tür bir etkileşimi temsil ettiği) vardır:
Yazar | Tür | Ne anlama gelir? |
|
| Sohbette yazdığınız mesaj |
|
| Temsilcinin metin yanıtı |
|
| Temsilci bir aracı çağırmaya karar verdi (işlev adı ve bağımsız değişkenler gösterilir). |
|
| Araç çağrısından döndürülen değer |
tool_call etkinliklerden birini (ör. set_dietary_preference görüşmesi) tıklayın. Aşağıdaki bilgileri görürsünüz:
- İşlev adı:
set_dietary_preference - Argümanlar:
{"preference": "lactose intolerant"}
Şimdi, doğrudan altındaki ilgili tool_response etkinliğini tıklayın. Döndürülen değeri görmeniz gerekir:
- Yanıt:
{"saved": "lactose intolerant", "all_preferences": ["lactose intolerant"]}

tool_response etkinliğinin içindeki state_delta alanını bulun. Bu, araç çağrısı sonucunda hangi durumun değiştiğini tam olarak gösterir:
state_delta: {"user:dietary_preferences": ["lactose intolerant"]}
Her durum değişikliği belirli bir etkinliğe kadar izlenebilir. ADK, durum not defterinin görüşme geçmişiyle senkronize kalmasını bu şekilde sağlar.
Oturum durumunu inceleme
Durum sekmesini tıklayın. Etkinlik günlüğünün (tam geçmişi gösterir) aksine, durum sekmesinde aracının şu anda bildiklerinin anlık görüntüsü (her durum anahtarının geçerli değeri) gösterilir.

İki giriş görmeniz gerekir:
current_order-{"items": ["oat milk latte", "banana bread"], "total": 9.0}user:dietary_preferences-["lactose intolerant"]
Anahtar adlarındaki farka dikkat edin:
current_orderöneki yoktur. Oturum kapsamlıdır. Yalnızca bu görüşmede yer alır ve oturum sona erdiğinde kaybolur.user:dietary_preferences,user:ön ekine sahipse kullanıcı kapsamlıdır. Bu kullanıcı için her oturumda paylaşılır.
Bu ayrım kodda görünmez (her ikisi de tool_context.state kullanır) ancak verilerin ne kadar uzağa ulaşacağını kontrol eder. Bunu bir sonraki testte göreceksiniz.
2. görüşme: Oturumlar arası kullanıcı durumunu doğrulama
Yeni bir görüşme başlatmak için geliştirici kullanıcı arayüzünde Yeni Oturum düğmesini tıklayın. Bu işlem, aynı kullanıcı için yeni bir oturum oluşturur.

Şu istemi deneyin:
What do you recommend for me?
Yeni oturumdaki Durum sekmesini kontrol edin. user:dietary_preferences tuşu taşınır ancak current_order tuşu kaybolur. Bu durum, önceki oturumla ilişkilendirilmiştir.

7. Yerel depolama alanı sınırlamasına uyun
Aracı, oturumlar arasında tercihleri hatırlar ancak yalnızca yerel depolama alanı mevcutken. Bu adım, yerel depolamanın temel sınırlamasını gösterir.
Aracıyı tekrar başlatın
Önceki adımın sonunda geliştirici kullanıcı arayüzünü durdurdunuz. Şimdi, durum bilgisi içermeyen sunucusuz ortamı simüle etmek için yerel depolamayı kaldıralım ve yeniden başlatalım:
cd ~/build-agent-adk-cloudsql
rm -f cafe_concierge/.adk/session.db
uv run adk web
Şimdi 8000 numaralı bağlantı noktasında Web Önizlemesi'ni açın ve cafe_concierge simgesini seçin.
Tercih hatırlamayı test etme
Tür:
Do you remember my dietary preferences?
Temsilci hatırlamıyor. Beslenme tercihleri, sipariş geçmişi gibi bilgiler silinir.

Yerel depolama alanını sildiğimizde her şey temizleniyordu. Bu durum genellikle sunucusuz bir ortam kullandığımızda meydana geliyordu. session.db, tüm durumu işlem belleğinde depolar. Kaldırdığınızda tümü silinir.
Çözüm: Bu eğitimde tüm oturum verilerini Cloud SQL'deki bir PostgreSQL veritabanında depolayacak olan DatabaseSessionService'ı belirtin. Aracı kodu ve araçlar tamamen aynı kalır. Yalnızca depolama arka ucu değişir.
Devam etmeden önce Ctrl+C ile geliştirici kullanıcı arayüzünü durdurun.
8. Veritabanı kurulumunu yeniden ziyaret etme
Bu noktada, veritabanı örneği oluşturma işlemimizin tamamlanmış olması gerekir. Doğrulamak için aşağıdaki komutu çalıştırın.
gcloud sql instances describe cafe-concierge-db --format="value(state)"
Aşağıdaki çıkışı görmeniz gerekir. Bunu tamamlandı olarak işaretleyin.
RUNNABLE
Veritabanını oluşturma
Temsilcinin oturum verileri için özel bir veritabanı oluşturun:
gcloud sql databases create agent_db --instance=cafe-concierge-db
Cloud SQL Auth Proxy'yi başlatma
Cloud SQL Auth Proxy, IP adreslerini izin verilenler listesine eklemenize gerek kalmadan Cloud Shell'den Cloud SQL örneğinize güvenli ve kimliği doğrulanmış bir bağlantı sağlar. Cloud Shell'e önceden yüklenmiştir.
cloud-sql-proxy ${GOOGLE_CLOUD_PROJECT}:${REGION}:cafe-concierge-db --port 5432 &
Komuttaki & soneki, proxy'nin arka planda çalışmasını sağlar. Aşağıda gösterildiği gibi, proxy'nin hazır olduğunu onaylayan bir çıkış görmeniz gerekir.
[your-project-id:your-region:cafe-concierge-db] Listening on 127.0.0.1:5432 The proxy has started successfully and is ready for new connections!
Bağlantıyı doğrulama
Proxy üzerinden veritabanına bağlanabildiğinizi test edin:
psql "host=127.0.0.1 port=5432 dbname=agent_db user=postgres password=$DB_PASSWORD" -c "SELECT 'Connection ok' AS status;"
Aşağıdaki bilgileri görürsünüz:
status --------------------- Connection ok (1 row)
9. Oturumlar Arasında Kalıcı Belleği Doğrulama
Bu adımda, cafe_concierge/.adk/session_db (yerel veritabanı) kaldırıldığından ve görüşme oturumlarına yayıldığından emin olarak aracınızın hafızasının sıfırlamadan sonra da devam ettiğini kanıtlıyoruz.
Aracıyı başlatma
Cloud SQL Auth Proxy'nin çalışmaya devam ettiğinden emin olun (işlerle kontrol edin). Değilse yeniden başlatın:
if ss -tlnp | grep -q ':5432 '; then
echo "Cloud SQL Auth Proxy is already running."
else
cloud-sql-proxy ${GOOGLE_CLOUD_PROJECT}:${REGION}:cafe-concierge-db --port 5432 &
fi
Ardından, oturum hizmeti olarak veritabanını belirterek ADK geliştirme kullanıcı arayüzünü başlatalım.
uv run adk web --session_service_uri postgresql+asyncpg://postgres:${DB_PASSWORD}@127.0.0.1:5432/agent_db
8000 numaralı bağlantı noktasında web önizlemesini açın ve cafe_concierge'ı seçin.
1. test: Sipariş verin ve tercihleri ayarlayın
İlk oturumda şu istemleri inceleyin:
Show me the menu
I'm vegan
What can I eat?
I'll have a cold brew and banana bread
2. Test: Yeniden başlatma işleminden sonra çalışmaya devam etme
Ctrl+C ile geliştirici kullanıcı arayüzünü durdurun ve yerel session.db'nin kaldırıldığından emin olun.
rm -f cafe_concierge/.adk/session.db
Ardından, geliştirici kullanıcı arayüzü sunucusunu yeniden çalıştırın.
uv run adk web --session_service_uri postgresql+asyncpg://postgres:${DB_PASSWORD}@127.0.0.1:5432/agent_db
8000 numaralı bağlantı noktasında Web Önizlemesi'ni açın, cafe_concierge simgesini seçin ve yeni bir oturum başlatın. Ardından
What are my dietary preferences?
Müşteri temsilcisi, kayıtlı tercihlerinizle (vegan) yanıt veriyor. Veriler artık yerel depolamada değil, PostgreSQL'de saklandığı için yeniden başlatma işleminden etkilenmedi. user: durumu bu kullanıcının her yeni oturumuna aktarıldığı için yeni oturum oluşturduğumuzda da aynı durum geçerli olur.

Veritabanını doğrudan inceleme
Cloud Shell'de yeni bir terminal sekmesi açın ve depolanan verileri görmek için veritabanını sorgulayın:
psql "host=127.0.0.1 port=5432 dbname=agent_db user=postgres password=$DB_PASSWORD" -c "\dt"
ADK'nın oturumları, etkinlikleri ve durumu depolamak için otomatik olarak oluşturduğu tabloları görmelisiniz. Örneğin:
List of relations Schema | Name | Type | Owner --------+-----------------------+-------+---------- public | adk_internal_metadata | table | postgres public | app_states | table | postgres public | events | table | postgres public | sessions | table | postgres public | user_states | table | postgres (5 rows)
Durum davranışının özeti
Durum anahtarı | Ön ek | Kapsam | Oturumlar arasında paylaşılıyor mu? |
| (yok) | Oturum | Hayır |
|
| Kullanıcı | Evet |
10. Tebrikler / Temizleme
Tebrikler! ADK ve Cloud SQL kullanarak kalıcı ve durum bilgisi olan bir yapay zeka aracısı oluşturmayı başardınız.
Öğrendikleriniz
- Oturum durumunu okuyan ve yazan özel araçlarla ADK temsilcisi oluşturma
- Oturum kapsamlı durum (önek yok) ile kullanıcı kapsamlı durum (
user:öneki) arasındaki fark - Neden varsayılan adk local
session.dbyalnızca geliştirme için uygundur? Kaldırıldığında tüm veriler kaybolur (ve kolayca kaldırılabilir, yedekleme yoktur), durum bilgisi olmayan sunucusuz dağıtım için uygun değildir. - Cloud SQL PostgreSQL örneği sağlama ve Cloud SQL Auth Proxy ile bu örneğe bağlanma
- En az kod değişikliğiyle Cloud SQL'de PostgreSQL kullanarak DatabaseSessionService'e bağlanma: Aynı araçlar, aynı aracı, farklı arka uç
- Kullanıcı kapsamlı durum, ayrı görüşme oturumlarında nasıl korunur?
Temizleme
Google Cloud hesabınızın ücretlendirilmesini önlemek için bu codelab'de oluşturulan kaynakları temizleyin.
1. seçenek: Projeyi silme (önerilir)
Temizlemenin en kolay yolu projeyi silmektir. Bu işlem, projeyle ilişkili tüm kaynakları kaldırır.
gcloud projects delete ${GOOGLE_CLOUD_PROJECT}
2. seçenek: Kaynakları tek tek silme
Projeyi korumak ancak yalnızca bu codelab'de oluşturulan kaynakları kaldırmak istiyorsanız:
gcloud sql instances delete cafe-concierge-db --quiet