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

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

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

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

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

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

הממשק של VertexAiMemoryBankService כולל:

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

    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 בקריאות החוזרות.

    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 הנוכחיים. אפשר לתזמן קריאות לשיטה הזו באמצעות כלי זיכרון מובנים (LoadMemoryTool או PreloadMemoryTool) או כלי מותאם אישית שמפעיל את tool_context.search_memory.

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

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

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

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

import os

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

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

יצירת סוכן ADK

כדי ליצור סוכן עם זיכרון, צריך להגדיר כלים ופונקציות קריאה חוזרת (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
)

הגדרת שירות זיכרון של ADK Memory Bank ומופע Memory Bank

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

יצירת מופע של Memory Bank

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

import vertexai

client = vertexai.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.agent_engines.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.api_resource.name)

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

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

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

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

רץ מקומי

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

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. לדוגמה, 789 ב-projects/my-project/locations/us-central1/reasoningEngines/789.

Agent Runtime on Gemini Enterprise Agent Platform

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

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

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

import asyncio

import vertexai
from vertexai.agent_engines import AdkApp

client = vertexai.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.
agent_engine = client.agent_engines.create(
      agent_engine=adk_app,
      config={
            "staging_bucket": "STAGING_BUCKET",
            "requirements": ["google-cloud-aiplatform[agent_engines,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.
agent_engine = client.agent_engines.update(
      name=agent_engine.api_resource.name,
      agent_engine=adk_app,
      config={
            "staging_bucket": "STAGING_BUCKET",
            "requirements": ["google-cloud-aiplatform[agent_engines,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.agent_engines.create(...)` or `client.agent_engines.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)

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

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

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

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

איך מתקשרים עם הסוכן

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

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

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

רץ מקומי

# 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: שם האפליקציה של הרצת התהליכים.
  • 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 מנסה לאחזר זיכרונות, אבל אין זיכרונות זמינים.

    • מודל: "What temperature do you prefer?"‎

    • (Callback): ADK triggers memory generation. לא חולצו זיכרונות.

  2. תור שני:

    • משתמש: נוח לי ב-71 מעלות.

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

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

    • (Callback): ADK triggers memory generation. נוצר זיכרון עם ההגדרה 'I like the temperature 71 degrees' (אני אוהב את הטמפרטורה 22 מעלות).

סשן שני

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

  1. התור הראשון

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

    • (קריאה לכלי): ADK מנסה לאחזר זיכרונות. הזיכרון "I like the temperature 71 degrees" (הטמפרטורה המועדפת עליי היא 22 מעלות) מאוחזר.

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

    • (Callback): ADK triggers memory generation. לא חולצו זיכרונות כי המשתמש לא שיתף תוכן משמעותי שצריך לשמור.

  2. תור שני

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

    • (קריאה לכלי): ADK מנסה לאחזר זיכרונות. הזיכרון "I like the temperature 71 degrees" (הטמפרטורה המועדפת עליי היא 22 מעלות) מאוחזר.

    • מודל: Ok, I've made the temperature warmer.

    • (התקשרות חזרה): ADK מפעיל יצירת זיכרון. הזיכרון הקיים 'I like the temperature 71 degrees' (אני אוהב שהטמפרטורה תהיה 22 מעלות) מתעדכן ל-'I generally like the temperature to be 71 degrees, but I like it to be warmer in the mornings' (באופן כללי אני אוהב שהטמפרטורה תהיה 22 מעלות, אבל אני אוהב שהיא תהיה חמה יותר בבוקר)'.

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

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

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

import vertexai
from google.adk.memory import VertexAiMemoryBankService
from vertexai.agent_engines import AdkApp

# Create the Memory Bank instance in a multi-region location (for example, 'us')
client_mb = vertexai.Client(project="PROJECT_ID", location="us")
memory_bank = client_mb.agent_engines.create()
memory_bank_id = memory_bank.api_resource.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 = vertexai.Client(project="PROJECT_ID", location="us-central1")
agent_engine = client_runtime.agent_engines.create(
    agent=adk_app,
    config={
        "staging_bucket": "STAGING_BUCKET",
        "requirements": ["google-cloud-aiplatform[agent_engines,adk]"]
    }
)

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

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

הסרת המשאבים

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

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

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

    agent_engine.delete(force=True)
    
  2. מוחקים את כל הקבצים שנוצרו באופן מקומי.

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

תחילת העבודה

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