評価を実行して結果を表示する方法

プレビュー

この機能はパブリックプレビュー段階です。

この記事では、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 の資料を参照してください。

要件

パートナーが提供するAI支援機能は、ワークスペースで有効にする必要があります。

評価実行に入力する方法

評価実行に意見を提供する方法は2つあります。

  • 評価セットと比較するために、以前に生成された出力を提供します。 このオプションは、すでに本番運用にデプロイされているアプリケーションからの出力を評価する場合、または評価構成間で評価結果を比較する場合に推奨されます。

    このオプションでは、次のコードに示すように評価セットを指定します。 評価セットには、以前に生成された出力が含まれている必要があります。 詳細な例については、「 例: 以前に生成された出力をエージェント評価に渡す方法」を参照してください。

    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 の外部にデプロイされている場合にはお勧めしません。

    このオプションでは、次のコードに示すように、関数呼び出しで評価セットとアプリケーションを指定します。 詳細な例については、「 例: エージェント評価にアプリケーションを渡す方法」を参照してください。

    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",
    )
    

評価セットスキーマの詳細については、「 エージェント評価入力スキーマ」を参照してください。

評価結果

エージェント評価は、 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 をクリックしてください。

overview_judges

この概要では、各リクエストに対するさまざまなジャッジの評価、これらの評価に基づく各リクエストの品質合格/不合格ステータス、および失敗したリクエストの根本原因を示しています。 テーブル内の行をクリックすると、そのリクエストの詳細ページに移動し、次の内容が表示されます。

  • モデル出力: エージェントアプリから生成された応答とそのトレース(含まれている場合)。

  • 期待される出力: 各要求に対して予想される応答。

  • 詳細な評価:このデータに対する LLM 審査員の評価。 [ 詳細を表示 ] をクリックして、裁判官が提示した正当な理由を表示します。

details_judges

全評価セットで集計された結果

評価セット全体の集計結果を表示するには、[ 概要 ] タブ (数値の場合) または [モデル メトリクス ] タブ (グラフの場合) をクリックします。

評価メトリクス、評価値
評価メトリクス、チャート

実行間での評価結果の比較

エージェント アプリケーションが変更にどのように反応するかを確認するには、実行間で評価結果を比較することが重要です。 結果を比較すると、変更が品質にプラスの影響を与えているかどうかを把握したり、動作の変化のトラブルシューティングに役立てたりできます。

実行間で要求ごとの結果を比較する

実行全体で個々のリクエストのデータを比較するには、実験ページの「評価」タブをクリックします。 評価セットの各質問を表に示します。 ドロップダウンメニューを使用して、表示する列を選択します。

評価セット内の個々の質問

集計された結果を複数の実行間で比較する

エクスペリメント ページから同じ集計結果にアクセスできるほか、異なる実行間で結果を比較することもできます。 エクスペリメントページにアクセスするには、ノートブックの右側のサイドバーにあるエクスペリメントアイコン エクスペリメントアイコン をクリックするか、 mlflow.evaluate()を実行したノートブックセルのセル結果に表示されるリンクをクリックします。

エクスペリメントページで、 をクリックします チャートの表示アイコン。 これにより、選択した実行の集計結果を視覚化し、過去の実行と比較できます。

集計結果

どの審査員が実行されます

デフォルトでは、各評価レコードに対して、Mosaic AI Agent Evaluation は、レコードに存在する情報に最も一致するジャッジのサブセットを適用します。 具体的には:

  • レコードにグラウンドトゥルース応答が含まれている場合、エージェント評価は、 context_sufficiencygroundednesscorrectness、および safety ジャッジを適用します。

  • レコードにグラウンドトゥルース応答が含まれていない場合、エージェント評価は chunk_relevancegroundednessrelevance_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"]
    }
  }
)

注:

チャンクの取得、チェーントークンの数、またはレイテンシのLLMジャッジ以外のメトリクスを無効にすることはできません。

組み込みのジャッジに加えて、カスタム LLM ジャッジを定義して、ユースケースに固有の基準を評価できます。 「LLM ジャッジのカスタマイズ」を参照してください。

LLMジャッジの信頼性と安全性に関する情報については、「LLMジャッジを強化するモデルに関する情報」を参照してください。

評価結果とメトリクスの詳細については 、「エージェント評価による品質、コスト、およびレイテンシの評価方法」を参照してください。

例: アプリケーションを Agent Evaluation に渡す方法

アプリケーションを mlflow_evaluate()に渡すには、 model 引数を使用します。 model引数でアプリケーションを渡すには、5つのオプションがあります。

  • Unity Catalog に登録されているモデルです。

  • 現行MLflowのエクスペリメントでMLflow記録済みモデル。

  • ノートブックに読み込まれる PyFunc モデル。

  • ノートブックのローカル関数。

  • デプロイされたエージェント エンドポイント。

各オプションを示すコード例については、次のセクションを参照してください。

オプション1.Unity Catalog 年登録モデル

%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 記録済みモデル in the current 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.",
          },
         ...
        }
      ],
      ...,
    }
    
  • StringResponse形式の辞書 ({ "content": "MLflow is a machine learning toolkit.", ... }など)

次の例では、ローカル関数を使用して基盤モデルのエンドポイントをラップし、評価します。

  %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 を使用してデプロイされ、SDK バージョン 0.8.0 以降でデプロイされたエージェントエンドポイントを使用する場合にのみ機能しますdatabricks-agents。基盤モデルまたは古い 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()呼び出しに含まれている場合に評価セットを渡す方法

次のコードでは、評価セットの Pandas DataFrame data です。 これらは簡単な例です。 詳細については、 入力スキーマ を参照してください。

# 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() 呼び出しで渡す方法について説明します。 必要な評価セット・スキーマについては、 エージェント評価入力スキーマを参照してください。

次のコードでは、data は評価セットとアプリケーションによって生成された出力の Pandas DataFrame です。 これらは簡単な例です。 詳細については、 入力スキーマ を参照してください。

%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 つの方法は、 カスタム関数 を使用して応答を処理することです。 次の例は、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などのサードパーティサービスを使用して生成AIアプリケーションを評価する場合があります。

  • Azure OpenAIの場合、Databricksは不正行為モニタリングをオプトアウトしているため、プロンプトや応答はAzure OpenAIに保存されません。

  • 欧州連合(EU)のワークスペースの場合、LLMジャッジはEUでホストされているモデルを使用します。他のすべてのリージョンでは、米国でホストされているモデルを使用します。

  • パートナー向けの AI 支援機能 を無効にすると、LLM の審査員がパートナー向けのモデルを呼び出すのを防ぐことができます。

  • LLMジャッジに送信されたデータは、モデルのトレーニングには使用されません。

  • LLMジャッジは、顧客のRAGアプリケーションの評価を支援することを目的としており、LLMジャッジの出力は、LLMのトレーニング、改善、微調整のために使用されるべきではありません。