はじめに
七尾百合子さん、お誕生日 85日目 おめでとうございます! nikkieです。
GoogleのADKを使っていて「ADKで実装したエージェントを配布できないのかな」という疑問がむくむくと頭をもたげてきました。
そこで実験してみました。
目次
- はじめに
- 目次
- Agent Development Kitはディレクトリで指定したエージェントをロードする
- 結論:adk api_serverに限れば、できる
- ADKで実装したエージェントをインストールし、adk api_server
- adk api_serverで立てたサーバに、site-packages下のエージェントを指定してリクエスト
- 終わりに
Agent Development Kitはディレクトリで指定したエージェントをロードする
ADKの実装を見ると、AgentLoader
にディレクトリを指定して、その中のエージェントの実装をロードします。
先日どんなディレクトリ構造に対応しているか調べました。
当ブログではADKでエージェントを実装する記事をいくつか書いてきました。
ADKが指定するディレクトリ構造でファイルを作る中で思ったのです。「開発者がサンプルコードを手元にコピペしてるけど、配布してこの状況を打開できるんじゃない?」
配布とはpip install
でエージェントを(仮想環境のsite-packages下に)インストールして、それを動かすということです。
「このアイデアが成立するのでは」という勝算がありました。
AgentLoader
の実装で、importlib.import_module()
を使っているのです。
https://github.com/google/adk-python/blob/v1.2.1/src/google/adk/cli/utils/agent_loader.py#L53
module_candidate = importlib.import_module(agent_name)
Sphinxの拡張はimportlib.import_module()
でsite-packages下からロードされます1。
「ADKでも同様なのでは?」と、ADKで実装したエージェントをインストールして実験します。
結論:adk api_server
に限れば、できる
adk v1.2.1時点での話です。
読みなよ... 俺の記事の続きを...
ADKで実装したエージェントをインストールし、adk api_server
コマンドの選択について
adk api_server
とadk web
はどちらもFastAPIアプリを起動します。
APIを直接呼べたほうが検証しやすいと考えて、adk api_server
を選びました。
adk run
もAgentLoader
を使っているのですが、adk run third_party_agent
とsite-packages下のエージェントは指定できません。
Error: Invalid value for 'AGENT': Directory 'third_party_agent' does not exist.
これはclick.Path(exists=True)
2で存在するディレクトリに限っている3ためです。
AgentLoader
にsite-packages下のエージェントが渡らないんですね(プルリクチャンスかも)
ADKで実装したエージェントをインストール可能にする
こちらに用意しています。
https://github.com/ftnext/agent-practice/tree/afdcd43e19980df8b4040da5dd72ab33120c01d9/packaging/adk_stop_loop_agent
adk_stop_loop_agent/ ├── src/ │ └── adk_stop_loop_agent/ │ ├── __init__.py │ └── agent.py # root_agent を用意 └── pyproject.toml # インストールするために用意
過去に作ったループを抜けるエージェント4を選択しました。
環境変数の指定不要で動かせるので、まず試しやすいのです。
元の実装との区別のために、ループを抜けるまでのカウントを変えています。
(.venv) % pip install ../packaging/adk_stop_loop_agent
site-packagesの下にadk_stop_loop_agent
が入りました。
(pip list | grep adk_stop_loop_agent
でも確認できます)
importもできます!
>>> import adk_stop_loop_agent
adk api_server
で立てたサーバに、site-packages下のエージェントを指定してリクエスト
(.venv) % adk api_server
FastAPIなので、ドキュメントが http://127.0.0.1:8000/docs で見られます。
私はヘルスチェック代わりにアプリの一覧を取得します。
これはadk api_server
を起動したディレクトリにあるディレクトリ一覧です。
site-packages下のadk_stop_loop_agent
は含まれません。
% curl http://127.0.0.1:8000/list-apps ["refine-loop","stop-loop"]
ここからの手順ですが
- Create Session (
POST /apps/{app_name}/users/{user_id}/sessions
) adk_stop_loop_agent
をRun (POST /run
)
となります。
Create Session
% curl -X POST http://127.0.0.1:8000/apps/adk_stop_loop_agent/users/nikkie/sessions | jq . { "id": "085aef5e-908f-4c27-bb68-a1cdf12dbef5", "appName": "adk_stop_loop_agent", "userId": "nikkie", "state": {}, "events": [], "lastUpdateTime": 1749467551.046664 }
Run
1のレスポンスの.id
を使って2のリクエストを組み立てて
{ "appName": "adk_stop_loop_agent", "userId": "nikkie", "sessionId": "085aef5e-908f-4c27-bb68-a1cdf12dbef5", "newMessage": { "parts": [ { "text": "こんにちは" } ], "role": "user" }, "streaming": false }
% curl -H 'Content-Type: application/json' -d@packaging/adk_stop_loop_agent/run_request.json http://127.0.0.1:8000/run | jq . [ { "content": { "parts": [ { "text": "Counter: 1" } ], "role": "model" }, "invocationId": "e-102b7187-7776-4472-938c-0b82134bac61", "author": "counter_agent", "actions": { "stateDelta": {}, "artifactDelta": {}, "requestedAuthConfigs": {} }, "id": "NdRCMC7U", "timestamp": 1749467751.870142 }, { "content": { "parts": [ { "text": "Counter: 2" } ], "role": "model" }, "invocationId": "e-102b7187-7776-4472-938c-0b82134bac61", "author": "counter_agent", "actions": { "stateDelta": {}, "artifactDelta": {}, "requestedAuthConfigs": {} }, "id": "644EcPgG", "timestamp": 1749467751.870288 }, { "content": { "parts": [ { "text": "Send STOP signal" } ], "role": "model" }, "invocationId": "e-102b7187-7776-4472-938c-0b82134bac61", "author": "counter_agent", "actions": { "stateDelta": {}, "artifactDelta": {}, "escalate": true, "requestedAuthConfigs": {} }, "id": "SovTGW8W", "timestamp": 1749467751.870328 } ]
Counterが2で止まりました!
site-packages下にインストールしたADK実装のエージェントを、動かせています🙌
終わりに
ADKで実装したエージェントをsite-packages下にインストールし、それをadk api_server
で動かせるか実験しました。
エージェントをロードするAgentLoader
がimportlib.import_module()
を使っているため、site-packages下のエージェントもロードできます!
adk api_server
はadk run
やadk web
(後述)と比べてエージェント指定の検証ロジックが緩いため、site-packages下のエージェントを指定してリクエストを送ることができました。
公式ドキュメントには今のところ記載がないですし、関係するissueやdiscussionは未調査ですが、ひとまず私はadk api_server
で使い倒そうと思っています。
PyPIに置いていくぞ〜
ちなみに、adk web
も同様のFastAPIアプリケーションなので同じように動くかと期待しましたが、 http://127.0.0.1:8000/dev-ui/?app=adk_stop_loop_agent というURLをブラウザに直接入力したところ
Agent 'adk_stop_loop_agent' not found
と表示されて進めませんでした。
- 恥ずかしい話が、ここで活きたぞ! ↩
- https://github.com/google/adk-python/blob/v1.2.1/src/google/adk/cli/cli_tools_click.py#L226-L231↩
-
「The
exists
argument will verify whether the path exists.」https://click.palletsprojects.com/en/stable/handling-files/#file-path-arguments↩ - ↩