「デモでは完璧に動いたのに、本番投入したら思ったように動かない」。LLMアプリを作っていると、これは驚くほど頻繁に起きる。
原因の多くは、モデルの性能不足ではない。デモを通す評価と、本番で求められる評価が、そもそも別物であることに気づかないまま作り進めてしまうことにある。ここでは、私がクライアントワークで実践している評価設計の考え方を書く。
目次
デモが「通ってしまう」理由
デモで使う入力は、たいてい作り手が選んだ数個のサンプルだ。作り手は当然、モデルが得意なパターンを無意識に選ぶ。だから「動いて見える」のは自然なことで、これ自体は悪いことではない。
問題は、この「動いて見えた」状態を、そのまま「できている」と錯覚してしまうことだ。デモの成功は、入力空間のごく一部を1回サンプリングした結果に過ぎない。本番では、作り手が想定しなかった表記ゆれ、想定外の長さの入力、境界的なケースが日常的に流れてくる。デモの評価軸のままでは、この違いを検知できない。
評価データセットを最初に作る
本番で使えるかどうかを判断するには、デモの「見た目の成功」とは別に、評価データセットを用意する必要がある。
私が最初にやるのは、想定される入力パターンを類型化することだ。典型的なケース(全体の大半を占める、素直な入力)、境界的なケース(表記ゆれ、極端に長い・短い入力、複数の意図が混ざった入力)、意図的な誤用(ユーザーが期待しない使い方をした場合)の3種類に分けて、それぞれサンプルを集める。
集めたサンプルには、正解(あるいは許容できる出力の範囲)を人手で用意しておく。これがないと、後で「動いているかどうか」を客観的に判定できない。この作業は地味だが、ここを省略した評価は、結局デモの延長にしかならない。
評価指標を「動くか動かないか」の2値にしない
もう一つよくある落とし穴は、評価を「正解か不正解か」の2値で見てしまうことだ。生成AIの出力は、完全な正解でなくても業務上許容できる場合と、一見それらしくても業務上致命的な場合がある。
私は評価軸を最低でも2つに分けている。ひとつは「タスクを達成できているか」という機能的な正しさ、もうひとつは「間違えたときの被害の大きさ」だ。同じ「不正解」でも、「多少表現が違うだけで実害はない不正解」と、「事実と異なる情報を自信満々に出力する不正解」では、業務上の意味がまったく違う。この2軸で評価しないと、致命的な失敗パターンを見逃す。
継続的に評価を回す
評価は、開発中に1回やって終わりではない。プロンプトやモデルを変更するたびに、同じ評価データセットで再評価する仕組みを作っておく。これがないと、ある変更で一部のケースの精度が上がった代わりに、別のケースが壊れていることに気づけない。
私の場合、評価データセットはコードと同じようにバージョン管理し、変更のたびに評価スクリプトを実行する運用にしている。これは従来のソフトウェア開発におけるテストスイートと同じ発想で、LLMアプリだからといって特別なことをしているわけではない。むしろ「動くことの確認」を体系立ててやる、という当たり前のことをやっているに過ぎない。
まとめ
「デモでは動くが本番で使えない」は、モデルの限界というより評価設計の不足が原因であることが多い。
- デモの成功は入力空間の一部をサンプリングした結果に過ぎないと認識する
- 典型的・境界的・誤用の3種類でサンプルを集めた評価データセットを作る
- 評価を2値ではなく「機能的な正しさ」と「失敗時の被害の大きさ」の2軸で見る
- プロンプトやモデルの変更のたびに、同じ評価データセットで継続的に評価を回す
これらは特別な技術というより、ソフトウェア開発の当たり前の作法をLLMアプリにも適用しているだけだ。だが、この当たり前を省略したまま本番投入してしまう案件は、実務では驚くほど多い。