Agent Development Kit によるクイックスタート

このチュートリアルでは、ADK で Memory Bank を使用して長期記憶を管理する方法について説明します。Memory Bank を使用するように Agent Development Kit(ADK)エージェントを構成すると、エージェントは Memory Bank への呼び出しをオーケストレートして、長期記憶を管理します。

ADK で Memory Bank を使用する手順は次のとおりです。

  1. ADK エージェントとランナーを作成します。ADK ランナーは、セッションとメモリの管理を提供するサービスにエージェントを接続します。

  2. エージェントとやり取りして、セッション間でアクセス可能な長期記憶を動的に生成します。

  3. クリーンアップします。

ADK オーケストレーションなしで Memory Bank への呼び出しを直接行うには、Agent Engine SDK のクイックスタートをご覧ください。Agent Engine SDK を使用すると、Memory Bank がメモリを生成する方法を理解することや、Memory Bank の内容を検査することが可能になります。

ADK メモリサービスと Memory Bank でメモリを管理する

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_idapp_name に関連するメモリを取得します。このメソッドの呼び出しは、組み込みのメモリツール(LoadMemoryTool または PreloadMemoryTool)または tool_context.search_memory を呼び出すカスタムツールを使用してオーケストレートできます。

始める前に

このチュートリアルで説明する手順を完了するには、まず Memory Bank の設定ページのスタートガイドの手順に沿って操作する必要があります。

環境変数を設定する

ADK を使用するには、環境変数を設定します。

import os

os.environ["GOOGLE_GENAI_USE_VERTEXAI"] = "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-2.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-2.5-flash",
      name='stateful_agent',
      instruction="""...""",
      tools=[FunctionTool(func=search_memories)],
      after_agent_callback=generate_memories_callback
  )

ADK Memory Bank のメモリサービスとランタイムを定義する

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

Agent Engine インスタンスを作成する

Memory Bank で使用する Agent Engine インスタンスを最初に作成する必要があります。Agent Engine Runtime を使用してエージェントをデプロイする場合は、この手順は省略可能です。Memory Bank の動作のカスタマイズの詳細については、Memory Bank の設定ページの Memory Bank 用に Agent Engine インスタンスを構成するをご覧ください。

import vertexai

client = vertexai.Client(
  project="PROJECT_ID",
  location="LOCATION"
)
# If you don't have an Agent Engine instance already, create an Agent Engine
# Memory Bank instance using the default configuration.
agent_engine = client.agent_engines.create()

# Optionally, print out the Agent Engine resource name. You will need the
# resource name if you want to interact with your Agent Engine instance later on.
print(agent_engine.api_resource.name)

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

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

ADK ランタイムを作成する

エージェントが Memory Bank を ADK メモリサービスとして使用するように、Agent Engine ID をランタイムまたはデプロイ スクリプトに渡します。

ローカル ランナー

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="AGENT_ENGINE_ID",
)

# You can use any ADK session service. This example uses Agent Engine Sessions.
session_service = VertexAiSessionService(
    project="PROJECT_ID",
    location="LOCATION",
    agent_engine_id="AGENT_ENGINE_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 ディクショナリに含まれます。これにより、ユーザーとアプリの両方でメモリが分離されます。
  • AGENT_ENGINE_ID: Memory Bank とセッションで使用する Agent Engine ID。たとえば、projects/my-project/locations/us-central1/reasoningEngines/456 では 456 です。

Agent Engine

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

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

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

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 Agent Engine with your agent deployed to Agent Engine Runtime.
# The Agent Engine instance will also include an empty Memory Bank.
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 Agent Engine to deploy your agent to Agent Engine Runtime.
# Your agent will have access to the Agent Engine 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 Engine Runtime のステージングに使用する Cloud Storage バケット。

ローカルで実行する場合、ADK テンプレートはデフォルトのメモリサービスとして InMemoryMemoryService を使用します。ただし、デフォルトのメモリサービスをオーバーライドして VertexAiMemoryBankService を使用することはできます。

def memory_bank_service_builder():
    return VertexAiMemoryBankService(
        project="PROJECT_ID",
        location="LOCATION",
        agent_engine_id="AGENT_ENGINE_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 Engine Runtime,
  # use `client.agent_engines.create(...)` or `client.agent_engines.update(...)`
  # and call the returned Agent Engine 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 のサポートされているリージョンをご覧ください。
  • AGENT_ENGINE_ID: Memory Bank で使用する Agent Engine 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

GKE

エージェントを Google Kubernetes Engine(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://AGENT_ENGINE_ID

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

  • PROJECT_ID: プロジェクト ID。
  • LOCATION: リージョン。Memory Bank のサポートされているリージョンをご覧ください。
  • AGENT_ENGINE_ID: Memory Bank で使用する Agent Engine 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 Engine

Agent Engine ADK テンプレートを使用すると、Agent Engine 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 Web

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 がメモリの取得を試みますが、メモリがありません。

    • モデル: 了解いたしました。温度を 22 度に設定しました。

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

2 回目のセッション

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

  1. 最初のターン

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

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

    • モデル: 了解いたしました。温度を 22 度に設定しました。

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

  2. 2 ターン目

    • ユーザー: 実は、朝は暖かくしてほしいんです。

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

    • モデル: 了解しました。温度を上げました。

    • (コールバック): ADK がメモリ生成をトリガーします。既存のメモリ「温度は 22 度が好き」が「温度は通常 22 度が好きですが、朝は暖かくしてほしい」に更新されます。

クリーンアップ

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

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

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

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

次のステップ