מדריך למתחילים ל-Memory Bank עם ADK

‫Agent Platform Memory Bank מאפשר לסוכנים לנהל זיכרונות לטווח ארוך בסשנים שונים. כשמשתמשים ב-Memory Bank עם Agent Development Kit ‏(ADK), הנציג יכול לתזמר באופן אוטומטי קריאות ל-Memory Bank כדי לאחסן ולאחזר זיכרונות על סמך אינטראקציות של משתמשים.

במאמר הזה מוסבר איך ליצור סוכן ADK, להגדיר אותו לשימוש ב-Memory Bank ולתקשר איתו כדי ליצור זיכרונות ולגשת אליהם.

כדי לקבל מידע על ביצוע קריאות ישירות ל-API בלי ADK, עיינו במדריך למתחילים של Memory Bank API.

ניהול זיכרונות באמצעות שירות הזיכרון של ADK ו-Memory Bank

‫VertexAiMemoryBankService הוא wrapper של ADK סביב Memory Bank שמוגדר על ידי BaseMemoryService של ADK. אתם יכולים להגדיר פונקציות קריאה חוזרת (callback) וכלים שמתקשרים עם שירות הזיכרון כדי לקרוא ולכתוב זיכרונות.

הממשק של VertexAiMemoryBankService כולל את הרכיבים הבאים:

  • ‫memory_service.add_session_to_memory מפעיל בקשת GenerateMemories ל-Memory Bank באמצעות כל האירועים ב-adk.Session שצוין כתוכן המקור. אפשר לתזמר קריאות ל-method הזה באמצעות callback_context.add_session_to_memory בקריאות החוזרות (callbacks).

    from google.adk.agents.callback_context import CallbackContext
    
    async def add_session_to_memory_callback(callback_context: CallbackContext):
        await callback_context.add_session_to_memory()
        return None
    
  • ‫memory_service.add_events_to_memory, שמפעיל בקשת GenerateMemories ל-Memory Bank באמצעות קבוצת משנה של אירועים. אתם יכולים לתזמר קריאות ל-method הזה באמצעות callback_context.add_events_to_memory בקריאות החוזרות (callbacks).

    from google.adk.agents.callback_context import CallbackContext
    
    async def add_events_to_memory_callback(callback_context: CallbackContext):
        await callback_context.add_events_to_memory(events=callback_context.session.events[-5:-1])
        return None
    
  • ‫memory_service.search_memory מפעיל בקשת RetrieveMemories ל-Memory Bank כדי לאחזר זיכרונות רלוונטיים ל-user_id ול-app_name הנוכחיים. אתם יכולים לתזמר קריאות ל-method הזה באמצעות כלים מובנים לניהול זיכרון (LoadMemoryTool או PreloadMemoryTool) או כלי בהתאמה אישית שמפעיל את tool_context.search_memory.

לפני שמתחילים

כדי להשלים את השלבים שמוצגים במדריך הזה, קודם צריך לבצע את השלבים בקטע "תחילת העבודה" בדף "הגדרת Memory Bank".

הגדרה של משתני סביבה

כדי להשתמש ב-ADK, מגדירים את משתני הסביבה:

import os

os.environ["GOOGLE_GENAI_USE_ENTERPRISE"] = "TRUE"
os.environ["GOOGLE_CLOUD_PROJECT"] = "PROJECT_ID"
os.environ["GOOGLE_CLOUD_LOCATION"] = "LOCATION"

מחליפים את מה שכתוב בשדות הבאים:

יצירת סוכן ADK

כדי ליצור נציג עם זיכרון, צריך להגדיר כלים וקריאות חוזרות (callbacks) שמנהלים את הקריאות לשירות הזיכרון.

הגדרת קריאה חוזרת (callback) לתהליך יצירת זיכרון

כדי לתזמר קריאות ליצירת זיכרון, יוצרים פונקציית קריאה חוזרת שמפעילה את יצירת הזיכרון. אפשר לשלוח קבוצת משנה של אירועים (באמצעות callback_context.add_events_to_memory) או את כל האירועים בסשן (באמצעות callback_context.add_session_to_memory) לעיבוד ברקע:

from google.adk.agents.callback_context import CallbackContext

async def generate_memories_callback(callback_context: CallbackContext):
    # Option 1 (Recommended): Send events to Memory Bank for memory generation,
    # which is ideal for incremental processing of events.
    await callback_context.add_events_to_memory(
      events=callback_context.session.events[-5:-1])

    # Option 2: Send the full session to Memory Bank for memory generation.
    # It's recommended to only call this at the end of a session to minimize
    # how many times a single event is re-processed.
    await callback_context.add_session_to_memory()

    return None

הגדרת כלי לאחזור זיכרונות

כשמפתחים סוכן ADK, צריך לכלול כלי זיכרון ששולט במקרים שבהם הסוכן מאחזר זיכרונות ובאופן שבו הזיכרונות נכללים בהנחיה.

אם אתם משתמשים ב-PreloadMemoryTool, הנציג שלכם ישלוף זיכרונות בתחילת כל תור ויכלול את הזיכרונות שנשלפו בהוראות המערכת, וזה טוב ליצירת הקשר בסיסי לגבי המשתמש. אם משתמשים ב-LoadMemoryTool, המודל יפעיל את הכלי הזה כשהוא יחליט שצריך זיכרונות כדי לענות על השאילתה של המשתמש.

from google import adk
from google.adk.tools.load_memory_tool import LoadMemoryTool
from google.adk.tools.preload_memory_tool import PreloadMemoryTool

memory_retrieval_tools = [
  # Option 1: Retrieve memories at the start of every turn.
  PreloadMemoryTool(),
  # Option 2: Retrieve memories via tool calls. The model will only call this tool
  # when it decides that memories are necessary to respond to the user query.
  LoadMemoryTool()
]

agent = adk.Agent(
    model="gemini-3.5-flash",
    name='stateful_agent',
    instruction="""You are a Vehicle Voice Agent, designed to assist users with information and in-vehicle actions.

1.  **Direct Action:** If a user requests a specific vehicle function (e.g., "turn on the AC"), execute it immediately using the corresponding tool. You don't have the outcome of the actual tool execution, so provide a hypothetical tool execution outcome.
2.  **Information Retrieval:** Respond concisely to general information requests with your own knowledge (e.g., restaurant recommendation).
3.  **Clarity:** When necessary, try to seek clarification to better understand the user's needs and preference before taking an action.
4.  **Brevity:** Limit responses to under 30 words.
""",
    tools=memory_retrieval_tools,
    after_agent_callback=generate_memories_callback
)

אפשר גם ליצור כלי מותאם אישית לאחזור זיכרונות, שימושי כשרוצים לתת לסוכן הוראות מתי לאחזר זיכרונות:

from google import adk
from google.adk.tools import ToolContext, FunctionTool

async def search_memories(query: str, tool_context: ToolContext):
  """Query this tool when you need to fetch information about user preferences."""
  return await tool_context.search_memory(query)

agent = adk.Agent(
    model="gemini-3.5-flash",
    name='stateful_agent',
    instruction="""...""",
    tools=[FunctionTool(func=search_memories)],
    after_agent_callback=generate_memories_callback
)

הגדרת שירות זיכרון ומכונה של Memory Bank ב-ADK

אחרי שיוצרים סוכן עם זיכרון, צריך לקשר אותו לשירות זיכרון. תהליך ההגדרה של שירות הזיכרון של ה-ADK משתנה בהתאם למקום שבו פועל סוכן ה-ADK. סביבת זמן הריצה מתזמרת את ההפעלה של הסוכנים, הכלים והקריאות החוזרות (callbacks).

יצירת מכונה של Memory Bank

קודם צריך ליצור מכונה של Memory Bank. השלב הזה הוא אופציונלי אם אתם משתמשים ב-Agent Runtime כדי לפרוס את הנציג. מידע נוסף על התאמה אישית של ההתנהגות של Memory Bank זמין בקטע הגדרת המכונה של Memory Bank בדף "הגדרת Memory Bank".

import agentplatform

client = agentplatform.Client(
  project="PROJECT_ID",
  location="LOCATION"
)
# If you don't have a Memory Bank instance already, create a
# Memory Bank instance using the default configuration.
memory_bank = client.memory_banks.create()

# Optionally, print out the resource name. You will need the
# resource name if you want to interact with your Memory Bank instance later on.
print(memory_bank.name)

memory_bank_id = memory_bank.name.split("/")[-1]

מחליפים את מה שכתוב בשדות הבאים:

יצירת סביבת זמן ריצה של ADK

מעבירים את מזהה המכונה של Memory Bank לסקריפטים של זמן הריצה או הפריסה, כדי שהסוכן ישתמש ב-Memory Bank כשירות הזיכרון של ADK.

מפעיל מקומי

בדרך כלל משתמשים ב-adk.Runner בסביבה מקומית, כמו Colab. במקרה כזה, צריך ליצור ישירות את שירות הזיכרון ואת ה-runner.

import asyncio

from google.adk.memory import VertexAiMemoryBankService
from google.adk.sessions import VertexAiSessionService
from google.genai import types

memory_service = VertexAiMemoryBankService(
    project="PROJECT_ID",
    location="LOCATION",
    agent_engine_id="MEMORY_BANK_ID",
)

# You can use any ADK session service. This example uses Sessions.
session_service = VertexAiSessionService(
    project="PROJECT_ID",
    location="LOCATION",
    agent_engine_id="SESSIONS_ID",
)

runner = adk.Runner(
    agent=agent,
    app_name="APP_NAME",
    session_service=session_service,
    memory_service=memory_service
)

async def call_agent(query, session, user_id):
  content = types.Content(role='user', parts=[types.Part(text=query)])
  events = runner.run_async(
    user_id=user_id, session_id=session, new_message=content)

  async for event in events:
      if event.is_final_response():
          final_response = event.content.parts[0].text
          print("Agent Response: ", final_response)

מחליפים את מה שכתוב בשדות הבאים:

  • ‫PROJECT_ID: מזהה הפרויקט.
  • ‫LOCATION: האזור שלכם. רשימת האזורים שבהם אפשר להשתמש ב-Memory Bank
  • ‫APP_NAME: שם האפליקציה ב-ADK. שם האפליקציה ייכלל במילון scope של הזיכרונות שנוצרו, כדי שהזיכרונות יהיו מבודדים בין המשתמשים ובין האפליקציות.
  • ‫MEMORY_BANK_ID: המזהה של המכונה ב-Memory Bank. לדוגמה, 456 ב-projects/my-project/locations/us-central1/reasoningEngines/456.
  • ‫SESSIONS_ID: המזהה של המכונה של Agent Platform Sessions. לדוגמה, 789 ב-projects/my-project/locations/us-central1/reasoningEngines/789.

‫Agent Runtime ב-Gemini Enterprise Agent Platform

אפשר להשתמש בתבנית של Agent Runtime ADK (AdkApp) גם באופן מקומי וגם כדי לפרוס סוכן ADK ב-Agent Runtime. כשפורסים את תבנית ה-ADK של Memory Bank ב-Agent Platform, היא משתמשת ב-VertexAiMemoryBankService כשירות הזיכרון שמוגדר כברירת מחדל. כך אפשר ליצור את המכונה של Memory Bank ולפרוס אותה בסביבת זמן ריצה בשלב אחד.

במאמר הגדרת Memory Bank מוסבר איך מגדירים את המכונה של Memory Bank, כולל איך להתאים אישית את ההתנהגות של Memory Bank.

כדי לפרוס את סוכן ה-ADK עם הזיכרון ב-Agent Runtime, משתמשים בקוד הבא:

import asyncio

import agentplatform
from agentplatform.frameworks import AdkApp

client = agentplatform.Client(
  project="PROJECT_ID",
  location="LOCATION"
)

adk_app = AdkApp(agent=agent)

# Create a new resource with your agent deployed to Agent Runtime.
# The Agent Runtime instance will also include an empty Memory Bank instance.
runtime_instance = client.runtimes.create(
      agent=adk_app,
      config={
            "staging_bucket": "STAGING_BUCKET",
            "requirements": ["google-cloud-agentplatform[runtimes,adk]"]
      }
)

# Alternatively, update an existing resource to deploy your agent to Agent Platform.
# Your agent will have access to the Runtime instance's existing memories.
runtime_instance = client.runtimes.update(
      name=agent_engine.api_resource.name,
      agent=adk_app,
      config={
            "staging_bucket": "STAGING_BUCKET",
            "requirements": ["google-cloud-agentplatform[runtimes,adk]"]
      }
)

async def call_agent(query, session_id, user_id):
    async for event in agent_engine.async_stream_query(
        user_id=user_id,
        session_id=session_id,
        message=query,
    ):
        print(event)

מחליפים את מה שכתוב בשדות הבאים:

כשמריצים את התבנית של ADK באופן מקומי, היא משתמשת ב-InMemoryMemoryService כשירות הזיכרון שמוגדר כברירת מחדל. עם זאת, אתם יכולים לשנות את שירות הזיכרון שמוגדר כברירת מחדל כדי להשתמש ב-VertexAiMemoryBankService:

def memory_bank_service_builder():
    return VertexAiMemoryBankService(
        project="PROJECT_ID",
        location="LOCATION",
        agent_engine_id="MEMORY_BANK_ID"
    )

adk_app = AdkApp(
      agent=adk_agent,
      # Override the default memory service.
      memory_service_builder=memory_bank_service_builder
)

async def call_agent(query, session_id, user_id):
  # adk_app is a local agent. If you want to deploy it to Agent Runtime,
  # use `client.runtimes.create(...)` or `client.runtimes.update(...)`
  # and call the returned Agent Runtime instance instead.
  async for event in adk_app.async_stream_query(
      user_id=user_id,
      session_id=session_id,
      message=query,
  ):
      print(event)

מחליפים את מה שכתוב בשדות הבאים:

Cloud Run

כדי לפרוס את הנציג ב-Cloud Run, קראו את ההוראות במסמכי התיעוד של ADK כדי ללמוד איך להגדיר את הנציג לפריסה ב-Cloud Run.

adk deploy cloud_run \
    ...
    --memory_service_uri=agentengine://AGENT_ENGINE_ID

Google Kubernetes Engine (GKE)

כדי לפרוס את הסוכן ב-GKE, קראו את ההוראות במסמכי התיעוד של ADK כדי ללמוד איך להגדיר את הסוכן לפריסה ב-GKE.

adk deploy gke \
    ...
    --memory_service_uri=agentengine://AGENT_ENGINE_ID

ADK Web

ממשק האינטרנט של ADK מאפשר לכם לבדוק את הנציגים ישירות בדפדפן.

export GOOGLE_CLOUD_PROJECT="PROJECT_ID"
export GOOGLE_CLOUD_LOCATION="LOCATION"

adk web --memory_service_uri=agentengine://MEMORY_BANK_ID

מחליפים את מה שכתוב בשדות הבאים:

אינטראקציה עם הסוכן

אחרי שמגדירים את הנציג ואת Memory Bank, אפשר לתקשר עם הנציג. אם סיפקתם קריאה חוזרת (callback) כדי להפעיל את תהליך יצירת הזיכרון כשהפעלתם את הנציג, תהליך יצירת הזיכרון יופעל בכל פעם שהנציג יופעל.

הזיכרונות יישמרו בהיקף {"user_id": USER_ID, "app_name": APP_NAME} בהתאם למזהה המשתמש ולשם האפליקציה שמשמשים להפעלת ה-Agent.

השיטה לאינטראקציה עם הנציג תלויה בסביבת ההפעלה שלו:

מפעיל מקומי

# Use `asyncio.run(session_service.create(...))` if you're running this
# code as a standard Python script.
session = await session_service.create_session(
    app_name="APP_NAME",
    user_id="USER_ID"
)

# Use `asyncio.run(call_agent(...))` if you're running this code as a
# standard Python script.
await call_agent(
    "Can you fix the temperature?",
    session.id,
    "USER_ID"
)

מחליפים את מה שכתוב בשדות הבאים:

  • ‫APP_NAME: שם האפליקציה של ה-runner.
  • ‫USER_ID: מזהה של המשתמש. הזיכרונות שנוצרים מהסשן הזה מקושרים למזהה האטום הזה. היקף הזיכרונות שנוצרו מאוחסן בתור {"user_id": "USER_ID"}.

Agent Runtime

כשמשתמשים בתבנית ADK, אפשר לקרוא ל-Agent Runtime כדי ליצור אינטראקציה עם הזיכרון והסשנים.

# Use `asyncio.run(agent_engine.async_create_session(...))` if you're
# running this code as a standard Python script.
session = await agent_engine.async_create_session(user_id="USER_ID")

# Use `asyncio.run(call_agent(...))` if you're running this code as a
# standard Python script.
await call_agent(
    "Can you fix the temperature?",
    session.get("id"),
    "USER_ID"
)

מחליפים את מה שכתוב בשדות הבאים:

  • ‫USER_ID: מזהה של המשתמש. הזיכרונות שנוצרים מהסשן הזה מקבלים מזהה אטום. ההיקף של הזיכרונות שנוצרו נשמר בתור {"user_id": "USER_ID"}.

Cloud Run

עיינו בקטע בדיקת הנציג במסמכי התיעוד של פריסת ADK ב-Cloud Run.

GKE

עיינו בקטע בדיקת הנציג במסמכי התיעוד של פריסת ADK GKE.

ADK Web

כדי להשתמש ב-ADK Web, עוברים לשרת המקומי בכתובת http://localhost:8000.

כברירת מחדל, ADK Web יגדיר את מזהה המשתמש בתור user. כדי לשנות את מזהה המשתמש שמוגדר כברירת מחדל, מוסיפים את userId לפרמטרים של השאילתה, למשל http://localhost:8000?userId=YOUR_USER_ID.

מידע נוסף זמין בדף ADK Web במסמכי התיעוד של ADK.

אינטראקציה לדוגמה

הסשן הראשון

אם השתמשתם ב-PreloadMemoryTool, הנציג ינסה לאחזר זיכרונות בתחילת כל תור כדי לגשת להעדפות שהמשתמש העביר לנציג בעבר. באינטראקציה הראשונה של הנציג עם המשתמש, אין זיכרונות זמינים לאחזור. לכן, הנציג לא יודע מהן העדפות המשתמש, כמו הטמפרטורה המועדפת, כפי שמוצג בדוגמה הבאה:

  1. הפנייה הראשונה:

    • המשתמש: "אתה יכול לשנות את הטמפרטורה?"

    • (קריאה לכלי): ה-ADK מנסה לאחזר זיכרונות, אבל אין זיכרונות זמינים.

    • המודל: "איזו טמפרטורה אתם מעדיפים?"

    • (קריאה חוזרת): ה-ADK מפעיל את תהליך יצירת הזיכרון. לא נשלפים זיכרונות.

  2. הפנייה השנייה:

    • משתמש: נעים לי ב-21 מעלות.

    • (קריאה לכלי): ה-ADK מנסה לאחזר זיכרונות, אבל אין זיכרונות זמינים.

    • המודל: בסדר, עדכנתי את הטמפרטורה ל-21 מעלות.

    • (קריאה חוזרת): ה-ADK מפעיל את תהליך יצירת הזיכרון. נוצר הזיכרון "אני אוהב שהטמפרטורה היא 21 מעלות".

סשן שני

הזיכרון שחולץ יהיה זמין בסשן הבא של אותו שם אפליקציה ומזהה משתמש. אם המשתמש מספק מידע דומה או סותר לזיכרונות קיימים, המידע החדש יתמזג עם הזיכרונות הקיימים.

  1. הפנייה הראשונה

    • משתמש: תתקן את הטמפרטורה. זה כל כך לא נוח!

    • (קריאה לכלי): ערכת ה-ADK מנסה לאחזר זיכרונות. הזיכרון "אני אוהב שהטמפרטורה היא 21 מעלות" מאוחזר.

    • המודל: בסדר, עדכנתי את הטמפרטורה ל-21 מעלות.

    • (קריאה חוזרת): ה-ADK מפעיל את תהליך יצירת הזיכרון. לא נשלפו זיכרונות כי המשתמש לא שיתף שום דבר משמעותי שצריך לשמור.

  2. הפנייה השנייה

    • המשתמש: האמת, אני מעדיף שיהיה חם יותר בבוקר.

    • (קריאה לכלי): ערכת ה-ADK מנסה לאחזר זיכרונות. הזיכרון "אני אוהב שהטמפרטורה היא 21 מעלות" מאוחזר.

    • המודל: אוקיי, העליתי את הטמפרטורה.

    • (קריאה חוזרת): ה-ADK מפעיל את תהליך יצירת הזיכרון. הזיכרון הקיים "אני אוהב שהטמפרטורה היא 21 מעלות" מתעדכן ל "בדרך כלל אני אוהב שהטמפרטורה היא 21 מעלות, אבל בבקרים אני מעדיף שיהיה חם יותר".

שימוש ב-Memory Bank במספר אזורים עם סביבת זמן ריצה אזורית

כשמשתמשים בסביבת זמן ריצה עם Memory Bank מובנה, הסוכן ו-Memory Bank נפרסים באותו אזור כברירת מחדל. עם זאת, אתם יכולים להפריד ביניהם כדי להשתמש ב-Memory Bank במספר אזורים (לדוגמה, us) עם סביבת זמן ריצה אזורית (לדוגמה, us-central1). ההגדרה הזו מאפשרת לכם לשמור על Memory Bank מרכזי בפריסות אזוריות שונות.

כדי להשתמש ב-Memory Bank במספר אזורים, צריך לשנות את ברירת המחדל של ה-builder של שירות הזיכרון ב-ADK, כך שיצביע על המיקום במספר אזורים ועל המזהה התואם של Memory Bank.

import agentplatform
from google.adk.memory import VertexAiMemoryBankService
from agentplatform.frameworks import AdkApp

# Create the Memory Bank instance in a multi-region location (for example, 'us')
client_mb = agentplatform.Client(project="PROJECT_ID", location="us")
memory_bank = client_mb.memory_banks.create()
memory_bank_id = memory_bank.name.split("/")[-1]


# Point your memory service to the 'us' location, 'us' Memory Bank
def memory_bank_service_builder():
    return VertexAiMemoryBankService(
        project="PROJECT_ID",
        location="us",
        agent_engine_id=memory_bank_id
    )

# Create the AdkApp with the overridden builder
adk_app = AdkApp(
    agent=agent,
    memory_service_builder=memory_bank_service_builder
)

# Deploy the runtime to a specific region (for example, 'us-central1')
client_runtime = agentplatform.Client(project="PROJECT_ID", location="us-central1")
runtime_instance = client_runtime.runtimes.create(
    agent=adk_app,
    config={
        "staging_bucket": "STAGING_BUCKET",
        "requirements": ["google-cloud-agentplatform[runtimes,adk]"]
    }
)

מחליפים את מה שכתוב בשדות הבאים:

  • ‫PROJECT_ID: מזהה הפרויקט.
  • ‫STAGING_BUCKET: הקטגוריה של Cloud Storage שמשמשת להכנת Agent Runtime.

הסרת המשאבים

כדי להסיר את כל המשאבים שבהם השתמשתם בפרויקט, אתם יכולים למחוק את הפרויקט ב- Google Cloud שבו השתמשתם במדריך למתחילים.

אם לא, אתם יכולים למחוק את המשאבים הספציפיים שיצרתם במדריך הזה, באופן הבא:

  1. כדי למחוק את המכונה של Agent Runtime, השתמשו בדוגמת הקוד הבאה. הפעולה הזו גם תמחק את כל הסשנים או הזיכרונות ששייכים לסביבת זמן הריצה הזו.

    client_runtime.runtimes.delete(name=runtime_instance.api_resource.name, force=True)
    client_mb.memory_banks.delete(name=memory_bank.name, force=True)
    
  2. מוחקים את כל הקבצים שנוצרו באופן מקומי.

המאמרים הבאים

התחלה מהירה

מתחילים להשתמש ב-Memory Bank API כדי לנהל זיכרונות לטווח ארוך.