nikkie-ftnextの日記

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

Agent Development Kitはエージェントの実装のどのようなディレクトリ構造をサポートするのか(AgentLoaderソースリーディング)

はじめに

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

GoogleADKで気になった箇所の実装を読みました。

目次

Agent Development Kit

Google Cloud Next ‘25で発表されたADK (Agent Development Kit)。
ADKを使って実装したエージェントを動かすには
https://google.github.io/adk-docs/get-started/quickstart/

ファイル配置

working_directory/
└── awesome_agent/
    ├── __init__.py
    ├── agent.py  # root_agent を宣言
    └── .env

動かし方

  • ターミナルで adk run awesome_agent
  • ブラウザで adk web
  • APIとして起動 adk api_server

ブラウザやAPIの2つはapp_nameとしてawesome_agentを指定します。

今回調べたのは、指定したawesome_agentディレクトリがロードされるにはどのような構造にする必要があるかという点です。

google.adk.cli.utils.agent_loader.AgentLoader

見つけたのがAgentLoaderクラス1
https://github.com/google/adk-python/blob/v1.2.1/src/google/adk/cli/utils/agent_loader.py#L28

上で紹介した3つのコマンドはいずれもAgentLoaderに繋がります。

AgentLoaderは3つのディレクトリ構造をサポート

https://github.com/google/adk-python/blob/v1.2.1/src/google/adk/cli/utils/agent_loader.py#L31-L36 より2CHANGELOG 1.1.0

  • a) agents_dir/{agent_name}/agent.py (agent.pyroot_agent定義)
  • b) agents_dir/{agent_name}.py ({agent_name}.pyroot_agent定義)
  • c) agents_dir/{agent_name}/__init__.py (パッケージ(すなわち__init__.py)にroot_agent)

AgentLoader.load_agent()3はキャッシュの実装です。
上記3つのディレクトリ構造を扱う実装は_perform_load()メソッド
https://github.com/google/adk-python/blob/v1.2.1/src/google/adk/cli/utils/agent_loader.py#L118

  1. _load_from_module_or_package()メソッドでロードできたらそれを返す
    • bとcのケース
  2. _load_from_submodule()メソッドでロードできたらそれを返す
    • aのケース
  3. 例外送出

例:過去に作ったAgentをロードする

作業ディレクトリを以下とし、
https://github.com/ftnext/agent-practice/tree/705f1eca81a18d34fd18b42b94d71f6957256486/adk
AgentLoaderでstop-loopエージェント4をロードしてみます。
エージェントの名前にハイフンを使っちゃってますが、ロードはできます

google_adk.google.adk.cli.utils.agent_loader:load_agent:150 - Loading agent stop-loop - not in cache.
google_adk.google.adk.cli.utils.agent_loader:_perform_load:124 - Loading .env for agent stop-loop from /.../agent-practice/adk
google_adk.google.adk.cli.utils.agent_loader:_load_from_module_or_package:65 - Module stop-loop has no root_agent. Trying next pattern.
google_adk.google.adk.cli.utils.agent_loader:_load_from_submodule:90 - Found root_agent in stop-loop.agent
  • 「not in cache」はload_agent()のキャッシュのロジックにて
  • 「Loading .env for agent」は_perform_load()でまず実行
  • 「Module stop-loop has no root_agent」は_load_from_module_or_package()で見つからず
  • 「Found root_agent in stop-loop.agent」:_load_from_submodule()で見つかりました

stop-loopは a のパターン (stop-loop/agent.py) なわけですね。

試しにstop-loop/__init__.pyroot_agentを用意してみる(c のパターン)と

from . import agent as agent

+root_agent = agent.root_agent
google_adk.google.adk.cli.utils.agent_loader:load_agent:150 - Loading agent stop-loop - not in cache.
google_adk.google.adk.cli.utils.agent_loader:_perform_load:124 - Loading .env for agent stop-loop from /.../agent-practice/adk
google_adk.google.adk.cli.utils.agent_loader:_load_from_module_or_package:56 - Found root_agent directly in stop-loop

_load_from_module_or_package()で見つかります!

終わりに

Agent Development Kitのadk runadk webadk api_serverコマンドは、AgentLoaderを使ってエージェントの実装をロードしています。
AgentLoaderはv1.2.1時点で3つのディレクトリ構造をサポートしています。

  • a) agents_dir/{agent_name}/agent.py(Quickstart)
  • b) agents_dir/{agent_name}.py
  • c) agents_dir/{agent_name}/__init__.py(Quickstartから__init__.pyroot_agentを追加)

リリースを重ねる中でエージェントの多様なディレクトリ構造に対応するようになっているというのが、今回実装を見ての収穫でした。


  1. 今回立ち入らなかったですが、テストコードという読み物もあります。 https://github.com/google/adk-python/blob/v1.2.1/tests/unittests/cli/utils/test_agent_loader.py
  2. 該当コミット
  3. https://github.com/google/adk-python/blob/v1.2.1/src/google/adk/cli/utils/agent_loader.py#L144
  4. ループを抜ける実験で爆誕しました