OpenAI Evals APIフレームワークの紹介
OpenAI Evals APIは、2025年4月9日に導入された、Large Language Models(LLMs)の体系的評価における重要な進展を示します。評価機能は以前からOpenAIダッシュボードを通じて利用可能でしたが、Evals APIは今や開発者がプログラム的にテストを定義し、自動的に評価を実行し、プロンプトやモデルの実装を迅速に繰り返すことを可能にします。この強力なインターフェイスは、モデル出力の体系的な評価をサポートし、モデルを選択したりプロンプトエンジニアリング戦略を洗練したりする際に証拠に基づいた意思決定を促進します。
このチュートリアルでは、OpenAI Evals APIを実装し、活用するための包括的な技術ガイドを提供します。基盤となるアーキテクチャ、実装パターン、頑健な評価パイプラインを作成するための高度な手法を探求し、LLMアプリケーションの性能を客観的に測定できるようにします。
OpenAI Evals API:どのように機能するのか?

OpenAI Evals APIは、主に2つの主要な抽象概念に基づいた階層構造を持っています:
- 評価設定 - 評価仕様のコンテナで、以下を含みます:
- データソーススキーマの定義
- テスト基準の設定
- 組織と取得のためのメタデータ
2. 評価実行 - 個々の評価実行を含みます:
- 親評価設定への参照
- 評価のための特定のデータサンプル
- モデルの応答と評価結果
この関心の分離は、評価基準の一貫性を維持しながら、複数のテストシナリオでの再利用性を可能にします。
Evals APIオブジェクトモデル
Evals API内のコアオブジェクトは、次の関係に従います:
- data_source_config(スキーマ定義)
- testing_criteria(評価方法)
- metadata(説明、タグなど)
- Run 1(特定のデータに対して)
- Run 2(代替実装)
- ...
- Run N(バージョン比較)
OpenAI Evals API用の環境設定
OpenAI Evals APIを実装する際、テストおよび開発ツールの選択は生産性と結果の質に大きな影響を与えます。

Apidogは、従来のソリューション(Postmanなど)をいくつかの重要な側面で上回る、プレミアAPIプラットフォームとして際立っており、技術的に複雑なEvals APIを扱う際の理想的な伴侶です。
評価を実施する前に、開発環境を適切に設定する必要があります:
import openai
import os
import pydantic
import json
from typing import Dict, List, Any, Optional
# 適切な権限を持つAPIアクセスを設定
os.environ["OPENAI_API_KEY"] = os.environ.get("OPENAI_API_KEY", "your-api-key")
# 本番環境では、.envファイルからロードされる環境変数のような、より安全な方法を使用してください
OpenAI Pythonクライアントライブラリは、Evals APIと対話するためのインターフェイスを提供します。Evals APIサポートを含む最新バージョンを使用していることを確認してください:
pip install --upgrade openai>=1.20.0 # Evals APIサポートを含むバージョン
OpenAI Evals APIを使用した初めての評価の作成
OpenAI Evals APIを使用して、完全な評価ワークフローを実装しましょう。評価の設計から結果の分析までの全プロセスを示すために、テキスト要約タスクの評価システムを作成します。
OpenAI Evals API用データモデルの定義
まず、Pydanticモデルを使用してテストデータの構造を定義する必要があります:
class ArticleSummaryData(pydantic.BaseModel):
"""記事要約評価のためのデータ構造。"""
article: str
reference_summary: Optional[str] = None # 比較のためのオプションの参照
class Config:
frozen = True # 一貫した評価のための不変性を保証
このモデルは、Evals APIが入力を検証し、テスト基準のためのテンプレート変数を提供するために使用される評価データのスキーマを定義します。
Evals APIテストのためのターゲット関数の実装
次に、評価したい出力を生成する関数を実装します:
def generate_article_summary(article_text: str) -> Dict[str, Any]:
"""
OpenAIのモデルを使用して、記事の簡潔な要約を生成します。
引数:
article_text: 要約する記事の内容
戻り値:
要約を含む完了応答オブジェクト
"""
summarization_prompt = """
次の記事を簡潔で情報的な方法で要約してください。
重要なポイントを捉えながら、正確性と文脈を維持してください。
要約は1-2段落にしてください。
記事:
{{article}}
"""
response = openai.chat.completions.create(
model="gpt-4o",
messages=[
{"role": "system", "content": summarization_prompt.replace("{{article}}", article_text)},
],
temperature=0.3, # より一貫した要約のための低い温度
max_tokens=300
)
return response.model_dump() # シリアライズ可能な辞書に変換
OpenAI Evals APIのデータソースの設定
Evals APIには、評価データのスキーマを指定するデータソース設定が必要です:
data_source_config = {
"type": "custom",
"item_schema": ArticleSummaryData.model_json_schema(),
"include_sample_schema": True, # モデル出力スキーマを自動的に含めます
}
print("データソーススキーマ:")
print(json.dumps(data_source_config, indent=2))
この設定は、Evals APIに対して評価データで期待されるフィールドとそれらの処理方法を伝えます。
OpenAI Evals APIによるテスト基準の実装
次に、Evals APIがモデル出力をどのように評価すべきかを定義します。複数の基準を持つ包括的な評価を作成します:
# 1. モデルベースの判断による精度評価
accuracy_grader = {
"name": "要約精度評価",
"type": "label_model",
"model": "gpt-4o",
"input": [
{
"role": "system",
"content": """
あなたは記事要約の精度を評価する専門の評価者です。
要約が元の記事の主要なポイントを正確に表現しているかどうかを評価してください。
要約を以下のいずれかとしてラベル付けしてください:
- "accurate": 重要な情報をすべて含んでおり、事実の誤りがない
- "partially_accurate": 重要な情報のほとんどを含んでおり、軽微な誤りや省略がある
- "inaccurate": 重大な誤りがあり、重要な情報が欠落しているか誤った表現をしている
あなたの評価に対する詳細な説明を提供してください。
"""
},
{
"role": "user",
"content": """
元の記事:
{{item.article}}
評価する要約:
{{sample.choices[0].message.content}}
評価:
"""
}
],
"passing_labels": ["accurate", "partially_accurate"],
"labels": ["accurate", "partially_accurate", "inaccurate"],
}
# 2. 簡潔性評価
conciseness_grader = {
"name": "要約簡潔性評価",
"type": "label_model",
"model": "gpt-4o",
"input": [
{
"role": "system",
"content": """
あなたは記事要約の簡潔性を評価する専門の評価者です。
要約が不必要な詳細なしに情報を効果的に表現しているかどうかを評価してください。
要約を以下のいずれかとしてラベル付けしてください:
- "concise": 完璧な長さで、不必要な情報がない
- "acceptable": やや冗長だが一般的には適切
- "verbose": 過度に長いか、不要な詳細を含む
あなたの評価に対する詳細な説明を提供してください。
"""
},
{
"role": "user",
"content": """
評価する要約:
{{sample.choices[0].message.content}}
評価:
"""
}
],
"passing_labels": ["concise", "acceptable"],
"labels": ["concise", "acceptable", "verbose"],
}
# 3. 参照要約が利用可能な場合、参照比較を追加
reference_comparison_grader = {
"name": "参照比較評価",
"type": "label_model",
"model": "gpt-4o",
"input": [
{
"role": "system",
"content": """
生成された要約を参照要約と比較してください。
生成された要約がどれだけ参照の主要な情報を捉えているかを評価してください。
比較を以下のいずれかとしてラベル付けしてください:
- "excellent": 参照と同等またはそれ以上
- "good": 参照から主要な情報のほとんどを捉えている
- "inadequate": 参照に存在する重要な情報が欠落している
あなたの評価に対する詳細な説明を提供してください。
"""
},
{
"role": "user",
"content": """
参照要約:
{{item.reference_summary}}
生成された要約:
{{sample.choices[0].message.content}}
評価:
"""
}
],
"passing_labels": ["excellent", "good"],
"labels": ["excellent", "good", "inadequate"],
"condition": "item.reference_summary != null" # 参照が存在する場合のみ適用
}
OpenAI Evals APIを使用した評価設定の作成
データスキーマとテスト基準が定義できたので、評価設定を作成できます:
eval_create_result = openai.evals.create(
name="記事要約品質評価",
metadata={
"description": "複数の次元にわたる記事要約品質の包括的評価",
"version": "1.0",
"created_by": "あなたの組織",
"tags": ["要約", "コンテンツの質", "精度"]
},
data_source_config=data_source_config,
testing_criteria=[
accuracy_grader,
conciseness_grader,
reference_comparison_grader
],
)
eval_id = eval_create_result.id
print(f"作成された評価のID: {eval_id}")
print(f"ダッシュボードで表示: {eval_create_result.dashboard_url}")
OpenAI Evals APIを使用した評価実行の実行
評価データの準備
これから評価のためのテストデータを準備します:
test_articles = [
{
"article": """
欧州宇宙機関(ESA)は、本日新しい地球観測衛星センダイ6の成功した展開を発表しました。
この衛星は、気候変動の影響に関する重要なデータを提供しつつ、前例のない精度で海面を監視します。
センダイ6は、ミリメートル単位の精度で海面変化を測定できる高度なレーダー高度計技術を搭載しています。
科学者たちは、このデータが気候モデルや沿岸計画戦略を大幅に改善すると期待しています。
この衛星はカリフォルニア州のバンデンバーグ空軍基地から打ち上げられ、ESA、NASA、NOAA、その他の国際的なパートナー間の協力に基づくコペルニクスプログラムの一部です。
""",
"reference_summary": """
ESAは、ミリメートル単位の精度で海面を監視するために設計された地球観測衛星センダイ6を成功裏に展開しました。
このミッションは国際的なコペルニクスプログラムの一部であり、気候変動研究や沿岸計画に重要なデータを提供します。
"""
},
# 追加のテスト記事はここに追加されます
]
# 評価のためにテストデータを処理
run_data = []
for item in test_articles:
# 関数を使用して要約を生成
article_data = ArticleSummaryData(**item)
result = generate_article_summary(article_data.article)
# 実行データエントリを準備
run_data.append({
"item": article_data.model_dump(),
"sample": result
})
評価実行の作成と実行
データが準備できたので、評価実行を作成できます:
eval_run_result = openai.evals.runs.create(
eval_id=eval_id,
name="ベースライン要約実行",
metadata={
"model": "gpt-4o",
"temperature": 0.3,
"max_tokens": 300
},
data_source={
"type": "jsonl",
"source": {
"type": "file_content",
"content": run_data,
}
},
)
print(f"評価実行が作成されました: {eval_run_result.id}")
print(f"詳細結果を表示: {eval_run_result.report_url}")
Evals APIから評価結果を取得し分析する
評価実行が完了すると、詳細な結果を取得できます:
def analyze_run_results(run_id: str) -> Dict[str, Any]:
"""
評価実行から結果を取得し分析します。
引数:
run_id: 評価実行のID
戻り値:
分析された結果を含む辞書
"""
# 実行の詳細を取得
run_details = openai.evals.runs.retrieve(run_id)
# 結果を抽出
results = {}
# 全体の合格率を計算
if run_details.results and "pass_rate" in run_details.results:
results["overall_pass_rate"] = run_details.results["pass_rate"]
# 基準ごとの特定のメトリックを抽出
if run_details.criteria_results:
results["criteria_performance"] = {}
for criterion, data in run_details.criteria_results.items():
results["criteria_performance"][criterion] = {
"pass_rate": data.get("pass_rate", 0),
"sample_count": data.get("total_count", 0)
}
# さらなる分析のための失敗を抽出
if run_details.raw_results:
results["failure_analysis"] = [
{
"item": item.get("item", {}),
"result": item.get("result", {}),
"criteria_results": item.get("criteria_results", {})
}
for item in run_details.raw_results
if not item.get("passed", True)
]
return results
# 実行を分析
results_analysis = analyze_run_results(eval_run_result.id)
print(json.dumps(results_analysis, indent=2))
高度なOpenAI Evals APIテクニック
Evals APIによるA/Bテストの実装
Evals APIは、異なる実装の比較に優れています。ここでは、2つのモデル設定のA/Bテストを設定する方法を示します:
def generate_summary_alternative_model(article_text: str) -> Dict[str, Any]:
"""異なるモデル設定を使用した代替実装。"""
response = openai.chat.completions.create(
model="gpt-4o-mini", # 異なるモデルを使用
messages=[
{"role": "system", "content": "この記事を簡潔に要約してください。"},
{"role": "user", "content": article_text},
],
temperature=0.7, # 比較のための高い温度
max_tokens=250
)
return response.model_dump()
# 代替モデルでテストデータを処理
alternative_run_data = []
for item in test_articles:
article_data = ArticleSummaryData(**item)
result = generate_summary_alternative_model(article_data.article)
alternative_run_data.append({
"item": article_data.model_dump(),
"sample": result
})
# 代替評価実行を作成
alternative_eval_run = openai.evals.runs.create(
eval_id=eval_id,
name="代替モデル実行",
metadata={
"model": "gpt-4o-mini",
"temperature": 0.7,
"max_tokens": 250
},
data_source={
"type": "jsonl",
"source": {
"type": "file_content",
"content": alternative_run_data,
}
},
)
# 結果をプログラム的に比較
def compare_evaluation_runs(run_id_1: str, run_id_2: str) -> Dict[str, Any]:
"""
2つの評価実行の結果を比較します。
引数:
run_id_1: 最初の評価実行のID
run_id_2: 2番目の評価実行のID
戻り値:
比較分析を含む辞書
"""
run_1_results = analyze_run_results(run_id_1)
run_2_results = analyze_run_results(run_id_2)
comparison = {
"overall_comparison": {
"run_1_pass_rate": run_1_results.get("overall_pass_rate", 0),
"run_2_pass_rate": run_2_results.get("overall_pass_rate", 0),
"difference": run_1_results.get("overall_pass_rate", 0) - run_2_results.get("overall_pass_rate", 0)
},
"criteria_comparison": {}
}
# 各基準を比較
all_criteria = set(run_1_results.get("criteria_performance", {}).keys()) | set(run_2_results.get("criteria_performance", {}).keys())
for criterion in all_criteria:
run_1_criterion = run_1_results.get("criteria_performance", {}).get(criterion, {})
run_2_criterion = run_2_results.get("criteria_performance", {}).get(criterion, {})
comparison["criteria_comparison"][criterion] = {
"run_1_pass_rate": run_1_criterion.get("pass_rate", 0),
"run_2_pass_rate": run_2_criterion.get("pass_rate", 0),
"difference": run_1_criterion.get("pass_rate", 0) - run_2_criterion.get("pass_rate", 0)
}
return comparison
# 2つの実行を比較する
comparison_results = compare_evaluation_runs(eval_run_result.id, alternative_eval_run.id)
print(json.dumps(comparison_results, indent=2))
OpenAI Evals APIによる回帰の検出
Evals APIの最も価値ある用途の1つは、プロンプトを更新した際の回帰検出です:
def create_regression_detection_pipeline(eval_id: str, baseline_run_id: str) -> None:
"""
新しいプロンプトをベースライン実行と比較する回帰検出パイプラインを作成します。
引数:
eval_id: 評価設定のID
baseline_run_id: 比較するベースライン実行のID
"""
def test_prompt_for_regression(new_prompt: str, threshold: float = 0.95) -> Dict[str, Any]:
"""
新しいプロンプトがベースラインに対して回帰を引き起こすかどうかをテストします。
引数:
new_prompt: テストする新しいプロンプト
threshold: 最小受け入れパフォーマンス比(新しい/ベースライン)
戻り値:
回帰分析を含む辞書
"""
# 新しいプロンプトを使用した関数を定義
def generate_summary_new_prompt(article_text: str) -> Dict[str, Any]:
response = openai.chat.completions.create(
model="gpt-4o", # ベースラインと同じモデル
messages=[
{"role": "system", "content": new_prompt},
{"role": "user", "content": article_text},
],
temperature=0.3,
max_tokens=300
)
return response.model_dump()
# 新しいプロンプトでテストデータを処理
new_prompt_run_data = []
for item in test_articles:
article_data = ArticleSummaryData(**item)
result = generate_summary_new_prompt(article_data.article)
new_prompt_run_data.append({
"item": article_data.model_dump(),
"sample": result
})
# 新しいプロンプトのための評価実行を作成
new_prompt_run = openai.evals.runs.create(
eval_id=eval_id,
name=f"回帰テスト-{int(time.time())}",
metadata={
"prompt": new_prompt,
"test_type": "回帰"
},
data_source={
"type": "jsonl",
"source": {
"type": "file_content",
"content": new_prompt_run_data,
}
},
)
# 完了を待機(本番環境では非同期処理の実装を検討することをお勧めします)
# これは簡素化された実装です
time.sleep(10) # 評価が完了するまで待機
# ベースラインと比較
comparison = compare_evaluation_runs(baseline_run_id, new_prompt_run.id)
# 回帰があったかどうかを判断
baseline_pass_rate = comparison["overall_comparison"]["run_1_pass_rate"]
new_pass_rate = comparison["overall_comparison"]["run_2_pass_rate"]
regression_detected = (new_pass_rate / baseline_pass_rate if baseline_pass_rate > 0 else 0) < threshold
return {
"regression_detected": regression_detected,
"baseline_pass_rate": baseline_pass_rate,
"new_pass_rate": new_pass_rate,
"performance_ratio": new_pass_rate / baseline_pass_rate if baseline_pass_rate > 0 else 0,
"threshold": threshold,
"detailed_comparison": comparison,
"report_url": new_prompt_run.report_url
}
return test_prompt_for_regression
# 回帰検出パイプラインを作成
regression_detector = create_regression_detection_pipeline(eval_id, eval_run_result.id)
# 問題が発生する可能性のあるプロンプトをテスト
problematic_prompt = """
この記事を過度に詳細に要約してください。すべての小さなポイントを含めることを確認してください。
要約は包括的で、何も省略してはいけません。
"""
regression_analysis = regression_detector(problematic_prompt)
print(json.dumps(regression_analysis, indent=2))
OpenAI Evals APIにおけるカスタムメトリックの活用
特化した評価ニーズに対して、カスタムメトリックを実装することができます:
# カスタム数値スコア評価の例
numeric_score_grader = {
"name": "要約品質スコア",
"type": "score_model",
"model": "gpt-4o",
"input": [
{
"role": "system",
"content": """
あなたは記事要約の品質を評価する専門の評価者です。
要約の全体の品質を1.0から10.0のスケールで評価してください。評価の範囲は以下の通りです:
- 1.0-3.9: 品質が悪い、重大な問題
- 4.0-6.9: 改善の余地があるが受け入れ可能な品質
- 7.0-8.9: 良好な品質、期待に応える
- 9.0-10.0: 優れた品質、期待を超えている
特定の数値スコアと詳細な理由付けを提供してください。
"""
},
{
"role": "user",
"content": """
元の記事:
{{item.article}}
評価する要約:
{{sample.choices[0].message.content}}
スコア(1.0-10.0):
"""
}
],
"passing_threshold": 7.0, # 合格のための最小スコア
"min_score": 1.0,
"max_score": 10.0
}
# 評価を作成するときにこれをテスト基準に追加する
OpenAI Evals APIを開発ワークフローに統合する
Evals APIとのCI/CD統合
Evals APIをCI/CDパイプラインに統合することで、一貫した品質を確保します:
def ci_cd_evaluation_workflow(
prompt_file_path: str,
baseline_eval_id: str,
baseline_run_id: str,
threshold: float = 0.95
) -> bool:
"""
デプロイ前にモデルプロンプトを評価するためのCI/CD統合。
引数:
prompt_file_path: 更新中のプロンプトファイルのパス
baseline_eval_id: ベースライン評価設定のID
baseline_run_id: 比較するベースライン実行のID
threshold: 最小受け入れパフォーマンス比
戻り値:
新しいプロンプトが評価に合格したかどうかを示すブール値
"""
# バージョン管理から新しいプロンプトを読み込みます
with open(prompt_file_path, 'r') as f:
new_prompt = f.read()
# ベースラインを使って回帰検出器を作成
regression_detector = create_regression_detection_pipeline(baseline_eval_id, baseline_run_id)
# 新しいプロンプトをテスト
regression_analysis = regression_detector(new_prompt)
# プロンプトがデプロイに安全かどうかを判断
is_approved = not regression_analysis["regression_detected"]
# 評価結果をログに記録
print(f"{prompt_file_path}の評価結果")
print(f"ベースライン合格率: {regression_analysis['baseline_pass_rate']:.2f}")
print(f"新しいプロンプト合格率: {regression_analysis['new_pass_rate']:.2f}")
print(f"パフォーマンス比: {regression_analysis['performance_ratio']:.2f}")
print(f"デプロイ決定: {'承認' if is_approved else '却下'}")
print(f"詳細レポート: {regression_analysis['report_url']}")
return is_approved
OpenAI Evals APIによる定期的監視
定期的な評価はモデルの漂流や劣化を検出するのに役立ちます:
def schedule_periodic_evaluation(
eval_id: str,
baseline_run_id: str,
interval_hours: int = 24
) -> None:
"""
パフォーマンス変化を監視するための定期的な評価をスケジュールします。
引数:
eval_id: 評価設定のID
baseline_run_id: 比較するベースライン実行のID
interval_hours: 評価の頻度(時間)
"""
# 本番システムでは、Airflow、Celery、またはクラウドネイティブソリューションのようなタスクスケジューラーを使用します。
# これは簡素化された例です。
def perform_periodic_evaluation():
while True:
try:
# 現在の生産設定で評価を実行
print(f"{datetime.now()}に定期評価を実行中")
# 評価ロジックを実装(回帰テストに類似)
# 次のスケジュールされた実行までスリープ
time.sleep(interval_hours * 60 * 60)
except Exception as e:
print(f"定期評価でエラーが発生しました: {e}")
# エラー処理とアラートの実装
# 実際の実装では、このスレッドを適切に管理するか、専用のスケジューリングシステムを使用します
import threading
evaluation_thread = threading.Thread(target=perform_periodic_evaluation)
evaluation_thread.daemon = True
evaluation_thread.start()
高度なOpenAI Evals API使用パターン
多段階評価パイプライン
複雑なアプリケーション向けに、多段階の評価パイプラインを実装します:
def create_multi_stage_evaluation_pipeline(
article_data: List[Dict[str, str]]
) -> Dict[str, Any]:
"""
コンテンツ生成のための多段階評価パイプラインを作成します。
引数:
article_data: 評価のための記事のリスト
戻り値:
各段階の評価結果を含む辞書
"""
# ステージ1: コンテンツ生成の評価
generation_eval_id = create_content_generation_eval()
generation_run_id = run_content_generation_eval(generation_eval_id, article_data)
# ステージ2: 事実の精度評価
accuracy_eval_id = create_factual_accuracy_eval()
accuracy_run_id = run_factual_accuracy_eval(accuracy_eval_id, article_data)
# ステージ3: トーンとスタイルの評価
tone_eval_id = create_tone_style_eval()
tone_run_id = run_tone_style_eval(tone_eval_id, article_data)
# すべての段階からの結果を集計
results = {
"generation": analyze_run_results(generation_run_id),
"accuracy": analyze_run_results(accuracy_run_id),
"tone": analyze_run_results(tone_run_id)
}
# 総合スコアを計算
composite_score = (
results["generation"].get("overall_pass_rate", 0) * 0.4 +
results["accuracy"].get("overall_pass_rate", 0) * 0.4 +
results["tone"].get("overall_pass_rate", 0) * 0.2
)
results["composite_score"] = composite_score
return results
結論: OpenAI Evals APIの習得
OpenAI Evals APIは、体系的なLLM評価における重要な進展を示し、開発者にモデルのパフォーマンスを客観的に評価し、データ駆動型の意思決定を行うための強力なツールを提供します。
LLMがますます重要なアプリケーションに統合される中で、体系的な評価の重要性もそれに応じて高まります。OpenAI Evals APIは、これらの評価プラクティスをスケールで実装するために必要なインフラを提供し、あなたのAIシステムが堅牢で信頼性があり、期待に沿ったものになることを保証します。
しかし、ここで止まる必要はありません。ApidogをOpenAI Evals APIワークフローに統合することで、以下のような大きな利点が得られます:
- テストの効率化: Apidogのリクエストテンプレートと自動テスト機能は、評価パイプラインの実装にかかる開発時間を短縮します
- 文書化の強化: 自動API文書生成により、評価基準および実装が適切に文書化されます
- チーム協力: 共有ワークスペースにより、開発チーム間で一貫した評価基準が促進されます
- CI/CD統合: コマンドライン機能により、既存のCI/CDパイプラインとの統合が可能です
- 視覚分析: 内蔵の視覚化ツールが複雑な評価結果を迅速に解釈します
