Bagikan melalui


Metrik kustom (MLflow 2)

Penting

Halaman ini menjelaskan penggunaan versi 0.22 Agent Evaluation dengan MLflow 2. Databricks merekomendasikan penggunaan MLflow 3, yang terintegrasi dengan >1.0 Evaluasi Agen. Di MLflow 3, API Evaluasi Agen sekarang menjadi bagian mlflow dari paket.

Untuk informasi tentang topik ini, lihat Membuat skor kustom.

Panduan ini menjelaskan cara menggunakan metrik kustom untuk mengevaluasi aplikasi AI dalam Mosaic AI Agent Framework. Metrik kustom memberikan fleksibilitas untuk menentukan metrik evaluasi yang disesuaikan dengan kasus penggunaan bisnis spesifik Anda, baik berdasarkan heuristik sederhana, logika tingkat lanjut, atau evaluasi terprogram.

Ikhtisar

Metrik kustom ditulis dalam Python dan memberi pengembang kontrol penuh untuk mengevaluasi jejak melalui aplikasi AI. Metrik berikut didukung:

  • metrik lulus/gagal : nilai string "yes" or "no" dirender sebagai "Lulus" atau "Gagal" di UI.
  • Metrik numerik: Nilai ordinal: bilangan bulat atau float.
  • metrik Boolean: True atau False.

Metrik kustom dapat menggunakan:

  • Bidang apa pun di baris evaluasi.
  • Bidang custom_expected untuk nilai tambahan yang diharapkan.
  • Akses lengkap ke jejak MLflow, termasuk rentang, atribut, dan output.

Penggunaan

Metrik kustom diteruskan ke kerangka evaluasi menggunakan bidang extra_metrics di mlflow.evaluate(). Contoh:

import mlflow
from databricks.agents.evals import metric

@metric
def not_empty(response):
    # "yes" for Pass and "no" for Fail.
    return "yes" if response.choices[0]['message']['content'].strip() != "" else "no"

@mlflow.trace(span_type="CHAT_MODEL")
def my_model(request):
    deploy_client = mlflow.deployments.get_deploy_client("databricks")
    return deploy_client.predict(
        endpoint="databricks-meta-llama-3-3-70b-instruct", inputs=request
    )

with mlflow.start_run(run_name="example_run"):
    eval_results = mlflow.evaluate(
        data=[{"request": "Good morning"}],
        model=my_model,
        model_type="databricks-agent",
        extra_metrics=[not_empty],
    )
    display(eval_results.tables["eval_results"])

dekorator @metric

Dekorator @metric memungkinkan pengguna untuk menentukan metrik evaluasi kustom yang dapat diteruskan ke mlflow.evaluate() menggunakan argumen extra_metrics. Harness evaluasi memanggil fungsi metrik dengan argumen yang diberi nama berdasarkan tanda tangan di bawah ini.

def my_metric(
  *,  # eval harness will always call it with named arguments
  request: Dict[str, Any],  # The agent's raw input as a serializable object
  response: Optional[Dict[str, Any]],  # The agent's raw output; directly passed from the eval harness
  retrieved_context: Optional[List[Dict[str, str]]],  # Retrieved context, either from input eval data or extracted from the trace
  expected_response: Optional[str],  # The expected output as defined in the evaluation dataset
  expected_facts: Optional[List[str]],  # A list of expected facts that can be compared against the output
  guidelines: Optional[Union[List[str], Dict[str, List[str]]]]  # A list of guidelines or mapping a name of guideline to an array of guidelines for that name
  expected_retrieved_context: Optional[List[Dict[str, str]]],  # Expected context for retrieval tasks
  trace: Optional[mlflow.entities.Trace],  # The trace object containing spans and other metadata
  custom_expected: Optional[Dict[str, Any]],  # A user-defined dictionary of extra expected values
  tool_calls: Optional[List[ToolCallInvocation]],
) -> float | bool | str | Assessment

Penjelasan argumen

  • request: Input yang diberikan kepada agen, diformat sebagai objek berseri arbitrer. Ini mewakili kueri atau perintah pengguna.
  • response: Output mentah dari agen, diformat sebagai objek serializable sembarang pilihan. Ini berisi respons yang dihasilkan agen untuk evaluasi.
  • retrieved_context: Daftar kamus yang berisi konteks yang diambil selama tugas. Konteks ini dapat berasal dari himpunan data evaluasi input atau jejak, dan pengguna dapat mengambil alih atau menyesuaikan ekstraksinya melalui bidang trace.
  • expected_response: String yang mewakili respons yang benar atau diinginkan untuk tugas tersebut. Ini bertindak sebagai kebenaran dasar untuk perbandingan terhadap respons agen.
  • expected_facts: Daftar fakta yang diharapkan muncul dalam respons agen, berguna untuk tugas pemeriksaan fakta.
  • guidelines: Daftar pedoman atau pemetaan nama pedoman ke array pedoman yang terkait dengan nama tersebut. Panduan memungkinkan Anda memberikan batasan pada bidang apa pun yang kemudian dapat dievaluasi oleh hakim kepatuhan pedoman.
  • expected_retrieved_context: Daftar kamus yang mewakili konteks pengambilan yang diharapkan. Ini sangat penting untuk tugas yang diperkuat dengan pengambilan kembali di mana ketepatan data yang diambil sangat berarti.
  • trace: Objek MLflow Trace opsional yang berisi rentang, atribut, dan metadata lainnya tentang eksekusi agen. Ini memungkinkan inspeksi mendalam dari langkah-langkah internal yang diambil oleh agen.
  • custom_expected: Kamus untuk meneruskan nilai yang diharapkan oleh pengguna. Bidang ini memberikan fleksibilitas untuk menyertakan ekspektasi kustom tambahan yang tidak tercakup oleh bidang standar.
  • tool_calls: Daftar ToolCallInvocation yang menjelaskan alat mana yang dipanggil serta hasil yang mereka berikan.

Mengembalikan nilai

Nilai pengembalian metrik kustom adalah penilaian per baris. Jika Anda mengembalikan nilai primitif, itu akan dibungkus dengan Assessment dengan justifikasi kosong.

  • float: Untuk metrik numerik (misalnya, skor kesamaan, persentase akurasi).
  • bool: Untuk metrik biner.
  • Assessment atau list[Assessment]: Jenis output yang lebih kaya yang mendukung penambahan alasan. Jika Anda mengembalikan daftar penilaian, fungsi metrik yang sama dapat digunakan kembali untuk mengembalikan beberapa penilaian.
    • name: Nama penilaian.
    • value: Nilai (float, int, bool, atau string).
    • rationale: (Opsional) Alasan yang menjelaskan bagaimana nilai ini dihitung. Ini dapat berguna untuk menunjukkan penalaran tambahan di UI. Bidang ini berguna, misalnya, saat memberikan penalaran dari LLM yang menghasilkan Penilaian ini.

Metrik lulus/gagal

Setiap metrik string yang mengembalikan "yes" dan "no" diperlakukan sebagai metrik pass/fail dan memiliki perlakuan khusus di UI.

Anda juga dapat membuat metrik pass/fail dengan menggunakan Python SDK yang dapat dipanggil. Ini memberi Anda lebih banyak kontrol atas bagian jejak apa yang akan dievaluasi dan bidang mana yang diharapkan untuk digunakan. Anda dapat menggunakan salah satu dari hakim Evaluasi Agen AI Mosaic AI yang sudah tersedia. Lihat Hakim AI bawaan (MLflow 2).

Pastikan konteks yang diambil tidak memiliki PII (Informasi Pribadi yang Dapat Diidentifikasi)

Contoh ini memanggil pengawas guideline_adherence untuk memastikan bahwa konteks yang diperoleh tidak memiliki PII.

import mlflow
import pandas as pd
from databricks.agents.evals import metric
from databricks.agents.evals import judges

evals = [
  {
    "request": "Good morning",
    "response": "Good morning to you too!",
    "retrieved_context": [{
      "content": "The email address is noreply@databricks.com",
    }],
  }, {
    "request": "Good afternoon",
    "response": "This is actually the morning!",
    "retrieved_context": [{
      "content": "fake retrieved context",
    }],
  }
]

@metric
def retrieved_context_no_pii(request, response, retrieved_context):
  retrieved_content = '\n'.join([c['content'] for c in retrieved_context])
  return judges.guideline_adherence(
    request=request,
    # You can also pass in per-row guidelines by adding `guidelines` to the signature of your metric
    guidelines=[
      "The retrieved context must not contain personally identifiable information.",
    ],
    # `guidelines_context` requires `databricks-agents>=0.20.0`
    guidelines_context={"retrieved_context": retrieved_content},
  )

with mlflow.start_run(run_name="safety"):
    eval_results = mlflow.evaluate(
        data=pd.DataFrame.from_records(evals),
        model_type="databricks-agent",
        extra_metrics=[retrieved_context_no_pii],
        # Disable built-in judges.
        evaluator_config={
            'databricks-agent': {
                "metrics": [],
            }
        }
    )
    display(eval_results.tables['eval_results'])

metode numerik

Metrik numerik mengevaluasi nilai ordinal, seperti float atau bilangan bulat. Metrik numerik ditampilkan di UI per baris, bersama dengan nilai rata-rata untuk evaluasi yang dijalankan.

Contoh: kesamaan respons

Metrik ini mengukur kesamaan antara response dan expected_response menggunakan pustaka python bawaan SequenceMatcher.

import mlflow
import pandas as pd
from databricks.agents.evals import metric
from difflib import SequenceMatcher

evals = [
  {
    "request": "Good morning",
    "response": "Good morning to you too!",
    "expected_response": "Hello and good morning to you!"
  }, {
    "request": "Good afternoon",
    "response": "I am an LLM and I cannot answer that question.",
    "expected_response": "Good afternoon to you too!"
  }
]

@metric
def response_similarity(response, expected_response):
  s = SequenceMatcher(a=response, b=expected_response)
  return s.ratio()

with mlflow.start_run(run_name="response_similarity"):
    eval_results = mlflow.evaluate(
        data=pd.DataFrame.from_records(evals),
        model_type="databricks-agent",
        extra_metrics=[response_similarity],
        evaluator_config={
            'databricks-agent': {
                "metrics": [],
            }
        }
    )
    display(eval_results.tables['eval_results'])

metrik Boolean

Metrik Boolean menghasilkan nilai True atau False. Ini berguna untuk keputusan biner, seperti memeriksa apakah respons memenuhi heuristik sederhana. Jika Anda ingin metrik memiliki perlakuan pass/fail khusus di UI, lihat metrik pass/fail .

Contoh: Periksa permintaan input diformat dengan benar

Metrik ini memeriksa apakah input arbitrer diformat seperti yang diharapkan dan mengembalikan True jika ya.

import mlflow
import pandas as pd
from databricks.agents.evals import metric

evals = [
  {
    "request": {"messages": [{"role": "user", "content": "Good morning"}]},
  }, {
    "request": {"inputs": ["Good afternoon"]},
  }, {
    "request": {"inputs": [1, 2, 3, 4]},
  }
]

@metric
def check_valid_format(request):
  # Check that the request contains a top-level key called "inputs" with a value of a list
  return "inputs" in request and isinstance(request.get("inputs"), list)

with mlflow.start_run(run_name="check_format"):
  eval_results = mlflow.evaluate(
      data=pd.DataFrame.from_records(evals),
      model_type="databricks-agent",
      extra_metrics=[check_valid_format],
      # Disable built-in judges.
      evaluator_config={
          'databricks-agent': {
              "metrics": [],
          }
      }
  )
eval_results.tables['eval_results']

Contoh: Referensi mandiri model bahasa

Metrik ini memeriksa apakah respons menyebutkan "LLM" dan mengembalikan True jika terjadi.

import mlflow
import pandas as pd
from databricks.agents.evals import metric

evals = [
  {
    "request": "Good morning",
    "response": "Good morning to you too!"
  }, {
    "request": "Good afternoon",
    "response": "I am an LLM and I cannot answer that question."
  }
]

@metric
def response_mentions_llm(response):
  return "LLM" in response

with mlflow.start_run(run_name="response_mentions_llm"):
    eval_results = mlflow.evaluate(
        data=pd.DataFrame.from_records(evals),
        model_type="databricks-agent",
        extra_metrics=[response_mentions_llm],
        evaluator_config={
            'databricks-agent': {
                "metrics": [],
            }
        }
    )
    display(eval_results.tables['eval_results'])

Menggunakan custom_expected

Bidang custom_expected dapat digunakan untuk meneruskan informasi lain yang diharapkan ke metrik kustom.

Contoh: Panjang respons terikat

Contoh ini menunjukkan cara mengharuskan panjang respons berada dalam batas (min_length, max_length) yang ditetapkan untuk setiap contoh. Gunakan custom_expected untuk menyimpan informasi tingkat baris apa pun yang akan diteruskan ke metrik kustom saat membuat penilaian.

import mlflow
import pandas as pd
from databricks.agents.evals import metric
from databricks.agents.evals import judges

evals = [
  {
    "request": "Good morning",
    "response": "Good night.",
    "custom_expected": {
      "max_length": 100,
      "min_length": 3
    }
  }, {
    "request": "What is the date?",
    "response": "12/19/2024",
    "custom_expected": {
      "min_length": 10,
      "max_length": 20,
    }
  }
]

# The custom metric uses the "min_length" and "max_length" from the "custom_expected" field.
@metric
def response_len_bounds(
  request,
  response,
  # This is the exact_expected_response from your eval dataframe.
  custom_expected
):
  return len(response) <= custom_expected["max_length"] and len(response) >= custom_expected["min_length"]

with mlflow.start_run(run_name="response_len_bounds"):
    eval_results = mlflow.evaluate(
        data=pd.DataFrame.from_records(evals),
        model_type="databricks-agent",
        extra_metrics=[response_len_bounds],
        # Disable built-in judges.
        evaluator_config={
            'databricks-agent': {
                "metrics": [],
            }
        }
    )
    display(eval_results.tables['eval_results'])

Pernyataan tentang jejak

Metrik kustom dapat menilai bagian mana pun dari jejak MLflow yang diproduksi oleh agen, termasuk rentang, atribut, dan output.

Contoh: Permintaan klasifikasi dan perutean

Contoh ini membangun agen yang menentukan apakah kueri pengguna adalah pertanyaan atau pernyataan dan mengembalikannya dalam bahasa Inggris biasa kepada pengguna. Dalam skenario yang lebih realistis, Anda mungkin menggunakan teknik ini untuk merutekan kueri yang berbeda ke fungsionalitas yang berbeda.

Kumpulan evaluasi memastikan bahwa pengklasifikasi jenis kueri menghasilkan hasil yang tepat untuk serangkaian input dengan menggunakan metrik kustom yang memeriksa jejak MLFlow.

Contoh ini menggunakan Trace.search_spans MLflow untuk menemukan rentang dengan jenis KEYWORD, yang merupakan jenis rentang kustom yang Anda tentukan untuk agen ini.


import mlflow
import pandas as pd
from mlflow.types.llm import ChatCompletionResponse, ChatCompletionRequest
from databricks.agents.evals import metric
from databricks.agents.evals import judges
from mlflow.evaluation import Assessment
from mlflow.entities import Trace
from mlflow.deployments import get_deploy_client

# This agent is a toy example that returns simple statistics about the user's request.
# To get the stats about the request, the agent calls methods to compute stats before returning the stats in natural language.

deploy_client = get_deploy_client("databricks")
ENDPOINT_NAME="databricks-meta-llama-3-3-70b-instruct"

@mlflow.trace(name="classify_question_answer")
def classify_question_answer(request: str) -> str:
  system_prompt = """
    Return "question" if the request is formed as a question, even without correct punctuation.
    Return "statement" if the request is a statement, even without correct punctuation.
    Return "unknown" otherwise.

    Do not return a preamble, only return a single word.
  """
  request = {
    "messages": [
      {"role": "system", "content": system_prompt},
      {"role": "user", "content": request},
    ],
    "temperature": .01,
    "max_tokens": 1000
  }

  result = deploy_client.predict(endpoint=ENDPOINT_NAME, inputs=request)
  return result.choices[0]['message']['content']

@mlflow.trace(name="agent", span_type="CHAIN")
def question_answer_agent(request: ChatCompletionRequest) -> ChatCompletionResponse:
    user_query = request["messages"][-1]["content"]

    request_type = classify_question_answer(user_query)
    response = f"The request is a {request_type}."

    return {
        "messages": [
            *request["messages"][:-1], # Keep the chat history.
            {"role": "user", "content": response}
        ]
    }

# Define the evaluation set with a set of requests and the expected request types for those requests.
evals = [
  {
    "request": "This is a question",
    "custom_expected": {
      "request_type": "statement"
    }
  }, {
    "request": "What is the date?",
    "custom_expected": {
      "request_type": "question"
    }
  },
]

# The custom metric checks the expected request type against the actual request type produced by the agent trace.
@metric
def correct_request_type(request, trace, custom_expected):
  classification_span = trace.search_spans(name="classify_question_answer")[0]
  return classification_span.outputs == custom_expected['request_type']

with mlflow.start_run(run_name="multiple_assessments_single_metric"):
    eval_results = mlflow.evaluate(
        data=pd.DataFrame.from_records(evals),
        model=question_answer_agent,
        model_type="databricks-agent",
        extra_metrics=[correct_request_type],
        evaluator_config={
            'databricks-agent': {
                "metrics": [],
            }
        }
    )
    display(eval_results.tables['eval_results'])

Dengan memanfaatkan contoh ini, Anda dapat merancang metrik kustom untuk memenuhi kebutuhan evaluasi unik Anda.

Mengevaluasi pemanggilan fungsi alat

Metrik kustom akan disediakan melalui tool_calls, yang merupakan daftar ToolCallInvocation, yang memberi Anda informasi tentang alat mana yang dipanggil serta apa hasil yang mereka berikan.

Contoh: Memastikan alat yang tepat disebut

Nota

Contoh ini tidak dapat disalin karena tidak menentukan agen LangGraph. Lihat notebook terlampir untuk contoh yang sepenuhnya dapat dijalankan.

import mlflow
import pandas as pd
from databricks.agents.evals import metric
from databricks.agents.evals import judges

eval_data = pd.DataFrame(
  [
    {
      "request": "what is 3 * 12?",
      "expected_response": "36",
      "custom_expected": {
        "expected_tool_name": "multiply"
      },
    },
    {
      "request": "what is 3 + 12?",
      "expected_response": "15",
      "custom_expected": {
        "expected_tool_name": "add"
      },
    },
  ]
)

@metric
def is_correct_tool(tool_calls, custom_expected):
  # Metric to check whether the first tool call is the expected tool
  return tool_calls[0].tool_name == custom_expected["expected_tool_name"]

@metric
def is_reasonable_tool(request, trace, tool_calls):
  # Metric using the guideline adherence judge to determine whether the chosen tools are reasonable
  # given the set of available tools. Note that `guidelines_context` requires `databricks-agents >= 0.20.0`

  return judges.guideline_adherence(
    request=request["messages"][0]["content"],
    guidelines=[
      "The selected tool must be a reasonable tool call with respect to the request and available tools.",
    ],
    # `guidelines_context` requires `databricks-agents>=0.20.0`
    guidelines_context={
      "available_tools": str(tool_calls[0].available_tools),
      "chosen_tools": str([tool_call.tool_name for tool_call in tool_calls]),
    },
  )

results = mlflow.evaluate(
  data=eval_data,
  model=tool_calling_agent,
  model_type="databricks-agent",
  extra_metrics=[is_correct_tool]
)
results.tables["eval_results"].display()

Mengembangkan metrik kustom

Saat Anda mengembangkan metrik, Anda perlu dengan cepat melakukan iterasi pada metrik tanpa harus menjalankan agen setiap kali Anda membuat perubahan. Untuk membuat ini lebih sederhana, gunakan strategi berikut:

  1. Buat lembar jawaban dari agen yang mengolah himpunan data evaluasi. Ini menjalankan agen untuk setiap entri dalam kumpulan evaluasi, menghasilkan respons dan jejak yang dapat Anda gunakan untuk memanggil metrik secara langsung.
  2. Tentukan metrik.
  3. Panggil metrik pada setiap nilai di lembar jawaban secara langsung dan lakukan iterasi pada definisi metriknya.
  4. Ketika metrik berperilaku seperti yang Anda harapkan, jalankan mlflow.evaluate() pada lembar jawaban yang sama untuk memverifikasi bahwa hasil dari menjalankan Evaluasi Agen adalah apa yang Anda harapkan. Kode dalam contoh ini tidak menggunakan bidang model=, sehingga evaluasi menggunakan respons yang telah dihitung sebelumnya.
  5. Ketika Anda puas dengan performa metrik, aktifkan bidang model= di mlflow.evaluate() untuk memanggil agen secara interaktif.
import mlflow
import pandas as pd
from databricks.agents.evals import metric
from databricks.agents.evals import judges
from mlflow.evaluation import Assessment
from mlflow.entities import Trace

evals = [
  {
    "request": "What is Databricks?",
    "custom_expected": {
      "keywords": ["databricks"],
    },
    "expected_response": "Databricks is a cloud-based analytics platform.",
    "expected_facts": ["Databricks is a cloud-based analytics platform."],
    "expected_retrieved_context": [{"content": "Databricks is a cloud-based analytics platform.", "doc_uri": "https://databricks.com/doc_uri"}]
  }, {
    "request": "When was Databricks founded?",
    "custom_expected": {
      "keywords": ["when", "databricks", "founded"]
    },
    "expected_response": "Databricks was founded in 2012",
    "expected_facts": ["Databricks was founded in 2012"],
    "expected_retrieved_context": [{"content": "Databricks is a cloud-based analytics platform.", "doc_uri": "https://databricks.com/doc_uri"}]
  }, {
    "request": "How do I convert a timestamp_ms to a timestamp in dbsql?",
    "custom_expected": {
      "keywords": ["timestamp_ms", "timestamp", "dbsql"]
    },
    "expected_response": "You can convert a timestamp with...",
    "expected_facts": ["You can convert a timestamp with..."],
    "expected_retrieved_context": [{"content": "You can convert a timestamp with...", "doc_uri": "https://databricks.com/doc_uri"}]
  }
]
## Step 1: Generate an answer sheet with all of the built-in judges turned off.
## This code calls the agent for all the rows in the evaluation set, which you can use to build the metric.
answer_sheet_df = mlflow.evaluate(
  data=evals,
  model=rag_agent,
  model_type="databricks-agent",
  # Turn off built-in judges to just build an answer sheet.
  evaluator_config={"databricks-agent": {"metrics": []}
  }
).tables['eval_results']
display(answer_sheet_df)

answer_sheet = answer_sheet_df.to_dict(orient='records')

## Step 2: Define the metric.
@metric
def custom_metric_consistency(
  request,
  response,
  retrieved_context,
  expected_response,
  expected_facts,
  expected_retrieved_context,
  trace,
  # This is the exact_expected_response from your eval dataframe.
  custom_expected
):
  print(f"[custom_metric] request: {request}")
  print(f"[custom_metric] response: {response}")
  print(f"[custom_metric] retrieved_context: {retrieved_context}")
  print(f"[custom_metric] expected_response: {expected_response}")
  print(f"[custom_metric] expected_facts: {expected_facts}")
  print(f"[custom_metric] expected_retrieved_context: {expected_retrieved_context}")
  print(f"[custom_metric] trace: {trace}")

  return True

## Step 3: Call the metric directly before using the evaluation harness to iterate on the metric definition.
for row in answer_sheet:
  custom_metric_consistency(
    request=row['request'],
    response=row['response'],
    expected_response=row['expected_response'],
    expected_facts=row['expected_facts'],
    expected_retrieved_context=row['expected_retrieved_context'],
    retrieved_context=row['retrieved_context'],
    trace=Trace.from_json(row['trace']),
    custom_expected=row['custom_expected']
  )

## Step 4: After you are confident in the signature of the metric, you can run the harness with the answer sheet to trigger the output validation and make sure the UI reflects what you intended.
with mlflow.start_run(run_name="exact_expected_response"):
    eval_results = mlflow.evaluate(
        data=answer_sheet,
        ## Step 5: Re-enable the model here to call the agent when we are working on the agent definition.
        # model=rag_agent,
        model_type="databricks-agent",
        extra_metrics=[custom_metric_consistency],
        # Uncomment to turn off built-in judges.
        # evaluator_config={
        #     'databricks-agent': {
        #         "metrics": [],
        #     }
        # }
    )
    display(eval_results.tables['eval_results'])

Contoh buku catatan

Contoh notebook berikut mengilustrasikan beberapa cara berbeda untuk menggunakan metrik kustom di Evaluasi Agen AI Mosaik.

Buku catatan contoh metrik kustom untuk Evaluasi Agen

Dapatkan buku catatan