Nuta
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować się zalogować lub zmienić katalog.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
Ważne
Usługa Databricks zaleca używanie platformy MLflow 3 do oceniania i monitorowania aplikacji GenAI. Na tej stronie opisano ocenę agenta MLflow 2.
- Aby zapoznać się z wprowadzeniem do oceny i monitorowania w usłudze MLflow 3, zobacz Ocena i monitorowanie agentów sztucznej inteligencji.
- Aby uzyskać informacje na temat migracji do platformy MLflow 3, zobacz Migrowanie do platformy MLflow 3 z wersji ewaluacyjnej agenta.
- Aby uzyskać informacje dotyczące platformy MLflow 3 w tym temacie, zobacz Create custom code-based scorers (Tworzenie niestandardowych punktatorów opartych na kodzie).
W tym przewodniku wyjaśniono, jak używać niestandardowych metryk do oceny aplikacji sztucznej inteligencji w ramach Mosaic AI Agent Framework. Metryki niestandardowe zapewniają elastyczność definiowania metryk oceny dostosowanych do konkretnego przypadku użycia biznesowego, niezależnie od tego, czy są oparte na prostych heurystyce, zaawansowanej logice czy ocenach programowych.
Przegląd
Wskaźniki niestandardowe są zapisywane w języku Python i dają deweloperom pełną kontrolę do oceny śladów przy użyciu aplikacji AI. Obsługiwane są następujące metryki:
-
Metryki zaliczone/niezaliczone:
"yes" or "no"wartości tekstowe wyświetlają się jako "Zaliczone" lub "Niezaliczone" w interfejsie użytkownika. - metryki liczbowe: wartości porządkowe: liczby całkowite lub zmiennoprzecinkowe.
-
metryki logiczne:
TruelubFalse.
Niestandardowych metryk można używać:
- Dowolne pole w wierszu oceny.
- Pole
custom_expecteddla dodatkowych oczekiwanych wartości. - Pełny dostęp do śladu MLflow, w tym spanów, atrybutów i danych wyjściowych.
Użycie
Metryka niestandardowa jest przekazywana do struktury oceny przy użyciu pola extra_metrics w pliku mlflow.evaluate(). Przykład:
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"])
@metric dekorator
Dekorator @metric umożliwia użytkownikom definiowanie niestandardowych metryk oceny, które można przekazać do mlflow.evaluate() przy użyciu argumentu extra_metrics. Narzędzie oceny wywołuje funkcję metriczną za pomocą nazwanych argumentów na podstawie poniższej sygnatury.
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
Wyjaśnienie argumentów
-
request: dane wejściowe dostarczone do agenta sformatowane jako dowolny obiekt z możliwością serializacji. Reprezentuje to zapytanie użytkownika lub monit. -
response: nieprzetworzone dane wyjściowe z agenta sformatowane jako opcjonalny dowolny obiekt z możliwością serializacji. Zawiera on wygenerowaną odpowiedź agenta na potrzeby oceny. -
retrieved_context: lista słowników zawierających kontekst pobrany podczas zadania. Ten kontekst może pochodzić z zestawu danych oceny wejściowej lub ze śledzenia, a użytkownicy mogą nadpisać lub dostosować jego wyodrębnianie za pomocą polatrace. -
expected_response: ciąg reprezentujący poprawną lub żądaną odpowiedź dla zadania. Działa jako podstawa prawdy do porównania z odpowiedzią agenta. -
expected_facts: Lista faktów, które powinny pojawić się w odpowiedzi agenta, przydatne w przypadku zadań sprawdzania faktów. -
guidelines: lista wytycznych lub mapowanie nazwy wytycznych na tablicę wytycznych powiązanych z tą nazwą. Wytyczne umożliwiają zapewnienie ograniczeń dla dowolnego pola, które można następnie ocenić przez sędziego przestrzegania wytycznych. -
expected_retrieved_context: lista słowników reprezentujących oczekiwany kontekst pobierania. Jest to niezbędne w przypadku zadań rozszerzonych pobierania, w których istotna jest poprawność pobranych danych. -
trace: opcjonalny obiekt MLflowTracezawierający zakresy, atrybuty i inne metadane dotyczące wykonywania agenta. Pozwala to na głęboką inspekcję wewnętrznych kroków podjętych przez agenta. -
custom_expected: słownik do przekazywania wartości oczekiwanych zdefiniowanych przez użytkownika. To pole zapewnia elastyczność dołączania dodatkowych oczekiwań niestandardowych, które nie są objęte polami standardowymi. -
tool_calls: Lista ToolCallInvocation, która opisuje, które narzędzia zostały wywołane i co zwróciły.
Wartość zwracana
Wartość zwracana metryki dostosowanej jest dla każdego wiersza określana jako Assessment. Jeśli zwracasz element pierwotny, jest on owinięty w Assessment z pustym uzasadnieniem.
-
float: w przypadku metryk liczbowych (np. wyników podobieństwa, wartości procentowe dokładności). -
bool: w przypadku metryk binarnych. -
Assessmentlublist[Assessment]: bogatszy typ danych wyjściowych obsługujący dodawanie uzasadnienia. Jeśli zwrócisz listę ocen, ta sama funkcja metryki może zostać ponownie użyta do zwrócenia wielu ocen.-
name: nazwa oceny. -
value: wartość (liczba zmiennoprzecinkowa, liczba całkowita, boolean lub ciąg). -
rationale: (Opcjonalnie) Uzasadnienie objaśniające sposób obliczania tej wartości. Może to być przydatne, aby pokazać dodatkowe rozumowanie w interfejsie użytkownika. To pole jest przydatne, na przykład podczas podawania rozumowania z modelu LLM, który wygenerował tę ocenę.
-
metryki zaliczone/niezaliczone
Każda metryka ciągu zwracająca "yes" i "no" jest traktowana jako metryka pass/fail i ma specjalne traktowanie w interfejsie użytkownika.
Możesz również utworzyć metrykę zaliczenie/niezaliczenie za pomocą zestawu SDK Python do oceniania. To daje ci większą kontrolę nad tym, które części śladu oceniać i które oczekiwane pola stosować. Możesz użyć dowolnych wbudowanych sędziów oceny agentów AI Mosaic. Zobacz Wbudowane sędziowie sztucznej inteligencji (MLflow 2).
Upewnij się, że pobrany kontekst nie zawiera danych osobowych (DPI).
W tym przykładzie wywoływany jest sędzia guideline_adherence, aby upewnić się, że pobrany kontekst nie zawiera 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'])
metryki liczbowe
Metryki numeryczne oceniają wartości numeryczne, takie jak liczby zmiennoprzecinkowe lub liczby całkowite. Metryki liczbowe są wyświetlane w interfejsie użytkownika na wiersz wraz ze średnią wartością przebiegu oceny.
Przykład: podobieństwo odpowiedzi
Ta metryka mierzy podobieństwo między response a expected_response przy użyciu wbudowanej biblioteki języka Python 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'])
metryki boolowskie
Metryki logiczne przyjmują wartość True lub False. Są one przydatne w przypadku decyzji binarnych, takich jak sprawdzanie, czy odpowiedź spełnia prostą heurystyczną. Jeśli chcesz, aby metryka miała specjalne podejście "pass/fail" w interfejsie użytkownika, zobacz metryki "pass/fail".
Przykład: Sprawdzanie, czy żądania wejściowe są prawidłowo sformatowane
Ta metryka sprawdza, czy dowolne dane wejściowe są sformatowane zgodnie z oczekiwaniami i zwracają True, jeśli tak jest.
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']
Przykład: Samoodniesienie modelu językowego
Ta metryka sprawdza, czy odpowiedź wspomina "LLM" i zwraca True, jeśli tak.
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'])
Korzystanie z custom_expected
Pole custom_expected może być używane do przekazywania dowolnych innych oczekiwanych informacji do dostosowanej metryki.
Przykład: długość odpowiedzi ograniczona
W tym przykładzie pokazano, jak wymagać, aby długość odpowiedzi mieściła się w granicach (min_length, max_length) ustawionych dla każdego przykładu. Użyj custom_expected do przechowywania dowolnych informacji na poziomie wiersza, które mają być przekazywane do metryk niestandardowych podczas tworzenia oceny.
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'])
Potwierdzenia dotyczące śladów
Metryki niestandardowe mogą oceniać dowolną część śladu MLflow generowanego przez agenta, w tym sekcje, atrybuty i dane wyjściowe.
Przykład: klasyfikacja i routing żądań
W tym przykładzie utworzono agenta, który określa, czy zapytanie użytkownika jest pytaniem, czy instrukcją i zwraca je w języku angielskim dla użytkownika. W bardziej realistycznym scenariuszu można użyć tej techniki do kierowania różnych zapytań do różnych funkcji.
Zestaw oceny zapewnia, że klasyfikator typu zapytania generuje odpowiednie wyniki dla zestawu danych wejściowych przy użyciu niestandardowych metryk, które analizują ścieżkę MLFlow.
W tym przykładzie użyto MLflow Trace.search_spans do znalezienia zakresów typu KEYWORD, który jest niestandardowym typem zakresu zdefiniowanym dla tego agenta.
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'])
Korzystając z tych przykładów, można zaprojektować metryki niestandardowe w celu spełnienia unikatowych potrzeb oceny.
Ocenianie wywołań narzędzi
Metryki niestandardowe będą dostarczane z tool_calls, które stanowią listę wywołań ToolCallInvocation, dającą informacje o tym, które narzędzia zostały wywołane i co zwróciły.
Przykład: deklarowanie właściwego narzędzia nazywa się
Notatka
Ten przykład nie jest możliwy do skopiowania, ponieważ nie definiuje agenta LangGraph. Zapoznaj się z dołączonym notesem , aby uzyskać w pełni działający przykład.
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()
Opracowywanie metryk niestandardowych
Podczas opracowywania metryk należy dokonywać szybkich iteracji na metrykach bez konieczności wykonywania agenta za każdym razem, gdy dokonujesz zmiany. Aby to ułatwić, użyj następującej strategii:
- Wygeneruj arkusz odpowiedzi przy użyciu agenta zestawu danych ewaluacyjnych. Uruchamia agenta dla każdego wpisu w zestawie oceny, generując odpowiedzi i ślady, które umożliwiają bezpośrednie użycie metryki.
- Zdefiniuj metryki.
- Wywołaj metrykę dla każdej wartości w arkuszu odpowiedzi bezpośrednio i iteruj nad definicją metryki.
- Gdy metryka działa zgodnie z oczekiwaniami, uruchom
mlflow.evaluate()na tym samym arkuszu odpowiedzi, aby zweryfikować, czy wyniki z procesu Oceny Agenta są zgodne z Twoimi przewidywaniami. Kod w tym przykładzie nie używa polamodel=, więc ocena używa wstępnie obliczonych odpowiedzi. - Jeśli wydajność metryki jest satysfakcjonująca, włącz pole
model=wmlflow.evaluate(), aby wywołać agenta interaktywnie.
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'])
Przykładowy notatnik
Poniższy przykładowy notes ilustruje kilka różnych sposobów używania metryk niestandardowych w narzędziu Mosaic AI Agent Evaluation.