在本文中,您將學習如何在雲端對測試資料集進行部署前測試的評估。
大多數情境都應使用雲端評估——尤其是在大規模測試、將評估整合進持續整合與持續交付(CI/CD)管線,或執行部署前測試時。 在雲端執行評估消除了管理本地運算基礎設施的需求,並支援大規模自動化的測試工作流程。 您也可以安排評估以定期執行,或設定持續評估,自動評估生產環境中的抽樣代理回應。
雲端評估結果會儲存在您的 Foundry 專案中。 你可以在入口網站查看結果,透過 SDK 檢索結果,或在連接後將其導向 Application Insights。 雲端評估支援所有Microsoft策劃的內建評估器以及您自己的自訂評估器。 評估者在 評估者目錄 中以相同的專案範圍、基於角色的存取控制來管理。
提示
欲了解完整的可執行範例,請參閱 GitHub 上的 Python SDK 評估範例。
雲端評估的運作方式
雲端評估包含三個步驟:
- 定義該評估什麼。 描述你的資料結構(即
data_source_config)以及對其進行評分的評估器(即測試標準)。 - 建立評估。 請使用
openai_client.evals.create()提交定義。 - 執行它並查看結果。 開始一輪時,先用
openai_client.evals.runs.create(),輪詢直到完成,然後閱讀評分結果。 請參閱 取得結果 結構。
本節其餘部分將逐步介紹第一步:選擇情境,然後選擇評估者。
選擇你的起點
現有資料集
當您已有收集在檔案中的查詢和回應 (或查詢加上基準真相),且只想要 Foundry 為其評分時,請使用此路徑。 JSONL 同時支援回合層級資料列和對話層級輸入;CSV 僅支援回合層級。
| 劇本 | 何時使用 | 資料來源類型 |
|---|---|---|
| 輪次層級資料集評估 | 每一列代表一組 query/response 配對,並可選擇搭配 context 或 ground_truth。 |
jsonl 或 csv |
| 對話層級資料集評估(預覽) | 每一列都是以 messages 陣列形式表達的對話。 |
jsonl |
Foundry 或 Application Insights 中的資料
當你的客服已經在執行任務,想評估實際發生了什麼時,可以使用這條路徑。 你不是將資料移出,而是讓 Foundry 透過 Foundry 回應 ID,或 Application Insights 的追蹤 ID 或對話 ID,直接指向資料原本所在的位置。
| 劇本 | 何時使用 | 資料來源類型 |
|---|---|---|
| 代理反應評估 | 您的 Agent 在 Foundry 中執行,且您有可評分的回應 ID。 | azure_ai_responses |
| 回合層級追蹤評估(預覽) | 您的 Agent 會將 OpenTelemetry 追蹤發出至 Application Insights,包括 LangChain 等非 Foundry 架構或自訂 OpenTelemetry 檢測 Agent。 每個追蹤會獨立評分。 | azure_ai_trace_data_source_preview |
| 對話層級追蹤評估(預覽) | 相同的追蹤來源,但會根據對話 ID 或代理人篩選器搭配抽樣來評分完整對話。 | azure_ai_trace_data_source_preview |
無回應的輸入
當你有輸入但還沒有回應時,使用這條路徑。 Foundry 會在評估時針對模型或代理人目標產生回應,然後對其進行評分。 根據您的輸入是查詢 (作為個別回合傳送) 或案例描述 (用於驅動交談層級互動),挑選一列。
| 劇本 | 何時使用 | 資料來源/目標 |
|---|---|---|
| 模型目標完成 | 你有查詢內容,並想評估模型部署所產生的回應。 |
azure_ai_target_completions → azure_ai_model |
| Agent 目標補全 | 你有疑問,想評估 Foundry 代理的回應。 |
azure_ai_target_completions → azure_ai_agent |
| 對話模擬(預覽) | 您有案例描述 (沒有查詢);Foundry 會模擬使用者,驅動與 Agent 的交談層級互動。 |
azure_ai_target_completions → azure_ai_agent |
目前還沒有數據
當你正在建立新模型或代理且尚未收集任何輸入時,可以使用這條路徑。 Foundry 從零開始產生測試資料——可選擇合成查詢以獲得廣泛的品質覆蓋,或是對抗性提示以進行安全測試。
| 劇本 | 何時使用 | 資料來源/目標 |
|---|---|---|
| 合成資料評估(預覽) | 你想要的報導品質比你手寫的還要好。 Foundry 會產生測試查詢,發送給目標,並對回應進行評分。 |
azure_ai_synthetic_data_gen_preview → azure_ai_model 或 azure_ai_agent |
| 紅隊評估 | 你需要自動化對抗式測試——Foundry 會產生越獄和有害內容提示,並評分目標的反應。 |
azure_ai_red_team → azure_ai_model 或 azure_ai_agent |
選擇評估者
每個情境都會透過 欄位映射將評估者綁定到資料中的欄位。 可用的欄位依資料來源而異。 資料集情境會暴露你自訂的項目欄位,而目標生成情境則透過範例結構揭露模型或代理的回應。 本文稍後的每個案例子區段會顯示每個案例的資料行對應。
關於可用評估器的概覽及選擇方式,請參閱 內建評估器 與 自訂評估器。
先決條件
Azure OpenAI 部署中使用了一個支援聊天完成功能的 GPT 模型(例如
gpt-5-mini)。Foundry 專案中的 Foundry 使用者角色。
重要
Foundry RBAC 角色最近已重新命名。 Foundry 用戶、Foundry 擁有者、Foundry Account Owner 以及 Foundry Project Manager 先前分別被稱為 Azure AI 使用者、Azure AI 擁有者、Azure AI 帳戶擁有者及 Azure AI Project 管理者。 在更名期間,你可能還會在某些地方看到之前的名字。角色 ID 與核心權限不會因命名而改變。
你也可以選擇 使用自己的儲存帳號 來進行評估。
註
部分評估功能有區域限制。 詳情請參閱 支援區域 。
開始
安裝 SDK 並設定你的客戶端:
pip install "azure-ai-projects>=2.2.0"
import os
from azure.identity import DefaultAzureCredential
from azure.ai.projects import AIProjectClient
from openai.types.eval_create_params import DataSourceConfigCustom
from openai.types.evals.create_eval_jsonl_run_data_source_param import (
CreateEvalJSONLRunDataSourceParam,
SourceFileContent,
SourceFileContentContent,
SourceFileID,
)
# Azure AI Project endpoint
# Example: https://<account_name>.services.ai.azure.com/api/projects/<project_name>
endpoint = os.environ["AZURE_AI_PROJECT_ENDPOINT"]
# Model deployment name (for AI-assisted evaluators)
# Example: gpt-5-mini
model_deployment_name = os.environ.get("AZURE_AI_MODEL_DEPLOYMENT_NAME", "")
# Dataset details (optional, for reusing existing datasets)
dataset_name = os.environ.get("DATASET_NAME", "")
dataset_version = os.environ.get("DATASET_VERSION", "1")
# Create the project client
project_client = AIProjectClient(
endpoint=endpoint,
credential=DefaultAzureCredential(),
)
# Get the OpenAI client for evaluation API
openai_client = project_client.get_openai_client()
準備輸入資料
大多數評估情境都需要輸入資料。 你可以用兩種方式提供資料:
上傳資料集(建議)
上傳 JSONL 或 CSV 檔案,在你的 Foundry 專案中建立版本化資料集。 資料集支援版本控制與跨多次評估運行的重複使用。 此方法用於生產測試及 CI/CD 工作流程。
準備一個 JSONL 檔案,每行包含一個 JSON 物件,包含評估者所需的欄位:
{"query": "What is machine learning?", "response": "Machine learning is a subset of AI.", "ground_truth": "Machine learning is a type of AI that learns from data."}
{"query": "Explain neural networks.", "response": "Neural networks are computing systems inspired by biological neural networks.", "ground_truth": "Neural networks are a set of algorithms modeled after the human brain."}
或者準備一個 CSV 檔案,欄頭與你的評估者欄位相符:
query,response,ground_truth
What is machine learning?,Machine learning is a subset of AI.,Machine learning is a type of AI that learns from data.
Explain neural networks.,Neural networks are computing systems inspired by biological neural networks.,Neural networks are a set of algorithms modeled after the human brain.
# Upload a local JSONL file. Skip this step if you already have a dataset registered.
data_id = project_client.datasets.upload_file(
name=dataset_name,
version=dataset_version,
file_path="./evaluate_test_data.jsonl",
).id
提供線上資料
若要快速進行小型測試集的實驗,請將資料直接提供於評估請求中 file_content。
source = SourceFileContent(
type="file_content",
content=[
SourceFileContentContent(
item={
"query": "How can I safely de-escalate a tense situation?",
"ground_truth": "Encourage calm communication, seek help if needed, and avoid harm.",
}
),
SourceFileContentContent(
item={
"query": "What is the largest city in France?",
"ground_truth": "Paris",
}
),
],
)
在建立執行程序時,於資料來源設定中把source 作為"source"欄位傳入。 接下來的劇本章節預設使用 file_id 。
資料集評估
Step 2:
利用jsonl資料來源類型評估預先計算好的回應,並以 JSONL 檔案呈現。 當你已經有模型輸出並想評估其品質時,這個情境非常有用。
定義資料結構與評估器
指定與你的 JSONL 欄位相符的結構,並選擇要執行的評估器(測試標準)。 使用 data_mapping 參數將輸入資料的欄位連接到評估器參數,並使用 {{item.field}} 語法。 務必包含所需的輸入欄位 data_mapping 以供每位評估者使用。 你的欄位名稱必須與 JSONL 檔案中的名稱相符——例如,如果你的資料使用 "question" 而非 "query",在映射中則需使用 "{{item.question}}"。 關於每個評估器所需的參數,請參見 內建評估器。
data_source_config = DataSourceConfigCustom(
type="custom",
item_schema={
"type": "object",
"properties": {
"query": {"type": "string"},
"response": {"type": "string"},
"ground_truth": {"type": "string"},
},
"required": ["query", "response", "ground_truth"],
},
)
testing_criteria = [
{
"type": "azure_ai_evaluator",
"name": "coherence",
"evaluator_name": "builtin.coherence",
"initialization_parameters": {
"model": model_deployment_name
},
"data_mapping": {
"query": "{{item.query}}",
"response": "{{item.response}}",
},
},
{
"type": "azure_ai_evaluator",
"name": "violence",
"evaluator_name": "builtin.violence",
"initialization_parameters": {
"model": model_deployment_name
},
"data_mapping": {
"query": "{{item.query}}",
"response": "{{item.response}}",
},
},
{
"type": "azure_ai_evaluator",
"name": "f1",
"evaluator_name": "builtin.f1_score",
"data_mapping": {
"response": "{{item.response}}",
"ground_truth": "{{item.ground_truth}}",
},
},
]
建立評估並執行
建立評估,然後開始對你上傳的資料集進行運算。 執行會在資料集的每一列上執行每個評估工具。
# Create the evaluation
eval_object = openai_client.evals.create(
name="dataset-evaluation",
data_source_config=data_source_config,
testing_criteria=testing_criteria,
)
# Create a run using the uploaded dataset
eval_run = openai_client.evals.runs.create(
eval_id=eval_object.id,
name="dataset-run",
data_source=CreateEvalJSONLRunDataSourceParam(
type="jsonl",
source=SourceFileID(
type="file_id",
id=data_id,
),
),
)
完整可執行範例請參見GitHub上的 sample_evaluations_builtin_with_dataset_id.py。 若要進行投票完成並解讀結果,請參閱 「取得結果」。
CSV 資料集評估
利用資料來源類型評估 CSV 檔案 csv 中預先計算的回應。 此情境運作方式與 資料集評估 相同,但接受的是 CSV 檔案而非 JSONL。 如果你的資料已經是試算表或表格格式,請使用 CSV
準備一份 CSV 檔案
建立一個 CSV 檔案,欄頭與評估者需要的欄位相符。 每一列代表一個測試案例。
query,response,context,ground_truth
What is cloud computing?,Cloud computing delivers computing services over the internet.,Cloud computing is a technology for on-demand resource delivery.,Cloud computing is the delivery of computing services including servers storage and databases over the internet.
What is machine learning?,Machine learning is a subset of AI that learns from data.,Machine learning is a branch of artificial intelligence.,Machine learning is a type of AI that enables computers to learn from data without being explicitly programmed.
Explain neural networks.,Neural networks are computing systems inspired by biological neural networks.,Neural networks are used in deep learning.,Neural networks are a set of algorithms modeled after the human brain designed to recognize patterns.
上傳並執行
將 CSV 檔案上傳為資料集。 接著,利用 csv 資料來源類型建立評估。 結構定義與評估器設定與 JSONL 評估相同。 唯一的差別在於資料來源中的 "type": "csv"。
# Upload the CSV file
data_id = project_client.datasets.upload_file(
name="eval-csv-data",
version="1",
file_path="./evaluation_data.csv",
).id
# Define the schema matching your CSV columns
data_source_config = DataSourceConfigCustom(
type="custom",
item_schema={
"type": "object",
"properties": {
"query": {"type": "string"},
"response": {"type": "string"},
"context": {"type": "string"},
"ground_truth": {"type": "string"},
},
"required": [],
},
include_sample_schema=True,
)
# Define evaluators with data mappings to CSV columns
testing_criteria = [
{
"type": "azure_ai_evaluator",
"name": "coherence",
"evaluator_name": "builtin.coherence",
"data_mapping": {
"query": "{{item.query}}",
"response": "{{item.response}}",
},
"initialization_parameters": {"model": model_deployment_name},
},
{
"type": "azure_ai_evaluator",
"name": "violence",
"evaluator_name": "builtin.violence",
"data_mapping": {
"query": "{{item.query}}",
"response": "{{item.response}}",
},
"initialization_parameters": {"model": model_deployment_name},
},
{
"type": "azure_ai_evaluator",
"name": "f1",
"evaluator_name": "builtin.f1_score",
},
]
# Create the evaluation
eval_object = openai_client.evals.create(
name="CSV evaluation with built-in evaluators",
data_source_config=data_source_config,
testing_criteria=testing_criteria,
)
# Create a run using the CSV data source type
eval_run = openai_client.evals.runs.create(
eval_id=eval_object.id,
name="csv-evaluation-run",
data_source={
"type": "csv",
"source": {
"type": "file_id",
"id": data_id,
},
},
)
若要進行投票完成並解讀結果,請參閱 「取得結果」。
模型目標評估
在執行時向已部署的模型發送查詢。 利用 azure_ai_target_completions 帶有 azure_ai_model 目標的資料來源類型來評估回應。 您的輸入資料包含查詢。 模型會產生回應,然後你再評估這些回應。
定義訊息範本與目標
範本 input_messages 控制查詢如何傳送到模型。 用 {{item.query}} 來參考輸入資料中的欄位。 指定要評估的模型及可選的抽樣參數:
input_messages = {
"type": "template",
"template": [
{
"type": "message",
"role": "user",
"content": {
"type": "input_text",
"text": "{{item.query}}"
}
}
]
}
target = {
"type": "azure_ai_model",
"model": "gpt-5-mini",
"sampling_params": {
"top_p": 1.0,
"max_completion_tokens": 2048,
},
}
設置評估器與資料映射
當模型在執行時產生回應時,請使用 {{sample.output_text}} in data_mapping 來參考模型的輸出。 用 {{item.field}} 來參考輸入資料中的欄位。
data_source_config = DataSourceConfigCustom(
type="custom",
item_schema={
"type": "object",
"properties": {
"query": {"type": "string"},
},
"required": ["query"],
},
include_sample_schema=True,
)
testing_criteria = [
{
"type": "azure_ai_evaluator",
"name": "coherence",
"evaluator_name": "builtin.coherence",
"initialization_parameters": {
"model": model_deployment_name,
},
"data_mapping": {
"query": "{{item.query}}",
"response": "{{sample.output_text}}",
},
},
{
"type": "azure_ai_evaluator",
"name": "violence",
"evaluator_name": "builtin.violence",
"data_mapping": {
"query": "{{item.query}}",
"response": "{{sample.output_text}}",
},
},
]
建立評估並執行
eval_object = openai_client.evals.create(
name="Model Target Evaluation",
data_source_config=data_source_config,
testing_criteria=testing_criteria,
)
data_source = {
"type": "azure_ai_target_completions",
"source": {
"type": "file_id",
"id": data_id,
},
"input_messages": input_messages,
"target": target,
}
eval_run = openai_client.evals.runs.create(
eval_id=eval_object.id,
name="model-target-evaluation",
data_source=data_source,
)
完整可執行範例請參見GitHub上的 sample_model_evaluation.py。 若要進行投票完成並解讀結果,請參閱 「取得結果」。
提示
若要新增另一個評估執行,請使用相同的程式碼。
代理人目標評估
在執行時向 Foundry 代理發送查詢,並利用 azure_ai_target_completions 帶有 azure_ai_agent 目標的資料來源類型來評估回應。 此情境適用於 提示代理 與 託管代理。
提示
使用回應協定的託管代理使用與此處所示相同的程式碼範例。 對於使用呼叫協定 input_messages 的託管代理,格式有所不同。 詳情請參閱 託管代理呼叫協定 。
定義訊息範本與目標
範本 input_messages 控制查詢如何傳送給代理人。 用 {{item.query}} 來參考輸入資料中的欄位。 請指定要評估的代理人名稱:
input_messages = {
"type": "template",
"template": [
{
"type": "message",
"role": "developer",
"content": {
"type": "input_text",
"text": "You are a helpful assistant. Answer clearly and safely."
}
},
{
"type": "message",
"role": "user",
"content": {
"type": "input_text",
"text": "{{item.query}}"
}
}
]
}
target = {
"type": "azure_ai_agent",
"name": "my-agent",
"version": "1" # Optional. Uses latest version if omitted.
}
設置評估器與資料映射
當 Agent 在執行階段產生回應時,請在 {{sample.*}} 中使用 data_mapping 變數參考 Agent 的輸出:
| 變數 | 描述 | 使用對象 |
|---|---|---|
{{sample.output_text}} |
代理人的純文字回覆。 | 期望字串回應的評估器(例如, coherence, violence)。 |
{{sample.output_items}} |
代理的結構化 JSON 輸出,包括工具呼叫。 | 需要完整互動上下文的評估器(例如, task_adherence)。 |
{{item.field}} |
一個來自你輸入資料的欄位。 | 輸入欄位如 query 或 ground_truth。 |
提示
該 query 欄位可包含結構化 JSON,包括系統訊息與對話歷史。 有些代理評估員 task_adherence 會使用此脈絡來進行更精確的評分。 關於查詢格式的詳細資訊,請參見代理評估器。
data_source_config = DataSourceConfigCustom(
type="custom",
item_schema={
"type": "object",
"properties": {
"query": {"type": "string"},
},
"required": ["query"],
},
include_sample_schema=True,
)
testing_criteria = [
{
"type": "azure_ai_evaluator",
"name": "coherence",
"evaluator_name": "builtin.coherence",
"initialization_parameters": {
"model": model_deployment_name,
},
"data_mapping": {
"query": "{{item.query}}",
"response": "{{sample.output_text}}",
},
},
{
"type": "azure_ai_evaluator",
"name": "violence",
"evaluator_name": "builtin.violence",
"data_mapping": {
"query": "{{item.query}}",
"response": "{{sample.output_text}}",
},
},
{
"type": "azure_ai_evaluator",
"name": "task_adherence",
"evaluator_name": "builtin.task_adherence",
"initialization_parameters": {
"model": model_deployment_name,
},
"data_mapping": {
"query": "{{item.query}}",
"response": "{{sample.output_items}}",
},
},
]
建立評估並執行
eval_object = openai_client.evals.create(
name="Agent Target Evaluation",
data_source_config=data_source_config,
testing_criteria=testing_criteria,
)
data_source = {
"type": "azure_ai_target_completions",
"source": {
"type": "file_id",
"id": data_id,
},
"input_messages": input_messages,
"target": target,
}
agent_eval_run = openai_client.evals.runs.create(
eval_id=eval_object.id,
name="agent-target-evaluation",
data_source=data_source,
)
完整可執行範例請參見GitHub上的 sample_agent_evaluation.py。 若要進行投票完成並解讀結果,請參閱 「取得結果」。
託管代理調用協定
使用呼叫協定的託管代理程式支援相同azure_ai_agent目標類型,但採用自由格式input_messages。 與其使用結構化範本格式,不如提供一個直接對應到代理 /invocations 請求主體的 JSON 物件。 使用 {{item.*}} 佔位符來替換輸入資料中的欄位。
若託管代理同時支援回應與呼叫協定,服務預設使用呼叫協定。
定義訊息格式與目標
input_messages = {"message": "{{item.query}}"}
target = {
"type": "azure_ai_agent",
"name": "my-hosted-agent", # Replace with your hosted agent name
"version": "1",
}
建立評估並執行
eval_object = openai_client.evals.create(
name="Hosted Agent Invocations Evaluation",
data_source_config=data_source_config,
testing_criteria=testing_criteria,
)
data_source = {
"type": "azure_ai_target_completions",
"source": {
"type": "file_id",
"id": data_id,
},
"input_messages": input_messages,
"target": target,
}
eval_run = openai_client.evals.runs.create(
eval_id=eval_object.id,
name="hosted-agent-invocations-evaluation",
data_source=data_source,
)
評估器的設定與資料映射與 即時代理評估相同。 請使用 {{sample.output_text}} 來標註代理的文字回應,並使用 {{sample.output_items}} 來表示包含工具呼叫的完整結構化輸出。
代理反應評估
利用資料來源類型,透過回應 ID azure_ai_responses 檢索並評估 Foundry 代理的回應。 利用此情境評估特定代理人互動發生後的情況。
提示
在開始之前,請先完成「 開始」。
回應 ID 是每次 Foundry 代理產生回應時回傳的唯一識別碼。 你可以透過 Responses API 或應用程式的追蹤日誌,從代理互動中收集回應 ID。 將 ID 內嵌為檔案內容,或上傳為資料集(參見 準備輸入資料)。
收集回應識別碼
每次呼叫回應 API 都會回傳一個具有唯一 id 欄位的回應物件。 從應用程式的互動中收集這些識別碼,或直接產生:
# Generate response IDs by calling a model through the Responses API
response = openai_client.responses.create(
model=model_deployment_name,
input="What is machine learning?",
)
print(response.id) # Example: resp_abc123
你也可以從應用程式的追蹤日誌或監控管線中,從代理互動中收集回應 ID。 每個回應 ID 唯一識別一個儲存的回應,評估服務可檢索。
建立評估並執行
data_source_config = {"type": "azure_ai_source", "scenario": "responses"}
testing_criteria = [
{
"type": "azure_ai_evaluator",
"name": "coherence",
"evaluator_name": "builtin.coherence",
"initialization_parameters": {
"model": model_deployment_name,
},
},
{
"type": "azure_ai_evaluator",
"name": "violence",
"evaluator_name": "builtin.violence",
},
]
eval_object = openai_client.evals.create(
name="Agent Response Evaluation",
data_source_config=data_source_config,
testing_criteria=testing_criteria,
)
data_source = {
"type": "azure_ai_responses",
"item_generation_params": {
"type": "response_retrieval",
"data_mapping": {"response_id": "{{item.resp_id}}"},
"source": {
"type": "file_content",
"content": [
{"item": {"resp_id": "resp_abc123"}},
{"item": {"resp_id": "resp_def456"}},
]
},
},
}
eval_run = openai_client.evals.runs.create(
eval_id=eval_object.id,
name="agent-response-evaluation",
data_source=data_source,
)
完整可執行範例請參見GitHub上的 sample_agent_response_evaluation.py。 若要進行投票完成並解讀結果,請參閱 「取得結果」。
追蹤評估 (預覽版)
評估 Application Insights 已經捕捉到的客服互動。 使用資料來源類型 azure_ai_traces 。 此情境對於部署後實際生產流量的評估非常有用。 您可以從監視管線選取追蹤,並針對這些追蹤執行評估工具,而不重播任何要求。
重要
追蹤評估是評估並非使用 Microsoft Foundry Agent Service 建置的代理程式(包括 LangChain 和自訂框架)的建議方法。 只要你的代理將 遵循 GenAI 語意慣例的 OpenTelemetry span 傳送至 Application Insights,追蹤評估就能使用 Foundry 代理可用的相同評估器來評估其互動。
追蹤評估支援兩種模式:
-
依據追蹤識別碼 - 提供來自 Application Insights 的
operation_Id值,以評估特定代理程式的互動。 - 透過代理篩選 器 - 自動發現並評估特定代理的近期追蹤,無需手動收集追蹤 ID。
提示
在開始之前,請先完成「 開始」。 此情境也需要與 你的 Foundry 專案連結的 Application Insights 資源。
智慧取樣
痕跡評估支援智慧取樣,選擇具代表性的痕跡子集進行評估,而非評估每一條捕獲的痕跡。 在配置追蹤評估執行時,請在 Foundry 入口開啟 智慧取樣 開關來啟用此功能。 智慧取樣降低評估成本,同時保留痕跡多樣性——確保邊緣案例、錯誤路徑及多樣的對話模式被納入評估集合中。
智慧取樣的運作原理
該抽樣演算法採用 MinHash 最遠優先多樣性方法,分多個階段執行:
- 精確去重 - 從集區中移除重複的追蹤記錄。
- 硬性篩選器 - 移除不適合評估的損壞工作階段、截斷追蹤和格式錯誤的工具呼叫。
- 聚合 - 將痕跡層級訊號合併成統一表示法。
- MinHash 最遠優先選擇 - 計算使用者文本的區域敏感雜湊值(MinHash 簽名)以估算痕跡間的相似度,然後從剩餘的痕跡池中迭代選擇最不相似的痕跡。 每次後續選取都會使其與先前所有已選軌跡的距離達到最大。
此方法相較於隨機抽樣,能帶來顯著更高的詞彙多樣性與更廣泛的詞彙覆蓋,意味著評估的集合能更完整地呈現代理間的互動範圍——包括隨機抽樣容易忽略的罕見、困難及新穎案例。
智慧抽樣對以下情況特別有效:
- 評估與基準測試 - 最大化輸入分布的覆蓋範圍,使評估分數反映真實世界的多樣性。
- 評分規準生成 ——透過揭示多元對話模式,產生更具聚焦性且可執行的評分標準。
- 微調資料集整理 - 選擇能幫助模型更有效率學習的軌跡資料。
該演算法完全以本地運算運行,沒有額外的 API 呼叫,因此除了評估本身外,不會產生額外的模型推論成本。
智慧取樣範例
# Eval group for trace-based evaluations
data_source_config = {
"type": "azure_ai_source",
"scenario": "traces",
}
print("Creating trace-based evaluation group")
eval_object = client.evals.create(
name="Trace Evaluation (Agent Smart Filter)",
data_source_config=data_source_config, # type: ignore
testing_criteria=testing_criteria,
)
print(f"Evaluation created (id: {eval_object.id})")
# Compute time window in unix seconds
# Pad end_time by +600s (10 min) to avoid ingestion-delay edge exclusion
now_unix = int(time.time())
end_time = now_unix + 600
start_time = now_unix - (args.lookback_hours * 3600)
# Build trace_source based on mode
trace_source: dict = {
"type": "agent_filter",
"start_time": start_time,
"end_time": end_time,
"max_traces": args.max_traces,
"filter_strategy": "smart_filtering"
}
# Add agent name/version or agent id
trace_source["agent_name"] = agent_name
trace_source["agent_version"] = agent_version
## trace_source["agent_id"] = args.agent_id
data_source = {
"type": "azure_ai_trace_data_source_preview",
"trace_source": trace_source,
}
eval_run = client.evals.runs.create(
eval_id=eval_object.id,
name="trace-evaluation-agent-smart-filter-run",
data_source=data_source, # type: ignore
)
追蹤資料需求
追蹤評估要求你的代理程式發出符合 OpenTelemetry 生成式 AI 語意慣例的跨度。 具體來說,評估服務會invoke_agent讀取 Application Insights 的範圍,並從其屬性中擷取對話資料。
以下跨度屬性被使用:
| 屬性 | 必需的 | 描述 |
|---|---|---|
gen_ai.operation.name |
是的 | 必須等於"invoke_agent"。 服務會忽略所有其他的跨度。 |
gen_ai.agent.id |
適用於代理程式篩選模式 | 唯一代理識別碼(格式: agent-name:version)。 |
gen_ai.agent.name |
適用於代理程式篩選模式 | 人類可讀的 Agent 名稱。 |
gen_ai.input.messages |
適用於評估器查詢輸入 | 遵循 生成式人工智慧語意慣例訊息格式的 JSON 輸入訊息陣列。 訊息角色 user 或 system 對應到 query;訊息角色 assistant 或 tool 對應到 response。 |
gen_ai.output.messages |
適用於評估器查詢輸入 | 模型產生的輸出訊息 JSON 陣列。 所有輸出訊息對應到 response。 若輸出同時包含類型:tool_call或類型:tool_result,則映射為 tool_calls。 |
gen_ai.tool.definitions |
可選 | 代理程式可用的 JSON 工具結構陣列。 若缺少,服務會嘗試從工具呼叫訊息推斷工具定義,但推斷出的結構可能不完整。 |
gen_ai.conversation.id |
可選 | 對話識別碼,會傳送至評估結果比對關聯性。 |
註
若 gen_ai.input.messages 和 gen_ai.output.messages 為空或缺失,則品質評估器(一致性、流暢性、相關性、意圖解析)返回 score=None。 安全評估者(暴力、自傷、性、仇恨/不公平)仍能產出部分數據的分數,但可能不會產生有意義的結果。
對於使用 Azure AI Agent Server SDK 建置的 Python agent,請額外加裝 [tracing] 以啟用自動區間發射:
pip install "azure-ai-agentserver-core[tracing]"
痕跡評估的前提條件
除了一般 的先決條件外,痕跡評估還要求:
- 一個與你的 Foundry 專案相關的 應用洞察資源 。 請參見 Microsoft Foundry 中的追蹤設定。
- 專案的受控身分識別必須在 Application Insights 資源及其連結的 Log Analytics 工作區上,具備 Log Analytics 讀者角色。
-
azure-monitor-queryPython 套件(僅當您手動收集追蹤 ID 時才需要)。
pip install "azure-ai-projects>=2.2.0" azure-monitor-query
設定以下環境變數:
-
APPINSIGHTS_RESOURCE_ID— Application Insights 資源 ID(例如/subscriptions/<subscription_id>/resourceGroups/<rg_name>/providers/Microsoft.Insights/components/<resource_name>)。 -
AGENT_ID— 由追蹤整合gen_ai.agent.id屬性所發出的代理識別碼,用於過濾追蹤記錄。 格式:agent-name:version。 -
TRACE_LOOKBACK_HOURS— (可選)查詢痕跡時可回溯的時數。 預設為1。
選項A:使用代理人過濾器進行評估
最簡單的方法是讓服務自動發現並評估特定代理人的最新追蹤紀錄。 不需要手動收集追蹤 ID。
import os
agent_id = os.environ["AGENT_ID"] # e.g., "my-weather-agent:1"
trace_lookback_hours = int(os.environ.get("TRACE_LOOKBACK_HOURS", "1"))
# Create the evaluation
data_source_config = {
"type": "azure_ai_source",
"scenario": "traces",
}
eval_object = openai_client.evals.create(
name="Agent Trace Evaluation (by agent)",
data_source_config=data_source_config,
testing_criteria=testing_criteria, # See "Set up evaluators" below
)
# Create a run — the service queries App Insights for matching traces
data_source = {
"type": "azure_ai_traces",
"agent_id": agent_id,
"max_traces": 50, # Maximum number of traces to evaluate
"lookback_hours": trace_lookback_hours,
}
eval_run = openai_client.evals.runs.create(
eval_id=eval_object.id,
name="agent-trace-eval-run",
data_source=data_source,
)
print(f"Evaluation run started: {eval_run.id}")
該服務會以invoke_agent Span,並依據gen_ai.agent.id屬性進行篩選,取樣最多max_traces個不同複的追蹤識別碼,然後評估來自這些追蹤的所有 Span。
選項B:依追蹤識別碼評估
為了更精確的控制,請從 Application Insights 收集特定的追蹤 ID,並進行評估。 當您想要評估精選互動集時,例如由警示標記或為品質審查取樣的追蹤,此方法很有用。
從 Application Insights 收集追蹤識別碼
查詢 Application Insights,以取得來自您代理程式追蹤的operation_Id值。 每個 operation_Id 代表一個完整的代理互動:
import os
from datetime import datetime, timedelta, timezone
from azure.identity import DefaultAzureCredential
from azure.monitor.query import LogsQueryClient, LogsQueryStatus
appinsights_resource_id = os.environ["APPINSIGHTS_RESOURCE_ID"]
agent_id = os.environ["AGENT_ID"]
trace_query_hours = int(os.environ.get("TRACE_LOOKBACK_HOURS", "1"))
end_time = datetime.now(timezone.utc)
start_time = end_time - timedelta(hours=trace_query_hours)
query = f"""dependencies
| where timestamp between (datetime({start_time.isoformat()}) .. datetime({end_time.isoformat()}))
| extend agent_id = tostring(customDimensions["gen_ai.agent.id"])
| where agent_id == "{agent_id}"
| distinct operation_Id"""
credential = DefaultAzureCredential()
logs_client = LogsQueryClient(credential)
response = logs_client.query_resource(
appinsights_resource_id,
query=query,
timespan=None, # Time range is specified in the query itself
)
trace_ids = []
if response.status == LogsQueryStatus.SUCCESS:
for table in response.tables:
for row in table.rows:
trace_ids.append(row[0])
print(f"Found {len(trace_ids)} trace IDs")
使用追蹤識別碼建立評估並執行
# Create the evaluation
data_source_config = {
"type": "azure_ai_source",
"scenario": "traces",
}
eval_object = openai_client.evals.create(
name="Agent Trace Evaluation (by trace IDs)",
data_source_config=data_source_config,
testing_criteria=testing_criteria, # See "Set up evaluators" below
)
# Create a run using the collected trace IDs
data_source = {
"type": "azure_ai_traces",
"trace_ids": trace_ids,
"lookback_hours": trace_query_hours,
}
eval_run = openai_client.evals.runs.create(
eval_id=eval_object.id,
name="agent-trace-eval-run",
metadata={
"agent_id": agent_id,
"start_time": start_time.isoformat(),
"end_time": end_time.isoformat(),
},
data_source=data_source,
)
print(f"Evaluation run started: {eval_run.id}")
設置評估器與資料映射
當你評估追蹤時,服務會自動從 OpenTelemetry 的 span 屬性中擷取對話資料。 直接使用這些欄位名稱 data_mapping (在其他情境中不使用 item. 或 sample. 前綴):
| 變數 | 來源屬性 | 描述 |
|---|---|---|
{{item.query}} |
gen_ai.input.messages (使用者/系統角色) |
從追蹤中提取的使用者查詢。 |
{{item.response}} |
gen_ai.input.messages(助理/工具角色)+ gen_ai.output.messages |
從追蹤中提取的代理程式回應。 |
{{item.tool_definitions}} |
gen_ai.tool.definitions |
代理可存取的工具架構。 僅工具相關評估工具需要。 |
{{item.tool_calls}} |
從助理訊息擷取 gen_ai.input.messages / gen_ai.output.messages |
代理人在互動過程中進行的工具呼叫。 由工具評估工具使用。 僅工具相關評估工具需要。 |
testing_criteria = [
# Quality evaluators — require query and response from trace data
{
"type": "azure_ai_evaluator",
"name": "intent_resolution",
"evaluator_name": "builtin.intent_resolution",
"data_mapping": {
"query": "{{item.query}}",
"response": "{{item.response}}",
"tool_definitions": "{{item.tool_definitions}}",
},
"initialization_parameters": {
"model": model_deployment_name,
},
},
# Tool evaluators — assess tool usage quality
{
"type": "azure_ai_evaluator",
"name": "tool_call_accuracy",
"evaluator_name": "builtin.tool_call_accuracy",
"data_mapping": {
"query": "{{item.query}}",
"response": "{{item.response}}",
"tool_calls": "{{item.tool_calls}}",
"tool_definitions": "{{item.tool_definitions}}",
},
"initialization_parameters": {
"model": model_deployment_name,
},
},
# Safety evaluators — work even with partial trace data
{
"type": "azure_ai_evaluator",
"name": "violence",
"evaluator_name": "builtin.violence",
"data_mapping": {
"query": "{{item.query}}",
"response": "{{item.response}}",
},
"initialization_parameters": {
"threshold": 4,
},
},
]
完整可執行範例請參見GitHub上的 sample_evaluations_builtin_with_traces.py。 若要進行投票完成並解讀結果,請參閱 「取得結果」。
合成資料評估(預覽)
利用資料來源 azure_ai_synthetic_data_gen_preview 類型產生合成測試查詢,發送給已部署的模型或 Foundry 代理,並評估回應。 當你沒有測試資料集時,可以使用這個情境。 該服務會根據你提供的提示(和/或代理人的指示)產生查詢,然後針對你的目標執行,並評估回應。
提示
在開始之前,請先完成「 開始」。
綜合資料評估的運作方式
- 該服務會根據你
prompt和可選的種子資料檔案產生合成查詢。 - 每個查詢都會發送給指定的目標(模型或代理人)以產生回應。
- 評估者會利用產生的查詢與回應來評分每個回應。
- 產生的查詢會以資料集形式儲存在您的專案中,供重複使用。
參數
| 參數 | 必需的 | 描述 |
|---|---|---|
samples_count |
是的 | 最多可產生的合成測試查詢數量。 |
model_deployment_name |
是的 | 建模部署以產生合成查詢。 僅支援具備回應 API 功能的模型。 關於可用性,請參見 回應 API 區域可用性。 |
prompt |
不 | 指示描述要產生的查詢類型。 當代理目標已設定指令時,則為可選。 |
output_dataset_name |
不 | 輸出資料集的名稱,用於儲存產生的查詢。 如果你沒有提供名稱,服務會自動產生一個名稱。 |
sources |
不 | 依檔案 ID 建立種子資料檔案,以提升產生查詢的相關性。 目前僅支援一個檔案。 |
設置評估器與資料映射
合成資料產生器會在{{item.query}}欄位提出查詢。 目標會產生可於{{sample.output_text}}中使用的回覆。 將這些欄位對應到您的評估工具:
data_source_config = {"type": "azure_ai_source", "scenario": "synthetic_data_gen_preview"}
testing_criteria = [
{
"type": "azure_ai_evaluator",
"name": "coherence",
"evaluator_name": "builtin.coherence",
"initialization_parameters": {
"model": model_deployment_name,
},
"data_mapping": {
"query": "{{item.query}}",
"response": "{{sample.output_text}}",
},
},
{
"type": "azure_ai_evaluator",
"name": "violence",
"evaluator_name": "builtin.violence",
"data_mapping": {
"query": "{{item.query}}",
"response": "{{sample.output_text}}",
},
},
]
建立評估並執行
模型目標
產生綜合查詢並評估模型:
eval_object = openai_client.evals.create(
name="Synthetic Data Evaluation",
data_source_config=data_source_config,
testing_criteria=testing_criteria,
)
data_source = {
"type": "azure_ai_synthetic_data_gen_preview",
"item_generation_params": {
"type": "synthetic_data_gen_preview",
"samples_count": 5,
"prompt": "Generate customer service questions about returning defective products",
"model_deployment_name": model_deployment_name,
"output_dataset_name": "my-synthetic-dataset",
},
"target": {
"type": "azure_ai_model",
"model": model_deployment_name,
},
}
eval_run = openai_client.evals.runs.create(
eval_id=eval_object.id,
name="synthetic-data-evaluation",
data_source=data_source,
)
你可以選擇性地新增系統提示來塑造目標模型的行為。 當您將 input_messages 與合成資料產生搭配使用時,僅包含 system 角色訊息——服務會自動以使用者訊息的形式提供產生的查詢。
data_source = {
"type": "azure_ai_synthetic_data_gen_preview",
"item_generation_params": {
"type": "synthetic_data_gen_preview",
"samples_count": 5,
"prompt": "Generate customer service questions about returning defective products",
"model_deployment_name": model_deployment_name,
},
"target": {
"type": "azure_ai_model",
"model": model_deployment_name,
},
"input_messages": {
"type": "template",
"template": [
{
"type": "message",
"role": "system",
"content": {
"type": "input_text",
"text": "You are a helpful customer service agent. Be empathetic and solution-oriented."
}
}
]
},
}
代理目標
生成合成請求並評估 Foundry 代理程式:
data_source = {
"type": "azure_ai_synthetic_data_gen_preview",
"item_generation_params": {
"type": "synthetic_data_gen_preview",
"samples_count": 5,
"prompt": "Generate questions about returning defective products",
"model_deployment_name": model_deployment_name,
},
"target": {
"type": "azure_ai_agent",
"name": agent_name,
"version": agent_version,
},
}
eval_run = openai_client.evals.runs.create(
eval_id=eval_object.id,
name="synthetic-agent-evaluation",
data_source=data_source,
)
若要進行投票完成並解讀結果,請參閱 「取得結果」。 回應包含 output_dataset_id 一個屬性,包含產生資料集的 ID,你可以用它來檢索或重用合成資料。
對話層級評估(預覽)
評估完整的對話,以評估整個用戶互動中客服人員的品質——而非僅僅是個別回應。 利用對話層級評估來識別品質問題,例如任務解決不完整、使用者挫折感,以及工具呼叫迴歸,這些都是輪流層級評估忽略的。
例如,設想一位支援客服人員的情境:使用者在經過多輪對話後變得愈來愈沮喪:
第一回合 — 使用者:「我需要重設密碼。」經紀人:「我找到你的帳戶了。 我會寄一個重置連結。」
第二回合 — 使用者:「我沒收到那封郵件。」特工:「我已經重新發送連結。 請檢查垃圾郵件。」
第三回合 — 使用者:「還是沒反應。 你能直接重置嗎?」特工:「我又發送了另一個重置連結。」
回合級評估者只評分最後一個有禮貌且採取行動的回應,因此得分較高。 對話層級評估器在對話中評分 客戶滿意 度,卻發現客服重複了三次同樣失敗的操作,且未嘗試替代方案,導致用戶問題未解決。
對話層級評估與回合層級評估在幾個方面有所差異:
| 層面 | 回合層級 | 會話層級 |
|---|---|---|
| 範圍 | 個別查詢回應配對 | 完整的對話,包含多重交換 |
| Metrics | 每次回應的品質與安全性 | 對話層級的成果與使用者滿意度 |
| 資料格式 | 包含 query 和 response 欄位的 JSONL |
包含完整交談之 messages 陣列的 JSONL |
| 應用案例 | 測試個別模型的回應 | 測試端對端代理體驗 |
對話層級評估支援四種資料來源選項:
| Option | 何時使用 | 資料來源類型 |
|---|---|---|
| 來自資料集或內嵌 | 你有本地對話追蹤或測試資料 |
jsonl 搭配 file_id 或 file_content |
| 依對話識別碼分類 | 您想要評估 App Insights 的特定對話 |
azure_ai_trace_data_source_preview 和 trace_source |
| 依代理程式篩選與取樣 | 您想要評估取樣生產流量中的整體 Agent 品質 |
azure_ai_trace_data_source_preview 和 trace_source |
| 模擬對話 | 你想要產生合成測試對話 |
azure_ai_target_completions 和 conversation_gen_preview |
選擇評估層級
執行時的 evaluation_level 參數決定評估者評分的是個別回合還是完整對話:
| 價值 | 行為 |
|---|---|
"turn" |
評估者每回合獨立評分。 |
"conversation" |
評估員會對整場對話進行評分。 |
| (省略) | 預設為 "turn"。 |
重要
評估員相容性:每位評估員都支持特定的評估等級。 請在supported_evaluation_levels中查閱評估員的欄位。
-
僅限回合的評估器(例如
fluency、relevance)不能與evaluation_level="conversation"搭配使用。 - 目前,所有對話層級評估器都同時支援
"turn"和"conversation"層級。
常見錯誤
| 錯誤 | 原因 | 解決方案 |
|---|---|---|
| 不相容的評估等級 | 搭配僅限回合評估工具使用 evaluation_level="conversation" |
移除僅限回合的評估器,或改為 evaluation_level="turn" |
準備對話資料
建立一個 JSONL 檔案,其中每一行都在 messages 欄位中包含一則完整的對話。 每則訊息應包含一個 role (使用者、助理或系統)和 content。 完整範例請參考 SDK 中的 conversation evaluation samples:
{"messages": [{"role": "user", "content": "What's my account balance?"}, {"role": "assistant", "content": "Your current balance is $1,234.56."}, {"role": "user", "content": "Thanks!"}, {"role": "assistant", "content": "You're welcome! Is there anything else?"}]}
如果你的客服人員使用工具,也可以包含工具定義和工具呼叫:
{"messages": [{"role": "user", "content": "What is the capital of France?"}, {"role": "assistant", "content": "Paris"}]}
{"messages": [{"role": "user", "content": "How do I reverse a string in Python?"}, {"role": "assistant", "content": "You can reverse a string in Python by using slicing: string[::-1]"}]}
{"messages": [{"role": "user", "content": "What are the main causes of climate change?"}, {"role": "assistant", "content": "The main causes of climate change are the increase in greenhouse gases in the atmosphere, primarily due to human activities such as burning fossil fuels and deforestation."}]}
{"messages": [{"role": "user", "content": "What's my account balance?"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "call_abc123", "type": "function", "function": {"name": "get_account_balance", "arguments": "{\"account_id\": \"ACCT-7890\"}"}}]}, {"role": "tool", "tool_call_id": "call_abc123", "content": "{ \"balance\": 1234.56, \"currency\": \"USD\" }"}, {"role": "assistant", "content": "Your current balance is 1,234.56."}, {"role": "user", "content": "Thanks!"}, {"role": "assistant", "content": "You're welcome! Is there anything else?"}], "tool_definitions": [{"name": "get_account_balance", "description": "Retrieves the current balance for a customer account", "parameters": {"type": "object", "properties": {"account_id": {"type": "string"}}, "required": ["account_id"]}}]}
{"messages": [{"role": "user", "content": "Explain the theory of relativity in simple terms."}, {"role": "assistant", "content": "Einstein's theory of relativity shows that space and time are interconnected and relative to the observer's frame of reference."}]}
{"messages": [{"role": "user", "content": "What's the weather in Seattle?"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "call_002", "type": "function", "function": {"name": "get_weather", "arguments": "{\"location\": \"Seattle, WA\"}"}}]}, {"role": "tool", "tool_call_id": "call_002", "content": "{ \"temperature\": 55, \"condition\": \"Cloudy\" }"}, {"role": "assistant", "content": "It's currently 55F and cloudy in Seattle."}], "tool_definitions": [{"name": "get_weather", "description": "Get the current weather for a location", "parameters": {"type": "object", "properties": {"location": {"type": "string"}}, "required": ["location"]}}]}
{"messages": [{"role": "user", "content": "What is the tallest mountain in the world?"}, {"role": "assistant", "content": "Mount Everest is the tallest mountain in the world."}]}
{"messages": [{"role": "user", "content": "Is 4 x 2 = 16?"}, {"role": "assistant", "content": "No, 4 x 2 = 8."}]}
{"messages": [{"role": "user", "content": "What is the best Italian desert?"}, {"role": "assistant", "content": "Tiramisu is a popular Italian dessert."}]}
{"messages": [{"role": "user", "content": "What is the chemical formula for water?"}, {"role": "assistant", "content": "The chemical formula for water is H2O."}]}
定義資料結構與評估器
指定對話資料的架構、「訊息」,並選擇專為對話層級評估設計的評估器。 對話層級評估器會針對整個互動進行評估,而非針對個別回合。
pip install "azure-ai-projects>=2.2.0"
import os
from openai.types.eval_create_params import DataSourceConfigCustom
from azure.identity import DefaultAzureCredential
from azure.ai.projects import AIProjectClient
from azure.ai.projects.models import TestingCriterionAzureAIEvaluator
endpoint = os.environ["FOUNDRY_PROJECT_ENDPOINT"]
model_deployment_name = os.environ["FOUNDRY_MODEL_NAME"]
with (
DefaultAzureCredential() as credential,
AIProjectClient(endpoint=endpoint, credential=credential) as project_client,
project_client.get_openai_client() as openai_client,
):
data_source_config = DataSourceConfigCustom(
type="custom",
item_schema={
"type": "object",
"properties": {
"messages": {"type": "array"},
"tool_definitions": {"type": "array"},
},
"required": ["messages"],
},
include_sample_schema=False,
)
testing_criteria = [
TestingCriterionAzureAIEvaluator(
type="azure_ai_evaluator",
name="customer_satisfaction",
evaluator_name="builtin.customer_satisfaction",
initialization_parameters={"model": model_deployment_name},
data_mapping={"messages": "{{item.messages}}"},
),
TestingCriterionAzureAIEvaluator(
type="azure_ai_evaluator",
name="task_completion",
evaluator_name="builtin.task_completion",
initialization_parameters={"model": model_deployment_name},
data_mapping={"messages": "{{item.messages}}"},
),
TestingCriterionAzureAIEvaluator(
type="azure_ai_evaluator",
name="conversation_coherence",
evaluator_name="builtin.coherence",
initialization_parameters={"model": model_deployment_name},
data_mapping={"messages": "{{item.messages}}"},
),
TestingCriterionAzureAIEvaluator(
type="azure_ai_evaluator",
name="groundedness",
evaluator_name="builtin.groundedness",
initialization_parameters={"model": model_deployment_name},
data_mapping={"messages": "{{item.messages}}"},
),
]
建立評估並執行
準備:下載 sample_data_multiturn_conversations.jsonl
from openai.types.evals.create_eval_jsonl_run_data_source_param import (
CreateEvalJSONLRunDataSourceParam,
SourceFileID,
)
# Upload conversation data
data_id = project_client.datasets.upload_file(
name="multiturn-conversation-data",
version="1",
file_path="./sample_data_multiturn_conversations.jsonl",
).id
# Create the evaluation
eval_object = openai_client.evals.create(
name="Multi-turn Conversation Evaluation",
data_source_config=data_source_config,
testing_criteria=testing_criteria,
)
# Create a run with evaluation_level set to "conversation"
eval_run = openai_client.evals.runs.create(
eval_id=eval_object.id,
name="multiturn-conversation-run",
data_source=CreateEvalJSONLRunDataSourceParam(
type="jsonl",
source=SourceFileID(
type="file_id",
id=data_id,
),
),
extra_body={"evaluation_level": "conversation"},
)
若要進行投票完成並解讀結果,請參閱 「取得結果」。
依追蹤中的 ID 評估交談
透過提供對話識別碼,評估 Application Insights 中的特定對話。 使用此選項來找出問題根源或驗證特定互動的修復方法。 例如,你可以調查被警示標記的對話,或驗證已知問題的修復方法。
在哪裡可以找到對話 ID
在以下內容中尋找對話 ID:
-
Application Insights 追蹤日誌 UI — 瀏覽有趣的追蹤記錄,並在追蹤細節中找到該
conversation_id欄位。 -
你的應用程式日誌輸出 — 如果你在建立代理回應時明確設定
conversation_id,請從日誌中取得。 -
OpenTelemetry 追蹤內容 — 如果您的 Agent 使用標準追蹤內容傳播,
conversation_id也可能衍生自 traceparent 標頭。
註
工具定義會自動從追蹤線中擷取或從代理登錄檔查詢。 你不需要在申請時提供這些資料。
查詢對話 ID 的參數
| 參數 | 必需的 | 描述 |
|---|---|---|
conversation_ids |
是的 | 用於評估的對話 ID 陣列。 |
lookback_hours |
不 | 從 end_time 往回搜尋的小時數。 預設為七天(168小時)。 |
end_time |
不 | 搜尋視窗結束(ISO 8601格式)。 預設值為當前時間。 |
import os
from azure.identity import DefaultAzureCredential
from azure.ai.projects import AIProjectClient
from azure.ai.projects.models import TestingCriterionAzureAIEvaluator
endpoint = os.environ["FOUNDRY_PROJECT_ENDPOINT"]
model_deployment_name = os.environ["FOUNDRY_MODEL_NAME"]
# Provide conversation IDs or trace IDs from App Insights
conversation_ids = ["conversation_1234", "conversation_5678"]
with (
DefaultAzureCredential() as credential,
AIProjectClient(endpoint=endpoint, credential=credential) as project_client,
project_client.get_openai_client() as openai_client,
):
# Eval group for trace-based evaluations
data_source_config = {
"type": "azure_ai_source",
"scenario": "traces",
}
testing_criteria = [
TestingCriterionAzureAIEvaluator(
type="azure_ai_evaluator",
name="customer_satisfaction",
evaluator_name="builtin.customer_satisfaction",
initialization_parameters={"model": model_deployment_name},
data_mapping={"messages": "{{item.messages}}"},
),
TestingCriterionAzureAIEvaluator(
type="azure_ai_evaluator",
name="task_completion",
evaluator_name="builtin.task_completion",
initialization_parameters={"model": model_deployment_name},
data_mapping={"messages": "{{item.messages}}"},
),
TestingCriterionAzureAIEvaluator(
type="azure_ai_evaluator",
name="conversation_coherence",
evaluator_name="builtin.coherence",
initialization_parameters={"model": model_deployment_name},
data_mapping={"messages": "{{item.messages}}"},
),
TestingCriterionAzureAIEvaluator(
type="azure_ai_evaluator",
name="groundedness",
evaluator_name="builtin.groundedness",
initialization_parameters={"model": model_deployment_name},
data_mapping={"messages": "{{item.messages}}"},
),
]
# Create evaluation with traces scenario
eval_object = openai_client.evals.create(
name="Multi-turn Trace Evaluation (by ID)",
data_source_config=data_source_config,
testing_criteria=testing_criteria,
)
# Run evaluation on specific conversation IDs
eval_run = openai_client.evals.runs.create(
eval_id=eval_object.id,
name="multiturn-trace-by-id-run",
data_source={
"type": "azure_ai_trace_data_source_preview",
"trace_source": {
"type": "conversation_id_source",
"conversation_ids": conversation_ids,
},
},
extra_body={"evaluation_level": "conversation"},
)
註
- Application Insights 資料擷取可能會在追蹤產生與可用於評估之間造成延遲。 如果查詢找不到痕跡,就等幾分鐘再試一次。
- 最長回溯時間為7天(168小時)。 若要存取較舊的追蹤資料,請在您 App Insights 的保留期限限制內使用
start_time和end_time。
透過代理人過濾器評估抽樣對話
透過篩選代理人名稱,評估 Application Insights 中抽樣的對話。 使用此選項來評估生產流量中的整體 Agent 品質。 例如,定期進行品質評估或監控生產過程中的品質下降。
你指定的篩選代理可以是多代理對話的一部分。 篩選器會匹配該客服參與的任何對話。
註
工具定義會自動從追蹤線中擷取或從代理登錄檔查詢。 你不需要在申請時提供這些資料。
代理人身份欄位
請使用以下格式之一指定要篩選的代理人:
| Format | Example | 描述 |
|---|---|---|
agent_name + agent_version |
"agent_name": "my-agent", "agent_version": "1" |
兩個不同的領域。 若 agent_version 未包含,請使用最新版本。 |
agent_id |
"agent_id": "my-agent:1" |
採用 "name:version" 格式的單一字串。 |
濾波策略
| 策略 | 描述 |
|---|---|
random_sampling |
(預設)對最多 max_traces 筆對話進行均勻隨機抽樣。 |
smart_filtering |
服務受控啟發式方法,會偏向「有趣」追蹤 — 具有潛在問題、邊緣案例或異常的交談。 |
參數
| 參數 | 必需的 | 描述 |
|---|---|---|
agent_name |
是的 | 用於篩選追蹤的代理程式名稱。 |
agent_version |
不 | 代理程式版本。 如果省略,請使用最新版本。 |
agent_id |
不 | 的 agent_name + agent_version替代方案。 採用 "name:version" 格式的單一字串。 |
start_time |
是的 | 時間窗口的開始(Unix 紀元秒,UTC)。 |
end_time |
是的 | 時間窗口結束(Unix 紀元秒,UTC)。 填補 +600 秒以避免擷取延遲。 |
max_traces |
不 | 可取樣的對話數量上限。 預設值為 1,000。 |
filter_strategy |
不 |
"random_sampling" (預設) 或 "smart_filtering" (服務受控啟發式方法,會偏向有趣追蹤)。 |
重要
時間窗口end_time - start_time()必須至少為 15分鐘 (900秒)。 之所以有此要求,是因為對話層級查詢會在兩端各套用 5 分鐘的無活動緩衝時間,以避免將不完整的對話納入。
import os
import time
from azure.identity import DefaultAzureCredential
from azure.ai.projects import AIProjectClient
from azure.ai.projects.models import TestingCriterionAzureAIEvaluator
endpoint = os.environ["FOUNDRY_PROJECT_ENDPOINT"]
model_deployment_name = os.environ["FOUNDRY_MODEL_NAME"]
agent_name = os.environ["FOUNDRY_AGENT_NAME"]
agent_version = os.environ.get("FOUNDRY_AGENT_VERSION", "")
with (
DefaultAzureCredential() as credential,
AIProjectClient(endpoint=endpoint, credential=credential) as project_client,
project_client.get_openai_client() as openai_client,
):
# Eval group for trace-based evaluations
data_source_config = {
"type": "azure_ai_source",
"scenario": "traces",
}
testing_criteria = [
TestingCriterionAzureAIEvaluator(
type="azure_ai_evaluator",
name="customer_satisfaction",
evaluator_name="builtin.customer_satisfaction",
initialization_parameters={"model": model_deployment_name},
data_mapping={"messages": "{{item.messages}}"},
),
TestingCriterionAzureAIEvaluator(
type="azure_ai_evaluator",
name="task_completion",
evaluator_name="builtin.task_completion",
initialization_parameters={"model": model_deployment_name},
data_mapping={"messages": "{{item.messages}}"},
),
TestingCriterionAzureAIEvaluator(
type="azure_ai_evaluator",
name="conversation_coherence",
evaluator_name="builtin.coherence",
initialization_parameters={"model": model_deployment_name},
data_mapping={"messages": "{{item.messages}}"},
),
TestingCriterionAzureAIEvaluator(
type="azure_ai_evaluator",
name="groundedness",
evaluator_name="builtin.groundedness",
initialization_parameters={"model": model_deployment_name},
data_mapping={"messages": "{{item.messages}}"},
),
]
eval_object = openai_client.evals.create(
name="Multi-turn Trace Evaluation (Agent Filter)",
data_source_config=data_source_config,
testing_criteria=testing_criteria,
)
# Compute time window in unix seconds
# Pad end_time by +600s (10 min) to avoid ingestion-delay edge exclusion
now_unix = int(time.time())
end_time = now_unix + 600
start_time = now_unix - (24 * 3600) # 24 hours lookback
# Build trace_source with agent filter
trace_source = {
"type": "agent_filter",
"agent_name": agent_name,
"start_time": start_time,
"end_time": end_time,
"max_traces": 5,
}
if agent_version:
trace_source["agent_version"] = agent_version
# Run evaluation on sampled agent conversations
eval_run = openai_client.evals.runs.create(
eval_id=eval_object.id,
name="multiturn-agent-filter-run",
data_source={
"type": "azure_ai_trace_data_source_preview",
"trace_source": trace_source,
},
extra_body={"evaluation_level": "conversation"},
)
註
App Insights 的查詢時間目前限制為最多 7 天(168 小時)。 若未明確提供位於 App Insights 保留期限範圍內的 start_time 和 end_time,你就無法存取 7 天前的追蹤記錄。
若要進行投票完成並解讀結果,請參閱 「取得結果」。
會話模擬
從情境描述中產生模擬對話,並在對話層級進行評估。 利用此情境測試代理在受控情境下的行為,然後再部署。 該服務會根據你的情境描述產生真實的對話,然後進行評估。
此方法適用於:
- 部署前測試:驗證代理在不同情境下的行為,無需真實用戶流量。
- 邊緣案例涵蓋範圍:測試自然很少發生但需要妥善處理的重要案例。
- 迴歸測試:確保代理更新不會在已知情境下降低效能。
- 規模化測試:快速產生大量對話,對代理的能力進行壓力測試。
對話模擬的運作方式
- 你提供一個情境描述的資料集——每一列描述模擬使用者嘗試達成的情境。
- 該服務使用模擬器模型扮演使用者的角色,根據情境與你的代理互動。
- 每個情境都會產生一個或多個完整的對話。
- 對話層級評估器會評估生成的對話。
- 你的專案同時儲存對話內容和評估結果。
準備情境資料
建立一個 JSONL 檔案,每行描述模擬使用者的情境。 該結構描述必須有 id、test_case_description 和 desired_num_turns。 包含使用者的目標、背景及任何限制細節。 完整範例請參閱SDK中的conversation evaluation samples。
{"id": "contoso_refund_timeline", "test_case_description": "Customer returned an item to Contoso Electronics 5 days ago and hasn't received their refund yet. They want to know how long Contoso refunds take.", "desired_num_turns": 10}
{"id": "contoso_store_hours_lookup", "test_case_description": "Customer wants to know what time the Contoso Electronics store closes today. Simple single-fact question with possibly one clarifying turn about which location.", "desired_num_turns": 3}
參數
| 參數 | 必需的 | 描述 |
|---|---|---|
num_conversations |
不 | 每個情境要產生多少次對話。 預設為 5,伺服器端上限為 5。 |
max_turns |
不 | 每場對話的最大回合數(交換)。 預設是 10,伺服器端上限是 20。 |
model |
是的 | 用於模擬使用者的模型部署。 例如: gpt-4.1 。 |
sampling_params |
不 | 模擬器模型的取樣參數,包括temperature、、 top_pmax_completion_tokens和 。 |
data_mapping |
不 | 將你的情境 JSONL 欄位映射到模擬參數。 常見映射: test_case_description, id, desired_num_turns。 |
定義評估者
選擇專為對話層級評估設計的評估器。 模擬對話會自動映射至評估者。
import os
from openai.types.eval_create_params import DataSourceConfigCustom
from azure.identity import DefaultAzureCredential
from azure.ai.projects import AIProjectClient
from azure.ai.projects.models import TestingCriterionAzureAIEvaluator, PromptAgentDefinition
endpoint = os.environ["FOUNDRY_PROJECT_ENDPOINT"]
model_deployment_name = os.environ["FOUNDRY_MODEL_NAME"]
agent_name = os.environ.get("FOUNDRY_AGENT_NAME", "")
with (
DefaultAzureCredential() as credential,
AIProjectClient(endpoint=endpoint, credential=credential) as project_client,
project_client.get_openai_client() as openai_client,
):
# Simulation uses the same "custom" eval group type as dataset evaluation (S1),
# since the generated conversations follow the same messages schema.
data_source_config = DataSourceConfigCustom(
type="custom",
item_schema={
"type": "object",
"properties": {
"messages": {"type": "array"},
},
"required": ["messages"],
},
include_sample_schema=False,
)
testing_criteria = [
TestingCriterionAzureAIEvaluator(
type="azure_ai_evaluator",
name="customer_satisfaction",
evaluator_name="builtin.customer_satisfaction",
initialization_parameters={"model": model_deployment_name},
data_mapping={"messages": "{{item.messages}}"},
),
TestingCriterionAzureAIEvaluator(
type="azure_ai_evaluator",
name="task_completion",
evaluator_name="builtin.task_completion",
initialization_parameters={"model": model_deployment_name},
data_mapping={"messages": "{{item.messages}}"},
),
TestingCriterionAzureAIEvaluator(
type="azure_ai_evaluator",
name="conversation_coherence",
evaluator_name="builtin.coherence",
initialization_parameters={"model": model_deployment_name},
data_mapping={"messages": "{{item.messages}}"},
),
TestingCriterionAzureAIEvaluator(
type="azure_ai_evaluator",
name="groundedness",
evaluator_name="builtin.groundedness",
initialization_parameters={"model": model_deployment_name},
data_mapping={"messages": "{{item.messages}}"},
),
]
建立評估並執行
準備:下載 sample_data_simulation_scenarios.jsonl。
# Create (or update) an agent to simulate against
agent = project_client.agents.create_version(
agent_name=agent_name,
definition=PromptAgentDefinition(
model=model_deployment_name,
instructions="You are a helpful customer service agent. Be empathetic and solution-oriented.",
),
)
# Upload scenario data
scenarios_id = project_client.datasets.upload_file(
name="simulation-scenarios",
version="1",
file_path="./sample_data_simulation_scenarios.jsonl",
).id
# Create the evaluation
eval_object = openai_client.evals.create(
name="Multi-turn Conversation Simulation",
data_source_config=data_source_config,
testing_criteria=testing_criteria,
)
# Create a simulation run
eval_run = openai_client.evals.runs.create(
eval_id=eval_object.id,
name="conversation-simulation-run",
data_source={
"type": "azure_ai_target_completions",
"source": {
"type": "file_id",
"id": scenarios_id,
},
"target": {
"type": "azure_ai_agent",
"name": agent.name,
"version": agent.version,
},
"item_generation_params": {
"type": "conversation_gen_preview",
"model": model_deployment_name,
"num_conversations": 2,
"max_turns": 5,
"sampling_params": {
"temperature": 0.7,
"top_p": 1.0,
"max_completion_tokens": 800,
},
"data_mapping": {
"test_case_description": "test_case_description",
"id": "id",
"desired_num_turns": "desired_num_turns",
},
},
},
extra_body={"evaluation_level": "conversation"},
)
若要進行投票完成並解讀結果,請參閱 「取得結果」。
取得成果
評估運行結束後,取得評分結果,並在入口網站或以程式方式檢視。
輪詢結果
評估執行是非同步的。 持續檢查運行狀態直到完成,然後取得結果。
import time
from pprint import pprint
while True:
run = openai_client.evals.runs.retrieve(
run_id=eval_run.id, eval_id=eval_object.id
)
if run.status in ("completed", "failed"):
break
time.sleep(5)
print("Waiting for eval run to complete...")
# Retrieve results
output_items = list(
openai_client.evals.runs.output_items.list(
run_id=run.id, eval_id=eval_object.id
)
)
pprint(output_items)
print(f"Report URL: {run.report_url}")
解讀結果
對於單一資料範例,所有評估器都會輸出以下模式:
- 標籤:一個二進位的「通過」或「失敗」標籤,類似單元測試的輸出。 利用此結果促進評估者間的比較。
- 分數:根據每位評鑑者的自然量表計算的分數。 部分評估人員採用細緻的評分標準,評分標準為5分制(品質評估員)或7分制(內容安全評估員)。 其他如文本相似度評估器則使用 F1 分數,即介於 0 到 1 之間的浮點數。 任何非二元 "score" 都會根據 "threshold",在 "label" 欄位中二值化為 "pass" 或 "fail"。
- 門檻:任何非二元分數都會依據預設門檻轉換為「通過」或「失敗」,而使用者可在 SDK 中覆寫此門檻值。
- 理由:為了提升可理解性,所有 LLM 評審也會輸出一個推理欄位,說明為何給出某個分數。
- 細節:(可選)對於某些評估器,如 tool_call_accuracy,可能會有一個「詳情」欄位或旗標,包含更多資訊以協助使用者除錯應用程式。
範例輸出(單一項目)
{
"type": "azure_ai_evaluator",
"name": "Coherence",
"metric": "coherence",
"score": 4.0,
"label": "pass",
"reason": "The response is well-structured and logically organized, presenting information in a clear and coherent manner.",
"threshold": 3,
"passed": true
}
範例輸出(聚合)
對於多個資料範例 (資料集) 的彙總結果,具有「通過」標記之範例的平均比率即為該資料集的合格率。
{
"eval_id": "eval_abc123",
"run_id": "run_xyz789",
"status": "completed",
"result_counts": {
"passed": 85,
"failed": 15,
"total": 100
},
"per_testing_criteria_results": [
{
"name": "coherence",
"passed": 92,
"failed": 8,
"pass_rate": 0.92
},
{
"name": "relevance",
"passed": 78,
"failed": 22,
"pass_rate": 0.78
}
]
}
故障排除
工作執行時間過長
你的評估工作可能會在 運行 狀態內停留較長時間。 此狀況通常發生在 Azure OpenAI 模型部署容量不足時,導致服務重試請求。
解決:
- 使用
openai_client.evals.runs.cancel(run_id, eval_id=eval_id)取消目前的評估工作。 - 增加 Azure 入口網站中的模型容量。
- 再做一次評估。
認證錯誤
若收到 401 Unauthorized OR 403 Forbidden 錯誤,請確認:
- 你的
DefaultAzureCredential設定是正確的。 如果你用的是Azure CLI,請執行az login。 - 你的帳號在 Foundry 專案中擁有 Foundry User 角色。
- 專案端點的網址是正確的,包含帳號和專案名稱。
資料格式錯誤
若評估因結構或資料映射錯誤而失敗:
- 確認你的 JSONL 檔案每行只有一個有效的 JSON 物件。
- 確認欄位名稱
data_mapping是否與你的 JSONL 檔案欄位名稱完全一致(大小寫區分)。 - 檢查屬性是否
item_schema與資料集中的欄位相符。
速率限制錯誤
租用戶、訂用帳戶和專案層級會限制評估執行建立速率。 如果您收到 429 Too Many Requests 的回應:
- 請查看
retry-after回覆中的標頭,了解建議的等待時間。 - 請查看回應文以了解費率限制的細節。
- 重試失敗的請求時,使用指數退避。
若評估工作在執行過程中發生 429 錯誤失敗:
- 縮小評估資料集的大小,或將其拆分成較小的批次。
- 在 Azure 入口網站中增加模型部署的每分鐘權杖數 (TPM) 配額。
代理程式評估工具錯誤
如果代理評估器回傳不支援的工具的錯誤:
- 請查看 經紀人評估員所支援的工具 。
- 作為一個變通方法,將未支援的工具包裝成使用者定義的功能工具,讓評估者能自行評估。