mcpField
A
arize-prompt-optimization

arize-prompt-optimization

github.com/githubエージェントワークフロー40.6k1.1k 回インストール1 日前に更新
リポジトリ

arize-prompt-optimization について

Arize と `ax` コマンドラインを使うチーム向けの、プロンプト最適化スキルです。トレースからプロンプトと性能データを抽出し、修正したうえで、実験によるテストと比較を行う手順を案内します。

主な機能

  1. 01トレーススパンからプロンプトを抽出
  2. 02アノテーションと評価結果を確認
  3. 03データセットと実験出力を結合
  4. 04変数を保ってプロンプトを修正
  5. 05実験でプロンプトの版を比較

活用シーン

  1. 01失敗した LLM トレースの調査
  2. 02低スコアの原因となるプロンプト傾向の特定
  3. 03データセットを使った修正版のテスト
  4. 04回帰を確認しながら二つの版を比較

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/github/awesome-copilot --skill arize-prompt-optimization

インストール後、Claude Code で/arize-prompt-optimizationを入力して読み込まれたか確認します。

同梱ファイルreferences/ax-profiles.mdreferences/ax-setup.md

詳細

Arize プロンプト最適化スキル

SPACE — すべての --space フラグと ARIZE_SPACE 環境変数には、スペースの名前(例:my-workspace)または base64 形式のスペースID(例:U3BhY2U6...)を指定できます。ax spaces list を実行して確認してください。

概念

トレースデータ内のプロンプトの保存場所

LLM アプリケーションは、OpenInference のセマンティック規約に従ったスパンを出力します。プロンプトは、スパンの種類や計装方法に応じて異なるスパン属性に保存されます。

列含まれる内容使用する場面
attributes.llm.input_messagesロールベース形式の構造化チャットメッセージ(system、user、assistant、tool)チャットベースの LLM プロンプトの主なデータソース
attributes.llm.input_messages.rolessystem、user、assistant、tool のロールの配列個々のメッセージのロールを抽出する
attributes.llm.input_messages.contentsメッセージ内容の文字列の配列メッセージテキストを抽出する
attributes.input.valueシリアライズされたプロンプトまたはユーザーの質問(すべてのスパン種類に共通)構造化メッセージがない場合の代替データソース
attributes.llm.prompt_template.template{variable} プレースホルダーを含むテンプレート(例:"Answer {question} using {context}")アプリでプロンプトテンプレートを使用している場合
attributes.llm.prompt_template.variablesテンプレート変数の値(JSON オブジェクト)テンプレートに代入された値を確認する
attributes.output.valueモデルの応答テキストLLM が生成した内容を確認する
attributes.llm.output_messages構造化されたモデル出力(ツール呼び出しを含む)ツール呼び出しの応答を調べる
スパンの種類別にプロンプトを見つける
  • LLM スパン(attributes.openinference.span.kind = 'LLM'):構造化チャットメッセージは attributes.llm.input_messages、シリアライズされたプロンプトは attributes.input.value を確認します。テンプレートは attributes.llm.prompt_template.template を確認します。
  • Chain/Agent スパン:attributes.input.value にユーザーの質問が含まれます。実際の LLM プロンプトは子 LLM スパンにあります。トレースツリーをたどって確認してください。
  • Tool スパン:attributes.input.value にツールへの入力、attributes.output.value にツールの結果が含まれます。通常、プロンプトが保存される場所ではありません。
パフォーマンスシグナルの列

これらの列には、最適化に使用するフィードバックデータが含まれます。

列のパターンソース内容
annotation.<name>.label人間のレビュアーカテゴリ別の評価(例:correct、incorrect、partial)
annotation.<name>.score人間のレビュアー数値による品質スコア(例:0.0 - 1.0)
annotation.<name>.text人間のレビュアー評価についての自由記述
eval.<name>.labelLLM-as-judge 評価自動によるカテゴリ別の評価
eval.<name>.scoreLLM-as-judge 評価自動による数値スコア
eval.<name>.explanationLLM-as-judge 評価評価でそのスコアが付けられた理由 — 最適化に最も役立つ情報
attributes.input.valueトレースデータLLM に渡された内容
attributes.output.valueトレースデータLLM が生成した内容
{experiment_name}.output実験の実行結果特定の実験からの出力

前提条件

タスクに直接進み、必要な ax コマンドを実行してください。事前にバージョン、環境変数、プロファイルを確認しないでください。

ax コマンドが失敗した場合は、エラーに基づいてトラブルシューティングしてください。

  • command not found またはバージョンエラー → references/ax-setup.md を参照してください
  • 401 Unauthorized / API キーがない → ax profiles show を実行して現在のプロファイルを確認してください。プロファイルがない場合、または API キーが間違っている場合は、references/ax-profiles.md に従って作成/更新してください。ユーザーがキーを持っていない場合は、https://app.arize.com/admin > API Keys を案内してください
  • Space が不明 → ax spaces list を実行して名前で選ぶか、ユーザーに尋ねてください
  • Project が不明確 → ユーザーに尋ねるか、ax projects list -o json --limit 100 を実行し、選択可能なオプションとして提示してください
  • LLM プロバイダーへの呼び出しが失敗(OPENAI_API_KEY / ANTHROPIC_API_KEY がない)→ ax ai-integrations list --space SPACE を実行して、プラットフォーム管理の認証情報があるか確認してください。ない場合は、ユーザーにキーを提供してもらうか、arize-ai-provider-integration スキルを使ってインテグレーションを作成してください
  • セキュリティ: .env ファイルを読み取ったり、ファイルシステムを検索して認証情報を探したりしないでください。Arize の認証情報には ax profiles を、LLM プロバイダーのキーには ax ai-integrations を使用してください。これらの方法で認証情報を入手できない場合は、ユーザーに尋ねてください。

フェーズ 1:現在のプロンプトを抽出する

プロンプトを含む LLM スパンを見つける
# Sample LLM spans (where prompts live)
ax spans export PROJECT --filter "attributes.openinference.span.kind = 'LLM'" -l 10 --stdout

# Filter by model
ax spans export PROJECT --filter "attributes.llm.model_name = 'gpt-4o'" -l 10 --stdout

# Filter by span name (e.g., a specific LLM call)
ax spans export PROJECT --filter "name = 'ChatCompletion'" -l 10 --stdout
トレースをエクスポートしてプロンプトの構造を確認する
# Export all spans in a trace
ax spans export PROJECT --trace-id TRACE_ID

# Export a single span
ax spans export PROJECT --span-id SPAN_ID
エクスポートした JSON からプロンプトを抽出する
# Extract structured chat messages (system + user + assistant)
jq '.[0] | {
  messages: .attributes.llm.input_messages,
  model: .attributes.llm.model_name
}' trace_*/spans.json

# Extract the system prompt specifically
jq '[.[] | select(.attributes.llm.input_messages.roles[]? == "system")] | .[0].attributes.llm.input_messages' trace_*/spans.json

# Extract prompt template and variables
jq '.[0].attributes.llm.prompt_template' trace_*/spans.json

# Extract from input.value (fallback for non-structured prompts)
jq '.[0].attributes.input.value' trace_*/spans.json
プロンプトをメッセージとして再構成する

スパンデータを取得したら、プロンプトをメッセージ配列として再構成します。

[
  {"role": "system", "content": "You are a helpful assistant that..."},
  {"role": "user", "content": "Given {input}, answer the question: {question}"}
]

スパンに attributes.llm.prompt_template.template がある場合、プロンプトでは変数が使用されています。これらのプレースホルダー({variable} または {{variable}})は保持してください。実行時に置き換えられます。

フェーズ 2:パフォーマンスデータを収集する

トレースから(本番環境のフィードバック)
# Find error spans -- these indicate prompt failures
ax spans export PROJECT \
  --filter "status_code = 'ERROR' AND attributes.openinference.span.kind = 'LLM'" \
  -l 20 --stdout

# Find spans with low eval scores
ax spans export PROJECT \
  --filter "annotation.correctness.label = 'incorrect'" \
  -l 20 --stdout

# Find spans with high latency (may indicate overly complex prompts)
ax spans export PROJECT \
  --filter "attributes.openinference.span.kind = 'LLM' AND latency_ms > 10000" \
  -l 20 --stdout

# Export error traces for detailed inspection
ax spans export PROJECT --trace-id TRACE_ID
データセットと実験から
# Export a dataset (ground truth examples)
ax datasets export DATASET_NAME --space SPACE
# -> dataset_*/examples.json

# Export experiment results (what the LLM produced)
ax experiments export EXPERIMENT_NAME --dataset DATASET_NAME --space SPACE
# -> experiment_*/runs.json
データセットと実験を結合して分析する

2 つのファイルを example_id で結合し、入力と出力、評価を確認します。

# Count examples and runs
jq 'length' dataset_*/examples.json
jq 'length' experiment_*/runs.json

# View a single joined record
jq -s '
  .[0] as $dataset |
  .[1][0] as $run |
  ($dataset[] | select(.id == $run.example_id)) as $example |
  {
    input: $example,
    output: $run.output,
    evaluations: $run.evaluations
  }
' dataset_*/examples.json experiment_*/runs.json

# Find failed examples (where eval score < threshold)
jq '[.[] | select(.evaluations.correctness.score < 0.5)]' experiment_*/runs.json
最適化する項目を特定する

失敗の傾向を確認します。

  1. 出力を正解データと比較する:LLM の出力は、期待される内容とどこが異なりますか?
  2. 評価の説明を読む:eval.*.explanation には、失敗した理由が記載されています
  3. アノテーションのテキストを確認する:人によるフィードバックには、具体的な問題が記載されています
  4. 冗長さの不一致を確認する:出力が正解データと比べて長すぎたり短すぎたりしていませんか?
  5. 形式への準拠を確認する:出力は期待される形式になっていますか?

フェーズ 3:プロンプトを最適化する

最適化用メタプロンプト

このテンプレートを使って、改善版のプロンプトを生成します。3 つのプレースホルダーを埋めて、LLM(GPT-4o、Claude など)に送信してください。

You are an expert in prompt optimization. Given the original baseline prompt
and the associated performance data (inputs, outputs, evaluation labels, and
explanations), generate a revised version that improves results.

ORIGINAL BASELINE PROMPT
========================

{PASTE_ORIGINAL_PROMPT_HERE}

========================

PERFORMANCE DATA
================

The following records show how the current prompt performed. Each record
includes the input, the LLM output, and evaluation feedback:

{PASTE_RECORDS_HERE}

================

HOW TO USE THIS DATA

1. Compare outputs: Look at what the LLM generated vs what was expected
2. Review eval scores: Check which examples scored poorly and why
3. Examine annotations: Human feedback shows what worked and what didn't
4. Identify patterns: Look for common issues across multiple examples
5. Focus on failures: The rows where the output DIFFERS from the expected
   value are the ones that need fixing

ALIGNMENT STRATEGY

- If outputs have extra text or reasoning not present in the ground truth,
  remove instructions that encourage explanation or verbose reasoning
- If outputs are missing information, add instructions to include it
- If outputs are in the wrong format, add explicit format instructions
- Focus on the rows where the output differs from the target -- these are
  the failures to fix

RULES

Maintain Structure:
- Use the same template variables as the current prompt ({var} or {{var}})
- Don't change sections that are already working
- Preserve the exact return format instructions from the original prompt

Avoid Overfitting:
- DO NOT copy examples verbatim into the prompt
- DO NOT quote specific test data outputs exactly
- INSTEAD: Extract the ESSENCE of what makes good vs bad outputs
- INSTEAD: Add general guidelines and principles
- INSTEAD: If adding few-shot examples, create SYNTHETIC examples that
  demonstrate the principle, not real data from above

Goal: Create a prompt that generalizes well to new inputs, not one that
memorizes the test data.

OUTPUT FORMAT

Return the revised prompt as a JSON array of messages:

[
  {"role": "system", "content": "..."},
  {"role": "user", "content": "..."}
]

Also provide a brief reasoning section (bulleted list) explaining:
- What problems you found
- How the revised prompt addresses each one
パフォーマンスデータを準備する

テンプレートに貼り付ける前に、レコードを JSON 配列として整形してください。

# From dataset + experiment: join and select relevant columns
jq -s '
  .[0] as $ds |
  [.[1][] | . as $run |
    ($ds[] | select(.id == $run.example_id)) as $ex |
    {
      input: $ex.input,
      expected: $ex.expected_output,
      actual_output: $run.output,
      eval_score: $run.evaluations.correctness.score,
      eval_label: $run.evaluations.correctness.label,
      eval_explanation: $run.evaluations.correctness.explanation
    }
  ]
' dataset_*/examples.json experiment_*/runs.json

# From exported spans: extract input/output pairs with annotations
jq '[.[] | select(.attributes.openinference.span.kind == "LLM") | {
  input: .attributes.input.value,
  output: .attributes.output.value,
  status: .status_code,
  model: .attributes.llm.model_name
}]' trace_*/spans.json
改訂版プロンプトを適用する

LLM が改訂版のメッセージ配列を返したら、次の手順を実行します。

  1. 元のプロンプトと改訂版のプロンプトを並べて比較する
  2. テンプレート変数がすべて保持されていることを確認する
  3. 形式に関する指示がそのまま残っていることを確認する
  4. 全面展開の前に、いくつかの例でテストする

フェーズ 4:反復する

最適化ループ
1. Extract prompt    -> Phase 1 (once)
2. Run experiment    -> ax experiments create ...
3. Export results    -> ax experiments export EXPERIMENT_NAME --dataset DATASET_NAME --space SPACE
4. Analyze failures  -> jq to find low scores
5. Run meta-prompt   -> Phase 3 with new failure data
6. Apply revised prompt
7. Repeat from step 2
改善を測定する
# Compare scores across experiments
# Experiment A (baseline)
jq '[.[] | .evaluations.correctness.score] | add / length' experiment_a/runs.json

# Experiment B (optimized)
jq '[.[] | .evaluations.correctness.score] | add / length' experiment_b/runs.json

# Find examples that flipped from fail to pass
jq -s '
  [.[0][] | select(.evaluations.correctness.label == "incorrect")] as $fails |
  [.[1][] | select(.evaluations.correctness.label == "correct") |
    select(.example_id as $id | $fails | any(.example_id == $id))
  ] | length
' experiment_a/runs.json experiment_b/runs.json
2 つのプロンプトを A/B 比較する
  1. 同じデータセットに対して、それぞれ異なるプロンプトバージョンを使う 2 つの実験を作成する
  2. 両方をエクスポートする:ax experiments export EXP_A と ax experiments export EXP_B
  3. 平均スコア、失敗率、個別の例での結果の変化を比較する
  4. リグレッションを確認する。つまり、プロンプト A では成功したものの、プロンプト B では失敗した例を確認する

プロンプトエンジニアリングのベストプラクティス

プロンプトを作成または改訂する際は、以下を適用します。

テクニック適用する場面例
明確で詳細な指示出力が曖昧、または話題から逸れている場合「感情を、ポジティブ、ネガティブ、ニュートラルのいずれか1つだけに分類してください」
冒頭に指示を置くモデルが後半の指示を無視する場合例の前にタスクの説明を置きます
段階的な分解複雑な複数ステップのプロセス「まずエンティティを抽出し、次にそれぞれを分類してから、要約してください」
具体的なペルソナ一貫したスタイルやトーンが必要な場合「あなたは、機関投資家向けに執筆するシニア金融アナリストです」
区切りトークンセクションが混ざり合う場合---、###、または XML タグを使って、入力と指示を分けます
少数ショットの例出力形式を明確にする必要がある場合合成した入出力のペアを2~3個提示します
出力の長さの指定回答が長すぎる、または短すぎる場合「ちょうど2~3文で回答してください」
推論の指示正確性が重要な場合「回答する前に、段階的に考えてください」
「わかりません」と答えるための指針幻覚のリスクがある場合「回答が提示されたコンテキストに含まれていない場合は、『十分な情報がありません』と答えてください」
変数の保持

テンプレート変数を使うプロンプトを最適化する際は、次の点に注意してください。

  • 単一の波括弧({variable}):Python の f-string/Jinja スタイルです。Arize で最も一般的です。
  • 二重の波括弧({{variable}}):Mustache スタイルです。フレームワークで必要な場合に使用します。
  • 最適化中に変数のプレースホルダーを追加または削除しないでください
  • 変数名を変更しないでください。実行時の置換では正確な名前が必要です
  • 少数ショットの例を追加する場合は、変数のプレースホルダーではなく、具体的な値を使ってください

ワークフロー

失敗したトレースからプロンプトを最適化する
  1. 失敗したトレースを探します。
    ax traces list PROJECT --filter "status_code = 'ERROR'" --limit 5
    
  2. トレースをエクスポートします。
    ax spans export PROJECT --trace-id TRACE_ID
    
  3. LLM スパンからプロンプトを抽出します。
    jq '[.[] | select(.attributes.openinference.span.kind == "LLM")][0] | {
      messages: .attributes.llm.input_messages,
      template: .attributes.llm.prompt_template,
      output: .attributes.output.value,
      error: .attributes.exception.message
    }' trace_*/spans.json
    
  4. エラーメッセージまたは出力から、何が失敗したかを特定します
  5. プロンプトとエラーのコンテキストを使って、最適化メタプロンプト(フェーズ3)を記入します
  6. 改訂したプロンプトを適用します
データセットと実験を使って最適化する
  1. データセットと実験を探します。
    ax datasets list --space SPACE
    ax experiments list --dataset DATASET_NAME --space SPACE
    
  2. 両方をエクスポートします。
    ax datasets export DATASET_NAME --space SPACE
    ax experiments export EXPERIMENT_NAME --dataset DATASET_NAME --space SPACE
    
  3. メタプロンプト用に結合データを準備します
  4. 最適化メタプロンプトを実行します
  5. 改訂したプロンプトを使って新しい実験を作成し、改善を測定します
誤った形式を出力するプロンプトをデバッグする
  1. 出力形式が誤っているスパンをエクスポートします。
    ax spans export PROJECT \
      --filter "attributes.openinference.span.kind = 'LLM' AND annotation.format.label = 'incorrect'" \
      -l 10 --stdout > bad_format.json
    
  2. LLM が生成している内容と、期待される内容を確認します
  3. プロンプトに明示的な形式の指示を追加します(JSON スキーマ、例、区切り文字など)
  4. よくある修正方法:望ましい出力形式を正確に示す少数ショットの例を追加します
RAG プロンプトの幻覚を減らす
  1. モデルが幻覚を起こしたトレースを探します。
    ax spans export PROJECT \
      --filter "annotation.faithfulness.label = 'unfaithful'" \
      -l 20 --stdout
    
  2. retriever と LLM のスパンを一緒にエクスポートして確認します。
    ax spans export PROJECT --trace-id TRACE_ID
    jq '[.[] | {kind: .attributes.openinference.span.kind, name, input: .attributes.input.value, output: .attributes.output.value}]' trace_*/spans.json
    
  3. 取得したコンテキストに実際に回答が含まれていたかを確認します
  4. システムプロンプトに根拠付けの指示を追加します:「提示されたコンテキストの情報のみを使用してください。回答がコンテキストに含まれていない場合は、そのように伝えてください。」

トラブルシューティング

問題解決策
ax: command not foundreferences/ax-setup.md を参照してください
No profile foundプロファイルが設定されていません。作成方法については references/ax-profiles.md を参照してください。
スパンに input_messages がないスパンの種類を確認してください。Chain/Agent スパンでは、プロンプトは自身ではなく子の LLM スパンに保存されます
プロンプトテンプレートが nullすべての計装が prompt_template を出力するわけではありません。代わりに input_messages または input.value を使用してください
最適化後に変数が失われる修正後のプロンプトに、元のプロンプトのすべての {var} プレースホルダーが保持されていることを確認してください
最適化によって結果が悪化する過剰適合がないか確認してください。メタプロンプトがテストデータを記憶している可能性があります。少数ショットの例が合成データであることを確認してください
評価/アノテーションの列がないまず評価を実行してから(Arize UI または SDK 経由)、再度エクスポートしてください
実験出力の列が見つからない列名は {experiment_name}.output です。ax experiments get で実験名が正確か確認してください
スパンの JSON で jq エラーが発生する正しいファイルパス(例:trace_*/spans.json)を指定していることを確認してください

コメント