opik-optimize について
opik-optimize は、Opik のプロンプトオプティマイザーと評価データを使ってプロンプトを改善するスキルです。保留データで候補を比較し、実行コストを報告します。ライブラリのプロンプトは新しいバージョンとして保存し、アプリケーションコードは変更しません。
主な機能
- 01最適化前にベースラインを測定
- 02保留した検証データを使用
- 03観測した失敗に応じて最適化手法を選択
- 04実行リンクとコストを記録
- 05ライブラリの勝者を新バージョンとして保存
- 06アプリケーションコードを変更しない
活用シーン
- 01既存データセットに合わせたプロンプト調整
- 02訓練データ外でも改善するかの確認
- 03Opik で改善したライブラリプロンプトをバージョン管理
MCP 対応
このスキルは Opik と opik-optimizer を使ってプロンプトを最適化し、ライブラリのプロンプトを新しいバージョンとして保存します。ツール説明の最適化にも対応しますが、README には MCP サーバーへの接続や管理についての記載はありません。
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ comet-ml/ opik-skills --skill opik-optimizeインストール後、Claude Code で/opik-optimizeを入力して読み込まれたか確認します。
詳細
最適化 — データに基づいてプロンプトを改善する
完了の定義: 指標において、調整に使っていないデータでベースラインを上回るスコアを出す最適化済みプロンプト、Opik の最適化実行リンク、そこに至るまでのコスト、そして勝者を新しいプロンプトバージョンとして保存すること(プロンプトがライブラリにある場合)です。コードへの差し替えは次のステップとして残します。明示された予算内で最適化を実行できない場合は、最初に見つかった実際のブロッカーで停止し、次のステップをちょうど1つ提示します。自身の学習用アイテムでしか高いスコアを出せないプロンプトは、改善とはいえません。
実施方針:まずベースラインを測定し、予算を使う前に明示し、データをホールドアウトし、確認した失敗に応じてアルゴリズムを選び、バージョン管理できる場所に勝者を保存します。アプリケーションコードは変更しません。 このスキルが書き込むファイルは、リポジトリ外のランナーだけです。プロンプトはコードベースではなく Opik に保存します。
入力
エントリーポイントは /opik-optimize <prompt-name>(プロンプトライブラリのプロンプト)、/opik-optimize <path or function>(コード内のプロンプト)、または /opik-optimize(このリポジトリ内のシステムプロンプトを検索)です。残りは推測し、以下は任意のオーバーライドとして扱います。
- データセット(デフォルト:プロジェクトの既存データセット → 回帰テストスイートをエクスポート → トレースから作成) · 指標(デフォルト:
expected_outputがあればヒューリスティック、それ以外は二値判定を1つ) · アルゴリズム(デフォルト:MetaPromptOptimizer) · 予算(デフォルト:n_samples=50、max_trials=10) · モデル · 検証用分割(デフォルト:20%をホールドアウト)。
実際に推測できないブロッカーがある場合に限り質問してください(ブロッカーを参照)。
有効化 — 対象範囲内の作業はこれだけです
1. プロンプトを特定する
- ライブラリ:
client.get_chat_prompt(name)(テキストプロンプトの場合はget_prompt)を使います。現在のversionを記録してください。これがベースラインです。 - コード: システムプロンプト/
messages=[...]を grep し、そのまま読みます。配置場所を記録してください。編集はしません。 - トレース: 代表的なトレースの
llmスパンにあるinput.messagesを使います。
オプティマイザーの opik_optimizer.ChatPrompt は、ライブラリの opik.ChatPrompt とは別のクラスです。生のメッセージから自分で構築してください。
from opik_optimizer import ChatPrompt
prompt = ChatPrompt(name="<name>", system="<system text>", user="{question}") # or messages=[...]; {var} names must match dataset keys
2. データセットを特定する(および一部をホールドアウトする)
オプティマイザーには、アイテムのキーがプロンプトの {variables} と一致する opik.Dataset が必要です。
import opik
client = opik.Opik()
dataset = client.get_dataset(name="<dataset>", project_name="<project>")
- テストスイートだけが存在する場合 → そのアイテムを一度データセットにエクスポートします:
suite.get_items()→client.get_or_create_dataset("<suite>-optimize", project_name=…)→insert([{**it["data"]} …])。 - 何も存在しない場合 → トレースから作成します(
search_traces→{"question": t.input[...], "expected_output": …})。または、先に/opik-evaluateを実行します。 - ホールドアウト: 学習用と検証用のデータセットに分割し、
validation_dataset=を渡します。その動作を把握しておいてください。オプティマイザーはすべての試行をvalidation_datasetで採点し、学習用データセットは推論モデルに例を示すために使います。つまり、検証用データセットが選定用データセットとなり、10件以上必要です。そうでないと、すべての候補が同点になります(4件に分割するとn_samples … larger than evaluation dataset sizeが記録され、プロンプトを比較できません)。オプティマイザーが一度も見ていないアイテムで測定した改善が必要な場合は、3つ目の分割を残し、evaluate()で勝者を再採点します。合計が約20件未満なら、結果にばらつきが出ると伝えてください。10件未満ならブロッカーです。
3. メトリクスを定義する
関数 (dataset_item, llm_output) -> float を作成します。値が大きいほど優れています。意味のある名前を付けてください(def refund_answer_similarity(...))。__name__ が UI の Optimization 実行の目的名および result.metric_name になります。関数名を metric にすると、「metric」と表示されます。
expected_outputがある場合 → ヒューリスティック(LevenshteinRatio、Equals、またはタスク固有のチェック)を使用します。決定論的で、費用もかかりません。完全一致よりも段階評価のメトリクスを優先してください。ベースラインがすべての項目で 0.0 を記録すると(厳密な出力形式に対してEqualsを使用した場合に確認されています)、候補もすべて 0.0 となり、オプティマイザーは改善の余地を見つけられません。5 回の試行でずっと 0 になるのは、プロンプトではなくメトリクスの問題です。- それ以外の場合 → 最適化対象の失敗モードに対する単一のバイナリージャッジ(
../opik-evaluate/references/write-judge-prompt.md)を使用し、スコアの.valueを返すようにラップします。複数の目的を扱う場合はMultiMetricObjectiveを使用します。 誰も検証していないジャッジを使って最適化しないでください。未検証のジャッジは、過剰適合を引き起こしやすいものです。
4. アルゴリズムを選ぶ
| 確認した失敗 | オプティマイザー |
|---|---|
| 指示が不明瞭/不十分(一般的なデフォルト) | MetaPromptOptimizer |
| モデルに正解例が必要で、少数ショットが許容される | FewShotBayesianOptimizer |
| 失敗がいくつかの根本原因に集約される | HierarchicalReflectiveOptimizer(HRPO) |
| より大きな予算で、幅広く探索したい | EvolutionaryOptimizer または GepaOptimizer |
| プロンプトには問題がなく、temperature/top_p に問題がある | ParameterOptimizer.optimize_parameter(...) |
| ツールの説明に問題がある | optimize_prompt(..., optimize_tools=True)(optimize_mcp は非推奨です) |
5. 予算を明示してから実行する
作業用の環境で uv add opik-optimizer(または pip install opik-optimizer)を実行します。ユーザーから希望がない限り、リポジトリのロックファイルは変更しないでください。各試行では、タスクモデルと推論モデルを使用して n_samples 件を評価します。実行前に、おおよその呼び出し回数をユーザーに伝えてください。プロバイダーのキーが設定されていない場合は、ブロッカーです。
from opik_optimizer import MetaPromptOptimizer
optimizer = MetaPromptOptimizer(model="<task model>", verbose=1, seed=42)
result = optimizer.optimize_prompt(
prompt=prompt, dataset=train, metric=metric,
validation_dataset=validation,
n_samples=50, max_trials=10,
project_name="<project>",
)
リポジトリの外に一時ファイルとしてランナーを作成します。実行結果は Opik に Optimization として表示されます(result.get_run_link())。
6. 結果を正直に読み取る
メトリクスの result.initial_score → result.score、result.details["stop_reason"] と ["trials_completed"]、result.llm_calls、result.llm_cost_total を確認します(プロバイダーが費用情報を返さない場合は None になることがあります。その場合は「費用情報なし」と伝え、費用を捏造しないでください)。報告するのは検証スコアであり、トレーニングスコアではありません。実行ごとのばらつきの範囲内の改善は(疑わしい場合はベースラインをもう一度実行して確認してください)「測定可能な改善なし」と伝え、現状とほぼ同じものをリリースしないでください。その場合、新しいバージョンも保存しないでください。結果が横ばいになる一般的な原因は、回答がプロンプトに含められないコンテキスト(検索、ツール、アカウントデータ)に依存していることです。その場合、ボトルネックはプロンプトではありません。次のステップは試行を増やすことではなく、最悪の項目に対して /opik-explain を実行することです。
7. 勝者を保存して(ライブラリのプロンプトの場合)、引き継ぐ
messages = result.prompt.get_messages() # optimizer ChatPrompt -> raw messages
new_version = client.create_chat_prompt(
name="<name>", messages=messages, project_name="<project>",
change_description=f"opik-optimize: {result.optimizer}, {result.metric_name} {result.initial_score:.2f} -> {result.score:.2f} (validation)",
)
コード内にあるプロンプトの場合、ファイルは編集しないでください。最適化したテキストと差分を次のステップとして返します。その後、次のステップを 1 つ示します(Output を参照)。通常は「新しいバージョンを回帰テストスイートと /opik-compare で比較する」または「アプリの参照先をバージョン vN にする」です。
ブロッカー
最初に見つかったブロッカーで停止し、次のステップを必ず 1 つだけ返してください。
- 「
opik configureを実行してから、/opik-optimizeを再実行してください。」 - 「どのプロンプトですか? ライブラリのプロンプト名を指定するか、システムプロンプトを含むファイル/関数を教えてください。」
- 「キーが一致するデータセットがありません。
/opik-evaluateを実行して作成するか、既存のデータセットを指定してください。」 - 「オプティマイザーにはプロバイダーの認証情報が必要です。
OPENAI_API_KEY(または該当するキー)を設定して再実行してください。」 - 「項目が 6 件しかありません。過剰適合せずに最適化するには少なすぎます。ケースを追加する(または
syntheticと指定する)か、再実行してください。」
出力
ユーザー向け: 短いメッセージです。検証データでのベースラインスコアと最適化後スコア、実行リンク、コスト、アルゴリズム、プロンプトの変更内容(1〜2行)、新しいバージョン(コードプロンプトの場合は差分)、次のステップを1つだけ伝えます。試行履歴全体は含めません。
内部では(構成/評価向けに)、次の形式に統一します。
status:improved|no_improvement|blockedprompt:name、source(library|code|trace)、baseline_version、new_version(保存した場合)dataset:train{name, count}、validation{name, count}metric:name、kind(heuristic|judge)、validated: true|falseoptimizer:algorithm、n_samples、max_trials、stop_reasonscores:initial、optimized、validation、deltacost:llm_calls、llm_cost_totalrun_urlnext_step:厳密に1つ
不変条件:improved は、ノイズを超えて scores.validation > scores.initial であることが必要で、run_url を含めます。no_improvement でも run_url とコストを含めます。validated: false の judge メトリクスはレポート内で明示します。コードベースは変更しません。ライブラリプロンプトは上書きせず、新しいバージョンとして保存します。
例
ライブラリプロンプト、ヒューリスティックメトリクス。 /opik-optimize support-system-prompt。データセットは support-qa(expected_output を含む120件)、96/24に分割し、LevenshteinRatio を使用します。MetaPromptOptimizer、50サンプル × 10試行、予算を明記。検証スコアは0.62 → 0.79、コストは$1.40。v7 として保存。→ improved;次のステップ = "/opik-compare support-bot-regressions を実行し、アプリで v7 を指定する"
実質的な改善なし。 検証スコアは0.71 → 0.73で、ベースラインを再実行すると±0.03変動します。→ no_improvement:「ノイズの範囲内です。ボトルネックはプロンプトではありません。最も悪い項目を /opik-explain で分析してください。」
コード内のプロンプト。 システムプロンプトが agent.py で見つかりました。最適化したテキストを差分とともに返し、ファイルには手を加えません。→ improved;次のステップ = 「差分を適用する(または、バージョン管理できるようにプロンプトをライブラリに移す)」
ブロック。 データセットもトレースもありません。→ blocked:「まず /opik-evaluate を実行してデータセットを作成してください。」
アンチパターン
学習データセットのスコアを改善結果として報告すること。未検証のジャッジに対して最適化すること。上限のない予算を使うこと(n_samples/max_trials を指定しない)、または予算を明記しないこと。新しいバージョンを作らずにプロンプトを上書きすること。コードベース内のプロンプトを編集すること。opik.ChatPrompt と opik_optimizer.ChatPrompt を相互に置き換え可能なものとして扱うこと。約20件未満の項目で最適化し、結果と呼ぶこと。観測された失敗ではなく新しさを基準にアルゴリズムを選ぶこと。非推奨の optimize_mcp を使うこと。
参考資料
データセットとプロンプトライブラリの詳細は、このスキルと同じ場所にインストールされる opik スキルにあります。このファイルを基準としたパスは、データセット、insert、バージョン、メトリクスについては ../opik/references/evaluation-datasets.md、プロンプトライブラリとバージョン管理については ../opik/references/best-practices.md、SDK クライアントについては ../opik/references/tracing-python.md です。ジャッジの設計と検証については、../opik-evaluate/references/write-judge-prompt.md と ../opik-evaluate/references/validate-evaluator.md を参照してください。ホストでスキルの配置が異なる場合は、opik スキルの references/ ディレクトリを探してください。
オプティマイザー API(opik-optimizer):https://www.comet.com/docs/opik/agent_optimization/overview。opik スキルがインストールされていない場合は、レポートでその旨を伝え、記憶に頼って作業するのではなく、https://www.comet.com/docs/opik/ を参照してください。