品質基準が一種類だと何が困るか

LLM 出力の品質チェックを「OK か NG か」の二値で作ると、すぐに行き詰まります。

性質の異なる二種類の問題を、同じ物差しで測ろうとするためです。一つは絶対に許せないエラー——事実と異なる記述(ハルシネーション)、必須項目の欠落、明らかな破綻。もう一つは許容範囲内の揺れ——文体のトーン、文章量の増減、言い回しの違い。

前者は問答無用でブロックすべきです。しかし後者まで同じ基準でブロックすると、プロンプトの改善すら通らなくなります。「前と違う出力 = 不合格」にしてしまうと、何も変えられない。

この行き詰まりを抜けるのが、品質ゲートを二段に分ける設計です。

Stage 1 — 絶対的な最低条件

Stage 1 は「この出力を本番に出して大丈夫か」を見ます。ゴールデンとの比較は一切せず、その出力単体が最低ラインを満たしているかだけを判定します。

判定の材料は、各出力に付与された品質ラベルです。OK / NG のような二値でも、high / medium / low のような段階でもよいですが、「これ以下は許さない」という下限を決めておきます。

RANK = {"low": 0, "ng": 0, "medium": 1, "high": 2, "ok": 2}

def stage1_pass(label: str) -> bool:
    return RANK[label] >= 1   # low / ng は即失敗

Stage 1 の失敗は「リリースを止めるべき事態」です。CI ではこれをエラー終了させ、マージをブロックします。

Stage 2 — ゴールデンとの比較(回帰防止)

Stage 2 は「以前より悪くなっていないか」を見ます。現在の出力を、承認済みのゴールデンデータと突き合わせ、品質ラベルが後退していれば回帰(regression)として記録します。

ゴールデン high → 現在 medium   →  Stage 2 失敗(後退)
ゴールデン medium → 現在 high   →  Stage 2 通過(改善)
ゴールデンなし → 現在 何でも    →  Stage 2 スキップ(新規ケース)

Stage 2 の失敗は「リリースを止めるほどではないが、人が見るべき変化」です。プロンプトを実験的に変えているときは一時的に Stage 2 失敗を許容して回す、という運用ができます。

終了コードで「何をブロックするか」を制御する

二つの Stage を別々の終了コードに割り当てると、CI 側で blocking の強さを選べます。

exit 0: Stage 1 / Stage 2 ともに通過
exit 1: Stage 1 通過、Stage 2 で回帰あり(警告)
exit 2: Stage 1 失敗(最低条件割れ)

exit 2 は必ず止める。exit 1 は止めるかどうかをプロジェクトの段階で決める——開発初期は警告に留め、リリース前は止める、といった使い分けです。

# CI 設定の例(GitHub Actions)
- name: quality gate
  run: sim quality-gate
  # シェルの終了コードで分岐:
  #   2 → ジョブ失敗
  #   1 → 警告として続行(後続でレビュー依頼を出す等)

STALE 検出(前回の記事で扱った「結果が古い」状態)を exit 2 に昇格させる --strict のようなオプションを足せば、リリース前の最終チェックとして「古い結果での合格」も塞げます。

カテゴリラベルと連続スコアの両建て

ここまではラベル(OK/NG、high/low)を前提にしましたが、タスクによっては連続値スコア(0.0〜1.0)で閾値判定したいこともあります。その場合は閾値を粒度別に指定できる設計にしておくと柔軟です。

sim quality-gate \
    --score-threshold screening=0.7 \
    --score-threshold scoring.comment=0.8

パイプライン単位・ステップ単位・項目単位と粒度を変えて指定できれば、「スクリーニング全体は 0.7 以上、採点コメントは 0.8 以上」のように、重要度に応じた基準を引けます。

まとめ

  • 品質基準を「絶対的な最低条件(Stage 1)」と「回帰防止(Stage 2)」に分けると、過剰ブロックを避けつつ品質を守れる
  • Stage 1 は出力単体の最低ライン、Stage 2 はゴールデンとの相対比較
  • 終了コード(0/1/2)を分けることで、CI 側で blocking の強さを選べる
  • --strict で STALE も止める、--score-threshold で連続値の粒度別閾値、と拡張できる

品質ゲートをクリアした後、ハルシネーション・法的配慮・品質改善の 3 シグナルを統合した上位のリリースゲートでリリース可否を最終判定する。