ADK を使用したメモリバンクのクイックスタート

Agent Platform メモリバンクを使用すると、エージェントはセッション間で長期記憶を管理できます。Agent Development Kit(ADK)と組み合わせて使用すると、エージェントはユーザーの操作に基づいて Memory Bank への呼び出しを自動的にオーケストレートし、記憶を保存して取得できます。

このドキュメントでは、ADK エージェントを作成し、Memory Bank を使用するように構成して、エージェントとやり取りして記憶を生成してアクセスする方法について説明します。

ADK を使用せずに API を直接呼び出す方法については、Memory Bank API のクイックスタートをご覧ください。

ADK メモリサービスとメモリバンクを使用して記憶を管理する

VertexAiMemoryBankService は、ADK の BaseMemoryService で定義された Memory Bank の ADK ラッパーです。メモリサービスとやり取りしてメモリの読み取りと書き込みを行うコールバックとツールを定義できます。

VertexAiMemoryBankService インターフェースには次のものが含まれます。

  • memory_service.add_session_to_memory は、指定された adk.Session 内のすべてのイベントをソース コンテンツとして使用して、Memory Bank への GenerateMemories リクエストをトリガーします。このメソッドの呼び出しは、コールバックで 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。イベントのサブセットを使用して、Memory Bank への GenerateMemories リクエストをトリガーします。コールバックで 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 は、Memory Bank への RetrieveMemories リクエストをトリガーし、現在の user_id と app_name に関連するメモリを取得します。このメソッドの呼び出しは、組み込みのメモリツール(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 エージェントを作成する

メモリ対応エージェントを作成するには、メモリサービスへの呼び出しをオーケストレートするツールとコールバックを設定します。

メモリ生成コールバックを定義する

メモリ生成の呼び出しをオーケストレートするには、メモリ生成をトリガーするコールバック関数を作成します。イベントのサブセット(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 エージェントが実行される場所によって異なります。ランタイムは、エージェント、ツール、コールバックの実行をオーケストレートします。

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 インスタンス ID をランタイム スクリプトまたはデプロイ スクリプトに渡して、エージェントが 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: プロジェクト ID。
  • LOCATION: リージョン。Memory Bank のサポート対象の地域をご覧ください。
  • APP_NAME: ADK アプリ名。アプリ名は、生成された思い出の scope 辞書に含まれるため、思い出はユーザーとアプリの両方で分離されます。
  • MEMORY_BANK_ID: Memory Bank インスタンス ID。たとえば、projects/my-project/locations/us-central1/reasoningEngines/456 では 456 です。
  • SESSIONS_ID: Agent Platform Sessions インスタンス ID。たとえば、projects/my-project/locations/us-central1/reasoningEngines/789 では 789 です。

Gemini Enterprise Agent Platform の Agent Runtime

Agent Runtime ADK テンプレート(AdkApp)は、ローカルで使用することも、ADK エージェントを Agent Runtime にデプロイすることもできます。Agent Platform にデプロイすると、Memory Bank ADK テンプレートはデフォルトのメモリサービスとして VertexAiMemoryBankService を使用します。そのため、Memory Bank インスタンスを作成してランタイムにデプロイする作業を 1 つのステップで行うことができます。

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)

次のように置き換えます。

  • PROJECT_ID: プロジェクト ID。
  • LOCATION: リージョン。Memory Bank のサポートされているリージョンをご覧ください。
  • STAGING_BUCKET: Agent Runtime のステージングに使用する Cloud Storage バケット。

ローカルで実行する場合、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)

次のように置き換えます。

  • PROJECT_ID: プロジェクト ID。
  • LOCATION: リージョン。Memory Bank のサポートされているリージョンをご覧ください。
  • MEMORY_BANK_ID: Memory Bank で使用する Memory Bank インスタンス ID。たとえば、projects/my-project/locations/us-central1/reasoningEngines/456 では 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 ウェブ

ADK ウェブ インターフェースを使用すると、ブラウザでエージェントを直接テストできます。

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

adk web --memory_service_uri=agentengine://MEMORY_BANK_ID

次のように置き換えます。

  • PROJECT_ID: プロジェクト ID。
  • LOCATION: リージョン。Memory Bank のサポートされているリージョンをご覧ください。
  • MEMORY_BANK_ID: Memory Bank インスタンス ID。たとえば、projects/my-project/locations/us-central1/reasoningEngines/456 では 456 です。

エージェントを操作する

エージェントを定義して Memory Bank を設定したら、エージェントとやり取りできます。エージェントの初期化時にメモリ生成をトリガーするコールバックを指定した場合、エージェントが呼び出されるたびにメモリ生成がトリガーされます。

メモリーは、エージェントの実行に使用されたユーザー ID とアプリ名に対応するスコープ {"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: ユーザーの識別子。このセッションから生成されたメモリは、この不透明な 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: ユーザーの識別子。このセッションから生成されたメモリは、この不透明な ID をキーとしています。生成されたメモリのスコープは {"user_id": "USER_ID"} として保存されます。

Cloud Run

ADK Cloud Run デプロイ ドキュメントのエージェントのテスト セクションをご覧ください。

GKE

ADK GKE デプロイ ドキュメントのエージェントをテストするセクションをご覧ください。

ADK ウェブ

ADK Web を使用するには、http://localhost:8000 のローカル サーバーに移動します。

デフォルトでは、ADK Web はユーザー ID を user に設定します。デフォルトのユーザー ID をオーバーライドするには、http://localhost:8000?userId=YOUR_USER_ID のように、クエリ パラメータに userId を含めます。

詳細については、ADK ドキュメントの ADK Web ページをご覧ください。

操作例

最初のセッション

PreloadMemoryTool を使用した場合、エージェントは各ターンの開始時にメモリを取得し、ユーザーが以前にエージェントに伝えた設定にアクセスしようとします。エージェントがユーザーと初めてやり取りする際は、取得可能なメモリはありません。そのため、次の例に示すように、エージェントはユーザーの好み(ユーザーが好む温度など)を認識していません。

  1. 最初のターン:

    • お客様: 「温度を調整して」

    • (ツール呼び出し): ADK がメモリの取得を試みますが、利用可能なメモリはありません。

    • モデル: 「ご希望の温度は?」

    • (コールバック): ADK がメモリ生成をトリガーします。メモリーは抽出されません。

  2. 2 回目のターン:

    • お客様: 71 度が快適です。

    • (ツール呼び出し): ADK がメモリの取得を試みますが、利用可能なメモリはありません。

    • モデル: わかりました。温度を 71 度に更新しました。

    • (コールバック): ADK がメモリ生成をトリガーします。「好みの温度は 22 度」というメモリーが作成されます。

2 回目のセッション

抽出されたメモリは、同じアプリ名とユーザー ID の次のセッションで使用できます。ユーザーが既存のメモリと類似または矛盾する情報を提供した場合、新しい情報は既存のメモリと統合されます。

  1. 最初のターン

    • ユーザー: 温度を調整して。とても不快です。

    • (ツール呼び出し): ADK がメモリの取得を試みます。「好みの温度は 22 度」という記憶が取得されます。

    • モデル: わかりました。温度を 71 度に更新しました。

    • (コールバック): ADK がメモリ生成をトリガーします。ユーザーが保存する価値のある情報を共有しなかったため、記憶は抽出されません。

  2. 2 回目のターン

    • お客様: 実は、朝はもっと暖かいほうがいいんです。

    • (ツール呼び出し): ADK がメモリの取得を試みます。「好みの温度は 22 度」という記憶が取得されます。

    • モデル: わかりました。温度を上げました。

    • (コールバック): ADK がメモリ生成をトリガーします。既存の記憶「好みの温度は 22 度」が「好みの温度は 22 度だが、朝はもっと暖かいほうがいい」に更新されます。

リージョン ランタイムでマルチリージョン メモリバンクを使用する

組み込みの Memory Bank で Runtime を使用する場合、エージェントと Memory Bank はデフォルトで同じリージョンにデプロイされます。ただし、これらを分離して、マルチリージョンの Memory Bank(us など)をリージョン ランタイム(us-central1 など)で使用することもできます。この構成により、異なるリージョン デプロイ間で一元化された Memory Bank を維持できます。

マルチリージョン Memory Bank を使用するには、デフォルトの ADK メモリサービス ビルダーをオーバーライドして、マルチリージョン ロケーションと対応する Memory Bank ID を参照するようにする必要があります。

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: プロジェクト ID。
  • STAGING_BUCKET: Agent Runtime のステージングに使用する Cloud Storage バケット。

クリーンアップ

このプロジェクトで使用しているすべてのリソースをクリーンアップするには、クイックスタートで使用した 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 を使ってみて、長期記憶を管理しましょう。