ADK ile Durumlu ve Kişiselleştirilmiş Ajanlar Oluşturma

1. Giriş

title

"Japon Balığı" Sorunu

Tokyo'da hayalinizdeki tatili planlamak için bir seyahat acentesiyle anlaştığınızı düşünün. "The Goldfish Problem"ın nasıl çalıştığını görmek için Oturum Aracısı'nı kullanın.

Ofislerine girip şö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ı'nı ziyaret etmeyi ve Sukiyabashi Jiro'da suşi yemeyi planladım."

Gülümseyerek şöyle diyorsunuz:

"That sounds perfect! Seyahat planını bana gönderebilir misin?"

Temsilci size boş boş bakıp sorar:

"Merhaba! Bugün size nasıl yardımcı olabilirim?"

Bu, "Japon Balığı Sorunu"dur. Bellek olmadan her etkileşim boş bir sayfa olur. Zeka var, temsilci seyahat planlamayı biliyor ancak süreklilik eksik. Yapay zeka aracısının gerçekten faydalı olması için hatırlaması gerekir.

Bugünkü Göreviniz

Bu atölyede, hatırlayan, öğrenen ve uyum sağlayan bir Seyahat Acentesi oluşturarak Goldfish Problem'i çözeceksiniz. 6 Ajan Hafızası Seviyesi'nde ilerleyerek chatbot gibi değil, ö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 aracı durumu

Ekip üyeleri arasında not paylaşma

3. Seviye

Kalıcılık (Persistence)

Sistem yeniden başlatıldıktan sonra bile sizi hatırlar.

4. Seviye

Geri aramalar

Belleği tamamen bağımsız olarak güncelleme

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 Bellek Yığını

Kod yazmadan önce kullandığımız araçları anlayalım. Google Agent Development Kit (ADK), belleği yönetmek için yapılandırılmış bir yöntem sunar:

  1. Oturum: Bir görüşmenin kapsayıcısı. Ne söylendiğinin geçmişini tutar.
  2. Durum: Oturuma eklenen bir anahtar/değer "not defteri". Aracılar, belirli bilgileri (ör. destination="Tokyo") depolamak için bunu kullanır.
  3. MemoryService: Uzun süreli depolama. Kullanıcı tercihleri veya analiz edilmiş dokümanlar gibi öğeleri burada kalıcı olarak saklarız.

2. Kur

Yapay zeka aracılarımızı desteklemek için iki şeye ihtiyacımız var: temel işlevleri sağlayacak bir Google Cloud projesi.

Birinci Bölüm: Fatura Hesabını Etkinleştirme

Bu codelab'i çalıştırmak için biraz kredisi olan bir faturalandırma hesabına ihtiyacınız var. Başlamak için bu codelab'in üst kısmındaki banner'da yer alan kredileri kullanın. Zaten bir faturalandırma hesabına bağlıysanız bu adımı atlayabilirsiniz.

2. Bölüm: Açık Ortam

  1. 👉 Doğrudan Cloud Shell Düzenleyici'ye gitmek için bu bağlantıyı tıklayın.
  2. 👉 Bugün herhangi bir noktada yetkilendirme yapmanız istenirse devam etmek için Yetkilendir'i tıklayın. Cloud Shell'i yetkilendirmek için tıklayın.
  3. 👉 Terminal ekranın alt kısmında görünmüyorsa açın:
    • Görünüm'ü tıklayın.
    • Terminal'i tıklayın.Cloud Shell Düzenleyici'de yeni terminal açma
  4. 👉💻 Terminalde, aşağıdaki komutu kullanarak kimliğinizin doğrulandığını ve projenin proje kimliğinize ayarlandığını doğrulayın:
    gcloud auth list
    
  5. 👉💻 Bootstrap projesini GitHub'dan kopyalayın:
    git clone https://github.com/cuppibla/memory_agent_starter
    
    
  6. 👉💻 Kurulum komut dosyasını proje dizininden çalıştırın.
    cd ~/memory_agent_starter
    ./init.sh
    
    Kurulum sürecinin geri kalanı, komut dosyası tarafından otomatik olarak gerçekleştirilir.
  7. 👉💻 Gerekli proje kimliğini ayarlayın:
    gcloud config set project $(cat ~/project_id.txt) --quiet
    

Üçüncü Bölüm: İzinleri ayarlama

  1. 👉💻 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
    
  2. 👉💻 Terminalde aşağıdaki komutları çalıştırarak gerekli izinleri verin:
    . ~/memory_agent_starter/set_env.sh
    

Sizin için bir .env dosyasının oluşturulduğunu fark edin. Bu bölümde proje bilgileriniz gösterilir.

3. The Foundation - Session & State

durum bilgili

Kavram: Bağlam Çok Önemlidir

En temel bellek biçimi Oturum Belleği'dir. Bu sayede, "Onu satın almak istiyorum" cümlesindeki "onu" kelimesinin 10 saniye önce bahsettiğiniz ayakkabıyı ifade ettiğini ajan anlayabilir.

ADK'da bunu Session nesnesiyle yönetiriz.

  • Durumsuz Yaklaşım: Her mesaj için yeni bir oturum oluşturma.
  • Durumlu Yaklaşım: Tek bir oturum oluşturup bu oturumu görüşmenin tamamında yeniden kullanma.

1. adım: Aracıyı 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ç.

👉 # TODO: Create a root agent işlevinin içindeki agent.py 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öylüyor ancak kod, hatırlama özelliğini sağlamalıdır.

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 öğesini açın, main.py işlevinin içindeki yorumu # TODO: Create a runner with in memorysession service 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
    )

👉 # TODO: create a different session to test işlevi içindeki main.py 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 etme

"Kısa" ve "uzun" süreli hafıza arasındaki farkı gösteren iki işlevimiz var.

1. Senaryo: Durumlu (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: Aracıyı çalıştırın

Farkı uygulamalı olarak görelim. Komut dosyasını çalıştırın:

👉💻 Komut satırında aşağıdaki komutu çalıştırın:

cd ~/memory_agent_starter
uv run python ~/memory_agent_starter/01_session_agent/main.py

1. Senaryoyu inceleyin: Aracı, ilk mesajdaki tercihleriniz hatırlıyor ve ikinci mesajdaki planı buna göre uyarlıyor.

2. Senaryoyu inceleyin: İkinci turda ("Yemekle ilgili neyi sevdiğimi hatırlıyor musun?") yeni bir oturum olduğu için temsilci tamamen başarısız oluyor. Bu hata mesajı, "Ne dediğini anlamıyorum" anlamına gelir.

Ana Fikir

Bellek ile ilgili 1. Kural: Sohbet bağlamını korumak için her zaman session.id simgesini yeniden kullanın. Session nesnesi, aracınızın kısa süreli bellek arabelleğidir.

4. The Team - Multi-Agent State

yiyecek

Konsept: "Telefon Oyunu"

Birden fazla temsilci birlikte çalıştığında, bir dosya klasörünü birbirine ileten iş arkadaşları gibi çalışırlar. Bir temsilci klasöre not yazdığında, sonraki temsilci bu notu okuyabilmelidir.

ADK'da bu "klasör" Durum'dur.

  • State, oturumun içinde bulunan bir sözlüktür ({"key": "value"}).
  • Oturumdaki tüm temsilciler bu dosyayı okuyabilir veya dosyaya yazabilir.

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']
)

👉 # TODO: transportation agent işlevi içindeki agent.py 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}.
    """,
)

👉 # TODO: root_agent işlevinin içindeki agent.py 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:

  1. Foodie Agent: Restoran bulur.
  2. Ulaşım Acentesi: İlgili restorana 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...
    """,
)
  1. output_key="destination": Yemek Uzmanı'nın yanıtı verimli bir şekilde kaydedilir.
  2. {destination}: Ulaşım Ajanı bu yanıtı otomatik olarak okur.

(İşlem Gerekmez) 2. adım: Düzenleyici

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: Takımı yönetin

👉💻 Cloud Shell terminalinde çoklu aracı iş akışını yürütün:

cd ~/memory_agent_starter
uv run python ~/memory_agent_starter/02_multi_agent/main.py

Ne olur?

  1. Foodie Agent: "Jin Sho"yu (veya benzerini) bulur.
  2. ADK: "Jin Sho"yu state['destination'] konumuna kaydeder.
  3. Ulaşım Ajanı: Talimatında "Jin Sho"yu alıyor.
  4. Sonuç: "Caltrain istasyonundan Jin Sho'ya gitmek için University Ave'den aşağı doğru yürüyün..."

Ana Fikir

Belleğin 2. Kuralı: Yapılandırılmış bilgileri aracılar arasında aktarmak için Durum'u kullanın. Yazmak için output_key, okumak için {placeholders} simgesini kullanın.

5. The Reboot - Persistence

durum bilgili

Kavram: "Yeniden Başlatma Sorunu"

Şu ana kadar belleğimiz InMemory oldu. Komut dosyasını durdurup tekrar başlatırsanız ajan her şeyi unutur. Bu, her kapatıldığında sabit sürücüsünü silen bir bilgisayara benzer.

Bu sorunu düzeltmek için kalıcılığa ihtiyacımız var. InMemorySessionService yerine DatabaseSessionService kullanırız.

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 kaydediliyor.

2. adım: Oturumlar arası alma

Kalıcılık, sohbetlere devam etmenin yanı sıra geçmiş sohbetlerden öğrenmeyi de sağlar.

Aynı dosyada ~/memory_agent_starter/03_persistent_agent/main.py Test Durumu 3: Oturumlar Arası Alma'ya 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
    )

👉 # TODO: Extract content from the OLD session işlevi içindeki main.py yorumunu bulun.

Bu satırın tamamını aşağıdaki kodla değiştirin:

                    previous_context += f"- {role}: {text}\n"

👉 # TODO: Manually inject the context to the query işlevi içindeki main.py 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, kullanıcının aylar sonra geri gelmesini simüle eder. Bu eski geçmişi yalnızca bir veritabanıyla alabilirsiniz.

3. adım: Yeniden başlatma işleminden sonra

👉💻 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şturulur. Şunu deneyin: Komut dosyasını iki kez çalıştırın.

  • İkinci çalıştırmada "Mevcut oturuma devam edildi" ifadesini bulun.
  • Ajan, veritabanı dosyasından yüklendiği için ilk çalıştırmadaki bağlamı hatırlar.

Ana Fikir

Bellek ile ilgili 3. Kural: Üretim için DatabaseSessionService kullanın. Kullanıcı etkileşimlerinin sunucu yeniden başlatma işlemlerinden etkilenmemesini sağlar ve uzun vadeli geçmiş analizine olanak tanır.

6. The Spy - Callbacks

durum bilgili

Bazen, hafızayı yalnızca ajanın söylediklerine göre değil, yaptıklarına göre de otomatik olarak güncellemeniz gerekir. Ajanı izleyip not alan bir "casus" istiyorsunuz.

ADK'da bu casus Callback'tir. adk_callback

  • after_tool_callback: Ajan her çalıştığında çalışan 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

👉 Dosyada ~/memory_agent_starter/04_stateful_agent/agent.py yorumu bulun # TODO: Implement call back logic.

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: Aracının talimatı artık bir dize değil, işlevdir. Duruma 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: Spy'ı 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 ajanı çalıştırdığınızda bir döngü görürsünüz.

  1. 1. tur: Müze istersiniz. Casusluk setleri last_activity="CULTURAL".
  2. 2. tur: Başka bir müze istersiniz.
  3. Agent Instruction güncellemeleri: "CULTURAL is BANNED".
  4. Temsilci: "Başka bir müze yapamam. Parka gitmeye ne dersin?"

[CALLBACK] ve [STATE UPDATE] için konsol günlüklerini izleyin. Aracı çalışırken belleğin nasıl değiştiğini gerçek zamanlı olarak görebilirsiniz.

Ana Fikir

Bellekle ilgili 4. Kural: Durum yönetimini otomatikleştirmek için geri çağırmaları kullanın. Ajanınız, yalnızca işini yaparak kendi bağlamını oluşturur.

7. Dosya Dolabı - Özel Araçlar

Kavram: "Yapılandırılmış Bellek"

durum bilgili

Şimdiye kadar "Bellek" bir sohbet günlüğü veya basit bir anahtar/değer çiftiydi. Ancak diet: vegan, budget: high, pets: [cat, dog] gibi karmaşık bir kullanıcı profilini hatırlamanız gerekirse ne olur?

Bu nedenle, hafızayı Araç olarak ele alırız. Temsilci, dosya dolabını ne zaman açacağına (okuma) ve ne zaman rapor oluşturacağına (yazma) açıkça karar verir. özel araçlar diyagramı

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

👉 Bu dosyada: ~/memory_agent_starter/05_profile_agent/tools.py.

Bu iki özel aracı uygulamamız gerekir:

  1. save_user_preferences: Veritabanına yazar.
  2. recall_user_preferences: Veritabanından okur.

# TODO: implement save_user_preferences tools işlevinin içindeki ~/memory_agent_starter/05_profile_agent/tools.py 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())}"

👉 # TODO: implement recall_user_preferences tools işlevi içindeki 05/tools.py 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: Yürütme

👉💻 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'nın durumu otomatik olarak yönettiği önceki modüllerin aksine, burada kontrol Agent'tadır.

  • Başlangıçta recall_user_preferences'ı aramayı seçer.
  • "Veganım" dediğinizde save_user_preferences'ı aramayı seçiyor.

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:

  1. "Merhaba, akşam yemeği planla." -> Ajan, veritabanını kontrol eder ancak hiçbir şey bulamaz. Tercihleri sorar.
  2. "Veganım." -> Temsilci, "vegan"ı veritabanına kaydeder.
  3. Komut dosyasını yeniden başlatın.
  4. "Merhaba, akşam yemeği planla." -> Ajan, veritabanını kontrol eder, "vegan"ı görür ve hemen bir vegan restoran önerir.

Ana Fikir

Belleğin 5. Kuralı: Karmaşık ve yapılandırılmış veriler için aracınıza Okuma/Yazma Araçları'nı verin. LLM'nin kendi uzun süreli depolama alanını yönetmesine izin verin.

8. Beyin - Çok Formatlı Bellek

durum bilgili

Kavram: "İnsan Deneyimi"

İnsanlar metinden daha fazlasını hatırlar. Fotoğrafın atmosferini, sesin tonunu, videonun duygusunu hatırlarız.

Vertex AI Memory Bank, aracınızın çok formatlı bellek işlemesini sağlar. Resimleri, videoları ve sesleri alabilir, "anlayabilir" ve daha sonra alabilir.

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 seçeneğini açın. Yorumu bulun # TODO: Configure Memory Bank Topic.

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""",
        )
    ),
]

Yorumu bulun # TODO: Configure Memory Bank Customization

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ı Yutmak

test_trip_planner tarihinde gönderdiğimiz:

  1. Kısa mesaj ("Merhaba")
  2. Resim (Önemli nokta)
  3. Video (Akdeniz)
  4. Ses klibi (Gaeta hakkında sesli not)

# TODO create session service and memory service işlevinin içindeki 6_multimodal_agent/main.py 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 yorumu # TODO: create memory from session 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 çizgi. Bu rich media'ların tümü, işleyip dizine eklemek üzere Vertex AI'a gönderilir.

3. adım: Alma

👉💻 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ç, Bellek Bankası'nda ilgili geçmiş deneyimleri otomatik olarak 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: Bu işlem için Vertex AI'ın etkinleştirildiği 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 yanıtı verir:

"Gaeta'yı ziyaret etmelisin! Bana Akdeniz'in videosunu ve Gaeta'yı sevdiğini söylediğin bir ses klibini göstermiştin."

Geçmişteki farklı medya türleri arasındaki bağlantıları kurdu.

Ana Fikir

Hafızayla ilgili 6. Kural: En iyi hafıza deneyimi için Vertex AI Memory Bank'ı kullanın. Metinleri, resimleri ve videoları tek bir aranabilir beyinde birleştirir.

9. Sonuç

Unutkan bir Japon balığından çok formatlı bir file dönüştünüz.

Oluşturduğunuz

Yetki

Session Agent

Kısa süreli görüşme belleği

Çoklu Temsilci (Multi-Agent)

Paylaşılan ekip belleği

Persistent Agent

Uzun süreli geçmiş

Durum bilgili aracı

Dinamik, kendi kendini güncelleyen bellek

Profil Aracısı

Yapılandırılmış veri belleği

Çok formatlı temsilci

İnsana benzer duyusal bellek

Güven, hafızaya dayanır. Bu kalıpları uygulayarak kullanıcının zamanına ve geçmişine saygı duyan aracıları oluşturur, böylece daha derin ve etkili etkileşimler elde edersiniz.

Kişiselleştirilmiş temsilcilerinizi oluşturmaya bugün başlayın.