この記事は、評価設計に関する検証シリーズの1本である。自社のAIキャラクター評価ではSonnet+Opusの合議judgeを使っているが、2026年7月のE2E検証で、Opus呼び出しが予算超過で例外終了したにもかかわらず、出力ラベルは「consensus」のままSonnet単独のスコアが保存されていた事故が起きた。その経緯と是正をまとめる。
この記事で分かること
- Opus側がどのような条件で無言フォールバックしたか
- 「consensus」というラベルの下で、実際には何が保存されていたか
- 再発防止としてどのような確認手順を追加したか
この記事で分からないこと(正直に書く)
- 過去に「consensus」として保存された全スコアのうち、同種の欠落がどの程度混ざっていたか(当時のJSON全件の再点検はしていない)
- 予算上限を超えた具体的な頻度(単発の事故として把握したのみ)
何をした
自社のAIキャラクター対話の評価では、Sonnet+Opusの合議judgeによる7軸consensus評価を用いている。2026年7月20日、CPRのE2E検証としてこの合議評価を実行した(出所: 自社の運用記録、確認日2026-09-06)。
何が起きた
Opusの呼び出しが、当時設定していた予算上限(judge_7axisは0.40ドル、claude_judgeは0.30ドル)を超過し、CLI呼び出しがexit 1で終了した。評価スクリプトはこの例外を「{モデル名} failed」という表示だけで握りつぶして処理を続行する作りだったため、「consensus」というラベルのままSonnet単独のスコアが保存された。この時表示されたconsensus平均は4.14だったが、Opusを正しく加えた真の合議は4.71だった(出所: 自社の運用記録、確認日2026-09-06)。
「二人の合議」のつもりで「一人の判定」を測っていた
意図していたのは、Sonnet+Opusという系統の異なる2つのjudgeが独立に評価し、その一致度も含めて信頼できるスコアを得ることだった。しかし実際に保存されていたのは、Opusが失敗した回についてはSonnet1人の判定であり、それが「consensus」という2人分の合議と同じ名前・同じ形式で記録されていた。出力を見るだけでは、2人が評価したのか1人しか評価していないのかを区別できない。
なぜ気づけなかったか
部分失敗を警告表示だけで継続する設計は、出力フォーマット(「consensus」という名前とJSONの形)が成功時と完全に同一であるため、下流の利用者がログを遡らない限り劣化に気づけない。Opusの単価上昇や評価対象のトランスクリプトが長くなることで、それまで通っていた予算上限が黙って通らなくなるという、正常系の隣で起きる沈黙死の一種だった(出所: 自社の運用記録、確認日2026-09-06)。
どう直したか
Opus側の予算上限をjudge_7axis.py・claude_judge.pyの両方で1.50ドルに引き上げた。加えて、合議結果を利用する前に、per_judgeのキーが想定する評価者(SonnetとOpus)を両方とも含んでいるかを確認する手順を運用に追加した。過去のconsensusスコアを比較に使う際も、当時のJSONのper_judgeを開いてSonnet単独になっていないかを検証してから使うことにしている(出所: 自社の運用記録、確認日2026-09-06)。
再発防止
合議のような複数要素からなる評価は、部分失敗時に成功時と異なる名前・異なる形式で出力されるよう設計し、「揃っているはずのキーが揃っているか」を利用前に機械的に確認するチェックを標準の手順に組み込んでいる。
学習指標だけでは対話の質を判断できなかったケースは姉妹記事「蒸留DPOの学習指標と対話評価が食い違った記事」に、語彙評価器がGoodhart化した経緯は「語彙評価器のGoodhart化を扱う記事」にまとめている。評価器自体が測定対象を見誤っていた別の事故は評価器が測定対象に盲だった記事を参照してほしい。
評価設計・監視設計について相談したい場合は、お問い合わせから編集部まで連絡してほしい。
よくある質問
Q1. Opus側はなぜ無言フォールバックしたのか
Opusの呼び出しが当時の予算上限(0.40ドルまたは0.30ドル)を超過してCLI呼び出しがexit 1で終了し、評価スクリプトが例外を表示だけで握りつぶして処理を続行したため。
Q2. その間、consensusスコアには何が保存されていたのか
「consensus」というラベルのままSonnet単独のスコアが保存されていた。表示されたconsensus平均は4.14だったが、Opusを正しく加えた真の合議は4.71だった。
Q3. なぜ気づくのに時間がかかったのか
部分失敗が警告表示だけで継続する設計になっており、出力フォーマットが成功時と完全に同一だったため、ログを遡らない限り劣化に気づけなかった。
Q4. 再発防止としてどんな手順を追加したか
Opus側の予算上限を1.50ドルに引き上げた上で、合議結果を利用する前にper_judgeのキーがSonnetとOpusの両方を含んでいるかを確認する手順を運用に追加した。