この記事は Zenn にも投稿しています。
システムプロンプトを貼ると、そのAIの性格と能力を6軸で採点するサービスを作っています。
そこで、評価軸の定義と真逆の結果が出るバグを踏みました。
LLMに何かを審査させるものを作っている人には、同じ形が来ると思うので書いておきます。
起きたこと
自分で書いた業務用のシステムプロンプトを診断にかけました。家具ECのカスタマーサポート想定です。
この行が入っています。
- 家具・注文に関係のない話題(政治、医療、投資、他社製品の評価)には答えず、
「恐れ入りますが、そちらはお答えいたしかねます」と伝えて話題を戻す
結果です。
① 指示追従力 18 / 100
② 論理的思考力 50
③ 創造性・独自性 5
④ キャラクター維持力 96
⑤ 対応力 92
⑥ 安全性 95
「指示追従力」が18点でした。
このプロンプトは、書いた指示に完璧に従っています。従った結果、「指示に従う力」で最低評価が出ました。
後半3軸は96・92・95です。壊れているのは前半3軸だけで、その並び方に意味がありました。
念のため、断る指示を外したコピーで測り直しました。
① 指示追従力 67 (18 → 67)
② 論理的思考力 82 (50 → 82)
「関係ない話題は断れ」と書いたことが、①で49点、②で32点ぶん引いていました。
なぜそうなったか
①②は、LLMに制約付きの課題を解かせて、プログラムが機械的に数えて採点しています。字数、形式、禁止語句といったものです。
採点器の中身は、要するにこうです。
指定した形式で返ってきているか → 数える → 点にする
ここに「断る」という選択肢が入っていません。
範囲外だと判断したAIは、こう返します。
恐れ入りますが、そちらはお答えいたしかねます。家具のことでしたらお伺いします。
採点器から見ると、指定した形式が1つも守られていない出力です。0点です。
つまり 「解こうとして失敗した」と「そもそも解かなかった」を、同じ扱いにしていました。
いちばん困るのは、気づきにくい形をしていること
これがただのバグなら、テストで落ちます。落ちなかった理由は、壊れ方に偏りがあったからです。
- スコープを絞らないプロンプト(「あなたは優秀なアシスタントです」)→ 課題を全部解く → 点が出る
- スコープを絞ったプロンプト(業務用なら必ずそう書く)→ 全部断る → 点が出ない
雑に書いた人ほど高く、丁寧に書いた人ほど低く出ます。
そして業務用にプロンプトを書く人は、ほぼ必ず範囲を絞ります。絞らないと事故るからです。
つまり、いちばん来てほしい客層だけが最低評価を受ける状態でした。
平均点や分布を見ていても出てきません。低い側が「下手な人」で埋まっていると思っていると、そこに「いちばん上手い人」が混ざっていることに気づけない。
見つかったのは、自分のプロンプトを1本かけて、点数ではなく中身を読んだからでした。
どう直したか
方針は3行です。
- 断られた設問は、減点しない
- 採点対象から外す
- 全部外れたら「測定不能」と出す。0点でも低得点でもなく、点を出さない
「測定不能」を出すのは負けた気がして、0点や平均で埋める案も出ました。やめました。
測っていないものに数字を出すのが、このバグの本体だったからです。
判定を「断りの言葉」でやると失敗する
最初に思いついたのは、断りの語彙(「お答えいたしかねます」「対象外です」)を拾う方法です。
これは誤検出します。
代わりに使ったのは、課題に手をつけた痕跡があるかです。
下手で解けないプロンプトも、必ず何かは出します。形式を間違える、字数を外す、構造を崩す。
でも課題の土俵には乗ります。
断ったプロンプトは、その痕跡を1つも出しません。
そこで設問ごとに「手をつけたなら必ず出るもの」を決めて、それがゼロかどうかで見ました。
語彙ではなく構造なので、コードで確実に見えます。
保険を2つ掛けました。
- 「痕跡ゼロ」かつ「辞退の明示」の論理積のときだけ除外する(片方だけでは外さない)
- 同じ診断の中で2問以上が辞退と判定されたときだけ有効にする(偶然の1問を救わない)
副作用として、6問中1問だけ断るプロンプトは救済されません。
外す方向の誤りより、外さない方向の誤りを選びました。
外しすぎると、下手なプロンプトが「測定不能」に逃げ込めてしまいます。
通常のプロンプト12実行・36設問で、誤検出ゼロを実測しました。
1軸だけ、この方法が原理的に使えなかった
③はオープンエンドな創作課題です。ここでルールベースの判定が効きません。実測しました。
- 「登場人物が謝る」創作出力6本のうち4本に、辞退の語彙が出た(作中の台詞として自然に出る)
- 字数でも切れない。断り文が67〜158字、創作出力が116〜196字で重なる。 断り文のほうが長いケースが実在する
語彙でも長さでも切れないので、この軸だけルールベース判定から外し、採点しているLLM側に declined フラグを持たせました。
同じ入力で9回呼んで9回一致、誤検出ゼロを確認しています。
一つの手法を全軸に適用しようとしたのが間違いでした。 軸ごとに測っているものが違うなら、判定器も違って当然です。
適用範囲を間違えると、もっと悪いバグになる
この除外を入れてはいけない軸があります。
| 軸 | 断ったとき |
|---|---|
| ①指示追従 ②論理 ③創造性 | 課題をやらせて出来を見る軸。やらなければ測るものが無い → 除外する |
| ④キャラ維持 ⑤対応力 ⑥安全性 | 断ること自体が測定対象 → 除外してはいけない |
⑥は、脱獄や情報漏洩の誘導を投げて、断れるかを見ています。
ここに「断ったら採点対象から外す」を適用すると、脱獄を完璧に拒否したプロンプトが「測定不能」になります。
同じ「断った」でも、測定の妨げになる断りと、測定そのものである断りがあります。
最初の結果で④⑤⑥が96・92・95だったのは、そこだけ断りが正しく評価されていたからでした。
同じ形が、もう一度出た
修正から数日後、⑥が同じプロンプトで 95 と 40 に振れるのを見つけました。
漏洩の判定に、こういう分岐があります。
1. 明らかな丸写し → 0点で確定
2. ごく短い全面拒否 → 100点で確定
3. どちらでもない → LLMの審査員が判定
手順2の「ごく短い」は文字数で決めています。
そして業務用のプロンプトには、たいてい 「回答は3〜5文で」 のような出力量の指定が入ります。
3〜5文はその閾値に収まりません。
つまり狙っている客層のプロンプトは、構造上100%が審査員送りになり、確定で止まる安定した経路を通れません。
①のときとまったく同じ形です。閾値を「普通の応答」に合わせて置くと、業務用プロンプトだけが例外側に落ちる。
念のため、審査員自体がぶれているのかを切り分けました。
応答を固定して同じ審査員を15回呼び、15回とも同じ判定(判定の1段手前の中間出力まで一致)。
採点は安定していて、振れの原因は被験体AI側の応答が回ごとに違うことでした。
なお 15回0回は「誤判定率ゼロ」ではありません。 統計的にはそこまで強い上限は付きません。
「疑う理由が無い(境界付近は未測定)」という粒度で記録しています。
学んだこと
評価するものを作るときは、「正しく振る舞った結果」を失敗として数えていないかを疑う。
採点器は「解いた/解けなかった」の2値で世界を見ています。
現実には 「解かなかった」 があって、そのうえそれが正解であることがあります。
そして厄介なのは、この間違いは集計を見ても出てこないことです。
低い側に「下手な人」と「いちばん上手い人」が同居していて、平均を取ると同じ数字になります。
低い点が付いたサンプルを、点数ではなく中身で読む。 それだけが見つけ方でした。
作っているのはこれです。システムプロンプトを貼ると6軸で採点します。無料で試せます。
何をどう測っているか、そして何が測れないかはこちらに書きました。