AIアプリの精度を毎日自動で測り差分で見つける

LLMを使うアプリは同じ入力でも出力が変わるため、通常の回帰テストが効きません。毎日ベンチを回して正答率だけをテキストに追記し、コミットして差分で気付けるようにした構成を書きます。

生成AIを使うアプリには、普通の回帰テストが効きません。 同じ入力でも出力が変わるので、期待値との一致で合否を決められないからです。

かといって何も測らずにいると、プロンプトを一行変えただけで精度が落ちても気付けません。 そこで「毎日測って、変化を差分で見る」という形にしました。

何を毎日やっているか

  1. 問題を自動生成する(乱数シード付き)
  2. 本番と同じ経路で解かせる
  3. 正解と突き合わせて正答率を出す
  4. 正答率の1行をテキストファイルへ追記してコミットする

4番が要点です。

なぜ「ファイルに追記してコミット」なのか

CIの実行結果は、そのままでは長期の比較に使えません。

正答率という1行の数字だけをファイルに追記してコミットすると、これが全部解決します。

「気付ける形にする」ことが、測ること自体より重要でした。

実行タイミングを無料枠のリセットに合わせる

無料枠のAPIには1日あたりの回数制限があります。 枠がリセットされた直後に実行すれば、日中の利用を圧迫しません。

schedule:
  # 日次枠のリセット後になる時刻を選ぶ。
  # サマータイムの有無で1時間ずれるため、両方の期間で確実に
  # リセット後になる時刻にしてある。
  - cron: '30 8 * * *'

サマータイムを考慮する必要がある点は見落としやすいところでした。 リセット時刻が現地時間で定義されている場合、UTCの固定時刻では 年に2回、リセット前に実行されてしまいます。

再現できるようにしておく

問題は毎回生成し直すので、悪化した日の結果をそのまま再現できないと原因を追えません。 そこで乱数シードを記録し、ワークフローの入力で指定できるようにしました。

workflow_dispatch:
  inputs:
    seed:
      description: 以前の実行を再現するための固定シード
    cases:
      description: 生成する問題数

履歴で悪化した行を見つけたら、その行のシードを指定して手動実行すれば同じ問題が出ます。

1日の上下では判断しない

生成する問題が毎回違うので、正答率は自然にばらつきます。 1日下がっただけで原因を探し始めると、時間を無駄にします。

運用ルールとして「数日の傾向で判断する」と明記しました。 自動化した仕組みほど、こうした「読み方」を一緒に書いておかないと誤用されます。

鍵が無いときは静かに飛ばす

APIキーはリポジトリのシークレットに置きますが、 フォークされた場合や設定前は存在しません。

その場合に失敗にせず、スキップするようにしました。 本質的でない失敗が続くと、CIの赤色そのものが無視されるようになるからです。

この仕組みが保証しないこと

正直に書いておくと、この自動ベンチは実物に対する精度を保証しません

自動生成する問題は、こちらが想定した形式のものだけです。 実際、生成していた問題の構造が実物と違っていて、 ベンチが高い正答率を保ったまま実際の精度が落ちた版を出荷したことがあります。

そのため役割を分けています。

毎日の自動ベンチ実物での確認
目的大きな劣化の検知精度の判断
頻度毎日変更のたび
問題自動生成手元の実物

詳しくは合成ベンチマークが100%でも、実物の精度は何も保証されないに書きました。

まとめ

関連する記事

最終更新日: