採点を機械に任せる:含有・JSON・ツール呼び出し
AI 公開日 更新日 中級

採点を機械に任せる:含有・JSON・ツール呼び出し

オフラインで回せる自動採点の役割分担と、AI判定を後段に回す理由を解説します。

クムビーバー
クムビーバー 現場実装 / Platform Engineer

現場実装の クムビーバー です。評価スイートを育てるとき、最初からLLMジャッジに頼ると運用が重くなります。門番は軽く、再現可能に。重い採点は残った候補へ。

この回の答え

門番はオフラインの自動採点(含有・JSON・ツール呼び出し)です。AIによる判定は後段に回し、軽い採点を先に再現可能にします。

この回だけの用語

用語ひとことで
scorer機械で合否を出す採点器。差し替え可能にする
contains必要断片が入っているかの判定
json_validJSON がパースでき、必須キーがあるかの判定
tool_call scorerツール名と必須引数の有無を見る判定
LLMジャッジ別モデルに良し悪しを聞く重い採点。後段向き
pluggable用途が増えても本体を書き換えず、採点器だけ足せる形
図1: 軽い採点から重い判定へ
図1: 軽い採点から重い判定へ

基本3 scorer

scorer見ること向いている用途
contains部分文字列/キーワードcoding smoke、必須フレーズ
json_validパース可否と必須キー業務API連携、構造化出力
tool_callツール名と必須引数エージェント、社内ツール連携

これらは外部モデルに依存せず、再現性が高いのが利点です。CIや夜間バッチにも載せやすいです。判定が揺れると、「モデルが変わったのか、採点が揺れたのか」が分からなくなります。

それぞれの設計メモ

contains
厳密一致より、必要断片の含有から始める。過検出を嫌うなら禁止パターン(空、明らかに無関係)も併用します。

json_valid
コードフェンスや前置きを許容する前処理を入れるか、厳格に落とすかを用途で決める。業務接続なら厳格寄りが安全です。

tool_call
期待ツール名だけでなく必須引数の有無を見る。プロファイル側の parser 設定とセットで読む必要があります。

なぜ pluggable にするか

用途が増えるたびに評価ハーネス本体を書き換えていると続きません。@scorer("name") のように関数を登録し、タスク定義側の scorer: から参照する形にすると、次が楽になります。

  • RAG用の出典チェック
  • 禁止用語の検出
  • 言語判定
  • スキーマバージョン差分
  • 文字数下限/上限

重要なのは、scorer を増やす前に「その失敗が意思決定に効くか」を確認することです。スコアは多いほど良いわけではありません。意思決定に使わない指標は、運用負債です。

増やしてよい条件増やさない方がよい条件
合否が採用判断を変える「あると安心」程度
失敗理由を人間が説明できる判定根拠が曖昧
CIで安定して回る外部依存で頻繁に落ちる

judge は後段

rubric(1〜5点など)で見る評価は強力ですが、前提が増えます。

  • judge モデルの endpoint が生きている
  • 採点プロンプトが安定している
  • コストと待ち時間を許容できる
  • 採点者モデル変更時の再校正方針がある

門番であるスモークを judge 依存にすると、基盤障害とモデル品質の切り分けが難しくなります。まずは deterministic な判定で足切りし、残った候補に judge を当てるのが安全です。judge は「優劣の微差」を見る道具であって、起動確認の代替ではありません。

設計チェックリスト

  1. タスクごとに「何をもって合格か」を一文で書けるか
  2. 人間が見て異議の少ない判定か
  3. 失敗時に詳細(どこが欠けたか)を残せるか
  4. プロファイル設定(tool parser等)と評価が噛み合っているか
  5. scorer 追加がハーネス本体の改修なしでできるか
  6. CI で外部 LLM 無しでも門番が回るか

失敗詳細に残すと効くもの

  • 期待値(キー、ツール名、必要断片)
  • 実際の抽出結果
  • 前処理の有無(フェンス除去など)
  • 到達性(HTTP ステータスや空応答)

pass/fail だけでは次の1軸が決まりません。詳細があるからスパイラルが前に進みます。

よくある落とし穴

  • scorer を増やしすぎて、レポートが読めなくなる
  • JSON 厳格度を用途ごとに変えず、全部同じにする
  • tool_call 失敗をモデル責任だけにして parser を疑わない
  • judge を門番にして、夜間バッチが judge 障害で止まる
  • 判定変更なのにスイート版を上げず、過去比較を壊す

実装時の最小インターフェース

現場で続きやすい scorer は、高機能である必要はありません。次が揃っていれば十分です。

  • 名前(タスクから参照できる ID)
  • 入力(モデル出力と期待値)
  • 出力(pass/fail と詳細メッセージ)
  • 副作用なし(ファイル書き込みや外部呼び出しを門番に混ぜない)

この形なら、contains / JSON / tool_call を同じ枠で増やせます。judge を足すときも、同じインターフェースの後ろに非同期ステージとしてぶら下げるだけで済みます。先に枠を決めると、評価要件の増殖に耐えやすくなります。

つまずいたこと

採点ロジックをハードコードした直後に、観点追加のたびに評価本体を改修する地獄を見ました。スコアの差し替えができないと、実験速度が落ちます。

困ったのは抽象化しすぎて、何を採点しているか読めなくなる逆効果です。差し替え可能と、説明可能の両立に一番時間がかかりました。

この回の要点

  • 採点器を差し替え可能にする
  • 抽象化しすぎて説明不能にしない
  • 観点追加で評価本体を壊さない

採点器の差し替え方は公開できますが、各 scorer の閾値や合格率はこの回では固定しません。実機での誤検知・取りこぼしは再計測と匿名化後に足します。

次は「候補から本番候補へ:モデル台帳の回し方」です。観点が増えたあとの昇格/棄却を、レジストリのステータスに接続します。

よくある質問

最初からLLMジャッジでよいですか?

いいえ。コストと再現性の面で重いです。オフライン scorer で門番を通し、残った候補へ judge を足します。

scorer の役割分担は?

contains・JSON妥当性・tool_call 形式など、用途に応じて差し替え可能な判定器として扱います。

この回でスコア閾値を固定しますか?

いいえ。役割と順序の型が先です。閾値は用途合意後に別途決めます。

Related

関連記事

Contact

検証や観光DXの進め方について、お気軽にご相談ください。