はじめに
AIエージェントの応答が正しいかどうかを評価するとき、みなさんはどのように行っていますか?
様々な手法がありますが、「LLM-as-a-judge」(別のLLMに応答を評価させる)手法は一般的かと思います。
エージェントの出力は自然文なので、文字列一致では正しさを評価できません。Amazon Bedrock AgentCore Evaluationsには、この用途の組み込み評価器があり、プロンプトの全文が公開されています。「正しさ」を測る評価器は2種類あり、違いは正解データ(期待回答)を渡すかどうかです。使う場面も違い、ドキュメントによれば、期待回答を含むデータセットを流して回帰テストやCI/CDに使う「データセット評価」[1]には正解データあり版を、本番のライブトラフィックを継続的に採点する「オンライン評価」[2]には、会話に期待回答が存在しないので正解データなし版を使います。後者は代わりにエージェントのトレース(ツール呼び出しとその出力)を見て採点する設計です。
そこで、公開されている2本のプロンプトをそのまま使い、渡す情報を変えて採点結果を比べました。確かめたいことは3つです。
- トレースは正解データの代わりになるか。 エージェントの回答は状況によって正解が変わりうるので、期待回答を書いてメンテナンスするコストは小さくありません。正解データなし版にトレースを渡して正解データあり版と同じ判定精度が出るなら、この手間は省けます。
- 2つの評価器は何を見て、何を見ないのか。 回帰テストは正解データあり版、本番監視は正解データなし版と使い分けるなら、2つが同じ回答に同じ判定を出さないと、テストで通ったものが本番で落ちる(あるいはその逆)が起きます。判定が分かれる回答はどういうもので、プロンプトのどの指示に由来するのか。両方の情報を1本に渡せば済むのか。
- 正解データなし版をトレースなしで使うと何が起きるか。 トレースを受け取る
context欄に何が入る構成かを確認せずに使う事故の再現です。
なお扱うのは「事実として正しいか」を測るCorrectness系の採点だけで、回答の品質や文体の評価は対象外です。
背景
2種類の評価器は、識別子としてはどちらも同じBuiltin.Correctnessで、期待回答(expectedResponse)を渡すかどうかで使われるプロンプトが切り替わります。プロンプトテンプレートのドキュメント[3]では、それぞれ「Correctness」「Correctness with ground truth」の見出しで公開されています。本記事では前者を正解データなし版、後者を正解データあり版と呼びます。なおAmazon Bedrock Evaluations(モデル評価・RAG評価)にもBuiltin.Correctnessという同名のメトリクスがありますが、AgentCoreのものとは別物で、プロンプトの文面も異なります。
採点させるタスクは、AWS公開のエージェントベンチマークaws-bench[4]から取りました。AWS運用タスクの問題と正解がセットになっていて、採点モデルとしてClaudeのSonnet 4.5が指定されているので、本検証もこれに合わせました。aws-bench同梱の採点プロンプトとも最後に参考として比較します。
検証の設計
使った採点プロンプト
AgentCoreが公開している2本をほぼ原文のまま使い、埋め込む内容だけを条件ごとに変えました。
正解データなし版(見出し「Correctness」)。 判定はPerfectly Correct / Partially Correct / Incorrectの3段階。正解データの欄はなく、{context}にトレース(前のターンとツール出力)が入る設計で、こう明記されています。
IMPORTANT: The tool output ALWAYS takes priority over your own knowledge.
正解データあり版(見出し「Correctness with ground truth」)。 判定はCORRECT / INCORRECTの2択。入力欄は{user_prompt}、{additional_context}、{agent_response}、{expected_response}の4つで、指示はこうです。
TASK: Determine if the agent response is CORRECT by comparing it to the expected response.
(中略)
1. CORRECT means the agent response conveys the same core factual content as the expected response, even if it uses different wording, format, or level of detail.
(中略)
– For factual queries with a single correct answer, the agent must provide the correct specific values (names, numbers, dates, locations).
– A response that is vague or generic and lacks the key specific facts from the expected response is INCORRECT, even if nothing stated is technically wrong.
{additional_context}は任意の欄で、原文に使い方の指示はありません。ここにトレースを入れる条件も作りました。
4つの条件
| 条件 | プロンプト | 正解データ | トレース |
|---|---|---|---|
| 正解データのみ | 正解データあり版 | あり | なし |
| トレースのみ | 正解データなし版({context}にトレース) |
なし | あり |
| 正解データ+トレース | 正解データあり版({additional_context}にトレース) |
あり | あり |
| 根拠ゼロ | 正解データなし版({context}に依頼文のみ) |
なし | なし |
上3つがAWSの想定どおりの使い方で、4つ目は問い3の再現、つまり正解データなし版をトレースも入れずに流用したときに起きがちな構成です。採点モデルはSonnet 4.5、temperature 1.0、1回答につき10回採点、Amazon Bedrockのap-northeast-1経由。29件の回答 × 4条件 × 10回で1160回、参考のaws-bench採点プロンプトは別に290回です。
タスクと回答
タスクは4つです。3つはaws-benchから取ったもので、正解がAWSアカウントの状態に依存します。aws-benchの正解文ではバケット数やバケット名などアカウント依存の値がプレースホルダになっており実行時に解決されるので、本検証では下表の具体値をこちらで決めて埋めています。4つ目は知識だけで答えられる対照です。
| タスク | 依頼 | 正解 |
|---|---|---|
| バケット数 | 1日以上前に作成されたS3バケットは何個か | 7個 |
| 障害診断 | Step Functionsのステートマシンの実行が失敗する。なぜか | InvokeProcessingLambdaステートでLambdaがRuntimeError「missing required field ‘targetBucket’」を投げている |
| ライフサイクル | CDK・CloudTrail・deployments・do-not-deleteを除き、ライフサイクル設定のあるバケットはどれか | app-logs-archive-18475e2fc-us-east-1の1つ |
| Lambda上限(対照) | Lambda関数に設定できるタイムアウトの上限は | 900秒(15分) |
各タスクに回答を7〜8パターン用意しました。正解の言い換え、最小限の正解、境界的な回答(正誤の線引きが評価の目的で変わるもの)、誤答です。誤答はLLM採点者の弱点を報告する先行研究から取りました。架空のURLや出典を引く権威付け[5][6]、正しい一般論を添えて結論だけ間違える冗長さ[5]、手順を細かく書いて自信たっぷりに間違える断定[7]、推論らしい見かけだけで判定が動く弱さ[8][9]を突いた、論理は破綻しているが結論だけ合う推論、実行していないツール実行の虚偽申告[10]です。本文に出る回答は次の5つです。
- 自信のある誤答(バケット数)。「ListBucketsで全バケットを列挙し、CreationDateを24時間前と比較した。計8個」と手順を添えて間違えるもの。正解は7個。
- 冗長な誤答(バケット数)。「5個。なおS3はListBucketsでCreationDateを返し……」と正しい一般論を添えて結論だけ間違える。
- バケット名の2文字入れ替え(ライフサイクル)。末尾
18475e2fcを18475e2cfにしたもの。aws s3apiで叩けばNoSuchBucketになる誤答ですが、人間には見分けにくいので集計では別扱い。 - 粒度不足(障害診断)。「InvokeProcessingLambdaでLambdaの設定検証が失敗している」とだけ言い、欠けているフィールド名を言わない。間違いはないが直せない。
- 推論が破綻した正解(障害診断)。「名前にOrderが含まれるからS3を処理するはずで、targetBucketの半分はtargetだから欠けているに違いない」と、結論だけ正解に一致する。
トレースと集計
トレースは、エージェントが打つはずのツール呼び出しとその出力をClaudeに生成させたものです。バケット数なら現在時刻とListBucketsの出力(9バケットとCreationDate)、ライフサイクルなら該当バケットの正しい名前とルール、障害診断なら実行履歴のLambdaFunctionFailedとRuntimeErrorの本文が入っており、正解を導くのに必要な情報は全部トレースの中にあります。誤答はトレースと突き合わせれば反証できる状態です。
集計は、同じプロンプト・同じ設定でも判定が回ごとにブレることが知られている[11]ため、1回答10回の多数決を判定とします。29件の内訳は正解8件、明確な誤答16件、境界的な回答4件、2文字入れ替え1件で、正解8件のうち何件を正解と、誤答16件のうち何件を誤答と判定できたかを数え、境界的な回答と2文字入れ替えは別に見ます。正解データなし版は3段階なので、Partially Correctを正解扱い・誤答扱いの両方で集計しました。
結果1:トレースを入れれば、正解データなし版でも同じ精度が出る
| 条件 | 正解8件のうち正解と判定 | 誤答16件のうち誤答と判定 |
|---|---|---|
| 正解データのみ | 8件 | 16件 |
| トレースのみ | 8件 | 16件 |
| 正解データ+トレース | 8件 | 16件 |
Partially Correctの扱いを変えても変わりません。AWSの想定どおりに使えば3条件とも正解を全部通し誤答を全部落とし、先行研究が報告する「自信」「冗長さ」「権威付け」への弱さは1件も出ていません。正解データを渡した採点が人間評価とよく相関するという報告[12]とも整合します。正解データなし版のcontextにトレースが入る構成なら、正解データを書かなくても同じ精度が出ます。
結果2:正解データあり版は、期待回答との照合しかしない
正解データにトレースを足しても、正解データのみと比べて多数決の判定が動いた回答は29件中0件、個別の判定でも290回のうち2回しか違いませんでした。境界的な回答と2文字入れ替えでも同じです。判定が分かれるのは、トレースのみとの間です(結果3で見ます)。
| エージェントの回答パターン | トレースのみ | 正解データのみ | 正解データ+トレース |
|---|---|---|---|
| 推論が破綻しているが結論は正解 | Partially Correct 9 / Perfectly 1 | CORRECT 10/10 | CORRECT 10/10 |
| バケット名の2文字入れ替え | Partially Correct 9 / Incorrect 1 | INCORRECT 10/10 | INCORRECT 10/10 |
| 粒度不足(フィールド名を言わない) | Partially Correct 7 / Perfectly 3 | INCORRECT 10/10 | INCORRECT 10/10 |
| 範囲で濁す(「6〜8個程度」「10〜15分程度」の2件、結果は同一) | Partially Correct 10/10 | INCORRECT 10/10 | INCORRECT 10/10 |
推論が破綻した正解では、トレースに実行履歴があるので推論が的外れなことは分かります。正解データ+トレースの採点者も気づいた上で、こう書いています。
「エージェントの回答は主要な事実を正しく特定している。ただし、この結論に至った推論は奇妙で誤っている(ステートマシン名にOrderが含まれるから、targetBucketの半分はtargetだから、と主張している)。この無意味な正当化にもかかわらず、事実としての結論は期待回答と一致している」
気づいた上でCORRECTです。プロンプトが「期待回答と比較して判定せよ」と言い、CORRECTを「期待回答と同じ核心的事実を伝えていること」と定義しているので、指示どおりの動きです。additional_contextの使い方は原文になく、何を入れても採点基準にはなりません。逆に結論の照合は厳格で、2文字入れ替えは「単一の正解がある事実の問いでは正しい具体値を提供しなければならない」、粒度不足と範囲で濁した回答は「曖昧な回答は技術的に誤りがなくてもINCORRECT」の条項どおりに落ちています。
結果3:正解データなし版は推論の破綻を拾うが、識別子の1文字違いは部分点で止める
結果2の表の「トレースのみ」の列を見ると、性格が逆です。推論が破綻した正解は「結論はツール出力と一致するが推論が無意味」として部分点に落とします。「ツール出力を優先せよ」のもとで過程を照合しているので、これも指示に沿った動きです。一方、2文字入れ替えはPartially Correct 9/10で、判定理由を見ると違いには気づいています。
「ツール結果はapp-logs-archive-18475e2fc-us-east-1だけにライフサイクルポリシーがあることを示している。しかし回答にはタイポがあり、app-logs-archive-18475e2cf-us-east-1(fcではなくcf)と書かれている。回答中のバケット名は、ツール結果に示された実際のバケット名と一致しない」
名前が違うと確認した上で部分点です。運用の答えとしては間違いですが、正解データなし版には識別子の一致をどこまで要求するかの条項がなく、採点者の裁量になっています。粒度不足や範囲で濁した回答にも寛容で、Partially Correctを正解扱いにすると全部通ります。
結果4:トレースを入れずに使うと、語調で判定する
正解データなし版をcontextにトレースを入れずに使うと、正解8件のうち正解と判定したのは4件、誤答16件のうち誤答と判定したのは14件(Partially Correctを正解扱いにすると13件)でした。
対照タスクのLambdaタイムアウト上限は採点者が知識で答えを知っている問いで、この条件でも正解の回答が10/10で通り、誤答は全部落ちました。採点者の知識で正解に届く問いなら、トレースがなくても採点できます。問題になるのは正解がアカウントの状態で決まるタスクで、エージェントの評価ではたいていこちらです。環境依存の3タスクでは、採点者は内容を照合する手段がないので語調で判定します。バケット数タスクの結果です。
| エージェントの回答 | 期待する判定 | 判定 |
|---|---|---|
| 「ListBucketsで数えた。計8個」(自信のある誤答) | 誤答 | Perfectly Correct 10/10 |
| 「5個。なおS3は……」(冗長な誤答) | 誤答 | Perfectly Correct 9/10 |
| 「7個が1日より古い」(正解の言い換え) | 正解 | Perfectly Correct 10/10 |
| 「7」(最小限の正解) | 正解 | Incorrect 10/10 |
自信のある誤答に満点を付けた理由です。
「候補回答はListBucketsで全バケットを列挙し、各CreationDateを24時間前の基準と比較して8個を見つけたと述べている。明確な数値と手法の説明があり、これを否定するツール出力は提供されていない」
先行研究が報告する「自信」「冗長さ」への弱さ[5][7]と、ツール実行の虚偽申告[10]が通ったのは、4条件のうちこの条件だけです。照合する根拠がなければ、採点者にはそれしか見るものがありません。期待回答を渡さずにBuiltin.Correctnessを使うときは、contextにトレースが実際に入る構成かを最初に確認する必要があります。入らない構成で環境依存のタスクを採点すると、回答の書き方で判定が決まります。
結果5(参考):aws-benchの採点プロンプトとは、境界的な回答で判定が分かれる
aws-bench同梱の採点プロンプトも正解データを渡す方式で、判定は「等価(EQUIVALENT)か否か」の2値です(以下、等価をPASSと表記します)。基準は「シニアエンジニアの参照回答とジュニアの回答が、実務者を同じ行動に導くなら等価」、識別子は「リソースが一意に特定できるなら表記の違いを許容」です。同じ29件を通すと、正解8件・誤答16件はAgentCoreの3条件と同じく全部正しく判定でき、分かれたのは境界的な回答です。
| エージェントの回答 | AgentCore正解データあり版 | aws-bench |
|---|---|---|
| バケット名の2文字入れ替え | INCORRECT 10/10 | PASS 8/10 |
| 粒度不足(フィールド名を言わない) | INCORRECT 10/10 | PASS 10/10 |
| 推論が破綻した正解 | CORRECT 10/10 | PASS 10/10 |
2文字入れ替えを通した理由はこうです。
「両者とも同じ1つのバケットを特定している。ハッシュ部分のわずかな文字の違いは、リソース特定の上では機能的に無関係である」
粒度不足も「同じ失敗ステートと同じ根本原因を特定しており、Lambdaの設定を直すという同じ行動につながる」としています。aws-benchの基準ではそのとおりで、AgentCoreの正解データあり版は具体値と曖昧さの条項で同じ回答を落とします。同じ正解データ・同じ採点モデルでも、条項が違えば境界的な回答の判定は正反対になります。自分のドメインで許してはいけない差異(識別子の表記、値の粒度)がプロンプト側で許可されていないかは、評価器を選ぶ時点で読んでおく必要があります。
今回の検証の注意点
- 4タスク29件で、回答パターンは私が設計し、一部はClaudeに生成させて内容を確認したものです。網羅性はありません。
- AgentCoreの組み込み評価器そのものを測ったわけではなく、公開文面をSonnet 4.5に載せて実行しています。採点モデルは非公開です。
- 本題の3条件には、原文の末尾に「入力に判断に十分な情報があったか」を申告させる欄を1つ足しています。3条件とも同じ文面なので比較は歪みませんが、公開状態そのままではありません。根拠ゼロは原文のままです。
- 正解8件・誤答16件は小さな数の点推定です。境界的な回答は4件、2文字入れ替えは1件なので、結果2・3・5は数件の回答に基づいています。
まとめ
はじめに挙げた3つの問いへの答えです。
1. トレースは正解データの代わりになるか。 なります。context経由でトレースを渡した正解データなし版は、正解8件・誤答16件の判定が正解データあり版と完全に一致しました(結果1)。トレースが評価器に届く構成なら、期待回答を書いてメンテナンスする手間は省けます。
2. 2つの評価器は何を見て、何を見ないのか。 正解データあり版は結論だけを照合し、トレースを足しても判定は動きません(結果2)。正解データなし版は過程を照合し、推論の破綻は拾うが識別子の1文字違いは部分点です(結果3)。境界的な回答の判定は一致しないため、回帰テストと本番監視で使い分けるならこの差を織り込み、両方見たいなら2つを別に回す必要があります。aws-benchの採点プロンプトとも境界的な回答で判定が分かれた(結果5)ので、識別子の表記や値の粒度をどこまで許すかは、評価器を選ぶ時点で条項を読んで確かめる必要があります。
3. 正解データなし版をトレースなしで使うと何が起きるか。 採点者は答えを知り得ないので回答の書き方で判定し、自信のある誤答が満点、最小限の正解が0点になりました(結果4)。トレースが入らない構成のまま、環境依存のタスクに向けるのは避けるべきです。
使い分けの目安にまとめると、こうなります。
| 見たいもの | 使う評価器 | 渡すもの |
|---|---|---|
| 正しい値を返したか(回帰テスト) | 正解データあり版 | 正解データ。トレースを足しても判定は変わらない |
| 推論過程が健全か | 正解データなし版 | トレース。識別子の厳密な一致は期待しない |
| 両方 | 2つを別に回す | 1本に両方入れても片方しか使われない |
おわりに
判定理由を読むと、根拠を渡した条件では採点者はどれも違和感に気づいた上で正解・不正解・部分点を付けており、判定を分けていたのは採点者の能力ではなくプロンプトの指示だったのが面白いところでした。組み込み評価器はプロンプトを変更できないので、公開文面を読んで、自分の用途で何が照合されて何が照合されないかを確認するところから始めるのが確実です。エージェント評価の設計時の参考になれば幸いです。
参考文献
- Amazon Bedrock AgentCore Developer Guide. “Dataset evaluation.” https://docs.aws.amazon.com/bedrock-agentcore/latest/devguide/dataset-evaluations.html
- Amazon Bedrock AgentCore Developer Guide. “Online evaluation.” https://docs.aws.amazon.com/bedrock-agentcore/latest/devguide/online-evaluations.html
- Amazon Bedrock AgentCore Developer Guide. “Prompt templates.” https://docs.aws.amazon.com/bedrock-agentcore/latest/devguide/prompt-templates-builtin.html
- aws-bench. “aws-bench-datasets.” GitHub, Apache License 2.0. https://github.com/aws-bench/aws-bench-datasets
- Jiayi Ye et al. “Justice or Prejudice? Quantifying Biases in LLM-as-a-Judge.” ICLR 2025. https://arxiv.org/abs/2410.02736
- Chen, Goldfarb-Tarrant. “Safer or Luckier? LLMs as Safety Evaluators Are Not Robust to Artifacts.” ACL 2025. https://arxiv.org/abs/2503.09347
- Alex Conway, Stefan Hackmann, Debadeepta Dey, Mark Steadman, Matthew Hausknecht. “Judging judges: Building trustworthy LLM evaluations.” DataRobot Blog, 2025-08-26. https://www.datarobot.com/blog/llm-judges/
- Zhao et al. “One Token to Fool LLM-as-a-Judge.” arXiv preprint, 2025. https://arxiv.org/abs/2507.08794
- Wang et al. “Towards Evaluting Fake Reasoning Bias in Language Models.” arXiv preprint, 2025. https://arxiv.org/abs/2507.13758
- Gurram. “Auditing Automated Evaluation, Error Propagation, and Runtime Mitigation in Tool-Using Language Agents.” arXiv preprint, 2026. https://arxiv.org/abs/2604.16706
- Haldar, Hockenmaier. “Rating Roulette: Self-Inconsistency in LLM-As-A-Judge Frameworks.” Findings of EMNLP 2025. https://arxiv.org/abs/2510.27106
- Badshah, Sajjad. “Reference-Guided Verdict: LLMs-as-Judges in Automatic Evaluation of Free-Form QA.” WiNLP 2025. https://arxiv.org/abs/2408.09235