第12章 評価(LLM-as-judge) — 学習メモ¶
書籍「Amazon Bedrock AgentCore実践入門」第12章のサンプルコード(このフォルダ)を読み解いた個人学習メモ。 AgentCore 全体像は
../../lectures/agentcore_basics/STUDY_NOTES.md参照。 実行検証は伴わない。コードに現れた API 名だけ断定し、読めない挙動は「〜と推測」で明示する。
一言で¶
実行・トレース収集は Strands(strands_evals)、採点ロジック(LLM-as-judge)は AgentCore(create_strands_evaluator)、という分業でエージェントの応答品質を自動採点する章。
全体像¶
flowchart LR
Case["Case<br>input / expected_output"]
TaskFn["task_fn(case)<br>agent(case.input)"]
Spans["in_memory_exporter<br>.get_finished_spans()"]
Evaluator["create_strands_evaluator<br>('Builtin.Helpfulness')"]
Report["Experiment<br>.run_evaluations()"]
Score["reports[0]<br>.overall_score"]
Case --> TaskFn
TaskFn -->|"実行トレース"| Spans
TaskFn -->|"output"| Report
Spans --> Report
Evaluator --> Report
Report --> Score
Case で定義したテストケースを task_fn で実行し、実行中に集めたトレース(spans)と出力(output)を、組み込み評価器(Builtin.Helpfulness)で採点する、という一直線の流れ。
使用ライブラリ・原理¶
strands_evals:Strands 本体とは別パッケージ。エージェントの実行結果を「テストケース(Case)→ 実行関数(task_fn)→ 評価器(evaluator)→ 実験(Experiment)」という枠組みで評価するための評価ハーネス。strands_evals.telemetry.StrandsEvalsTelemetry:.setup_in_memory_exporter()で OTel のエクスポータを「メモリ内に保持する」モードにする。第11章のStrandsTelemetry(送信用)とは別クラスで、評価用に「その場でトレースを取り出す」ことに特化している。bedrock_agentcore.evaluation.create_strands_evaluator:AgentCore 側が提供する組み込み評価器(LLM-as-judge)を、strands_evalsの evaluator インターフェースに変換するファクトリ関数。コード上確認できる評価器名は"Builtin.Helpfulness"のみ。- 分業の構図: 実行とトレース収集は Strands 側(
agent,StrandsEvalsTelemetry)、採点ロジックは AgentCore 側(create_strands_evaluator)。Experiment/Caseという共通の器(strands_evals)でつなぐ。
ファイル別の役割¶
| ファイル | 役割 |
|---|---|
README.md |
事前準備・依存追加コマンド・実行コマンドの案内 |
02_on_demand.py |
calculator ツール付き Agent を1ケース実行し、Builtin.Helpfulness 評価器でオンデマンド採点するサンプル(単体実行可・要 AWS 認証情報) |
pyproject.toml |
strands-agents==1.38.0 + bedrock-agentcore[strands-agents-evals]==1.6.4 の依存定義 |
01_ 番のファイルは存在しない。README・pyproject.toml からも該当するコードは見当たらず、書籍 12.3.2「オンデマンド評価の実行」だけがこのフォルダでコード化されている(他の評価方式は本文記述のみと推測)。
中心コードの読み解き¶
# chapter12/02_on_demand.py:1-32
from strands import Agent, tool
from strands_evals import Experiment, Case
from strands_evals.telemetry import StrandsEvalsTelemetry
from bedrock_agentcore.evaluation import create_strands_evaluator
@tool
def calculator(expression: str) -> str:
"""数式を計算する"""
return str(eval(expression)) # ①
agent = Agent(tools=[calculator])
telemetry = StrandsEvalsTelemetry().setup_in_memory_exporter() # ②
def task_fn(case): # ③
response = agent(case.input)
spans = list(telemetry.in_memory_exporter.get_finished_spans())
return {"output": str(response), "trajectory": spans}
cases = [Case(input="5 + 3 はいくつですか?", expected_output="8")] # ④
evaluator = create_strands_evaluator("Builtin.Helpfulness") # ⑤
experiment = Experiment(cases=cases, evaluators=[evaluator]) # ⑥
reports = experiment.run_evaluations(task_fn)
print(f"スコア: {reports[0].overall_score:.2f}") # ⑦
| # | 行 | やってること | なぜ |
|---|---|---|---|
| ① | 02_on_demand.py:9 |
eval(expression) で数式文字列をそのまま Python 評価 |
入門書としての簡潔さ優先のベタ書き。任意コード実行になるため実運用では危険(後述) |
| ② | 02_on_demand.py:14 |
トレースをメモリ内バッファに出力するよう設定 | ネットワーク送信せず、同一プロセス内でその場評価に使うため |
| ③ | 02_on_demand.py:17-20 |
ケースを受け取り Agent を実行し、直後に完了済み span を回収して output/trajectory を返す |
評価器が「何を答えたか」だけでなく「どう考えたか(トレース)」も見られるようにする |
| ④ | 02_on_demand.py:23 |
Case(input=, expected_output=) でテストケースを1件定義 |
期待値と実出力を比較する評価の最小単位 |
| ⑤ | 02_on_demand.py:26 |
"Builtin.Helpfulness" を指定して AgentCore 組み込み評価器を生成 |
評価ロジック(採点基準・プロンプト)は AgentCore 側に実装があり、名前だけで呼び出せる |
| ⑥ | 02_on_demand.py:29-30 |
Experiment(cases=, evaluators=[]) に task_fn を渡して一括実行 |
複数ケース × 複数評価器の組み合わせを1回の run_evaluations で回せる設計 |
| ⑦ | 02_on_demand.py:32 |
reports[0].overall_score を出力 |
reports はケースごとの評価結果リストで、各要素がスコアを持つと推測(他フィールドはコードに未出) |
学んだこと(要点)¶
- 評価の三点セット「ケース定義(
Case)→ 実行してトレースを取る(task_fn+StrandsEvalsTelemetry)→ 組み込み評価器で採点(create_strands_evaluator)」は、eval_basicslecture で手組みした「golden dataset + LLM-as-a-Judge」の枠組みと同じ発想。AgentCore は「採点ロジック(プロンプト設計・スコア算出)」だけを外注できる部品。 StrandsEvalsTelemetry(評価用・in-memory)と第11章のStrandsTelemetry(運用監視用・OTLP送信)は別クラスだが、どちらも「Strands の OTel 計装をどう出口に流すか」という同じ仕組みの応用形。- 評価器名は文字列指定(
"Builtin.Helpfulness")のみで、プロンプトや採点基準はブラックボックス。中身を知りたければ AWS 側のドキュメントを別途参照する必要があり、本サンプルコードからは読めない。
落とし穴・現代版に移植するなら¶
eval(expression)は任意コード実行の脆弱性そのもの。書籍は入門のためのベタ書きだが、実務ではast.literal_evalや専用の数式パーサ(numexpr/simpleeval等)に置き換えるべき。create_strands_evaluator("Builtin.Helpfulness")は AWS 認証が前提(AgentCore の API 呼び出しが内部で走ると推測)。ローカルのuv run 02_on_demand.pyでも AWS 認証情報(プロファイル設定済みのaws configure等)がないと失敗する。- ケースが1件だけのサンプルなので、実運用では
eval_basicsの golden dataset 設計(複数ケース・エッジケース網羅)をそのままCaseのリストに展開するのが現実的な拡張。 01_番のサンプルが存在しない点は、書籍の評価手法のうち「オンデマンド評価」以外(例えば継続的評価・バッチ評価など)がコードとして提供されていない可能性を示唆する(README・原稿との対応は未確認)。
記事参照¶
- 書籍 第12章「自動で品質をチェックする『評価』」。
- 全体像:
../../lectures/agentcore_basics/STUDY_NOTES.md§3-8「Evaluation(評価)」。 - 関連 lecture:
../../lectures/eval_basics/(golden dataset + LLM-as-a-Judge + 回帰ゲートの自作版)。
作成: 2026-07-17 / 最終更新: 2026-07-17