動画で見る(3分54秒)
動画の台詞を読む
部長:大事な判定は、2人で、ダブルチェックしてるの。報告にも、2名確認済み、って書いてあるわ
トラ猫:……2人目の確認の跡は、見ましたか
部長:2名、って書いてあるのよ
トラ猫:編集部は、2つのAIに、同じ会話を採点させていました。ある日の記録は、2人目が、途中で止まっていました
部長:止まってたのに、気づかなかったの?
トラ猫:記録の名前は、2人の合議、のままでした。中身は、1人目の点数だけです
AIのキャラクターの会話を、2つのAIで採点してきた、編集部の記録です。
トラ猫:2つのAIは、系統の違う、別々のモデルです。それぞれが別々に採点して、2人分を合わせた点数を、合議、と呼んでいました
トラ猫:2026年の7月、この合議で、会話の改良を確かめました
トラ猫:ところが、保存されていたのは、1つのAIの点数だけ。名前は、合議、のままです
部長:2名確認済み、の判子だけ、押してあったのね
トラ猫:1人目は、採点を終えました
トラ猫:2人目は、1回の採点に使ってよい金額の上限を超えて、途中で終わりました
トラ猫:でも、仕組みは、失敗しました、という1行を出しただけで、止まらずに、先へ進みました
トラ猫:そして、合議、という名前のまま、1人目の点数を、保存しました
部長:1行だけ出されても、誰も読まないわ
トラ猫:その時、合議の平均として表示されたのは、4.14でした
トラ猫:2人目を正しく加えた、本当の合議は、4.71です
部長:0.5以上、違うじゃない
トラ猫:はい。しかも、保存の形は、2人そろった時と、まったく同じでした
部長:どうして、すぐ、分からなかったの
トラ猫:2人そろった時も、1人しかいない時も、名前と形が同じだからです
トラ猫:結果だけを見る人には、見分けられません。その時の記録を遡らない限り、気づけない
トラ猫:それに、それまで通っていた上限が、黙って、通らなくなります。AIの料金が上がったり、採点する会話が長くなったりするだけで、です
部長:昨日まで大丈夫だった、が、一番危ないのね
部長:それで、どう、直したの
トラ猫:まず、2人目の上限を、1.50ドルに上げました。あわせて、合議の点数を使う前に、2人分がそろっているかを、確かめる手順を、足しています
トラ猫:過去の合議の点数を比べる時も、その時の記録を開いて、1人分になっていないかを見てから、使います
トラ猫:そして、片方が欠けた時は、そろった時と、別の名前、別の形で、出すようにしました
部長:欠けたら、欠けたと、分かる形にするのね
部長:うちで、私が、やることは?
トラ猫:まず、2名確認済み、の書類で、2人目の確認の跡を、見ます。名前と、時刻と、結果です
トラ猫:次に、片方が欠けた時は、1名のみ、と書く決まりにする。そろった時と、同じ書き方をさせません
トラ猫:最後に、AIの採点や、自動の検査を使っているなら、何人分そろった結果かを、必ず出させてください
部長:……2名確認済み、と書いてあれば、2人が見た。私、そう思ってたわ
トラ猫:名前が同じでも、中身が同じとは、限りません
部長:今週の、2名確認済みの書類、2人目の欄を、開いてみる
トラ猫:はい。そろっているか、からです
あなたの会社の、2名確認済み、2人目は、本当にいましたか。記事は、AIコンパス、合議、単独判定、で検索。
この記事は、評価設計に関する検証シリーズの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の呼び出しが、当時設定していた予算上限(7軸judgeの実装(社内コード)は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側の予算上限を7軸judgeの実装(社内コード)・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の両方を含んでいるかを確認する手順を運用に追加した。