評価を実行して結果を表示する方法
重要
この機能はパブリック プレビュー段階にあります。
この記事では、AI アプリケーションの開発時に評価を実行し、結果を表示する方法について説明します。 運用トラフィックでデプロイされたエージェントの品質を監視する方法については、「 運用トラフィックでエージェントの品質を監視する方法を参照してください。
アプリの開発中にエージェント評価を使用するには、評価セットを指定する必要があります。 評価セットは、ユーザーがアプリケーションに対して行う一連の一般的な要求です。 評価セットには、各入力要求に対して予想される応答 (グラウンド・トゥルース) を含めることもできます。 予想される応答が提供された場合、エージェント評価では、正確性やコンテキスト不足などの追加の品質メトリックを計算できます。 評価セットの目的は、代表的な質問でテストすることでユーザーがエージェント アプリケーションのパフォーマンスの測定と予測を行うことができるようにすることです。
評価セットの詳細については、 評価セットを参照してください。 必要なスキーマについては、 Agent Evaluation 入力スキーマを参照してください。
評価を開始するには、MLflow API の mlflow.evaluate()
メソッドを使います。 mlflow.evaluate()
は、評価セット内の各入力の待機時間とコストメトリックと共に品質評価を計算し、すべての入力にわたってこれらの結果を集計します。 これらの結果は、評価結果とも呼ばれます。 次に示すコードは、mlflow.evaluate()
の呼び出しの例です。
%pip install databricks-agents
dbutils.library.restartPython()
import mlflow
import pandas as pd
eval_df = pd.DataFrame(...)
# Puts the evaluation results in the current Run, alongside the logged model parameters
with mlflow.start_run():
logged_model_info = mlflow.langchain.log_model(...)
mlflow.evaluate(data=eval_df, model=logged_model_info.model_uri,
model_type="databricks-agent")
この例では、 mlflow.evaluate()
、その評価結果を囲む MLflow 実行と、他のコマンド (モデル パラメーターなど) によってログに記録される情報をログに記録します。 MLflow 実行の外部で mlflow.evaluate()
を呼び出すと、新しい実行が開始して、評価結果がその実行でログに記録されます。 実行に記録される評価結果の詳細など、mlflow.evaluate()
の詳細については、MLflow のドキュメントをご覧ください。
要件
Azure AI 搭載の AI 支援機能をワークスペースで有効にする必要があります。
評価実行に対して入力を指定する方法
評価実行に対して入力を指定するには、次の 2 つの方法があります。
前に生成された出力を指定して、評価セットと比較します。 このオプションは、既に運用環境にデプロイされているアプリケーションからの出力を評価する場合、または評価構成間で評価結果を比較する場合に推奨されます。
このオプションでは、次のコードに示すように評価セットを指定します。 評価セットには、以前に生成された出力が含まれている必要があります。 詳細な例については、「 Example: 以前に生成された出力をエージェント評価に渡す方法を参照してください。
evaluation_results = mlflow.evaluate( data=eval_set_with_chain_outputs_df, # pandas DataFrame with the evaluation set and application outputs model_type="databricks-agent", )
アプリケーションを入力引数として渡します。
mlflow.evaluate()
評価セット内の入力ごとにアプリケーションを呼び出し、生成された各出力の品質評価とその他のメトリックを報告します。 このオプションは、MLflow トレースが有効になっている MLflow を使ってアプリケーションがログされている場合、またはアプリケーションがノートブックの Python 機能として実装されている場合に推奨されます。 アプリケーションが Databricks の外部で開発された場合、または Databricks の外部にデプロイされている場合は、このオプションは推奨されません。このオプションでは、次のコードに示すように、関数呼び出しで評価セットとアプリケーションを指定します。 詳細な例については、「 Example: アプリケーションを Agent Evaluation に渡す方法」を参照してください。
evaluation_results = mlflow.evaluate( data=eval_set_df, # pandas DataFrame containing just the evaluation set model=model, # Reference to the MLflow model that represents the application model_type="databricks-agent", )
評価セット スキーマの詳細については、「 Agent Evaluation 入力スキーマを参照してください。
評価の出力
エージェント評価では、 mlflow.evaluate()
からの出力がデータフレームとして返され、これらの出力も MLflow 実行に記録されます。 出力は、ノートブック内で、または対応する MLflow 実行のページから検査できます。
ノートブックの出力を確認する
次のコードは、ノートブックから評価実行の結果を確認する方法のいくつかの例を示しています。
%pip install databricks-agents pandas
dbutils.library.restartPython()
import mlflow
import pandas as pd
###
# Run evaluation
###
evaluation_results = mlflow.evaluate(..., model_type="databricks-agent")
###
# Access aggregated evaluation results across the entire evaluation set
###
results_as_dict = evaluation_results.metrics
results_as_pd_df = pd.DataFrame([evaluation_results.metrics])
# Sample usage
print(f"The percentage of generated responses that are grounded: {results_as_dict['response/llm_judged/groundedness/percentage']}")
###
# Access data about each question in the evaluation set
###
per_question_results_df = evaluation_results.tables['eval_results']
# Show information about responses that are not grounded
per_question_results_df[per_question_results_df["response/llm_judged/groundedness/rating"] == "no"].display()
per_question_results_df
データフレームには、入力スキーマ内のすべての列と、各要求に固有のすべての評価結果が含まれます。 計算結果の詳細については、「 エージェント評価によって品質、コスト、待機時間を評価する方法を参照してください。
MLflow UI を使用して出力を確認する
評価結果は MLflow UI でも確認できます。 MLflow UI にアクセスするには、ノートブックの右側のサイドバーにある実験アイコン 、対応する実行の順にクリックするか、mlflow.evaluate()
を実行したノートブック セルのセル結果に表示されるリンクをクリックします。
1 回の実行の評価結果を確認する
このセクションでは、個々の実行の評価結果を確認する方法について説明します。 実行間で結果を比較するには、「 実行全体の比較結果を比較するを参照してください。
LLM審査委員による品質評価の概要
要求ごとのジャッジ評価は、 databricks-agents
バージョン 0.3.0 以降で利用できます。
評価セット内の各要求の LLM 判定品質の概要を表示するには、[MLflow 実行] ページの [ 評価結果 ] タブをクリックします。 このページには、各評価実行の概要一覧が表示されます。 詳細については、実行の [評価 ID] をクリックします。
この概要では、要求ごとに異なるジャッジの評価、これらの評価に基づく各要求の品質合格/失敗状態、失敗した要求の根本原因を示します。 テーブル内の行をクリックすると、次のような要求の詳細ページが表示されます。
- モデルの出力: エージェント アプリから生成された応答とそのトレース (含まれている場合)。
- 想定される出力: 各要求に対して想定される応答。
- 詳細な評価: このデータに対する LLM ジャッジの評価。 [詳細を表示する] をクリックすると、ジャッジによる正当性の根拠が表示されます。
評価セット全体の集計結果
完全な評価セット全体で集計された結果を表示するには、[ Overview ] タブ (数値の場合) または [ Model メトリック タブ (グラフの場合) をクリックします。
実行間で評価結果を比較する
複数の実行に関する評価結果を比較し、エージェント アプリケーションが変更にどのように応答するかを確認することが重要です。 結果を比較すると、変更が品質にプラスの影響を与えているかどうかを理解し、変化する動作をトラブルシューティングするのに役立ちます。
実行間で要求ごとの結果を比較する
複数の実行に関する個々の要求のデータを比較するには、[実験] ページの [評価] タブをクリックします。 表に評価セット内の各質問が示されます。 表示する列を選択するには、ドロップダウン メニューを使います。
実行間で集計された結果を比較する
[実験] ページから同じ集計結果にアクセスできます。これにより、異なる実行間で結果を比較することもできます。 [実験] ページにアクセスするには、ノートブックの右側のサイドバーにある実験アイコン をクリックするか、mlflow.evaluate()
を実行したノートブック セルのセル結果に表示されるリンクをクリックします。
[実験] ページで をクリックします。 これにより、選択した実行の集計結果を視覚化し、過去の実行と比較できます。
どのジャッジが実行されているか
既定では、各評価レコードに対して、モザイク AI エージェント評価は、レコードに存在する情報に最も一致するジャッジのサブセットを適用します。 具体的には、次のように使用します。
- 記録に地上真実の対応が含まれている場合、エージェント評価は、
context_sufficiency
、groundedness
、correctness
、およびsafety
の判事を適用します。 - 記録に地上真偽の対応が含まれていない場合、エージェント評価は、
chunk_relevance
、groundedness
、relevance_to_query
、およびsafety
の判事を適用します。
次のように、mlflow.evaluate()
のevaluator_config
引数を使用して、各要求に適用するジャッジを明示的に指定することもできます。
# Complete list of built-in LLM judges
# "chunk_relevance", "context_sufficiency", "correctness", "groundedness", "relevance_to_query", "safety"
evaluation_results = mlflow.evaluate(
data=eval_df,
model_type="databricks-agent",
evaluator_config={
"databricks-agent": {
# Run only LLM judges that don't require ground-truth. Use an empty list to not run any built-in judge.
"metrics": ["groundedness", "relevance_to_query", "chunk_relevance", "safety"]
}
}
)
Note
チャンク取得、チェーン トークン数、または待機時間に関する LLM 以外のジャッジ メトリックを無効にすることはできません。
組み込みのジャッジに加えて、ユース ケースに固有の条件を評価するカスタム LLM ジャッジを定義できます。 「 LLM のジャッジをカスタマイズするを参照してください。
LLM ジャッジの信頼性と安全性に関する情報については、「LLMジャッジをサポートするモデルに関する情報」を参照してください。
評価結果とメトリックの詳細については、「 エージェント評価によって品質、コスト、待機時間を評価する方法を参照してください。
例: アプリケーションをエージェント評価に渡す方法
アプリケーションを mlflow_evaluate()
に渡すには、 model
引数を使用します。 model
引数にアプリケーションを渡すための 5 つのオプションがあります。
- Unity カタログに登録されているモデル。
- 現在の MLflow 実験でログに記録された MLflow モデル。
- ノートブックに読み込まれる PyFunc モデル。
- ノートブック内のローカル関数。
- デプロイされたエージェント エンドポイント。
各オプションを示すコード例については、次のセクションを参照してください。
オプション 1. Unity カタログに登録されているモデル
%pip install databricks-agents pandas
dbutils.library.restartPython()
import mlflow
import pandas as pd
evaluation_results = mlflow.evaluate(
data=eval_set_df, # pandas DataFrame with just the evaluation set
model = "models:/catalog.schema.model_name/1" # 1 is the version number
model_type="databricks-agent",
)
オプション 2. 現在の MLflow 実験でログに記録された MLflow モデル
%pip install databricks-agents pandas
dbutils.library.restartPython()
import mlflow
import pandas as pd
# In the following lines, `6b69501828264f9s9a64eff825371711` is the run_id, and `chain` is the artifact_path that was
# passed with mlflow.xxx.log_model(...).
# If you called model_info = mlflow.langchain.log_model() or mlflow.pyfunc.log_model(), you can access this value using `model_info.model_uri`.
evaluation_results = mlflow.evaluate(
data=eval_set_df, # pandas DataFrame with just the evaluation set
model = "runs:/6b69501828264f9s9a64eff825371711/chain"
model_type="databricks-agent",
)
方法 3. ノートブックに読み込まれる PyFunc モデル
%pip install databricks-agents pandas
dbutils.library.restartPython()
import mlflow
import pandas as pd
evaluation_results = mlflow.evaluate(
data=eval_set_df, # pandas DataFrame with just the evaluation set
model = mlflow.pyfunc.load_model(...)
model_type="databricks-agent",
)
オプション 4: ノートブックのローカル関数
この関数は、次のように書式設定された入力を受け取ります。
{
"messages": [
{
"role": "user",
"content": "What is MLflow?",
}
],
...
}
この関数は、次の 3 つのサポートされている形式のいずれかで値を返す必要があります。
モデルの応答を含むプレーン文字列。
ChatCompletionResponse
形式のディクショナリ。 次に例を示します。{ "choices": [ { "message": { "role": "assistant", "content": "MLflow is a machine learning toolkit.", }, ... } ], ..., }
{ "content": "MLflow is a machine learning toolkit.", ... }
などのStringResponse
形式のディクショナリ。
次の例では、ローカル関数を使用して基礎モデル エンドポイントをラップし、評価します。
%pip install databricks-agents pandas
dbutils.library.restartPython()
import mlflow
import pandas as pd
def model(model_input):
client = mlflow.deployments.get_deploy_client("databricks")
return client.predict(endpoint="endpoints:/databricks-meta-llama-3-1-405b-instruct", inputs={"messages": model_input["messages"]})
evaluation_results = mlflow.evaluate(
data=eval_set_df, # pandas DataFrame with just the evaluation set
model = model
model_type="databricks-agent",
)
オプション 5. デプロイされたエージェント エンドポイント
このオプションは、 databricks.agents.deploy
を使用してデプロイされたエージェント エンドポイントと、 databricks-agents
SDK バージョン 0.8.0
以降を使用する場合にのみ機能します。 基盤モデルまたは古い SDK バージョンの場合は、オプション 4 を使用してモデルをローカル関数でラップします。
%pip install databricks-agents pandas
dbutils.library.restartPython()
import mlflow
import pandas as pd
# In the following lines, `endpoint-name-of-your-agent` is the name of the agent endpoint.
evaluation_results = mlflow.evaluate(
data=eval_set_df, # pandas DataFrame with just the evaluation set
model = "endpoints:/endpoint-name-of-your-agent"
model_type="databricks-agent",
)
アプリケーションが mlflow_evaluate()
呼び出しに含まれるときに評価セットを渡す方法
次のコードでは、 data
は評価セットを持つ pandas DataFrame です。 これらは簡単な例です。 詳細については、 input スキーマ を参照してください。
# You do not have to start from a dictionary - you can use any existing pandas or Spark DataFrame with this schema.
# Minimal evaluation set
bare_minimum_eval_set_schema = [
{
"request": "What is the difference between reduceByKey and groupByKey in Spark?",
}]
# Complete evaluation set
complete_eval_set_schema = [
{
"request_id": "your-request-id",
"request": "What is the difference between reduceByKey and groupByKey in Spark?",
"expected_retrieved_context": [
{
# In `expected_retrieved_context`, `content` is optional, and does not provide any additional functionality.
"content": "Answer segment 1 related to What is the difference between reduceByKey and groupByKey in Spark?",
"doc_uri": "doc_uri_2_1",
},
{
"content": "Answer segment 2 related to What is the difference between reduceByKey and groupByKey in Spark?",
"doc_uri": "doc_uri_2_2",
},
],
"expected_response": "There's no significant difference.",
}]
# Convert dictionary to a pandas DataFrame
eval_set_df = pd.DataFrame(bare_minimum_eval_set_schema)
# Use a Spark DataFrame
import numpy as np
spark_df = spark.table("catalog.schema.table") # or any other way to get a Spark DataFrame
eval_set_df = spark_df.toPandas()
例: 以前に生成された出力をエージェント評価に渡す方法
このセクションでは、 mlflow_evaluate()
呼び出しで以前に生成された出力を渡す方法について説明します。 必要な評価セット スキーマについては、 Agent Evaluation 入力スキーマを参照してください。
次のコードでは、 data
は、アプリケーションによって生成された評価セットと出力を含む pandas DataFrame です。 これらは簡単な例です。 詳細については、 input スキーマ を参照してください。
%pip install databricks-agents pandas
dbutils.library.restartPython()
import mlflow
import pandas as pd
evaluation_results = mlflow.evaluate(
data=eval_set_with_app_outputs_df, # pandas DataFrame with the evaluation set and application outputs
model_type="databricks-agent",
)
# You do not have to start from a dictionary - you can use any existing pandas or Spark DataFrame with this schema.
# Minimum required input
bare_minimum_input_schema = [
{
"request": "What is the difference between reduceByKey and groupByKey in Spark?",
"response": "reduceByKey aggregates data before shuffling, whereas groupByKey shuffles all data, making reduceByKey more efficient.",
}]
# Input including optional arguments
complete_input_schema = [
{
"request_id": "your-request-id",
"request": "What is the difference between reduceByKey and groupByKey in Spark?",
"expected_retrieved_context": [
{
# In `expected_retrieved_context`, `content` is optional, and does not provide any additional functionality.
"content": "Answer segment 1 related to What is the difference between reduceByKey and groupByKey in Spark?",
"doc_uri": "doc_uri_2_1",
},
{
"content": "Answer segment 2 related to What is the difference between reduceByKey and groupByKey in Spark?",
"doc_uri": "doc_uri_2_2",
},
],
"expected_response": "There's no significant difference.",
"response": "reduceByKey aggregates data before shuffling, whereas groupByKey shuffles all data, making reduceByKey more efficient.",
"retrieved_context": [
{
# In `retrieved_context`, `content` is optional. If provided, the Databricks Context Relevance LLM Judge is executed to check the `content`'s relevance to the `request`.
"content": "reduceByKey reduces the amount of data shuffled by merging values before shuffling.",
"doc_uri": "doc_uri_2_1",
},
{
"content": "groupByKey may lead to inefficient data shuffling due to sending all values across the network.",
"doc_uri": "doc_uri_6_extra",
},
],
}]
# Convert dictionary to a pandas DataFrame
eval_set_with_app_outputs_df = pd.DataFrame(bare_minimum_input_schema)
# Use a Spark DataFrame
import numpy as np
spark_df = spark.table("catalog.schema.table") # or any other way to get a Spark DataFrame
eval_set_with_app_outputs_df = spark_df.toPandas()
例: カスタム関数を使用して LangGraph からの応答を処理する
LangGraph エージェント (特にチャット機能を持つエージェント) は、1 回の推論呼び出しで複数のメッセージを返すことができます。 エージェントの応答を、Agent Evaluation がサポートする形式に変換するのはユーザーの責任です。
1 つの方法は、 custom 関数 を使用して応答を処理することです。 次の例は、LangGraph モデルから最後のチャット メッセージを抽出するカスタム関数を示しています。 この関数は、 mlflow.evaluate()
で 1 つの文字列応答を返すために使用されます。これは、 ground_truth
列と比較できます。
このコード例では、次の前提条件を想定しています。
- モデルは、{"messages": [{"role": "user", "content": "hello"}} という形式の入力を受け入れます。
- モデルは、["response 1", "response 2"] という形式の文字列のリストを返します。
次のコードは、"response 1nresponse2" という形式で、連結された応答をジャッジに送信します。
import mlflow
import pandas as pd
from typing import List
loaded_model = mlflow.langchain.load_model(model_uri)
eval_data = pd.DataFrame(
{
"inputs": [
"What is MLflow?",
"What is Spark?",
],
"expected_response": [
"MLflow is an open-source platform for managing the end-to-end machine learning (ML) lifecycle. It was developed by Databricks, a company that specializes in big data and machine learning solutions. MLflow is designed to address the challenges that data scientists and machine learning engineers face when developing, training, and deploying machine learning models.",
"Apache Spark is an open-source, distributed computing system designed for big data processing and analytics. It was developed in response to limitations of the Hadoop MapReduce computing model, offering improvements in speed and ease of use. Spark provides libraries for various tasks such as data ingestion, processing, and analysis through its components like Spark SQL for structured data, Spark Streaming for real-time data processing, and MLlib for machine learning tasks",
],
}
)
def custom_langgraph_wrapper(model_input):
predictions = loaded_model.invoke({"messages": model_input["messages"]})
# Assuming `predictions` is a list of strings
return predictions.join("\n")
with mlflow.start_run() as run:
results = mlflow.evaluate(
custom_langgraph_wrapper, # Pass the function defined above
data=eval_data,
model_type="databricks-agent",
)
print(results.metrics)
メトリックを含むダッシュボードを作成する
エージェントの品質を反復処理する場合は、時間の経過と共に品質がどのように向上したかを示すダッシュボードを関係者と共有することができます。 MLflow 評価実行からメトリックを抽出し、値を Delta テーブルに保存して、ダッシュボードを作成できます。
次の例は、ノートブックで最新の評価実行からメトリック値を抽出して保存する方法を示しています。
uc_catalog_name = "catalog"
uc_schema_name = "schema"
table_name = "results"
eval_results = mlflow.evaluate(
model=logged_agent_info.model_uri, # use the logged Agent
data=evaluation_set, # Run the logged Agent for all queries defined above
model_type="databricks-agent", # use Agent Evaluation
)
# The `append_metrics_to_table function` is defined below
append_metrics_to_table("<identifier-for-table>", eval_results.metrics, f"{uc_catalog_name}.{uc_schema_name}.{table_name}")
次の例は、MLflow 実験で保存した過去の実行のメトリック値を抽出して保存する方法を示しています。
import pandas as pd
def get_mlflow_run(experiment_name, run_name):
runs = mlflow.search_runs(experiment_names=[experiment_name], filter_string=f"run_name = '{run_name}'", output_format="list")
if len(runs) != 1:
raise ValueError(f"Found {len(runs)} runs with name {run_name}. {run_name} must identify a single run. Alternatively, you can adjust this code to search for a run based on `run_id`")
return runs[0]
run = get_mlflow_run(experiment_name ="/Users/<user_name>/db_docs_mlflow_experiment", run_name="evaluation__2024-10-09_02:27:17_AM")
# The `append_metrics_to_table` function is defined below
append_metrics_to_table("<identifier-for-table>", run.data.metrics, f"{uc_catalog_name}.{uc_schema_name}.{table_name}")
これで、このデータを使用してダッシュボードを作成できるようになりました。
次のコードでは、前の例で使用した関数 append_metrics_to_table
を定義します。
# Definition of `append_metrics_to_table`
def append_metrics_to_table(run_name, mlflow_metrics, delta_table_name):
data = mlflow_metrics.copy()
# Add identifying run_name and timestamp
data["run_name"] = run_name
data["timestamp"] = pd.Timestamp.now()
# Remove metrics with error counts
data = {k: v for k, v in mlflow_metrics.items() if "error_count" not in k}
# Convert to a Spark DataFrame(
metrics_df = pd.DataFrame([data])
metrics_df_spark = spark.createDataFrame(metrics_df)
# Append to the Delta table
metrics_df_spark.write.mode("append").saveAsTable(delta_table_name)
制限事項
複数ターンの会話の場合、評価の出力レコードには会話の最後のエントリのみが記録されます。
LLM ジャッジをサポートするモデルに関する情報
- LLM ジャッジではサードパーティのサービスを使用して、Microsoft が運営する Azure OpenAI などの、GenAI アプリケーションを評価する場合があります。
- Azure OpenAI の場合、Databricks は不正使用の監視をオプトアウトしているため、Azure OpenAI ではプロンプトや応答が格納されません。
- 欧州連合 (EU) ワークスペースの場合、LLM ジャッジは EU でホストされているモデルを使用します。 他のすべてのリージョンでは、米国でホストされているモデルが使用されます。
- Azure の AI 搭載 AI アシスタント機能を無効にすると、LLM ジャッジが Azure AI 搭載 モデルを呼び出せなくなります。
- LLM ジャッジに送信されるデータは、モデル トレーニングには使用されません。
- LLM ジャッジは、お客様が RAG アプリケーションを評価するのを支援することを目的としています。LLM ジャッジの出力は、LLM のトレーニング、改善、微調整には使用しないでください。