Arize Prompt LearningでLLMプロンプトは自己改善できるのか?感情分類と金融ニュース要約で検証してみた
はじめに
LLMアプリケーションを開発していると、最初に作ったプロンプトだけで期待どおりの出力を得ることは難しく、次のような修正を何度も繰り返すことになります。
- 指示をより具体的にする
- 出力フォーマットを固定する
- 失敗例をFew-shot Exampleとして追加する
- Hallucinationを防ぐルールを追加する
- 評価結果を確認して、再びプロンプトを書き直す
この作業を人間が毎回行うのではなく、モデルの失敗と自然言語フィードバックを利用して自動化できないかと考えました。
そこで本記事では、Arize AIのprompt-learning SDKを使い、次の2つのタスクでSelf-Improving Promptを実装・検証します。
1. 感情分類プロンプトの改善
2. 金融ニュース要約プロンプトの改善
結論を先に述べると、Prompt Learningは失敗を具体的な指示へ変換する仕組みとして有効でした。一方で、プロンプトを更新すれば必ず性能が上がるわけではありません。特にLLM Evaluatorを使用するタスクでは、評価基準の設計が最適化結果を大きく左右しました。
Prompt Learningとは
Prompt Learningはモデルの重みを再学習するのではなく、評価結果を基にプロンプト自体を書き換えるアプローチです。
今回構築したパイプラインは、主に次の3つの役割で構成されています。
Agent
現在のプロンプトを使って分類や要約を実行する
↓
Evaluator
Agentの出力を評価し、自然言語フィードバックを生成する
↓
Meta Model
現在のプロンプトとフィードバックから新しいプロンプトを作る
従来の正解・不正解や単純な数値スコアだけでなく、次のような具体的な自然言語フィードバックを利用できる点が特徴です。
The expected emotion was "anger", but the model predicted "sadness".
Clarify how to distinguish anger from sadness using the text's central
emotional state rather than isolated words.
このフィードバックをMeta Modelへ渡すことで、失敗を防ぐための指示やFew-shot Exampleを元のプロンプトへ追加します。
Arize Prompt Learning SDKについて
今回使用したprompt-learningは、Arize AIが公開しているプロンプト最適化SDKです。
SDKがモデルをFine-tuningするわけではありません。現在のプロンプト、モデル出力、自然言語フィードバックをメタプロンプトとして構成し、GPT-4oに改善版プロンプトを生成させます。
インストール
今回使用したバージョンはGitHubリポジトリからインストールしました。
prompt-learning-enhanced @ git+https://github.com/Arize-ai/prompt-learning.git
検証時点では依存パッケージとの互換性を保つため、次の環境を使用しています。
Python 3.12
arize-phoenix-evals==2.7.0
インストール例は次のとおりです。
python3.12 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
SDKの基本的な使い方
from optimizer_sdk.prompt_learning_optimizer import (
PromptLearningOptimizer,
)
optimizer = PromptLearningOptimizer(
prompt=current_prompt,
model_choice="gpt-4o",
openai_api_key=os.environ["OPENAI_API_KEY"],
)
optimized_prompt = optimizer.optimize(
dataset=evaluated_data,
output_column="output",
feedback_columns=["feedback"],
)
optimize()へ渡す主要な情報は次の3つです。
| 項目 | 内容 |
|---|---|
| dataset | 入力、モデル出力、フィードバックを含むDataFrame |
| output_column | 現在のプロンプトで生成された出力列 |
| feedback_columns | 問題点と改善方法を記述した自然言語フィードバック列 |
SDK内部では、おおよそ次の処理が行われます。
現在のプロンプト
+ 入力データ
+ モデル出力
+ 自然言語フィードバック
↓
Arize Prompt Learning SDK
↓
メタプロンプトを構築
↓
GPT-4oへプロンプト改善を依頼
↓
新しいプロンプトを返す
今回のSDKは、最適化時にmetaprompt.txtも自動生成しました。このファイルには元のプロンプト、各入力、モデル出力、評価フィードバック、Meta Modelへの最終指示が含まれます。
ただし、SDKがSelf-Improving Pipelineのすべてを管理するわけではありません。
| 処理 | 担当 |
|---|---|
| 分類・要約の生成 | GPT-4o-mini |
| フィードバック生成 | PythonロジックまたはEvaluator LLM |
| メタプロンプト構築 | Arize Prompt Learning SDK |
| 改善プロンプト生成 | SDK経由で呼び出すGPT-4o |
| Iteration管理・再評価 | 独自のPythonコード |
したがって、Arize Prompt Learningは「自然言語フィードバックを使ったプロンプト書き換えを自動化するSDK」と整理できます。
Self-Improving Pipelineの共通設計
2つの実験では、次のループを共通して使用しました。
1. Hugging Faceからデータを取得
2. 現在のプロンプトでAgentを実行
3. Agentの出力を評価
4. 自然言語フィードバックを生成
5. PromptLearningOptimizer.optimize()を実行
6. 更新されたプロンプトを次のIterationへ適用
なお、各Iterationの結果保存はタスクごとに異なります。金融ニュース要約では、回次別のプロンプト、評価結果CSV、集計スコアを保存します。感情分類では、回次別の結果は保存せず、最終プロンプトのみを保存します。
重要なのは、Optimizerへ数値スコアだけを渡すのではなく、何が問題で、次のプロンプトへどのようなルールを追加すべきかを文章で渡すことです。
実験1:感情分類プロンプトの自己改善
概要
最初の実験では、Hugging Faceのdair-ai/emotionを使用しました。
データセットの整数ラベルを次の文字列へ変換します。
LABELS = (
"sadness",
"joy",
"love",
"anger",
"fear",
"surprise",
)
今回は動作をすばやく確認するため、先頭の5件で簡易実験を行いました。
初期プロンプト
Classify the emotion expressed in the text.
Choose exactly one label from: sadness, joy, love, anger, fear, surprise.
Return only the lowercase label and no explanation.
Text: {text}
Label:
推論処理
現在のプロンプトへtextを挿入し、GPT-4o-miniを呼び出します。
response = client.chat.completions.create(
model="gpt-4o-mini",
temperature=0.0,
messages=[
{
"role": "user",
"content": prompt_template.replace("{text}", text),
}
],
)
モデルがラベル以外の説明を付けた場合に備え、出力から許可されたラベルを正規化して取得する処理も追加しました。
自然言語フィードバック
感情分類では正解ラベルが存在するため、Evaluator LLMを使わずPythonで正解と予測を比較できます。
if expected == predicted:
feedback = (
f"Correct. The response selected '{expected}', "
"matching the expected emotion."
)
else:
feedback = (
f"Incorrect. The expected emotion was '{expected}', "
f"but the model predicted '{predicted}'. "
f"Clarify how to distinguish '{expected}' from '{predicted}' "
"using the text's central emotional state rather than isolated words."
)
1回目の結果
| 入力の概要 | 正解 | 予測 | 結果 |
|---|---|---|---|
| humiliated | sadness | sadness | Correct |
| hopelessからhopefulへ変化 | sadness | joy | Incorrect |
| greedy, wrong | anger | sadness | Incorrect |
| 暖炉を懐かしむ文章 | love | sadness | Incorrect |
| grouchy | anger | anger | Correct |
正解は2件、誤分類は3件で、正解率は40%でした。
主な問題はjoy、anger、loveをsadnessと混同していたことです。モデルは文章全体の感情より、hopeful、wrong、nostalgicといった一部の単語に強く反応していました。
Arizeが生成したメタプロンプト
Arize SDKが生成したmetaprompt.txtには、次の情報がまとめられていました。
- 元の分類プロンプト
- 5件の入力テキスト
- GPT-4o-miniの予測
- 正解・不正解に関する自然言語フィードバック
- GPT-4oへ新しいプロンプトを生成させる指示
たとえば、sadnessをjoyと誤分類したケースは次のように渡されます。
LLM Output using baseline prompt: joy
feedback: Incorrect. The expected emotion was 'sadness',
but the model predicted 'joy'. Clarify how to distinguish
'sadness' from 'joy' using the text's central emotional state
rather than isolated words.
改善後のプロンプト
Prompt Learningによって、次の重要なルールが追加されました。
Consider the overall emotional tone of the text rather than
focusing on isolated words.
また、誤分類した文章がFew-shot Exampleとしてプロンプトへ追加されました。
Example:
Text: "i can go from feeling so hopeless to so damned hopeful ..."
Expected Label: sadness
Example:
Text: "im grabbing a minute to post i feel greedy wrong"
Expected Label: anger
Example:
Text: "i am ever feeling nostalgic about the fireplace ..."
Expected Label: love
この結果から、Arize Prompt Learningが自然言語フィードバックを次の2種類の改善へ変換したことが分かります。
1. 一部の単語ではなく、文章全体の感情を判断するという一般ルール
2. 実際に失敗した入力を利用したFew-shot Example
注意点
この簡易実験では、改善後のプロンプトを別の未使用データで評価していません。そのため、Few-shot Exampleとして追加された文章を再び正しく分類できたとしても、それが一般化性能の向上なのか、単なる記憶なのかは判断できません。
本格的に評価する場合は、最適化に使うTrainデータと、最終性能を確認するTestデータを分離する必要があります。
実験2:金融ニュース要約プロンプトの自己改善
概要
2つ目の実験では、金融ニュース記事をGPT-4o-miniで要約し、GPT-4o Evaluatorの自然言語フィードバックからプロンプトを改善しました。
データセットにはHugging Faceのkdave/Indian_Financial_Newsを使用しました。
Content → article
Summary → reference_summary
このデータセットのSummaryはT5-baseによって生成されたものです。そのため、人間が作成した絶対的な正解ではなく、Evaluatorが比較するための参考要約として扱いました。事実確認では、常に元の記事を最優先します。
評価には先頭の20件を使用しました。
初期プロンプト
Summarize the following financial news article:
Article: {article}
Summary:
Evaluatorの設計
要約では完全一致による評価ができないため、GPT-4oをEvaluatorとして使用しました。
評価軸は次の3つです。
1. 重要な財務数値を含んでいるか
2. 不要な説明がなく、簡潔か
3. 元記事に忠実で、Hallucinationがないか
EvaluatorにはJSON形式で回答させます。
{
"financial_figures_score": 4,
"conciseness_score": 5,
"faithfulness_score": 5,
"feedback": "具体的な評価と改善ルール"
}
各スコアは1から5で、3つの平均を100点満点へ変換しました。
score_columns = [
"financial_figures_score",
"conciseness_score",
"faithfulness_score",
]
evaluated["overall_score"] = (
evaluated[score_columns].mean(axis=1) * 20.0
)
自然言語フィードバックには、単なる評価だけでなく、次のプロンプトへ反映できる具体的なルールを含めるよう指示しています。
Explicitly identify omissions, unnecessary details, and hallucinations.
Give concrete prompt rules that would prevent the observed problems.
Iterationごとの結果
3回の評価結果は次のとおりです。
| Iteration | 総合点 | 財務数値 | 簡潔性 | 忠実性 |
|---|---:|---:|---:|---:|
| 1 | 83.67 | 3.85 | 3.95 | 4.75 |
| 2 | 83.67 | 4.00 | 3.95 | 4.60 |
| 3 | 83.33 | 3.95 | 3.90 | 4.65 |
Iteration 1と2の総合点は同じで、Iteration 3ではわずかに低下しました。
Iteration 1から2への変更
最初のフィードバックから、Arize Prompt Learningは次の要素をプロンプトへ追加しました。
- 重要な財務数値を強調する
- 経済的要因と主要な影響を含める
- 不要な詳細を避ける
- 元記事の文脈を維持する
- 根拠のない主張や推測を追加しない
生成されたプロンプトの一部は次のとおりです。
Summarize the following financial news article by highlighting
key financial figures, significant economic factors, and major
impacts or implications.
Focus on providing concise and clear information that accurately
represents the source content and avoids unnecessary details.
財務数値スコアは3.85から4.00へ改善しました。一方、忠実性は4.75から4.60へ低下したため、総合点は83.67のままでした。
Iteration 2から3への変更
次のIterationでは、金融市場や経済政策の重要な変化を特に重視する指示が追加されました。
Pay special attention to capturing the most significant shifts
in financial markets or economic policies.
しかし、Iteration 3の総合点は83.33へ低下しました。
なぜ改善しなかったのか
今回の結果から、大きく2つの問題が確認できました。
1. 財務数値を強調しすぎた
Iteration 2では、財務数値を含める能力は改善しました。しかし、一部の記事では数値や周辺情報を過剰に列挙し、要約の中心が不明確になりました。
たとえば20番目の記事は、次のように変化しました。
Iteration 1: 66.67
Iteration 2: 46.67
Iteration 3: 73.33
Iteration 2では市場指数だけでなく、複数の企業ニュースや経済要因まで追加し、Evaluatorから「中心的ではない情報が含まれている」と指摘されました。
2. 数値が存在しない記事も低く評価された
一部の記事には売上、利益、成長率などの財務数値が存在しません。それにもかかわらずEvaluatorは、次のような理由で財務数値スコアを低くしました。
financial figures are not present in the source article,
so the financial_figures_score is low
これは要約モデルの失敗ではなく、評価基準の設計上の問題です。
さらに、プロンプトが財務数値を強調したことで、数値がない記事でも「Key financial figures」という構造を作り、元記事にない解釈や意味づけを追加するケースが発生しました。
19番目の記事は次のように低下しました。
Iteration 1: 66.67
Iteration 2: 66.67
Iteration 3: 40.00
Evaluatorは、具体的な財務数値がないにもかかわらず数値の存在を暗示し、記事から直接確認できない影響まで追加した点を問題として挙げました。
最終プロンプトの選択
実装では、後のプロンプトが必ず良いとは仮定せず、評価済みのプロンプトから平均点が最も高いものを保存します。
if mean_score > best_score:
best_score = mean_score
best_prompt = current_prompt
今回はIteration 1と2が同点でした。コードは同点の場合に先に登場したプロンプトを維持するため、最終ファイルには初期プロンプトが保存されました。
Summarize the following financial news article:
Article: {article}
Summary:
つまり、今回の金融ニュース要約実験では、最適化後のプロンプトが初期プロンプトを明確に上回ったとは言えません。
2つの実験結果を比較する
| 観点 | 感情分類 | 金融ニュース要約 |
|---|---|---|
| タスク | 単一ラベル分類 | 自由形式の要約生成 |
| 評価方法 | 正解ラベルとの完全一致 | GPT-4o Evaluator |
| フィードバック生成 | Pythonロジック | Evaluator LLM |
| 改善内容 | 全体の感情を見るルールとFew-shot例 | 財務数値・簡潔性・忠実性のルール |
| 主な問題 | 同一データの記憶、ラベルの主観性 | Evaluatorの偏り、評価軸のトレードオフ |
| 結果 | 具体的な改善プロンプトを生成 | 総合スコアは改善しなかった |
感情分類では、正解ラベルと予測ラベルの差が明確です。そのため「何を間違えたか」を比較的安定してフィードバックへ変換できました。
一方、要約は複数の正しい回答が存在します。Evaluator自身が評価基準を誤って適用すると、その誤ったフィードバックがPrompt Learningを通じて次のプロンプトへ反映されます。
不適切な評価基準
↓
偏った自然言語フィードバック
↓
偏ったメタプロンプト
↓
過度に最適化された新しいプロンプト
この違いから、自由形式の生成タスクではOptimizerより先にEvaluatorを十分に検証する必要があると分かりました。
Prompt Learningが有効だった点
失敗を読みやすいルールへ変換できる
従来のスコアだけでは、なぜ失敗したのか、何を変更すべきかが分かりません。自然言語フィードバックを使うことで、次のような具体的な変更を生成できました。
- 単語単位ではなく文章全体の感情を確認する
- 重要な数値を含める
- 根拠のない内容を追加しない
- 失敗例をFew-shot Exampleとして追加する
プロンプト変更の過程を追跡できる
金融ニュース要約では、各Iterationの結果を次の形式で保存しました。
financial_results/
├── iteration_1_prompt.txt
├── iteration_1_results.csv
├── iteration_2_prompt.txt
├── iteration_2_results.csv
├── iteration_3_prompt.txt
├── iteration_3_results.csv
├── iteration_history.csv
├── iteration_history.json
├── optimization_1_metaprompt.txt
└── optimization_2_metaprompt.txt
これにより、次の内容を後から確認できます。
- どのフィードバックが生成されたか
- プロンプトへどのルールが追加されたか
- 各評価軸がどのように変化したか
- 特定の記事でなぜスコアが低下したか
性能が低下した場合にロールバックできる
最新のプロンプトを無条件に採用するのではなく、評価済みプロンプトの中から最も高いスコアを持つものを選択できます。
今回の金融ニュース実験では、実際にIteration 3の性能が低下したため、このロールバック設計が重要でした。
Prompt Learningの限界
プロンプト更新は性能向上を保証しない
Prompt Learningはフィードバックに沿ってプロンプトを書き換えますが、そのフィードバックが正しいことや、新しいプロンプトが未知データでも良い結果を出すことは保証しません。
Evaluatorの品質が最適化結果を決める
特に自由形式の生成タスクでは、Evaluatorが事実上の目的関数になります。
Evaluatorが「財務数値が存在しない記事」を低く評価すると、Optimizerはすべての記事で数値を強調する方向へ進みます。結果として、不要な数値の列挙やHallucinationを誘発する可能性があります。
評価指標間にはトレードオフがある
金融ニュース実験では、財務数値スコアが上がる一方で忠実性が下がりました。
財務数値を増やす
→ 情報量は増える
→ 不要な詳細も増える可能性がある
→ 簡潔性や忠実性が下がる可能性がある
単一の総合点だけでなく、評価軸ごとの変化を確認することが重要です。
同一データでの最適化と評価は過学習を招く
最適化に使った入力をそのまま再評価すると、特定例をFew-shotとして記憶しただけでもスコアが上がります。
実用的な検証では、最低でも次のように分離する必要があります。
Train
フィードバック生成とプロンプト最適化に使用
Validation
Iterationごとのプロンプト選択に使用
Test
最後に一度だけ一般化性能を確認
まとめ
本記事では、Arize Prompt LearningとOpenAI APIを利用し、感情分類と金融ニュース要約の2つのSelf-Improving Pipelineを構築しました。
感情分類では、自然言語フィードバックから「単語ではなく文章全体の感情を見る」というルールと、実際の失敗例を使ったFew-shot Exampleが自動的に追加されました。
金融ニュース要約では、財務数値を重視するプロンプトへ改善されましたが、忠実性とのトレードオフが発生し、最終的な総合スコアは向上しませんでした。
この結果から得た最も重要な知見は、次のとおりです。
> Prompt Learningはプロンプトを必ず改善する魔法の仕組みではない。しかし、LLMの失敗を自然言語で分析し、その分析を次のプロンプトへ反映するループを自動化できる点は非常に有用である。
そして、Self-Improving Pipelineの品質を決めるのはOptimizerだけではありません。
良いデータ
+ 良いEvaluator
+ 具体的な自然言語フィードバック
+ 独立した検証データ
= 信頼できるPrompt Improvement
特に自由形式の生成タスクでは、プロンプトを最適化する前にEvaluatorが人間の判断と整合しているかを検証することが重要です。
Self-Improving Pipelineはどのような課題に活用できるか
今回扱った感情分類やニュース要約以外にも、出力の良し悪しを一定の基準で評価でき、フィードバックを次の試行へ反映できる課題であれば、Self-Improving Pipelineを活用できると思います。
1. カスタマーサポートの回答改善
問い合わせ、生成された回答、オペレーターによる修正内容を学習ループへ渡すことで、次のような観点からプロンプトを改善できます。
- 質問に対して直接回答しているか
- 社内ポリシーや製品仕様と一致しているか
- 不要に長い説明や不適切な表現がないか
- 人間のオペレーターへ引き継ぐべきケースを正しく判断しているか
たとえば「返金条件の説明が不足している」というフィードバックが繰り返し発生した場合、その失敗パターンをルールやFew-shot Exampleとして回答プロンプトへ反映できます。
2. RAGシステムの回答品質改善
社内文書やFAQを検索して回答するRAGでは、回答の正確性だけでなく、取得した根拠を正しく利用しているかも評価できます。
ユーザーの質問
↓
検索された文書
↓
LLMの回答
↓
根拠との整合性・引用・回答漏れを評価
↓
回答プロンプトを改善
この仕組みにより、「検索文書にない内容を推測しない」「回答の根拠を明示する」「情報がない場合は分からないと答える」といったルールを、実際の失敗例から具体化できます。ただし、検索結果そのものが不適切な場合は、プロンプトだけでは解決できないため、Retrieverの評価と分けて考える必要があります。
3. 文書からの情報抽出
請求書、契約書、履歴書、問い合わせメールなどから構造化データを抽出するタスクにも適しています。
- 必須項目の抽出漏れ
- 日付・金額・単位の誤認識
- JSON Schema違反
- 原文にない値の補完
これらはルールベースで評価しやすく、失敗理由も明確です。そのため、自由形式の文章生成よりも、改善前後の効果を客観的に測定しやすいユースケースです。
4. コンテンツ生成とブランドトーンの統一
商品説明、メール、SNS投稿、レポートなどでは、事実性に加えて文体やブランドガイドラインへの適合性も評価できます。編集者の修正履歴を自然言語フィードバックへ変換すれば、「専門用語を減らす」「断定しすぎない」「対象読者に合わせて説明する」といった組織固有のルールをプロンプトへ蓄積できます。
ただし、単一のEvaluatorへすべての判断を任せると、文章が画一的になったり、長さと情報量のような評価基準が競合したりします。事実性、読みやすさ、トーンなどを個別に評価し、優先順位を決める設計が必要です。
5. エージェントのツール選択と業務フロー改善
複数のツールを使用するLLM Agentでは、最終回答だけでなく、途中の行動も評価対象にできます。
- 適切なツールを選択したか
- 必要な引数を正しく渡したか
- 不要なAPI呼び出しをしていないか
- 実行前にユーザー確認が必要な操作を判別したか
- 失敗時に安全な代替手段を選んだか
成功・失敗の実行履歴から、ツール選択条件や停止条件をプロンプトへ追加することで、Agentの再現性と安全性を高められます。
参考リンク
- Arize AI Prompt Learning GitHub Repository
- Hugging Face: dair-ai/emotion
- Hugging Face: kdave/Indian_Financial_News
- OpenAI API Documentation
Mentions
Arize Prompt LearningでLLMプロンプトは自己改善できるのか?感情分類と金融ニュース要約で検証してみた はじめに LLMアプリケーションを開発していると、最初に作ったプロンプトだけで期待どおりの出力を得ることは難しく、次のような修正を何度も繰り返すことになります。 - 指示をより具体的にする - 出力フォーマットを固定する - 失敗例をFew-shot Exampleとして追加する - Hallucinationを防ぐルールを追加する - 評価結果を確認して、再びプロンプトを書き直す この作業を人間が毎回行うのではなく、モデルの失敗と自然言語フィードバックを利用して自動化できないかと考えました。 そこで本記事では、Arize AIのprompt-learning SDKを使い、次の2つのタスクでSelf-Improving Promptを実装・検証します。 1. 感情分類プロンプトの改善 2. 金融ニュース要約プロンプトの改善 結論を先に述べると、Prompt Learningは失敗を具体的な指示へ変換する仕組みとして有効でした。一方で、プロンプトを更新すれば必ず性能が上がるわけではありません。特にLLM Evaluatorを使用するタスクでは、評価基準の設計が最適化結果を大きく左右しました。 Prompt Learningとは Prompt Learningはモデルの重みを再学習するのではなく、評価結果を基にプロンプト自体を書き換えるアプローチです。 今回構築したパイプラインは、主に次の3つの役割で構成されています。 Agent 現在のプロンプトを使って分類や要約を実行する ↓ Evaluator Agentの出力を評価し、自然言語フィードバックを生成する ↓ Meta Model 現在のプロンプトとフィードバックから新しいプロンプトを作る 従来の正解・不正解や単純な数値スコアだけでなく、次のような具体的な自然言語フィードバックを利用できる点が特徴です。 The expected emotion was "anger", but the model predicted "sadness". Clarify how to distinguish anger from sadness using the text's central emotional state rather than isolated words. このフィードバックをMeta Modelへ渡すことで、失敗を防ぐための指示やFew-shot Exampleを元のプロンプトへ追加します。 Arize Prompt Learning SDKについて 今回使用したprompt-learningは、Arize AIが公開しているプロンプト最適化SDKです。 SDKがモデルをFine-tuningするわけではありません。現在のプロンプト、モデル出力、自然言語フィードバックをメタプロンプトとして構成し、GPT-4oに改善版プロンプトを生成させます。 インストール 今回使用したバージョンはGitHubリポジトリからインストールしました。 prompt-learning-enhanced @ git+https://github.com/Arize-ai/prompt-learning.git 検証時点では依存パッケージとの互換性を保つため、次の環境を使用しています。 Python 3.12 arize-phoenix-evals==2.7.0 インストール例は次のとおりです。 python3.12 -m venv .venv source .venv/bin/activate pip install -r requirements.txt SDKの基本的な使い方 from optimizer_sdk.prompt_learning_optimizer import ( PromptLearningOptimizer, ) optimizer = PromptLearningOptimizer( prompt=current_prompt, model_choice="gpt-4o", openai_api_key=os.environ["OPENAI_API_KEY"], ) optimized_prompt = optimizer.optimize( dataset=evaluated_data, output_column="output", feedback_columns=["feedback"], ) optimize()へ渡す主要な情報は次の3つです。 | 項目 | 内容 | |---|---| | dataset | 入力、モデル出力、フィードバックを含むDataFrame | | output_column | 現在のプロンプトで生成された出力列 | | feedback_columns | 問題点と改善方法を記述した自然言語フィードバック列 | SDK内部では、おおよそ次の処理が行われます。 現在のプロンプト + 入力データ + モデル出力 + 自然言語フィードバック ↓ Arize Prompt Learning SDK ↓ メタプロンプトを構築 ↓ GPT-4oへプロンプト改善を依頼 ↓ 新しいプロンプトを返す 今回のSDKは、最適化時にmetaprompt.txtも自動生成しました。このファイルには元のプロンプト、各入力、モデル出力、評価フィードバック、Meta Modelへの最終指示が含まれます。 ただし、SDKがSelf-Improving Pipelineのすべてを管理するわけではありません。 | 処理 | 担当 | |---|---| | 分類・要約の生成 | GPT-4o-mini | | フィードバック生成 | PythonロジックまたはEvaluator LLM | | メタプロンプト構築 | Arize Prompt Learning SDK | | 改善プロンプト生成 | SDK経由で呼び出すGPT-4o | | Iteration管理・再評価 | 独自のPythonコード | したがって、Arize Prompt Learningは「自然言語フィードバックを使ったプロンプト書き換えを自動化するSDK」と整理できます。 Self-Improving Pipelineの共通設計 2つの実験では、次のループを共通して使用しました。 1. Hugging Faceからデータを取得 2. 現在のプロンプトでAgentを実行 3. Agentの出力を評価 4. 自然言語フィードバックを生成 5. PromptLearningOptimizer.optimize()を実行 6. 更新されたプロンプトを次のIterationへ適用 なお、各Iterationの結果保存はタスクごとに異なります。金融ニュース要約では、回次別のプロンプト、評価結果CSV、集計スコアを保存します。感情分類では、回次別の結果は保存せず、最終プロンプトのみを保存します。 重要なのは、Optimizerへ数値スコアだけを渡すのではなく、何が問題で、次のプロンプトへどのようなルールを追加すべきかを文章で渡すことです。 実験1:感情分類プロンプトの自己改善 概要 最初の実験では、Hugging Faceのdair-ai/emotionを使用しました。 データセットの整数ラベルを次の文字列へ変換します。 LABELS = ( "sadness", "joy", "love", "anger", "fear", "surprise", ) 今回は動作をすばやく確認するため、先頭の5件で簡易実験を行いました。 初期プロンプト Classify the emotion expressed in the text. Choose exactly one label from: sadness, joy, love, anger, fear, surprise. Return only the lowercase label and no explanation. Text: {text} Label: 推論処理 現在のプロンプトへtextを挿入し、GPT-4o-miniを呼び出します。 response = client.chat.completions.create( model="gpt-4o-mini", temperature=0.0, messages=[ { "role": "user", "content": prompt_template.replace("{text}", text), } ], ) モデルがラベル以外の説明を付けた場合に備え、出力から許可されたラベルを正規化して取得する処理も追加しました。 自然言語フィードバック 感情分類では正解ラベルが存在するため、Evaluator LLMを使わずPythonで正解と予測を比較できます。 if expected == predicted: feedback = ( f"Correct. The response selected '{expected}', " "matching the expected emotion." ) else: feedback = ( f"Incorrect. The expected emotion was '{expected}', " f"but the model predicted '{predicted}'. " f"Clarify how to distinguish '{expected}' from '{predicted}' " "using the text's central emotional state rather than isolated words." ) 1回目の結果 | 入力の概要 | 正解 | 予測 | 結果 | |---|---|---|---| | humiliated | sadness | sadness | Correct | | hopelessからhopefulへ変化 | sadness | joy | Incorrect | | greedy, wrong | anger | sadness | Incorrect | | 暖炉を懐かしむ文章 | love | sadness | Incorrect | | grouchy | anger | anger | Correct | 正解は2件、誤分類は3件で、正解率は40%でした。 主な問題はjoy、anger、loveをsadnessと混同していたことです。モデルは文章全体の感情より、hopeful、wrong、nostalgicといった一部の単語に強く反応していました。 Arizeが生成したメタプロンプト Arize SDKが生成したmetaprompt.txtには、次の情報がまとめられていました。 - 元の分類プロンプト - 5件の入力テキスト - GPT-4o-miniの予測 - 正解・不正解に関する自然言語フィードバック - GPT-4oへ新しいプロンプトを生成させる指示 たとえば、sadnessをjoyと誤分類したケースは次のように渡されます。 LLM Output using baseline prompt: joy feedback: Incorrect. The expected emotion was 'sadness', but the model predicted 'joy'. Clarify how to distinguish 'sadness' from 'joy' using the text's central emotional state rather than isolated words. 改善後のプロンプト Prompt Learningによって、次の重要なルールが追加されました。 Consider the overall emotional tone of the text rather than focusing on isolated words. また、誤分類した文章がFew-shot Exampleとしてプロンプトへ追加されました。 Example: Text: "i can go from feeling so hopeless to so damned hopeful ..." Expected Label: sadness Example: Text: "im grabbing a minute to post i feel greedy wrong" Expected Label: anger Example: Text: "i am ever feeling nostalgic about the fireplace ..." Expected Label: love この結果から、Arize Prompt Learningが自然言語フィードバックを次の2種類の改善へ変換したことが分かります。 1. 一部の単語ではなく、文章全体の感情を判断するという一般ルール 2. 実際に失敗した入力を利用したFew-shot Example 注意点 この簡易実験では、改善後のプロンプトを別の未使用データで評価していません。そのため、Few-shot Exampleとして追加された文章を再び正しく分類できたとしても、それが一般化性能の向上なのか、単なる記憶なのかは判断できません。 本格的に評価する場合は、最適化に使うTrainデータと、最終性能を確認するTestデータを分離する必要があります。 実験2:金融ニュース要約プロンプトの自己改善 概要 2つ目の実験では、金融ニュース記事をGPT-4o-miniで要約し、GPT-4o Evaluatorの自然言語フィードバックからプロンプトを改善しました。 データセットにはHugging Faceのkdave/Indian_Financial_Newsを使用しました。 Content → article Summary → reference_summary このデータセットのSummaryはT5-baseによって生成されたものです。そのため、人間が作成した絶対的な正解ではなく、Evaluatorが比較するための参考要約として扱いました。事実確認では、常に元の記事を最優先します。 評価には先頭の20件を使用しました。 初期プロンプト Summarize the following financial news article: Article: {article} Summary: Evaluatorの設計 要約では完全一致による評価ができないため、GPT-4oをEvaluatorとして使用しました。 評価軸は次の3つです。 1. 重要な財務数値を含んでいるか 2. 不要な説明がなく、簡潔か 3. 元記事に忠実で、Hallucinationがないか EvaluatorにはJSON形式で回答させます。 { "financial_figures_score": 4, "conciseness_score": 5, "faithfulness_score": 5, "feedback": "具体的な評価と改善ルール" } 各スコアは1から5で、3つの平均を100点満点へ変換しました。 score_columns = [ "financial_figures_score", "conciseness_score", "faithfulness_score", ] evaluated["overall_score"] = ( evaluated[score_columns].mean(axis=1) * 20.0 ) 自然言語フィードバックには、単なる評価だけでなく、次のプロンプトへ反映できる具体的なルールを含めるよう指示しています。 Explicitly identify omissions, unnecessary details, and hallucinations. Give concrete prompt rules that would prevent the observed problems. Iterationごとの結果 3回の評価結果は次のとおりです。 | Iteration | 総合点 | 財務数値 | 簡潔性 | 忠実性 | |---|---:|---:|---:|---:| | 1 | 83.67 | 3.85 | 3.95 | 4.75 | | 2 | 83.67 | 4.00 | 3.95 | 4.60 | | 3 | 83.33 | 3.95 | 3.90 | 4.65 | Iteration 1と2の総合点は同じで、Iteration 3ではわずかに低下しました。 Iteration 1から2への変更 最初のフィードバックから、Arize Prompt Learningは次の要素をプロンプトへ追加しました。 - 重要な財務数値を強調する - 経済的要因と主要な影響を含める - 不要な詳細を避ける - 元記事の文脈を維持する - 根拠のない主張や推測を追加しない 生成されたプロンプトの一部は次のとおりです。 Summarize the following financial news article by highlighting key financial figures, significant economic factors, and major impacts or implications. Focus on providing concise and clear information that accurately represents the source content and avoids unnecessary details. 財務数値スコアは3.85から4.00へ改善しました。一方、忠実性は4.75から4.60へ低下したため、総合点は83.67のままでした。 Iteration 2から3への変更 次のIterationでは、金融市場や経済政策の重要な変化を特に重視する指示が追加されました。 Pay special attention to capturing the most significant shifts in financial markets or economic policies. しかし、Iteration 3の総合点は83.33へ低下しました。 なぜ改善しなかったのか 今回の結果から、大きく2つの問題が確認できました。 1. 財務数値を強調しすぎた Iteration 2では、財務数値を含める能力は改善しました。しかし、一部の記事では数値や周辺情報を過剰に列挙し、要約の中心が不明確になりました。 たとえば20番目の記事は、次のように変化しました。 Iteration 1: 66.67 Iteration 2: 46.67 Iteration 3: 73.33 Iteration 2では市場指数だけでなく、複数の企業ニュースや経済要因まで追加し、Evaluatorから「中心的ではない情報が含まれている」と指摘されました。 2. 数値が存在しない記事も低く評価された 一部の記事には売上、利益、成長率などの財務数値が存在しません。それにもかかわらずEvaluatorは、次のような理由で財務数値スコアを低くしました。 financial figures are not present in the source article, so the financial_figures_score is low これは要約モデルの失敗ではなく、評価基準の設計上の問題です。 さらに、プロンプトが財務数値を強調したことで、数値がない記事でも「Key financial figures」という構造を作り、元記事にない解釈や意味づけを追加するケースが発生しました。 19番目の記事は次のように低下しました。 Iteration 1: 66.67 Iteration 2: 66.67 Iteration 3: 40.00 Evaluatorは、具体的な財務数値がないにもかかわらず数値の存在を暗示し、記事から直接確認できない影響まで追加した点を問題として挙げました。 最終プロンプトの選択 実装では、後のプロンプトが必ず良いとは仮定せず、評価済みのプロンプトから平均点が最も高いものを保存します。 if mean_score > best_score: best_score = mean_score best_prompt = current_prompt 今回はIteration 1と2が同点でした。コードは同点の場合に先に登場したプロンプトを維持するため、最終ファイルには初期プロンプトが保存されました。 Summarize the following financial news article: Article: {article} Summary: つまり、今回の金融ニュース要約実験では、最適化後のプロンプトが初期プロンプトを明確に上回ったとは言えません。 2つの実験結果を比較する | 観点 | 感情分類 | 金融ニュース要約 | |---|---|---| | タスク | 単一ラベル分類 | 自由形式の要約生成 | | 評価方法 | 正解ラベルとの完全一致 | GPT-4o Evaluator | | フィードバック生成 | Pythonロジック | Evaluator LLM | | 改善内容 | 全体の感情を見るルールとFew-shot例 | 財務数値・簡潔性・忠実性のルール | | 主な問題 | 同一データの記憶、ラベルの主観性 | Evaluatorの偏り、評価軸のトレードオフ | | 結果 | 具体的な改善プロンプトを生成 | 総合スコアは改善しなかった | 感情分類では、正解ラベルと予測ラベルの差が明確です。そのため「何を間違えたか」を比較的安定してフィードバックへ変換できました。 一方、要約は複数の正しい回答が存在します。Evaluator自身が評価基準を誤って適用すると、その誤ったフィードバックがPrompt Learningを通じて次のプロンプトへ反映されます。 不適切な評価基準 ↓ 偏った自然言語フィードバック ↓ 偏ったメタプロンプト ↓ 過度に最適化された新しいプロンプト この違いから、自由形式の生成タスクではOptimizerより先にEvaluatorを十分に検証する必要があると分かりました。 Prompt Learningが有効だった点 失敗を読みやすいルールへ変換できる 従来のスコアだけでは、なぜ失敗したのか、何を変更すべきかが分かりません。自然言語フィードバックを使うことで、次のような具体的な変更を生成できました。 - 単語単位ではなく文章全体の感情を確認する - 重要な数値を含める - 根拠のない内容を追加しない - 失敗例をFew-shot Exampleとして追加する プロンプト変更の過程を追跡できる 金融ニュース要約では、各Iterationの結果を次の形式で保存しました。 financial_results/ ├── iteration_1_prompt.txt ├── iteration_1_results.csv ├── iteration_2_prompt.txt ├── iteration_2_results.csv ├── iteration_3_prompt.txt ├── iteration_3_results.csv ├── iteration_history.csv ├── iteration_history.json ├── optimization_1_metaprompt.txt └── optimization_2_metaprompt.txt これにより、次の内容を後から確認できます。 - どのフィードバックが生成されたか - プロンプトへどのルールが追加されたか - 各評価軸がどのように変化したか - 特定の記事でなぜスコアが低下したか 性能が低下した場合にロールバックできる 最新のプロンプトを無条件に採用するのではなく、評価済みプロンプトの中から最も高いスコアを持つものを選択できます。 今回の金融ニュース実験では、実際にIteration 3の性能が低下したため、このロールバック設計が重要でした。 Prompt Learningの限界 プロンプト更新は性能向上を保証しない Prompt Learningはフィードバックに沿ってプロンプトを書き換えますが、そのフィードバックが正しいことや、新しいプロンプトが未知データでも良い結果を出すことは保証しません。 Evaluatorの品質が最適化結果を決める 特に自由形式の生成タスクでは、Evaluatorが事実上の目的関数になります。 Evaluatorが「財務数値が存在しない記事」を低く評価すると、Optimizerはすべての記事で数値を強調する方向へ進みます。結果として、不要な数値の列挙やHallucinationを誘発する可能性があります。 評価指標間にはトレードオフがある 金融ニュース実験では、財務数値スコアが上がる一方で忠実性が下がりました。 財務数値を増やす → 情報量は増える → 不要な詳細も増える可能性がある → 簡潔性や忠実性が下がる可能性がある 単一の総合点だけでなく、評価軸ごとの変化を確認することが重要です。 同一データでの最適化と評価は過学習を招く 最適化に使った入力をそのまま再評価すると、特定例をFew-shotとして記憶しただけでもスコアが上がります。 実用的な検証では、最低でも次のように分離する必要があります。 Train フィードバック生成とプロンプト最適化に使用 Validation Iterationごとのプロンプト選択に使用 Test 最後に一度だけ一般化性能を確認 まとめ 本記事では、Arize Prompt LearningとOpenAI APIを利用し、感情分類と金融ニュース要約の2つのSelf-Improving Pipelineを構築しました。 感情分類では、自然言語フィードバックから「単語ではなく文章全体の感情を見る」というルールと、実際の失敗例を使ったFew-shot Exampleが自動的に追加されました。 金融ニュース要約では、財務数値を重視するプロンプトへ改善されましたが、忠実性とのトレードオフが発生し、最終的な総合スコアは向上しませんでした。 この結果から得た最も重要な知見は、次のとおりです。 > Prompt Learningはプロンプトを必ず改善する魔法の仕組みではない。しかし、LLMの失敗を自然言語で分析し、その分析を次のプロンプトへ反映するループを自動化できる点は非常に有用である。 そして、Self-Improving Pipelineの品質を決めるのはOptimizerだけではありません。 良いデータ + 良いEvaluator + 具体的な自然言語フィードバック + 独立した検証データ = 信頼できるPrompt Improvement 特に自由形式の生成タスクでは、プロンプトを最適化する前にEvaluatorが人間の判断と整合しているかを検証することが重要です。 Self-Improving Pipelineはどのような課題に活用できるか 今回扱った感情分類やニュース要約以外にも、出力の良し悪しを一定の基準で評価でき、フィードバックを次の試行へ反映できる課題であれば、Self-Improving Pipelineを活用できると思います。 1. カスタマーサポートの回答改善 問い合わせ、生成された回答、オペレーターによる修正内容を学習ループへ渡すことで、次のような観点からプロンプトを改善できます。 - 質問に対して直接回答しているか - 社内ポリシーや製品仕様と一致しているか - 不要に長い説明や不適切な表現がないか - 人間のオペレーターへ引き継ぐべきケースを正しく判断しているか たとえば「返金条件の説明が不足している」というフィードバックが繰り返し発生した場合、その失敗パターンをルールやFew-shot Exampleとして回答プロンプトへ反映できます。 2. RAGシステムの回答品質改善 社内文書やFAQを検索して回答するRAGでは、回答の正確性だけでなく、取得した根拠を正しく利用しているかも評価できます。 ユーザーの質問 ↓ 検索された文書 ↓ LLMの回答 ↓ 根拠との整合性・引用・回答漏れを評価 ↓ 回答プロンプトを改善 この仕組みにより、「検索文書にない内容を推測しない」「回答の根拠を明示する」「情報がない場合は分からないと答える」といったルールを、実際の失敗例から具体化できます。ただし、検索結果そのものが不適切な場合は、プロンプトだけでは解決できないため、Retrieverの評価と分けて考える必要があります。 3. 文書からの情報抽出 請求書、契約書、履歴書、問い合わせメールなどから構造化データを抽出するタスクにも適しています。 - 必須項目の抽出漏れ - 日付・金額・単位の誤認識 - JSON Schema違反 - 原文にない値の補完 これらはルールベースで評価しやすく、失敗理由も明確です。そのため、自由形式の文章生成よりも、改善前後の効果を客観的に測定しやすいユースケースです。 4. コンテンツ生成とブランドトーンの統一 商品説明、メール、SNS投稿、レポートなどでは、事実性に加えて文体やブランドガイドラインへの適合性も評価できます。編集者の修正履歴を自然言語フィードバックへ変換すれば、「専門用語を減らす」「断定しすぎない」「対象読者に合わせて説明する」といった組織固有のルールをプロンプトへ蓄積できます。 ただし、単一のEvaluatorへすべての判断を任せると、文章が画一的になったり、長さと情報量のような評価基準が競合したりします。事実性、読みやすさ、トーンなどを個別に評価し、優先順位を決める設計が必要です。 5. エージェントのツール選択と業務フロー改善 複数のツールを使用するLLM Agentでは、最終回答だけでなく、途中の行動も評価対象にできます。 - 適切なツールを選択したか - 必要な引数を正しく渡したか - 不要なAPI呼び出しをしていないか - 実行前にユーザー確認が必要な操作を判別したか - 失敗時に安全な代替手段を選んだか 成功・失敗の実行履歴から、ツール選択条件や停止条件をプロンプトへ追加することで、Agentの再現性と安全性を高められます。 参考リンク - Arize AI Prompt Learning GitHub Repository - Hugging Face: dair-ai/emotion - Hugging Face: kdave/Indian_Financial_News - OpenAI API Documentation