ADK を使用したエージェントの状態と記憶

Megan O'Keefe
Senior Staff Developer Advocate
Amit Maraj
AI Developer Relations Engineer
※この投稿は米国時間 2025 年 8 月 2 日に、Google Cloud blog に投稿されたものの抄訳です。
あなたが開発者で、初めてコーディングを学ぼうとしている友人がいるとします。友人は、Python の辞書など、いくつかのコンセプトの理解に苦労しています。
そこであなたはいい考えを思いつきました。会話形式で複雑なトピックを学習するのに役立つ AI エージェントを設計するというアイデアです。そのエージェントが、友人の学習スタイルに合わせてパーソナライズされ、友人の過去の成果を記憶し、学習計画をリアルタイムで調整できるとしたらどうでしょうか。エージェントの状態と記憶があれば、これらすべてが可能になります。この投稿では、Agent Development Kit(ADK)を使用してこれを行う方法を説明します。


Python Tutor エージェント
まず、ADK を使用してシンプルな会話型エージェントを設計します。このエージェントは、Gemini 2.5 Flash をモデルとして使用し、その推論能力を活用します。また、エージェントは、Python の辞書に関する簡単なクイズを進めるために一連の関数ツールも使用します。


たとえば、start_quiz ツールは、新しいクイズのワークフローを開始します(state については後ほど詳しく説明します)。
これらのツールを組み合わせてエージェントに実行してほしいクイズの全体的なワークフローを下に示します。


次に、エージェントにプロンプトでシステム指示を入力し、モデルがワークフローに沿って推論できるようにします。
ここから、ADK エージェントを定義して、本格的に始動します。


しかし、生徒の名前やクイズの進捗状況など、生徒のセッション中に起こったことをエージェントに記憶させるにはどうすればよいでしょうか?ここで短期記憶が役立ちます。
短期記憶
AI エージェントのコンテキストでは、「短期記憶」とは、エージェントが 1 回のセッション内で記憶できることです。
では、セッションとは何でしょうか。セッションは、電話をかけるたびに別の担当者が対応するカスタマー サポートでの担当者との電話のようなものです。その担当者は、その会話中にあなたが話したことしか覚えていません。電話を切ると、すべてのコンテキストが失われます。


短期記憶は悪いことのように聞こえるかもしれませんが、AI エージェントでは重要な役割を果たします。たとえば、この Python Tutor エージェントは、ユーザーのクイズの進捗状況(これまでに完了した問題数など)を把握する必要があるかもしれません。エージェントがその進捗状況を長期的に保存する必要はないでしょう。最終スコアを保存するだけでよいかもしれません。
ADK エージェントとのユーザー インタラクションごとにセッションが作成され、そのセッションは ADK SessionService によって管理されます。各セッションには、セッション ID、ユーザー ID、イベント履歴(会話スレッド)、状態などの重要なフィールドが含まれています。


セッションの状態とは、ユーザーとの「電話」の際の、エージェントのメモ帳のようなものだと考えてください。各セッションの状態には、Key-Value ペアのリストが含まれており、その値はセッション全体を通してエージェントによって更新されます。


ADK は、セッションの状態にいくつかの方法で書き込むことができます。1 つはツール内で行う方法です。ADK の ToolContext を使用して現在のセッションの状態を取得し、フィールドを作成または更新できます。
そこから、エージェントのモデルに ADK のキー テンプレート機能を使用して現在の状態フィールドから読み取るよう指示できます。波かっこ {} で状態フィールドをで囲むだけで、ADK はモデル呼び出しごとに状態キーの値をプロンプトに挿入します。
Python Tutor エージェントがこれらの状態フィールドをリアルタイムで更新する様子を以下に示します。


デフォルトでは、状態フィールドは現在のセッション内でのみ保持されます。同じユーザーであっても、新しいセッションを開始すると値は消えます。ただし、ADK には user: や app: などの特殊な状態キー接頭辞があり、これを使用すると、すべてのユーザー セッションまたはすべてのユーザーのすべてのセッションで状態キーの値を永続化できます。これらの特殊な接頭辞は、dark-mode=true のように、セッション間で保持したいシンプルなテキスト設定がある場合に便利です。
これが ADK の短期記憶の基本です。では、ADK はセッションと状態のデータをどのように保存するのでしょうか。


デフォルトでは、ADK WEB UI の SessionService はセッション データをメモリに書き込みます。つまり、ADK のランナーがクラッシュしたり、シャットダウンされたりすると、すべてのセッション データが失われます。ADK を使用して本番環境グレードのスケールされたエージェントを実行していて、ADK エージェントのインスタンスが複数ある場合、ユーザーのリクエストが常に同じインスタンスにヒットするとは限りません。つまり、リクエスト 1 がインスタンス A に送信され、リクエスト 2 がインスタンス B に送信された場合、インスタンス B にはインスタンス A に保存されているインメモリのセッション状態がありません。
そのため、本番環境レベルのエージェントでは、セッション データをエージェントのランタイムの外部に保存する必要があります。ADK には、これを行う 2 つの方法が用意されています。1 つ目は DatabaseSessionService です。SQLite、MySQL、PostgreSQL などの SQL データベースにセッション データを保存します。設定は簡単で、データベースがあればすぐに利用できます。次に、データベースの URI を ADK ランナーに渡します。
そこから SQL データベースにアクセスし、セッション テーブルと状態テーブルを確認できます。
もう 1 つのオプションは VertexAISessionService で、セッション データを Agent Engine に保存します。ADK ランタイムとして Agent Engine をすでに使用している場合は、この方法が適しています。
長期記憶
ここまでで、ADK がセッション内でデータを保存する方法について説明しました。しかし、同じユーザーのセッション間で永続化したいデータがある場合はどうすればよいでしょうか。ここで ADK の長期記憶が役立ちます。
長期記憶を備えた ADK エージェントは、毎回同じカスタマー サービス担当者と話しているようなものです。そして、その担当者は過去のすべての会話から重要な情報をすべて把握しています。


たとえば、Python Tutor エージェントは、生徒がどのように上達したかを把握するために、これまでのクイズのスコアを保存したいと考えるかもしれません。長期記憶は、エージェントが、生徒が常につまずくトピックは何かを理解し、パーソナライズされた学習計画を立てるのにも役立ちます。
ADK では、2 つの方法で長期記憶を保存できます。デフォルトは、InMemoryMemoryService を使用してメモリ内に保存する方法です。ここでは、すべてのセッションが会話スレッド全体を含む未加工の状態で保存され、エージェントは単純なキーワード検索を使って以降のセッションでこれにアクセスできます。この方法はローカル開発には適していますが、InMemorySessionService と同じ落とし穴があります。ADK が再起動またはクラッシュすると、すべてのメモリが永久に失われてしまうのです。この方法のもう一つの欠点は、過去のユーザー セッションが大量にある場合、セッションのイベント履歴を未加工の形式で取得すると、コンテキストが多すぎてエージェントのモデルが圧倒される可能性があることです。
幸いなことに、ADK には、ADK ランタイムの外部に長期記憶を永続的に保存する方法が用意されています。それが VertexAIMemoryBankService です。この記憶サービスは、Vertex AI Memory Bank(プレビュー版)を使用して、過去のユーザー インタラクションからインテリジェントに記憶を保存および取得します。
Memory Bank は Gemini モデルを使用してセッション データから重要な情報を抽出し、将来の使用に備えて重要な記憶だけを保存します。


Memory Bank に記憶を保存するために、Python Tutor エージェントにコールバックを実装して、現在のセッション データをバンクに追加します。
次に、エージェントに、キーワードによるベクトルベースの類似性検索を使用して、それらの記憶を検索するように指示します。
ユーザーの過去のクイズの結果を記憶できるよう、クイズフローが更新されました。


長期記憶の取得に Memory Bank を使用した、更新された Python Tutor エージェントの動作は次のとおりです。


その仕組みを見てみましょう。エージェントがその after-agent コールバックで記憶生成をトリガーすると、Memory Bank は Gemini を使用して重要な情報を抽出します。ユーザーが新しいクイズを開始し、過去の結果に対して search_memory をトリガーすると、Memory Bank は次のように返します。


Memory Bank は Vertex AI Agent Engine の一部ですが、この機能を使用するために、ADK エージェントを Agent Engine のランタイムで実行する必要はありません。たとえば、エージェントを Cloud Run で実行し、長期記憶ストアとして Memory Bank を統合するだけで十分です。
構築してみる
要約すると、短期記憶と長期記憶は AI エージェントにおいて重要な役割を果たします。エージェントがユーザー セッション内およびセッション間で重要な情報を記憶できるようにすることで、よりコンテキストを認識し、パーソナライズされたユーザー エクスペリエンスを実現します。ADK は、SQL データベースから Vertex AI Agent Engine まで、さまざまなセッションと記憶のストレージ オプションをサポートしています。
GitHub でソースコードを確認して、Python Tutor エージェントをデプロイして実際にお試しください。
また、以下のリソースで詳細をご覧いただけます。
最後までお読みいただきありがとうございました。
画像提供: 絵文字ミックス
ー デベロッパー アドボケイト、Megan O'Keefe
ー デベロッパー リレーションズ エンジニア、Amit Maraj



