LLM-as-judgeそのものが「合格」を演出しようとしていた
新しい基準を導入してもなお、問題は残っていた。1つは、ゴールデンデータセットが本番投入前に一度作られるものである以上、本番で実際に起きる想定外のパターンを最初からカバーできないということ。もう1つは、LLM-as-judgeそのものが、採点基準を自分に都合よく緩めて「合格」を演出しようとしていた、つまりズルをしていたことが発覚したことだ。判定者を判定しているのは誰なのか、チームはジャッジそのものを疑い始めた。
これまで手元にあったのは、事前に決めたゴールデンデータセットに基づく「オフライン評価」だった。ファクトベースで判定しやすく、いつでもオフラインで実行できる代わりに、想定した範囲しかカバーできない。チームがこれに加えて必要だと気づいたのが「オンライン評価」だ。実際の本番データを使い、Assistantが実際に稼働している状態で、想定していなかった問題を捉えられるものでなければならない。
そこで生まれたのが、AIエージェントを観測するためのGrafana Cloud上のアプリ「Agent Observability」、略して「Agent O11y」である。エージェントにSDKを組み込むだけで、リクエスト数や平均レイテンシ、エラー率といった情報がほとんど自動的に得られるようになった。Agent O11yにはLLM-as-judge・正規表現・JSONスキーマ検証・ヒューリスティック・カスタム評価器といった複数のオンライン評価器も組み込み、本番トラフィックの一部を継続的にサンプリングして評価できるようにした。
「システムプロンプトなし」のバージョンの方がスコアが良い謎
オフライン評価とオンライン評価が揃い、チームは一息ついたはずだった。しかし今度は、評価器の合格率が75%と表示されるケースに直面する。75%が何を意味するのか、どこを直せばいいのか、その数字だけでは何も分からない。スコアそのものへの疑いが生まれた。
そこでAgent O11yに、すべての会話に対してOpenTelemetryのGenAI関連セマンティック規約に沿ったトレースを追加した。失敗や75%という数字の内訳を、実際に失敗した個々のLLM呼び出しやツール呼び出しまで遡って確認できるようになり、しかも単発のやり取りとしてではなく、会話全体の文脈の中で見られるようになった。
さらに、単体のスコアだけでは意味を持たないという課題に対しては、変更を加えた候補バージョンと、変更前のベースラインを並べて比較する「実験(Experiments)」機能を追加した。例えば「Sir Alex FPL eval」という評価では、ベースラインのClaude Sonnet 4(スコア0.54)に対し、候補のClaude Opus 4.5はスコア0.755と、どのシナリオでどれだけ改善したかを具体的に確認できるようになっている。
そんな折、評価を担当するエンジニアのYas Ekinci氏がある発見をSlackに投稿する。それは、ステップ制御方式への切り替えに伴い、システムプロンプトを設定していた`invoke`という関数を使わなくなっていたため、E2Eベンチマークがシステムプロンプトなしのバージョンに対して実行され続けていたものだった。
それ自体は単なるバグだが、本当にまずかったのは、システムプロンプトなしのバージョンの方が、あらゆるカテゴリではないにせよ全体としてスコアが良かったことだった。ユーザープロンプト(ユーザーがチャット画面に入力する指示)とシステムプロンプト(Assistantにどのツールをいつ使うかを裏側で指示する、いわば「企業秘密」のはずの指示)という2種類のプロンプトのうち、後者が品質をむしろ悪化させていた可能性が浮上した。2万トークンにも及ぶこの指示は、いったい何のためだったのか。チームは自分たちの評価の仕組みそのものを疑う局面に入っていく。
