nikkie-ftnextの日記

イベントレポートや読書メモを発信

Agent2Agent サーバにする Agent Development Kit 製エージェントに、session を永続化しない NullSessionService を渡すというアイデアを試す

はじめに

七尾百合子さん、お誕生日 334日目 おめでとうございます! nikkieです。

Agent Development Kit に宛てた session についての技術的な怪文書です

目次

ADK で作ったエージェントを A2A サーバにするときの session service

Agent Development Kit (ADK) では、会話スレッドを session として扱います。
話者A -> 話者B -> A -> B と1つの session に積まれていきます1
session はSessionServiceが管理します。

ADK のエージェントを A2A サーバにする場合のSessionServiceを考えました。

  • VertexAiSessionService:A2A サーバではバグで動かない
  • DatabaseSessionService:A2A サーバで動くが、ADK のマイナーバージョンアップでテーブル定義が変わって壊れるので、選択したくない
  • 選択肢:InMemorySessionServiceSqliteSessionService

考えている中で、A2A での session は私のユースケースでは再利用することがないので、実は永続化しなくてよいのではという考えが頭をもたげました。

イデアNullSessionServiceを作れるのでは

InMemorySessionServiceはメモリに session を保存します。
保持する session の分メモリ使用量が増えていくわけですが、「いっそ保持せずに捨てればいいのではないか」と閃きました。
あたかも logging における NullHandler2 のように、永続せずに session を捨てます

google/adk-python の samples を使って、動作確認しました。
以下の記事にならって a2a-basic を動かしています(Python 3.13.8・google-adk 1.25.0)。

準備:.env配置
Google Cloud に向けていますが、Gemini API でも動くと思います)

  • contributing/samples/a2a_basic/.env
  • contributing/samples/a2a_basic/remote_a2a/check_prime_agent/.env
GOOGLE_GENAI_USE_VERTEXAI=true
GOOGLE_CLOUD_PROJECT=adk-practice-480404
GOOGLE_CLOUD_LOCATION=global

A2A クライアント起動

% uv run adk web contributing/samples/

ブラウザで a2a_basic を選びます

A2A サーバ起動

% uv run contributing/samples/a2a_basic/remote_a2a/main.py

session service にNullSessionServiceを指定するために、スクリプト(後述)を書きました。

A2A サーバで function calling して、「7は素数」と正しく返答できています

Contents:
{"parts":[{"text":"Is 7 a prime number?"},{"text":"For context:"},{"text":"[root_agent] called tool `transfer_to_agent` with parameters: {'agent_name': 'prime_agent'}"},{"text":"For context:"},{"text":"[root_agent] `transfer_to_agent` tool returned result: {'result': None}"}],"role":"user"}
{"parts":[{"function_call":{"args":{"nums":[7]},"name":"check_prime"}}],"role":"model"}
{"parts":[{"function_response":{"name":"check_prime","response":{"result":"7 are prime numbers."}}}],"role":"user"}

ログを見ると get_session を1回していました。
この session に function calling が積まれたようです

2026-02-14 15:54:43,362 | DEBUG | google_adk.__main__:get_session:62 - get_session: app_name=check_prime_agent user_id=A2A_USER_ee5fadd3-3ba0-491e-bc6a-f6685500de70 session_id=ee5fadd3-3ba0-491e-bc6a-f6685500de70

NullSessionService実装メモ

gpt-5.3-codex にまず書き上げてもらい、それを読み返して手を入れました。
Codex はInMemorySessionServiceに引っ張られていたので、私の方でより単純にしています

ADK 1.19.0 で導入された service factory を使って、NullSessionServiceを登録しています。
https://github.com/google/adk-python/releases/tag/v1.19.0

Add service factory for configurable session and artifact backends (a12ae81)

URI のスキームがnullならNullSessionServiceが使われるように設定しました。

NullSessionService自体は、BaseSessionServiceに宣言された4つのメソッドを実装しました。

  • create_session()
  • get_session()
  • list_sessions()
  • delete_session()

InMemorySessionServiceからメモリに保持する処理を除いて、この実装に至ります

BaseSessionServiceが持つappend_event()メソッドでsession.events.append(event)と積まれます3
一度取得された session は event 追加のたびに永続化する必要はないために、今回の捨てる実装でも function calling が動いたのかなと思っています(※理解を深めるために読み込む余地は多分にあります4

終わりに

ADK のエージェントを A2A サーバにしたときに session を永続化する必要がなさそうなので、NullSessionServiceというアイデアを試しました。

  • samples の A2A サーバで function calling の例は動いた
  • ADK 1.19.0 から service factory を使って、自作の session service を登録できるようになっている

本番利用に当たっては考慮漏れがあるかもしれないので、InMemorySessionServiceSqliteSessionServiceをおすすめします。

gpt-5.3-codex は、InMemorySessionServiceTTLを追加したらいいのではないかと言っていました。こいつ、できる


  1. 人間とエージェントの場合もエージェントどうし(A2A)の場合も含める意図で「話者」と使いました
  2. https://github.com/google/adk-python/blob/v1.25.0/src/google/adk/sessions/base_session_service.py#L111
  3. この図の理解を深めたいところです https://google.github.io/adk-docs/runtime/event-loop/#how-it-works-a-simplified-invocation