1. Giriş

"Japon Balığı" Sorunu
Tokyo'ya hayalinizdeki tatili planlamak için bir seyahat acentesiyle çalıştığınızı düşünün. "Japon Balığı Problemi"ni uygulamalı olarak görmek için Session Agent'ı kullanın.
Ofisine gidip şöyle diyorsunuz:
"Merhaba. Tokyo'ya 2 günlük bir gezi planlamak istiyorum. Tarihi yerler ve suşiyle ilgileniyorum."
Temsilci heyecanla yanıt verir:
"Harika. İmparatorluk Sarayı'na bir ziyaret ve Sukiyabashi Jiro'da suşi akşam yemeği planladım."
Gülümseyerek şöyle diyorsunuz:
"Kulağa harika geliyor. Seyahat planını bana gönderebilir misin?"
Temsilci size boş boş bakıp sorar:
"Merhaba. Bugün gezi planlamanıza nasıl yardımcı olabilirim?"
Buna "Japon Balığı Problemi" denir. Hafıza olmadan her etkileşim sıfırdan başlar. Zeka mevcut. Temsilci, gezileri nasıl planlayacağını biliyor ancak süreklilik yok. Yapay zeka ajanlarının gerçekten faydalı olabilmesi için hatırlaması gerekir.
Bugünkü Göreviniz
Bu atölyede, hatırlayan, öğrenen ve uyum sağlayan bir seyahat acentesi oluşturarak Japon Balığı Sorunu'nu çözeceksiniz. 6 Temsilci Hafızası Seviyesi'ni tamamlayarak chatbot'tan ziyade özel bir kişisel asistan gibi davranan bir sistem oluşturacaksınız.
Seviye | Kavram | "Süper güç" |
1. seviye | Oturum ve Durum | Unutmadan sohbet etme |
2. seviye | Çoklu Temsilci Durumu | Ekip üyeleri arasında not paylaşma |
3. seviye | Kalıcılık | Sistem yeniden başlatıldıktan sonra bile sizi hatırlar. |
4. seviye | Geri aramalar | Hafıza tamamen otonom olarak güncelleniyor |
5. seviye | Özel Araçlar | Yapılandırılmış kullanıcı profillerini okuma ve yazma |
6. seviye | Çok formatlı bellek | Fotoğraf ve videoları "görme" ve hatırlama |
ADK Memory Stack
Kod yazmadan önce kullanacağımız araçları tanıyalım. Google Agent Development Kit (ADK), belleği yönetmek için yapılandırılmış bir yöntem sunar:
- Oturum: Bir görüşmenin kapsayıcısıdır. Söylenenlerin geçmişini tutar.
- State: Oturuma eklenen bir anahtar/değer "not defteri". Temsilciler, belirli bilgileri (ör.
destination="Tokyo") saklamak için bu özelliği kullanır. - MemoryService: Uzun süreli depolama. Kullanıcı tercihleri veya analiz edilen dokümanlar gibi öğeleri burada süresiz olarak saklarız.
2. Kur
Yapay zeka temsilcilerimizi desteklemek için iki şeye ihtiyacımız var: Temeli sağlayacak bir Google Cloud projesi.
Birinci Bölüm: Faturalandırma Hesabını Etkinleştirme
Bu codelab'i çalıştırmak için kredisi olan bir faturalandırma hesabınız olmalıdır. Başlamak için bu codelab'in üst kısmındaki banner'da bulunan kredileri kullanın. Bir faturalandırma hesabına zaten bağlıysanız bu adımı atlayabilirsiniz.
2. Bölüm: Açık Ortam
- 👉 Doğrudan Cloud Shell Düzenleyici'ye gitmek için bu bağlantıyı tıklayın.
- 👉 Bugün herhangi bir noktada yetkilendirme yapmanız istenirse devam etmek için Authorize'ı (Yetkilendir) tıklayın.

- 👉 Terminal, ekranın alt kısmında görünmüyorsa açın:
- Görüntüle'yi tıklayın.
- Terminal'i tıklayın.

- 👉💻 Terminalde, kimliğinizin doğrulandığını ve projenin, proje kimliğinize ayarlandığını doğrulamak için aşağıdaki komutu kullanın:
gcloud auth list - 👉💻 Bootstrap projesini GitHub'dan kopyalayın:
git clone https://github.com/cuppibla/memory_agent_starter - 👉💻 Kurulum komut dosyasını proje dizininden çalıştırın.
Kurulum işleminin geri kalanını komut dosyası otomatik olarak halleder.cd ~/memory_agent_starter ./init.sh - 👉💻 Gerekli proje kimliğini ayarlayın:
gcloud config set project $(cat ~/project_id.txt) --quiet
3. Bölüm: İzinleri ayarlama
- 👉💻 Aşağıdaki komutu kullanarak gerekli API'leri etkinleştirin. Bu işlem birkaç dakika sürebilir.
gcloud services enable \ cloudresourcemanager.googleapis.com \ servicenetworking.googleapis.com \ run.googleapis.com \ aiplatform.googleapis.com \ compute.googleapis.com - 👉💻 Terminalde aşağıdaki komutları çalıştırarak gerekli izinleri verin:
. ~/memory_agent_starter/set_env.sh
Sizin için bir .env dosyası oluşturulduğunu göreceksiniz. Bu, proje bilgilerinizi gösterir.
3. Temel Bilgiler: Oturum ve Durum

Kavram: Bağlam Çok Önemlidir
Belleğin en temel biçimi oturum belleğidir. Bu sayede temsilci, "Onu satın almak istiyorum" cümlesindeki "onu" kelimesinin 10 saniye önce bahsettiğiniz ayakkabı olduğunu anlayabilir.
ADK'da bunu Session nesnesiyle yönetiriz.
- Durumsuz yaklaşım: Her mesaj için yeni bir oturum oluşturma.
- Durum bilgili yaklaşım: Bir oturum oluşturup bu oturumu tüm görüşme için yeniden kullanma.
1. adım: Temsilciyi inceleyin
👉💻 Cloud Shell terminalinizde aşağıdaki komutu çalıştırarak dosyayı Cloud Shell Düzenleyici'de açın:
cloudshell edit ~/memory_agent_starter/01_session_agent/agent.py
~/memory_agent_starter/01_session_agent/agent.py adlı kişiyi aç.
👉 agent.py işlevinin içindeki # TODO: Create a root agent yorumunu bulun.
Bu satırın tamamını aşağıdaki kodla değiştirin:
root_agent = LlmAgent(
name="multi_day_trip_agent",
model="gemini-2.5-flash",
description="Agent that progressively plans a multi-day trip, remembering previous days and adapting to user feedback.",
instruction="""
You are the "Adaptive Trip Planner" 🗺️ - an AI assistant that builds multi-day travel itineraries step-by-step.
Your Defining Feature:
You have short-term memory. You MUST refer back to our conversation to understand the trip's context, what has already been planned, and the user's preferences. If the user asks for a change, you must adapt the plan while keeping the unchanged parts consistent.
Your Mission:
1. **Initiate**: Start by asking for the destination, trip duration, and interests.
2. **Plan Progressively**: Plan ONLY ONE DAY at a time. After presenting a plan, ask for confirmation.
3. **Handle Feedback**: If a user dislikes a suggestion (e.g., "I don't like museums"), acknowledge their feedback, and provide a *new, alternative* suggestion for that time slot that still fits the overall theme.
4. **Maintain Context**: For each new day, ensure the activities are unique and build logically on the previous days. Do not suggest the same things repeatedly.
5. **Final Output**: Return each day's itinerary in MARKDOWN format.
""",
tools=[google_search]
)
Talimat, LLM'ye hatırlamasını söyler ancak kodun hatırlama özelliğini sağlaması gerekir.
2. adım: İki senaryo
~/memory_agent_starter/01_session_agent/main.py adlı kişiyi aç.
👉 Cloud Shell terminalinizde aşağıdaki komutu çalıştırarak dosyayı Cloud Shell Düzenleyici'de açın:
cloudshell edit ~/memory_agent_starter/01_session_agent/main.py
~/memory_agent_starter/01_session_agent/main.py dosyasını açın ve main.py işlevinin içindeki # TODO: Create a runner with in memorysession service yorumunu bulun.
Bu satırın tamamını aşağıdaki kodla değiştirin:
runner = Runner(
agent=agent,
session_service=session_service,
app_name=agent.name
)
👉 main.py işlevinin içindeki # TODO: create a different session to test yorumunu bulun.
Bu satırın tamamını aşağıdaki kodla değiştirin:
tokyo_session_2 = await session_service.create_session(
app_name=multi_day_agent.name,
user_id=user_id
)
Test et
"Japon balığı" ve "fil" hafızası arasındaki farkı gösteren iki işlevimiz var.
1. Senaryo: Durum bilgisi olan (Paylaşılan Oturum)
async def run_trip_same_session_scenario(session_service, user_id):
# 1. Create ONE session
trip_session = await session_service.create_session(...)
# 2. Turn 1
await run_agent_query(..., trip_session, ...)
# 3. Turn 2 - REUSING the same session!
# The agent can "see" Turn 1 because it's in the session history.
await run_agent_query(..., trip_session, ...)
2. Senaryo: Durum Bilgisiz (Her Seferinde Yeni Oturum)
async def run_trip_different_session_scenario(session_service, user_id):
# Turn 1
tokyo_session = await session_service.create_session(...)
await run_agent_query(..., tokyo_session, ...)
# Turn 2 - Creating a FREASH session
# The agent has NO IDEA what happened in Turn 1.
tokyo_session_2 = await session_service.create_session(...)
await run_agent_query(..., tokyo_session_2, ...)
3. adım: Temsilciyi çalıştırın
Aradaki farkı uygulamalı olarak görelim. Komut dosyasını çalıştırın:
👉💻 Komut satırında aşağıdaki komut satırını çalıştırın:
cd ~/memory_agent_starter
uv run python ~/memory_agent_starter/01_session_agent/main.py
1. senaryoyu inceleyin: Temsilci, ilk mesajdaki tercihlerinizi hatırlar ve ikinci mesajda planı buna göre uyarlar.
2. senaryoyu inceleyin: İkinci sırada ("Yemekle ilgili neyi sevdiğimi hatırlıyor musun?") temsilci, yeni bir oturum olduğu için tamamen başarısız olur. Bu, "Neden bahsettiğinizi bilmiyorum" anlamına gelir.
Ana Fikir
Hafıza ile ilgili 1 numaralı kural: Sohbet bağlamını korumak için her zaman session.id öğesini yeniden kullanın. Session nesnesi, temsilcinizin kısa süreli bellek arabelleğidir.
4. Ekip - Çoklu Temsilci Durumu

Konsept: "Kulaktan Kulağa"
Birden fazla temsilci birlikte çalışırken, bir dosya klasörünü birbirine ileten iş arkadaşları gibi davranırlar. Bir temsilci klasöre not yazarsa sonraki temsilci bu notu okuyabilmelidir.
ADK'da bu "klasör" Eyalet'tir.
- State, oturumun içinde bulunan bir sözlüktür (
{"key": "value"}). - Oturumdaki tüm temsilciler bu oturumdan okuma veya oturuma yazma işlemi yapabilir.
1. adım: İş akışını inceleyin
👉💻 Cloud Shell terminalinizde aşağıdaki komutu çalıştırarak dosyayı Cloud Shell Düzenleyici'de açın:
cloudshell edit ~/memory_agent_starter/02_multi_agent/agent.py
👉~/memory_agent_starter/02_multi_agent/agent.py dosyasında # TODO: foodie agent yorumunu bulun.
Bu satırın tamamını aşağıdaki kodla değiştirin:
foodie_agent = LlmAgent(
name="foodie_agent",
model="gemini-2.5-flash",
tools=[google_search],
instruction="""You are an expert food critic. Your goal is to find the best restaurant based on a user's request.
When you recommend a place, you must output *only* the name of the establishment and nothing else.
For example, if the best sushi is at 'Jin Sho', you should output only: Jin Sho
""",
output_key="destination" # ADK will save the agent's final response to state['destination']
)
👉 agent.py işlevinin içindeki # TODO: transportation agent yorumunu bulun.
Bu satırın tamamını aşağıdaki kodla değiştirin:
transportation_agent = LlmAgent(
name="transportation_agent",
model="gemini-2.5-flash",
tools=[google_search],
instruction="""You are a navigation assistant. Given a destination, provide clear directions.
The user wants to go to: {destination}.
Analyze the user's full original query to find their starting point.
Then, provide clear directions from that starting point to {destination}.
""",
)
👉 agent.py işlevinin içindeki # TODO: root_agent yorumunu bulun.
Bu satırın tamamını aşağıdaki kodla değiştirin:
root_agent = SequentialAgent(
name="find_and_navigate_agent",
sub_agents=[foodie_agent, transportation_agent],
description="A workflow that first finds a location and then provides directions to it."
)
Şimdi sırayla çalışan iki temsilcimiz var:
- Foodie Agent: Restoran bulur.
- Ulaşım Temsilcisi: Bu restoran için yol tarifi verir.
Sihirli Devir: foodie_agent'nin bayrağı transportation_agent'ye nasıl devrettiğine dikkat edin.
foodie_agent = LlmAgent(
# ...
# CRITICAL: This tells ADK to save the agent's output to state['destination']
output_key="destination"
)
transportation_agent = LlmAgent(
# ...
# CRITICAL: This injects state['destination'] into the prompt
instruction="""
The user wants to go to: {destination}.
Provide clear directions...
""",
)
output_key="destination": Foodie Agent'ın yanıtı verimli bir şekilde kaydedildi.{destination}: Transportation Agent bu yanıtı otomatik olarak okur.
(İşlem Gerekmez) 2. Adım: Orkestratör
02_multi_agent/main.py adlı kişiyi aç.
Bunları sırayla çalıştırmak için SequentialAgent kullanırız.
# 1. Create a single session for the sequential agent
session = await session_service.create_session(...)
# 2. Run the query
# The SequentialAgent manages the state flow:
# Query -> Foodie -> state['destination'] -> Transportation -> Final Answer
await run_agent_query(root_agent, query, ...)
Kullanıcı bir istem gönderir:
"Find best sushi in Palo Alto and then tell me how to get there."
Temsilciler soruyu yanıtlamak için birlikte çalışır.
3. adım: Ekibi yönetme
👉💻 Cloud Shell terminalinde çoklu temsilci iş akışını çalıştırın:
cd ~/memory_agent_starter
uv run python ~/memory_agent_starter/02_multi_agent/main.py
Süreç
- Gurme Temsilci: "Jin Sho"yu (veya benzerini) bulur.
- ADK: "Jin Sho"yu
state['destination']klasörüne kaydeder. - Taşıma Temsilcisi: Talimatında "Jin Sho" ifadesini alır.
- Sonuç: "Caltrain istasyonundan Jin Sho'ya gitmek için University Ave'den aşağı doğru yürüyün..."
Ana Fikir
Bellekle ilgili 2. kural: Temsilciler arasında yapılandırılmış bilgi aktarmak için State'i kullanın. Yazmak için output_key, okumak için {placeholders} kullanın.
5. The Reboot - Persistence

Kavram: "Yeniden Başlatma Sorunu"
Şu ana kadar hafızamız InMemory. Komut dosyasını durdurup tekrar başlatırsanız temsilci her şeyi unutur. Bu, her kapatıldığında sabit diskini silen bir bilgisayara benzer.
Bu sorunu çözmek için kalıcılığa ihtiyacımız var. InMemorySessionService yerine DatabaseSessionService kullanıyoruz.
1. adım: Veritabanı geçişi
👉💻 Cloud Shell terminalinizde aşağıdaki komutu çalıştırarak dosyayı Cloud Shell Düzenleyici'de açın:
cloudshell edit ~/memory_agent_starter/03_persistent_agent/main.py
👉 ~/memory_agent_starter/03_persistent_agent/main.py dosyasında # TODO: Configuration for Persistent Sessions yorumunu bulun.
Bu satırın tamamını aşağıdaki kodla değiştirin:
SESSIONS_DIR = Path(os.path.expanduser("~")) / ".adk_codelab" / "sessions"
os.makedirs(SESSIONS_DIR, exist_ok=True)
SESSION_DB_FILE = SESSIONS_DIR / "trip_planner.db"
SESSION_URL = f"sqlite:///{SESSION_DB_FILE}"
Artık her oturum ve etkinlik bir SQLite dosyasına kaydedilir.
2. adım: Oturumlar arası erişim
Kalıcılık, yalnızca bir sohbeti devam ettirmeyi değil, geçmiş sohbetlerden öğrenmeyi de sağlar.
Aynı dosyada ~/memory_agent_starter/03_persistent_agent/main.py, Test Case 3: Cross-Session Retrieval (Test Durumu 3: Oturumlar Arası Alma) bölümüne bakın.
👉 Yorumu bulun # TODO: retrieve the previous session manually
Bu satırın tamamını aşağıdaki kodla değiştirin:
old_session = await session_service.get_session(
app_name=root_agent.name, user_id="user_01", session_id=session_id
)
👉 main.py işlevinin içindeki # TODO: Extract content from the OLD session yorumunu bulun.
Bu satırın tamamını aşağıdaki kodla değiştirin:
previous_context += f"- {role}: {text}\n"
👉 main.py işlevinin içindeki # TODO: Manually inject the context to the query yorumunu bulun.
Bu satırın tamamını aşağıdaki kodla değiştirin:
query_3 = f"""
{previous_context}
I'm planning a new trip to Osaka this time.
Based on my previous preferences (above), what should I eat?
"""
Bu, aylar sonra geri dönen bir kullanıcıyı simüle eder. Eski geçmişi yalnızca bir veritabanı kullanarak alabilirsiniz.
3. Adım: Yeniden başlatma işleminden sonra devam etme
👉💻 Terminalde komut dosyasını çalıştırın:
cd ~/memory_agent_starter
uv run python ~/memory_agent_starter/03_persistent_agent/main.py
~/memory_agent_starter/trip_planner.db adlı bir dosya oluşturur. Şunu deneyin: Komut dosyasını iki kez çalıştırın.
- İkinci çalıştırmada "Mevcut oturum devam ettirildi" ifadesini arayın.
- Temsilci, veritabanı dosyasından yüklendiği için ilk çalıştırmadaki bağlamı hatırlar.
Ana Fikir
Bellekle ilgili 3. kural: Üretim için DatabaseSessionService kullanın. Kullanıcı sohbetlerinin sunucu yeniden başlatma işlemlerinden etkilenmemesini sağlar ve uzun vadeli geçmiş analizine olanak tanır.
6. Casus - Geri Çağırmalar

Bazen hafızayı yalnızca temsilcinin söylediklerine göre değil, yaptıklarına göre de otomatik olarak güncellemeniz gerekir. Temsilciyi izleyip not alan bir "casus" istiyorsunuz.
ADK'da bu casus, geri çağırma işlevidir. 
after_tool_callback: Temsilci her çalıştığında yürütülen bir işlev.ToolContext: Bu işlevin içinden State'e yazma yöntemi.
1. adım: Mantık
👉💻 Cloud Shell terminalinizde aşağıdaki komutu çalıştırarak dosyayı Cloud Shell Düzenleyici'de açın:
cloudshell edit ~/memory_agent_starter/04_stateful_agent/agent.py
👉 ~/memory_agent_starter/04_stateful_agent/agent.py dosyasında # TODO: Implement call back logic yorumunu bulun.
Bu satırın tamamını aşağıdaki kodla değiştirin:
def save_activity_type_callback(
tool,
args: Dict[str, Any],
tool_context: ToolContext,
tool_response: Dict[str, Any],
) -> Optional[Dict[str, Any]]:
"""
Callback to save the TYPE of activity just planned into the session state.
"""
# 1. Get the actual agent name.
if tool.name == "transfer_to_agent":
agent_name = args.get("agent_name")
else:
agent_name = tool.name
activity_type = "unknown"
# 2. Determine the type based on which agent was actually used
if agent_name == "museum_expert":
activity_type = "CULTURAL"
elif agent_name == "restaurant_expert":
activity_type = "FOOD"
elif agent_name == "outdoor_expert":
activity_type = "OUTDOOR"
print(f"\n🔔 [CALLBACK] The planner transferred to '{agent_name}'.")
# 3. Update the state directly
tool_context.state["last_activity_type"] = activity_type
print(f"💾 [STATE UPDATE] 'last_activity_type' is now set to: {activity_type}\n")
return tool_response
👉 Aynı dosyada, 04_stateful_agent/agent.py işlevinin içindeki # TODO: add callback to root agent yorumunu bulun.
Bu satırın tamamını aşağıdaki kodla değiştirin:
after_tool_callback=save_activity_type_callback,
Dinamik talimat: Temsilcinin talimatı artık dize değil, işlev olarak kabul edilir. Bu, eyalete göre değişir.
def get_planner_instruction(context):
last_activity = context.state.get("last_activity_type", "None")
return f"""
The last activity was: {last_activity}
If last_activity is 'CULTURAL' -> `museum_expert` is BANNED.
"""
3. adım: Casusu test edin
👉💻 Terminalde, aşağıdaki komutu kopyalayıp yapıştırarak komut dosyasını çalıştırın:
cd ~/memory_agent_starter
uv run python ~/memory_agent_starter/04_stateful_agent/main.py
Bu temsilciyi çalıştırdığınızda bir döngü görürsünüz.
- 1. adım: Bir müze soruyorsunuz. Casus setleri
last_activity="CULTURAL". - 2. adım: Başka bir müze önerisi istersiniz.
- Temsilci talimatı güncellemeleri: "KÜLTÜREL YASAKLANDI".
- Temsilci: "Başka bir müzeye gidemem. Parka ne dersin?"
[CALLBACK] ve [STATE UPDATE] için konsol günlüklerini izleyin. Temsilci çalışırken belleğin anlık olarak değiştiğini görebilirsiniz.
Ana Fikir
Bellekle ilgili 4. kural: Durum yönetimini otomatikleştirmek için geri çağırmaları kullanın. Temsilciniz, yalnızca işini yaparak kendi bağlamını oluşturur.
7. Dosya Dolabı Sayfası - Özel Araçlar
Kavram: "Yapılandırılmış Bellek"

"Hafıza" şimdiye kadar bir sohbet günlüğü veya basit bir anahtar/değer çiftiydi. Ancak karmaşık bir kullanıcı profilini (ör. diet: vegan, budget: high, pets: [cat, dog]) hatırlamanız gerekiyorsa ne yapacaksınız?
Bu nedenle, hafızayı bir araç olarak ele alırız. Temsilci, dosya dolabı sayfasını ne zaman açacağına (okuma) ve ne zaman rapor oluşturacağına (yazma) açıkça karar verir. 
1. adım: Araçlar
👉💻 Cloud Shell terminalinizde aşağıdaki komutu çalıştırarak dosyayı Cloud Shell Düzenleyici'de açın:
cloudshell edit ~/memory_agent_starter/05_profile_agent/tools.py
👉 Şu dosyada: ~/memory_agent_starter/05_profile_agent/tools.py.
Şu iki aracı uygulamamız gerekir:
save_user_preferences: Veritabanına yazar.recall_user_preferences: Veritabanından okur.
~/memory_agent_starter/05_profile_agent/tools.py işlevinin içindeki # TODO: implement save_user_preferences tools yorumunu bulun.
Bu satırın tamamını aşağıdaki kodla değiştirin:
def save_user_preferences(tool_context: ToolContext, new_preferences: Dict[str, Any]) -> str:
user_id = tool_context.session.user_id
with sqlite3.connect(USER_DB_FILE) as conn:
for key, value in new_preferences.items():
conn.execute("INSERT INTO user_preferences (user_id, pref_key, pref_value) VALUES (?, ?, ?) ON CONFLICT(user_id, pref_key) DO UPDATE SET pref_value = excluded.pref_value;",
(user_id, key, json.dumps(value)))
return f"Preferences updated: {list(new_preferences.keys())}"
👉 05/tools.py işlevinin içindeki # TODO: implement recall_user_preferences tools yorumunu bulun.
Bu satırın tamamını aşağıdaki kodla değiştirin:
def recall_user_preferences(tool_context: ToolContext) -> Dict[str, Any]:
user_id = tool_context.session.user_id
preferences = {}
with sqlite3.connect(USER_DB_FILE) as conn:
rows = conn.execute("SELECT pref_key, pref_value FROM user_preferences WHERE user_id = ?", (user_id,)).fetchall()
if not rows: return {"message": "No preferences found."}
for key, value_str in rows: preferences[key] = json.loads(value_str)
return preferences
Talimat, bir iş akışını zorunlu kılar:
instruction="""
1. RECALL FIRST: First action MUST be `recall_user_preferences`.
3. LEARN: If a user states a new preference, use `save_user_preferences`.
"""
2. adım: Uygulama
👉💻 Cloud Shell terminalinizde aşağıdaki komutu çalıştırarak dosyayı Cloud Shell Düzenleyici'de açın:
cloudshell edit ~/memory_agent_starter/05_profile_agent/main.py
~/memory_agent_starter/05_profile_agent/main.py adlı kişiyi aç.
ADK'nin durumu otomatik olarak işlediği önceki modüllerin aksine, burada Temsilci kontrolü elinde tutar.
- Başlangıçta
recall_user_preferencesadlı kişiyi aramayı seçer. - "Veganım" dediğinizde
save_user_preferencesadlı kişiyi aramayı seçer.
3. adım: Profili oluşturun
👉💻 Komut dosyasını çalıştırın:
cd ~/memory_agent_starter
uv run python ~/memory_agent_starter/05_profile_agent/main.py
Şu sohbet akışını deneyin:
- "Merhaba, akşam yemeği planla." -> Temsilci veritabanını kontrol eder ve bir şey bulamaz. Tercihleri sorar.
- "Veganım." -> Temsilci, "vegan"ı veritabanına kaydeder.
- Komut dosyasını yeniden başlatın.
- "Merhaba, akşam yemeği planla." -> Temsilci veritabanını kontrol eder, "vegan" ifadesini görür ve hemen vegan bir restoran önerir.
Ana Fikir
Hafıza ile ilgili 5. kural: Karmaşık ve yapılandırılmış veriler için temsilcinize Okuma/Yazma Araçları verin. LLM'nin kendi uzun süreli depolama alanını yönetmesine izin verin.
8. Beyin: Çoklu Format Destekli Bellek

Konsept: "İnsan Deneyimi"
İnsanlar metinden daha fazlasını hatırlar. Bir fotoğrafın havasını, bir sesin tınısını, bir videonun hissettirdiklerini hatırlarız.
Vertex AI Memory Bank, temsilcinizin çok formatlı bellek kullanmasına olanak tanır. Görüntü, video ve sesleri alabilir, "anlayabilir" ve daha sonra geri getirebilir.
1. adım: Yapılandırma
👉💻 Cloud Shell terminalinizde aşağıdaki komutu çalıştırarak dosyayı Cloud Shell Düzenleyici'de açın:
cloudshell edit ~/memory_agent_starter/06_multimodal_agent/main.py
👉 06_multimodal_agent/main.py sayfasını açın. # TODO: Configure Memory Bank Topic yorumunu bulun.
Bu satırın tamamını aşağıdaki kodla değiştirin:
travel_topics = [
MemoryTopic(
managed_memory_topic=ManagedMemoryTopic(
managed_topic_enum=ManagedTopicEnum.USER_PREFERENCES
)
),
MemoryTopic(
managed_memory_topic=ManagedMemoryTopic(
managed_topic_enum=ManagedTopicEnum.USER_PERSONAL_INFO
)
),
MemoryTopic(
custom_memory_topic=CustomMemoryTopic(
label="travel_experiences",
description="""Memorable travel experiences including:
- Places visited and impressions
- Favorite restaurants, cafes, and food experiences
- Preferred accommodation types and locations
- Activities enjoyed (museums, hiking, beaches, etc.)
- Travel companions and social preferences
- Photos and videos from trips with location context""",
)
),
MemoryTopic(
custom_memory_topic=CustomMemoryTopic(
label="travel_preferences",
description="""Travel style and preferences:
- Budget preferences (luxury, mid-range, budget)
- Transportation preferences (flying, trains, driving)
- Trip duration preferences
- Season and weather preferences
- Cultural interests and language abilities
- Dietary restrictions and food preferences""",
)
),
MemoryTopic(
custom_memory_topic=CustomMemoryTopic(
label="travel_logistics",
description="""Practical travel information:
- Passport and visa information
- Frequent flyer numbers and hotel loyalty programs
- Emergency contacts
- Medical considerations and insurance
- Packing preferences and essentials
- Time zone preferences and jet lag strategies""",
)
),
]
# TODO: Configure Memory Bank Customization yorumunu bulma
Bu satırın tamamını aşağıdaki kodla değiştirin:
memory_bank_config = {
"customization_configs": [
{
"memory_topics": travel_topics,
}
],
"similarity_search_config": {
"embedding_model": f"projects/{PROJECT_ID}/locations/{LOCATION}/publishers/google/models/gemini-embedding-001"
},
"generation_config": {
"model": f"projects/{PROJECT_ID}/locations/{LOCATION}/publishers/google/models/gemini-2.5-flash"
},
}
2. adım: Dünyayı sindirme
test_trip_planner ayında şunları göndeririz:
- Kısa mesaj ("Merhaba")
- Resim (Önemli nokta)
- Video (Akdeniz)
- Ses klibi (Gaeta hakkında sesli not)
6_multimodal_agent/main.py işlevinin içindeki # TODO create session service and memory service yorumunu bulun.
Bu satırın tamamını aşağıdaki kodla değiştirin:
session_service = VertexAiSessionService(
project=PROJECT_ID, location=LOCATION, agent_engine_id=agent_engine_id
)
memory_service = VertexAiMemoryBankService(
project=PROJECT_ID, location=LOCATION, agent_engine_id=agent_engine_id
)
👉 Aynı dosyada (06_multimodal_agent/main.py) # TODO: create memory from session yorumunu bulun.
Bu satırın tamamını aşağıdaki kodla değiştirin:
await memory_service.add_session_to_memory(final_session_state)
Bu, sihirli çizgidir. Tüm bu rich media'yı Vertex AI'a gönderir. Vertex AI da bu verileri işler ve dizine ekler.
3. adım: Alım
👉💻 Cloud Shell terminalinizde aşağıdaki komutu çalıştırarak dosyayı Cloud Shell Düzenleyici'de açın:
cloudshell edit ~/memory_agent_starter/06_multimodal_agent/agent.py
Temsilcinin PreloadMemoryTool var.
tools=[PreloadMemoryTool(), budget_tool]
Yeni bir oturum başladığında bu araç, Hafıza Bankası'nda otomatik olarak alakalı geçmiş deneyimleri arar ve bunları bağlama ekler.
4. adım: Brain'i çalıştırın
👉💻 Cloud Shell terminalinizde komut dosyasını çalıştırın (Not: Bunun için Vertex AI'ın etkin olduğu bir Google Cloud projesi gerekir):
cd ~/memory_agent_starter
uv run python ~/memory_agent_starter/06_multimodal_agent/main.py
Son doğrulama adımını izleyin:
"Daha önce sizinle paylaştığım resim, video VE sese göre..."
Temsilci şu şekilde yanıt verir:
"Gaeta'yı ziyaret etmelisiniz. Bana Akdeniz'in videosunu gösterdin ve Gaeta'yı sevdiğini söylediğin bir ses klibi dinlettin."
Geçmişteki farklı medya türleri arasında bağlantı kurdu.
Ana Fikir
Hafıza ile ilgili 6. kural: En iyi hafıza deneyimi için Vertex AI Memory Bank'i kullanın. Metin, resim ve videoları tek bir aranabilir beyinde birleştirir.
9. Sonuç
Unutkan Japon Balığı'ndan Çok Kalemli Fil'e kadar yol katettiniz.
Oluşturduklarınız | Yetenek |
Oturum Temsilcisi | Kısa süreli sohbet belleği |
Çoklu Temsilci | Paylaşılan ekip hafızası |
Kalıcı Temsilci | Uzun vadeli geçmiş |
Stateful Agent | Dinamik, kendi kendini güncelleyen bellek |
Profil Temsilcisi | Yapılandırılmış veri belleği |
Çok formatlı temsilci | İnsan benzeri duyusal bellek |
Güven, hafızaya dayalıdır. Bu kalıpları uygulayarak kullanıcının zamanına ve geçmişine saygı duyan temsilciler oluşturabilir, böylece daha derin ve etkili etkileşimler sağlayabilirsiniz.
Kişiselleştirilmiş temsilcilerinizi oluşturmaya hemen başlayın.