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

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

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

ADK なしで API を直接呼び出す方法については、メモリバンク API のクイックスタートをご覧ください。

ADK メモリサービスとメモリバンクで記憶を管理する

VertexAiMemoryBankService は、ADK の BaseMemoryService で定義される メモリバンク の 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。イベントのサブセットを使用して、メモリバンク への 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_idapp_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_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 メモリバンク メモリサービスとメモリバンク インスタンスを定義する

メモリ対応エージェントを作成したら、メモリ サービスにリンクする必要があります。ADK メモリ サービスを構成するプロセスは、ADK エージェントが実行される場所によって異なります。ランタイムは、エージェント、ツール、コールバックの実行をオーケストレートします。

メモリバンク インスタンスを作成する

まず、メモリバンク インスタンスを作成する必要があります。エージェントのデプロイに 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 インスタンス 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: メモリバンク インスタンス 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 にデプロイすると、メモリバンク ADK テンプレートはデフォルトのメモリサービスとして VertexAiMemoryBankService を使用します。そのため、メモリバンク インスタンスを作成して、1 つの手順でランタイムにデプロイできます。

Memory Bank の動作をカスタマイズする方法など、Memory Bank インスタンスの設定の詳細については、メモリバンクを構成するをご覧ください。

次のコードを使用して、メモリ対応の ADK エージェントを Agent Runtime にデプロイします。

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)

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

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

エージェントを操作する

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

メモリーは、エージェントの実行に使用されたユーザー 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 度が好きですが、朝は暖かくしてほしい」に更新されます。

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

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

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

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

クリーンアップ

このプロジェクトで使用しているすべてのリソースをクリーンアップするには、クイックスタートで使用した Google Cloudプロジェクトを削除します。

それ以外の場合は、このチュートリアルで作成した個々のリソースを次のように削除できます。

  1. 次のコードサンプルを使用して Agent Runtime インスタンスを削除します。これにより、そのランタイムに属しているセッションまたはメモリも削除されます。

    agent_engine.delete(force=True)
    
  2. ローカルで作成したファイルを削除します。

次のステップ

クイックスタート

Memory Bank API を使ってみて、長期記憶を管理しましょう。