opik-verify について
opik-verify は、宣言されたリリースポリシーに基づき Opik のベースラインと候補の実行結果を評価するスキルです。変更のリリース可否を判断するチーム向けに、閾値、観測値、失敗ケースを示し、アプリケーションコードの変更やデプロイは行いません。
主な機能
- 01ポリシーファイルまたは文書化された既定値を適用
- 02回帰、安全性、合格率を確認
- 03サブグループ、レイテンシー、コストを評価
- 04証拠数と評価器の検証状態を報告
- 05不合格の基準と該当ケースを提示
- 06依頼時に判定結果を記録
活用シーン
- 01評価実行を比較した後のリリース判定
- 02リリース前の安全性回帰の確認
- 03評価証拠の追加が必要かを判断
MCP 対応
Opik のホスト型 MCP では、実行概要の検索に実験一覧ツールを利用できます。項目単位の比較には SDK を使用し、MCP は必須ではありません。
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ comet-ml/ opik-skills --skill opik-verifyインストール後、Claude Code で/opik-verifyを入力して読み込まれたか確認します。
詳細
Verify — 読み取れるポリシーに基づくリリース可否の判定
完了の定義: ベースラインと候補の数値に対して、宣言されたポリシーを適用して算出した判定を 1 つ示します。判定は ship、hold、needs_review、insufficient_evidence のいずれかです。各基準について、しきい値、観測値、合否を一覧にし、不合格の原因となったケースを特定し、比較ビューへのリンクも記載します。ポリシーはリポジトリの opik-release-policy.yaml または文書化されたデフォルトのいずれかで、レポートにはどちらを使用したかを記載します。2 つの実行結果を読み取れない、または比較できない場合は、最初の実質的なブロッカーで停止し、次のステップを正確に 1 つ返します。「問題なさそうです」は判定ではありません。基準を示していない判定も判定ではありません。
運用方針:ポリシーを機械的に適用し、計算過程を示し、誰も検証していないジャッジでのリリースは拒否し、アプリケーションコードは変更しません。 このスキルが書き込めるファイルはポリシーファイルのみで、ユーザーが指示した場合に限ります。デプロイは行いません。
入力
エントリーポイントは /opik-compare の直後(そのベースラインと候補を使用)、/opik-verify <suite>(そのスイートの直近 2 件の実行を使用)、または /opik-verify <baseline-id> <candidate-id> です。それ以外は推測し、以下を任意のオーバーライドとして扱います。
- policy(デフォルト:リポジトリルートまたは
.opik/にあるopik-release-policy.yaml。なければ以下のデフォルト)・比較する実験(デフォルト:上記のとおり)・--record(デフォルト:オフ。判定を候補実験の設定に書き込みます)。
実質的で推測できないブロッカーがある場合にのみ質問してください(ブロッカーを参照)。
ポリシー
すべてのキーは任意です。キーがない場合は、以下のデフォルトが適用されます。レポートには、どのポリシーソースを適用したかを記載してください。
# opik-release-policy.yaml — repo root or .opik/. Versioned with the code so the gate is reproducible.
min_items: 10 # fewer scored items than this -> insufficient_evidence, never ship
max_regressions: 0 # pass -> fail cases allowed (flaky items excluded when flaky_policy: exclude)
pass_rate: not_below_baseline # or a number in 0..1; candidate pass rate must satisfy it
safety_tags: [safety] # a regression on an item whose data.tags contains one of these -> hold, always
subgroup_key: null # a data key (e.g. "category"); no subgroup's pass rate may fall
latency_p90_max_increase: 0.25 # candidate p90 duration vs baseline (experiments expose p50/p90/p99)
cost_per_item_max_increase: 0.25 # candidate mean cost per item vs baseline, as a fraction
flaky_policy: exclude # exclude | count — an item that flips between runs of the SAME code is flaky
judge_validated: false # set true once the suite's judge has been checked against human labels
judge_validated: false は人によるレビューのゲートです。ジャッジが人の判断と一致することを誰かが確認するまで(/opik-evaluate の validate-evaluator リファレンスを参照)、合格した実行の判定は ship ではなく needs_review になります。確認後にファイル内で true に変更してください。これは意図的に人が編集するものであり、このスキルが独自に設定することはありません。
実行 — 対象範囲に含まれる作業のみ
1. ポリシーを読み込む
リポジトリルート、次に .opik/ で opik-release-policy.yaml を探します。解析し、不明なキーがあればブロッカーにします(キー名を示してください)。ファイルがなければデフォルトを使用し、その旨を伝えます。ファイルまたはデフォルトにないしきい値を作り出してはいけません。
2. 2 つの実行を特定する
直前に実行された /opik-compare の出力から取得します。それ以外の場合:
import opik
client = opik.Opik()
runs = sorted(client.get_test_suite_experiments(name="<suite>", project_name="<project>"),
key=lambda e: e.get_experiment_data().created_at)
baseline, candidate = runs[-2], runs[-1] # or the two ids the user gave
ジャッジ失敗の実行(ジャッジに認証情報がなかった実行は候補ではありません。発生する理由は /opik-compare で説明しています)は除外します。scoring_failed は読み取り経路には残りません。読み戻し時のシグナルは、すべての項目が失敗し、すべてのアサーションの reason に認証情報の不足または LLM インフラストラクチャエラーが記載されていることです。スキップした実行とその理由を伝えてください。ホスト型 MCP が接続されている場合、list('experiment', name=…) に各実行の平均値と合格率が表示されるので、候補を選ぶ際に使用できます。以下の項目レベルの読み取りでは引き続き SDK を使用します。
3. 両方の実行を項目ごとに読み取る
実験には実行ごとに項目が 1 つあります。runs_per_item: 3 の場合、データセット項目は 3 回表示され、同じ dataset_item_id と異なる trace_id を持ちます。グループ化に辞書を使うと、dataset_item_id をキーにした場合に 1 回分だけが保持され、件数が失われます。
from collections import defaultdict
def by_item(exp):
groups = defaultdict(list)
for i in exp.get_items():
groups[i.dataset_item_id].append(i) # each: dataset_item_data (tags / subgroup key),
return groups # assertion_results [{passed, reason}], trace_id
b, c = by_item(baseline), by_item(candidate)
def run_passed(i): return bool(i.assertion_results) and all(a.get("passed") for a in i.assertion_results)
def counts(runs): return sum(run_passed(r) for r in runs), len(runs) # runs_passed, runs_total
thresholds = {it["id"]: (it.get("execution_policy") or suite.get_global_execution_policy() or {}).get("pass_threshold", 1)
for it in suite.get_items()} # the suite, not the experiment, holds the policy
def passed(item_id, runs): return counts(runs)[0] >= thresholds.get(item_id, 1)
# experiment level (client.rest_client.experiments.get_experiment_by_id(id)): pass_rate,
# duration (p50/p90/p99), total_estimated_cost_avg, dataset_version_id
まず比較可能性を確認: dataset_version_id、項目セット、ジャッジモデル(実験設定)が同じであること。異なる場合はブロッカーです(「スイートのバージョン X とジャッジ Y を指定して候補を再実行し、その後 /opik-verify を実行してください」)。比較できない実行に基づく判定は、判定ではありません。
4. すべての基準をこの順序で評価する
最初の失敗が見つかった後も、すべての基準を計算します — レポートには表全体を表示します。
- エビデンスの量 — スコア対象の項目(アサーションがある項目)が
min_items以上であること。これを下回る場合、他の条件にかかわらず判定はinsufficient_evidenceです。ただし、ゲート基準(2〜7)も失敗している場合はholdです。既知の安全性のリグレッションは、エビデンス不足より優先されます。すべての基準は引き続き報告してください。 - リグレッション — ベースラインでは
passedで、候補ではそうでない項目。runs_passedがいずれかの実行(ステップ 3 のカウント)で 0 より大きくruns_totalより小さい場合、または同じコードでの 2 回の実行間で結果が変わる場合、その項目は不安定です。flaky_policy: excludeの場合、不安定な項目はリグレッション数から除外し、その件数とともに別途一覧表示します。countの場合はカウントに含めます。すべての項目でruns_total == 1の場合、不安定性は観測できません。不安定性のチェックはnot_evaluatedと報告し、excludeでは何も除外されなかったことを明記してください。この保護を適用したい場合は、スイートでruns_per_item: 3を指定するよう提案します。カウントはmax_regressions以下であること。 - 安全性 —
data.tagsがsafety_tagsと交差するリグレッションがあれば、例外や除外なく失敗です。 - 合格率 — 候補の
pass_rateをベースライン、または指定された件数と比較します。 - サブグループ —
subgroup_keyが設定されている場合、そのキーの値ごとの合格率が低下してはなりません。 - レイテンシ — 候補の p90 所要時間が、ベースラインの p90 × (1 +
latency_p90_max_increase) 以下であること。実験のdurationパーセンタイル(実験レコードのp50/p90/p99)、または REST の実験項目ごとのdurationから算出します。 - コスト — 候補の項目ごとの
total_estimated_cost平均が、ベースライン × (1 +cost_per_item_max_increase) 以下であること。どちらの実行にもコストデータがない場合はスキップし、「no cost data」と記載します。 集計値の反映には遅延があります。 実行の直後は、バックエンドでの集計中に、実験レコードのdurationが0.0、total_estimated_cost_avgがNoneと数秒間表示されることがあります(確認済み)。片側だけ集計値がゼロまたは欠落している場合、それはデータとして扱いません。少し待ってから再読み込みするか、REST の実験項目にあるduration/total_estimated_costフィールドから p90 と平均コストを算出してください。0.0をゲートの合格または不合格の判定に決して使わないでください。 - エビデンスの強さ — 反転に対する対応のある符号検定を行います。
fを修正数、rをリグレッション数として、50/50 の帰無仮説における両側二項 p 値を報告します。これはゲートではありません。f + r < 6の場合は、「ノイズ以上のものと判断するには反転が少なすぎます」と記載します。 - ジャッジ — ポリシーの
judge_validatedを確認します。False の場合、判定の上限はneeds_reviewです。 - 帰属 — 変更されていない出力に対するジャッジの迷いを示す
reason(/opik-compareのステップ 5.6 を参照)を持つ反転は、いずれの方向にも暗黙にカウントせず、人による確認のためneeds_reviewとして一覧表示します。
5. 判定する
優先順位は上から順です。最初に該当した行が適用されます。
- 基準 2〜7 のいずれかが失敗 →
hold(基準 1 も失敗している場合を含む)。 - 基準 1 が失敗 →
insufficient_evidence。 - すべてのゲートに合格しているが、
judge_validated: falseまたは帰属要確認の項目がある →needs_review。人が確認すべき対象を具体的に示します。 - それ以外 →
ship。
差分が「ほぼプラス」だからといって hold の判定を引き上げてはいけません。勘を理由に ship の判定を引き下げてはいけません。判断基準はポリシーです。変更するかどうかはユーザーが決めます。
6. レポートし、依頼があった場合のみ記録する
表(基準・しきい値・観測値・合否)、アサーションとトレースリンクを付けたリグレッションの一覧、両方の ID を含む比較 URL、ポリシーの参照元、および次のステップを 1 つ記載します。--record を指定した場合は、候補の実験の設定に判定を書き込みます。既存の設定を先に読み込み、マージしてください。update_experiment は設定を置き換えます。
exp = client.rest_client.experiments.get_experiment_by_id(candidate.id)
cfg = dict(exp.metadata or {}); cfg["verdict"] = {"status": "hold", "policy": "opik-release-policy.yaml", "failed": ["regressions"], "at": "<iso time>"}
client.update_experiment(id=candidate.id, experiment_config=cfg)
ファイルが存在しない場合は、デフォルト値を使って opik-release-policy.yaml を書き込むことを提案してください。ただし、実際には書き込まないでください。これにより、次回の判定を再現できるようになります。
ブロッカー
最も早いブロッカーで停止し、次のステップを1つだけ返してください。
- "
opik configureを実行してから、/opik-verifyを再実行してください。" - "スイート
<name>には比較可能な実行が2件未満です。まず/opik-compare <suite>を実行してください。" - "ベースラインと候補のスイートバージョンが異なります(v3 と v4)。候補を v3 で再実行するか、v4 でベースラインを再設定してから、
/opik-verifyを実行してください。" - "
opik-release-policy.yamlに不明なキー<key>があります。修正するか削除してください。" - "候補の実行ではジャッジに失敗しました(すべての項目が
scoring_failed)。ジャッジのプロバイダーキーを設定して、/opik-compareを再実行してください。"
出力
ユーザー向け: 1行の判定、基準テーブル、リグレッション(ケース、アサーション、理由、リンク)、ポリシーのソース、比較リンク、そして次のステップを1つ。説明文や JSON にはしません。
内部(構成/評価用)では、次の形式を1つ使用します。
status:ship|hold|needs_review|insufficient_evidence|blockedpolicy:source(file|defaults)、path、values(有効なポリシー)suite:name、id、versionbaseline/candidate:experiment_id、name、url、items、pass_ratecriteria:{name, threshold, observed, passed, note}のリスト。常にすべての基準を含めます。regressions:{dataset_item_id, input, assertion, reason, trace_url, safety: bool, flaky: bool}のリストflaky:flaky_policyに応じて除外または計上された{dataset_item_id, baseline_runs, candidate_runs}のリスト。単一実行のスイートでは文字列not_evaluatedreview_items:{dataset_item_id, why}のリスト(needs_reviewの場合)evidence:{items, fixes, regressions, sign_test_p}compare_urlrecorded:true|falsenext_step: 1つだけ
不変条件:ship には、すべてのゲート基準が passed であり、かつ judge_validated: true であることが必要です。hold には、少なくとも1つの失敗した基準が含まれ、失敗がリグレッションの場合は、空ではない regressions が必要です。insufficient_evidence には、min_items が失敗した criteria が含まれます。needs_review には、空ではない review_items、または policy.values の judge_validated: false が含まれます。criteria を部分的にすることはできません。コードベースは変更しません。デプロイもしません。
例
出荷。 比較後に /opik-verify を実行:スコア付き項目24件、修正3件、リグレッション0件、合格率0.79 → 0.92、p90レイテンシ+4%、コスト+2%、符号検定 p = 0.25(「ノイズ以上と判断するには反転が少なすぎますが、リグレッションはありません」)、judge_validated: true を含むポリシーファイルあり。→ ship。次のステップ = "マージします。/opik-online-eval が本番環境で返金に関するアサーションを監視します。"
保留。 同じ条件ですが、「法律に関する助言をしない」という項目が合格 → 不合格に反転し、safety とタグ付けされています。リグレッション1件 > 0件で、安全性に関する失敗があります。→ hold。該当ケースを理由とトレースリンクとともに最初に示します。次のステップ = "法律に関する助言の項目に対して /opik-explain <trace> を実行します。"
レビューが必要。 すべてのゲートを通過していますが、ポリシーファイルがないため(デフォルト値)、judge_validated は false です。→ needs_review:「デフォルト設定で20件の項目が合格しました。担当者がジャッジの判定5件(リンクあり)を確認してから、opik-release-policy.yaml で judge_validated: true に設定する必要があります。デフォルト値を使ってファイルを書き込みましょうか?」
エビデンス不足。 2件のスイートで、両方とも修正され、リグレッションはありません。→ insufficient_evidence:「2件では min_items: 10 を下回っています。/opik-test でケースを追加するか、ポリシーの min_items を下げてください(どちらにするかはお任せします。変更内容はファイルに表示されます)。」
アンチパターン
基準テーブルのない判定。ファイルやデフォルト値ではなく、根拠なく設定されたしきい値。検証されていないジャッジでの出荷。実行データで判断できないのに、不安定な項目をリグレッションとして扱う(またはリグレッションを不安定な項目として扱う)。異なるスイートバージョンの実行を比較する。安全性に関するリグレッションを平均化して見えなくする。反転が6件しかないのに p 値をゲートとして提示する。集計値が上がったという理由で hold を ship に丸める。依頼されていないのにポリシーファイルを書き込む、または判定を記録する。アプリケーションコードを編集すること。デプロイすること。
参照
テストスイートと実験の詳細は、このスキルと同じ場所にインストールされている opik スキルにあります。このファイルからの相対パスは、../opik/references/evaluation-test-suites.md(実行ポリシー、runs_passed/runs_total、バージョン、get_test_suite_experiments)、../opik/references/evaluation-datasets.md(実験、OQL)です。このスキルが評価する数値については ../opik-compare/SKILL.md を、評価者の検証については ../opik-evaluate/references/validate-evaluator.md を参照してください。ホスト上でスキルの配置が異なる場合は、opik スキルの references/ ディレクトリを探してください。
opik スキルがインストールされていない場合は、レポートにその旨を記載し、記憶を頼りにせず https://www.comet.com/docs/opik/ を参照してください。