Azure REST API documentation update: [Multi-Turn Evals] clean-up - move evaluation level to openai-evaluations は、ひと言でいうと、Evals APIの evaluation_level を「評価そのもの」ではなく「評価実行」に紐づく設定として整理する変更です。通常の推論APIやAzureリソース管理APIを使っているだけなら影響は限定的ですが、Azure AI Foundry / OpenAI Evals系のREST API、SDK生成、マルチターン評価を扱う開発者は確認が必要です。該当PRでは、evaluation_level が既存の evaluations 側から外され、openai-evaluations 側の EvalRun / CreateEvalRunRequest 文脈で扱われるように整理されています。(GitHub)
Azure REST API documentation updateで何が変わったのか
今回の変更対象は、Azure REST APIの中でもAzure AI FoundryのData Plane API仕様です。PR #42872は feature/foundry-release ブランチ向けの変更として作成され、ラベル上も data-plane と TypeSpec が付いています。通常のAzure Resource Manager、仮想マシン、ストレージ、ネットワークなどの管理API変更ではありません。(GitHub)
変更の中心は、evaluation_level の配置です。PRの差分では、OpenAPI3のJSON/YAMLから既存の Evaluation 定義内にあった evaluation_level が削除されています。また、TypeSpecの src/evaluations/models.tsp からも evaluation_level と EvaluationLevel union が削除されています。(GitHub)
一方で、src/openai-evaluations/models.tsp には EvaluationLevel が追加され、turn と conversation が定義されています。さらに、EvalRun と CreateEvalRunRequest では evaluation_level が任意項目として残り、未指定時は turn が既定値として扱われる構成です。(GitHub)
| 観点 | 変更前に読み取りやすかった意味 | 変更後の整理 |
|---|---|---|
evaluation_level の位置 | 評価定義そのものの属性 | 評価実行、つまりEval Run側の属性 |
| 指定するタイミング | Evalを作成するときに指定するように見える | Eval Runを作成するときに指定する |
| 既定値 | turn | turn |
| マルチターン評価 | 評価定義側で固定するように見える | 実行ごとに conversation を選べる |
この整理により、「同じ評価定義を使いながら、ある実行ではターン単位、別の実行では会話全体で評価する」という読み方がしやすくなります。マルチターン評価では、評価基準や対象データだけでなく、評価をどの粒度で実行するかが重要になるためです。
evaluation_level は何を意味するのか
evaluation_level は、評価をどの単位で実行するかを示す設定です。今回の仕様では、主に次の2つの値を意識します。
| 値 | 意味 | 向いている用途 |
|---|---|---|
turn | 1回の入力と応答など、個別ターンを評価する | FAQ応答、分類、単発の回答品質チェック |
conversation | 複数ターンにまたがる会話全体を評価する | エージェント、カスタマーサポート、手順案内、文脈保持の評価 |
たとえば、ユーザーが「返品したい」と言い、次に「注文番号は123です」と続け、最後に「返金ではなく交換がいい」と希望を変えるケースを考えます。turn 評価では各応答の正しさを個別に見ます。一方、conversation 評価では、会話全体として目的を達成できたか、途中の条件変更を保持できたか、最後に適切な案内へ着地できたかを見ます。
マルチターン評価で失敗しやすいのは、1ターンごとの応答は自然なのに、会話全体では目的を達成していないケースです。たとえば、前のターンで聞いた注文番号を忘れる、ユーザーが条件を変更したのに古い条件で処理する、最後に必要な確認事項を漏らす、といった問題です。conversation は、こうした会話全体の品質を見るための粒度として使います。
影響を受ける可能性が高い人
今回のAzure REST API documentation updateで特に確認すべきなのは、Evals APIを直接または間接的に使っている開発者です。Microsoft Learnの現行Evals REST API referenceでも、Evalの作成とEval Runの作成は別の操作として定義されています。Evalは評価の構造を作成する操作で、Eval Runは実際に採点処理を開始する操作です。(Microsoft Learn)
| 利用状況 | 影響度 | 確認ポイント |
|---|---|---|
| Evals APIを使っていない | 低 | 今回の変更は基本的に監視のみ |
POST /openai/v1/evals で評価定義を作っている | 中 | リクエストに evaluation_level を入れていないか確認 |
POST /openai/v1/evals/{eval_id}/runs で評価実行を作っている | 高 | evaluation_level をRun側に置く設計へ合わせる |
| TypeSpecやOpenAPIからSDKを生成している | 高 | 生成モデル、型定義、テストの差分を確認 |
| マルチターン評価を導入している | 高 | turn と conversation の使い分けを明確にする |
とくに注意したいのは、SDKや社内ラッパーを自動生成しているケースです。PR上ではSwagger BreakingChangeチェックの失敗が表示され、APIViewでもTypeSpec、Python、JavaScriptのAPIレベル変更が検出されています。これは、実装者側で「単なるドキュメント文言の修正」と見なさず、型・スキーマ・テストに影響する可能性がある変更として扱うべきサインです。(GitHub)
確認すべきAPI設計のポイント
今回の変更で最も重要なのは、EvalとEval Runの役割を分けて考えることです。
Evalは「評価の設計図」
Evalは、評価の名前、データソース設定、採点基準などを定義するものです。たとえば「サポートエージェントの回答品質を評価する」「FAQ分類の正確性を測る」といった評価グループを作る位置づけです。
この段階では、評価対象のスキーマや採点基準を決めます。毎回の実行条件まで固定するというより、評価の枠組みを作るイメージです。
Eval Runは「実際の評価実行」
Eval Runは、作成済みのEvalに対して、具体的なデータソースを使って採点を走らせるものです。今回の変更では、evaluation_level がこのRun側に整理されています。
つまり、評価粒度は「評価定義に永久に固定するもの」ではなく、「この実行ではターン単位で見る」「この実行では会話全体で見る」と実行ごとに選ぶ設定として扱うのが自然です。
移行・設定確認の進め方
既存コードがある場合は、次の順で確認すると手戻りを減らせます。
| 手順 | 作業 | 見るべきポイント |
|---|---|---|
| 1 | コード全体を検索 | evaluation_level と EvaluationLevel の参照箇所 |
| 2 | API呼び出しを分類 | Eval作成か、Eval Run作成か |
| 3 | リクエストボディを確認 | evaluation_level がRun側にあるか |
| 4 | 型定義を更新 | 古い Evaluation モデルに依存していないか |
| 5 | テストを分ける | turn と conversation の両方を検証 |
| 6 | レポートを確認 | 評価結果を同じ粒度同士で比較しているか |
実務では、まずリポジトリ内で次の文字列を検索します。
evaluation_level
EvaluationLevel
conversation
turn
検索結果が POST /openai/v1/evals のリクエスト生成処理に集中している場合は、Run作成側へ移す必要があるか確認します。反対に、すでに POST /openai/v1/evals/{eval_id}/runs のリクエストに入っている場合は、既定値やレスポンス処理の確認が中心になります。
リクエスト例で見る配置の違い
以下は、配置の考え方を示す簡略例です。data_source_config や testing_criteria、data_source の詳細は、利用中のAPIバージョンと実際の評価設計に合わせて調整してください。
避けたいのは、Eval作成時に evaluation_level を置く形です。
POST {endpoint}/openai/v1/evals
{
"name": "support-agent-eval",
"data_source_config": {
"type": "custom",
"schema": {}
},
"testing_criteria": [],
"evaluation_level": "conversation"
}
今回の整理に合わせるなら、evaluation_level はEval Run作成時に指定します。
POST {endpoint}/openai/v1/evals/{eval_id}/runs
{
"name": "support-agent-eval-run-2026-05",
"data_source": {
"type": "jsonl",
"source": {
"type": "file_id",
"id": "file_xxxxx"
}
},
"evaluation_level": "conversation"
}
単発の回答品質を見るだけなら、turn を明示するか、既定値に任せます。PR上のTypeSpecでは、未指定時の既定値は turn として定義されています。(GitHub)
{
"name": "faq-answer-eval-run",
"data_source": {
"type": "jsonl",
"source": {
"type": "file_id",
"id": "file_xxxxx"
}
},
"evaluation_level": "turn"
}
turn と conversation の使い分け
evaluation_level は、何となく conversation を選べば高度になる、というものではありません。評価したい失敗パターンに合わせて選ぶ必要があります。
turn が向いているケース
turn は、1つの入力に対する1つの応答を評価したいときに向いています。
たとえば、次のような評価です。
- FAQへの回答が正しいか
- 分類ラベルが期待値と一致しているか
- 禁止表現を含んでいないか
- 1回の回答として根拠が十分か
turn は結果が読みやすく、テストケースごとの失敗原因も追いやすいのが利点です。プロンプト改善やモデル比較の初期段階では、まず turn で小さく検証すると扱いやすいです。
conversation が向いているケース
conversation は、複数ターンの文脈をまたいで品質を見たい場合に向いています。
たとえば、次のような評価です。
- 前の発言内容を保持できているか
- ユーザーの条件変更に追従できているか
- 会話全体として目的を達成できたか
- ツール呼び出しや確認質問の順序が自然か
- 最後に必要なアクションへ誘導できたか
カスタマーサポート、予約変更、社内問い合わせボット、AIエージェントのタスク実行などでは、1ターンだけでは評価しきれません。この場合は、conversation を使うことで、会話全体の成否を評価しやすくなります。
失敗しやすいポイント
Eval作成とEval Run作成を混同する
最も多いミスは、Eval作成時のボディに evaluation_level を残したままにすることです。仕様変更後の読み方では、評価粒度はRun側の設定です。
社内コードで createEvaluation() のような関数に評価粒度を渡している場合は、その関数がEvalを作るだけなのか、Runまで作るのかを確認してください。名前だけで判断すると見落とします。
未指定のまま会話全体評価を期待する
evaluation_level は未指定時に turn が既定値です。マルチターン評価のつもりでデータを用意しても、Run作成時に conversation を明示していなければ、期待した粒度で評価されない可能性があります。
会話全体の品質を見たい場合は、Run作成時のリクエストに次のように明示します。
{
"evaluation_level": "conversation"
}
enumを固定しすぎる
EvaluationLevel には turn と conversation が定義されていますが、TypeSpec上は文字列の拡張も許容する形です。将来の値が追加される可能性を考えると、クライアント側で未知の値を即エラーにする実装は避けたほうが安全です。(GitHub)
たとえば、ログ出力や画面表示では未知の値をそのまま表示し、評価ロジックで未対応の場合だけ警告を出す設計にすると、API仕様の拡張に追従しやすくなります。
評価結果を異なる粒度で比較する
turn の結果と conversation の結果を同列に比較すると、改善判断を誤ります。
たとえば、turn では80点、conversation では60点だった場合、それはモデルが劣化したというより、評価対象が「個別応答」から「会話全体の完了度」に変わった可能性があります。ダッシュボードやレポートでは、評価粒度をメタ情報として残し、同じ粒度同士で比較するのが安全です。
SDK生成やCIで確認すべきこと
OpenAPIやTypeSpecからSDKを生成しているチームは、今回の変更をコード生成の差分として確認する必要があります。PRではOpenAPI3のJSON/YAML、TypeSpecの evaluations と openai-evaluations が変更対象になっています。(GitHub)
確認すべき項目は次のとおりです。
| 確認項目 | 具体的な見方 |
|---|---|
| 生成モデル | Evaluation に evaluation_level が残っていないか |
| Run作成モデル | CreateEvalRunRequest に evaluation_level があるか |
| レスポンスモデル | EvalRun の evaluation_level を読めるか |
| import / namespace | 古い EvaluationLevel 参照でビルドエラーが出ないか |
| JSON Schema検証 | Eval作成ボディで不要項目を許可していないか |
| APIテスト | turn と conversation のリクエストを分けて検証しているか |
CIでは、単にコンパイルが通るかだけでは不十分です。古いスナップショットテストが Evaluation 内の evaluation_level を期待している場合、仕様に合わないテストが残り続けます。生成後の型差分、サンプルJSON、APIモック、契約テストをまとめて見直すのが現実的です。
マルチターン評価での実務的な判断基準
conversation を使うべきか迷ったら、次の基準で判断します。
| 判断基準 | turn で十分 | conversation を検討 |
|---|---|---|
| 評価対象 | 1問1答 | 複数往復の会話 |
| 失敗パターン | 回答内容の誤り | 文脈忘れ、手順ミス、目的未達 |
| データ | 独立した入力と期待値 | 会話履歴、シナリオ、トレース |
| 改善対象 | プロンプトの文言、単発回答 | エージェント設計、状態管理、ツール順序 |
| レポート | ケース単位の合否 | 会話単位の完了度や失敗理由 |
最初からすべてを conversation で評価する必要はありません。おすすめは、まず turn で基本的な回答品質を固め、その後に conversation で実利用に近い失敗を拾う流れです。
たとえば、社内問い合わせボットなら、最初は「休暇申請の締切を正しく答えるか」を turn で評価します。次に、「ユーザーが途中で部署や雇用形態を伝えた場合に、最終的に正しい申請方法へ案内できるか」を conversation で評価します。この2段階にすると、単発回答の問題と会話設計の問題を切り分けやすくなります。
すぐに取るべき対応
今回のAzure REST API documentation updateを受けて、実務で最初にやるべきことは3つです。
まず、コードと設定ファイルから evaluation_level を検索します。次に、その指定がEval作成側にあるのか、Eval Run作成側にあるのかを分けます。最後に、マルチターン評価をしているRunでは conversation を明示し、単発評価では turn または未指定の既定値で問題ないか確認します。
Evals APIを使っていないチームは、今すぐ大きな対応は不要です。ただし、今後Azure AI Foundryでエージェント評価や継続評価を導入する予定があるなら、評価定義と評価実行を分けて設計しておくと、今回のような仕様整理にも対応しやすくなります。
この変更の本質は、evaluation_level の削除ではなく、責務の移動です。評価の設計図であるEvalではなく、実際の採点を行うEval Runに評価粒度を持たせる。そう理解しておけば、移行時に見るべきリクエスト、型定義、テスト範囲が明確になります。

コメント