はじめに
七尾百合子さん、お誕生日 299日目 おめでとうございます! nikkieです。
Agent Development Kit で pytest を使った評価をしてみて辛かったところに策を考えます。
目次
ADKでテストファイルを使った評価
ADK 組み込みの評価の記事の続きです。
import pytest from google.adk.evaluation import AgentEvaluator @pytest.mark.asyncio async def test_should_use_search_tool(): await AgentEvaluator.evaluate( agent_module="search_agent", eval_dataset_file_path_or_dir="tests/integration/fixtures/search_agent/test_should_use_search_tool", )
search_agentが google_search tool を使っていることはどうやら評価できないことが分かりました。
これが分かるまでが大変だったため、評価中に生成されたデータを永続化する方法を考えていきます。
上の記事では ADK のコード側に breakpoint() を入れていました。
ファイルを見たら評価の内訳が分かるといった具合に、もっと楽にしたいです!
※この記事としては、評価における Agent の応答や評価モデルの応答をファイルに保存する方法だけを扱います。
google_search tool の使用を評価できないままなので、評価は落ち続けています
pytestを使った評価の結果をファイルに保存する
こんな実装になりました。
ソースコード全体はこちらから:
最初に discussion を見つけました。
getting eval_metric_results_with_invocations using pytest · google adk-python · Discussion #3437 · GitHub
adk-bot の一次回答はハルシネーションしていたので、AgentEvaluator.evaluate()の実装1をコーディングエージェントと一緒に読んで、上記コードに至りました。
AgentEvaluator.evaluate()という車輪を再発明せざるを得なかったため、実装は長くなってしまっています(やむなくプライベートAPI呼び出し...)
永続化にはpytest のtmp_pathフィクスチャを使って、何回分か保持される2一時ディレクトリに保存しています。
テスト(ここでは評価)が落ちたときは pytest が(テスト関数の引数である)tmp_pathの値を示してくれます3。
=================================== FAILURES ===================================
_________________________ test_should_use_search_tool __________________________
tmp_path = PosixPath('/.../pytest-126/test_should_use_search_tool0')
tmp_pathにtest_app/.adk/eval_history/test_app_search_agent_should_use_search_tool_eval_set_1768048274.701115.evalset_result.jsonのようなファイルができています。
内容はこんな感じです。
エージェントがどんな応答をして、評価モデルがなぜ NG としたのか、直接確認できてめちゃめちゃ分かりやすくなりました。
実装が長いのが伸びしろですが、やりたいことは実現できました!
num_runsを増やすとeval_case_resultsの配列の要素が増えます。
ファイルに書かれているとだいぶ追いやすいはず!
脱線:v1.22.0 から評価結果の JSON がきれいに出ます
ADK v1.21.0 ではLocalEvalSetResultsManagerが評価結果の JSON をきれいに出せませんでした。
2重でエンコードする実装になっていたためです(この issue のコードが永続化の実装 v1 です)。
pull request も送っていて反応もあったのですが、Google 内部からの別のコミットで直されて v1.22.0 で世に出ました。
リポジトリ持ってる Google がルールだと思うので割り切るしかないですね(とはいえ、感情的なしこりがないと言えば嘘になります👹)
終わりに
ADK のテストファイルを使った評価について、評価における Agent の応答や評価モデルの応答が確認しづらいという課題感にアプローチしました。
pytest のtmp_pathフィクスチャを使い、LocalEvalSetResultsManagerを使うように再実装して、評価結果を表す JSON ファイルを保存します。
永続化するファイルパスを指定したいだけなのにこんなにたくさん書かないといけないのは美しくないと感じるので、懲りずに pull request を送ることを考えてみます
- https://github.com/google/adk-python/blob/v1.22.0/src/google/adk/evaluation/agent_evaluator.py#L196↩
- (注を追加 2026/01/11)デフォルトは3回保持 https://docs.pytest.org/en/stable/reference/reference.html#confval-tmp_path_retention_count↩
-
テストが通ることのほうが多い場合は
print(tmp_path)とpytest -sの合わせ技でしょうか↩