Pular para o conteúdo principal

Monitorar GenAI em produção

info

Beta

Este recurso está em versão Beta. Os administradores do espaço de trabalho podem controlar o acesso a este recurso na página de Pré-visualizações . Veja as prévias do Gerenciador Databricks.

O monitoramento de produção para GenAI no Databricks permite que você execute automaticamente os scorers MLflow 3 em rastros de seus aplicativos de produção GenAI para monitorar continuamente a qualidade.

Você pode programar pontuadores para avaliar automaticamente uma amostra do seu tráfego de produção. Os resultados da avaliação do pontuador são automaticamente anexados como feedback aos traços avaliados.

O monitoramento da produção inclui o seguinte:

  • Avaliação de qualidade automatizada usando pontuadores integrados ou personalizados.
  • Taxas de amostragem configuráveis para que você possa controlar a compensação entre cobertura e custo computacional.
  • Use os mesmos avaliadores no desenvolvimento e na produção para garantir uma avaliação consistente.
  • Avaliação contínua da qualidade com monitoramento em segundo plano.
nota

MLflow O monitoramento da produção 3 é compatível com os registros de traços do site MLflow 2.

Para informações sobre monitoramento de produção legado, consulte Referência API de monitoramento de produção (legado).

Pré-requisitos

Antes de configurar o monitoramento de qualidade, certifique-se de que possui:

  • ExperimentoMLflow : Um experimento MLflow onde os rastros estão sendo registrados. Se nenhum experimento for especificado, o experimento ativo será usado.

  • Aplicação de produção instrumentada : seu aplicativo GenAI deve estar registrando rastreamentos usando o MLflow Tracing. Consulte o guia Rastreamento de produção.

  • Pontuadores definidos : Pontuadores testados que funcionam com o formato de rastreamento do seu aplicativo. Se você usou seu aplicativo de produção como o predict_fn em mlflow.genai.evaluate() durante o desenvolvimento, seus avaliadores provavelmente já são compatíveis.

  • IDSQL warehouse (para rastreamentos Unity Catalog ) : Se seus rastreamentos estiverem armazenados no Unity Catalog, você deve configurar um ID SQL warehouse para que o monitoramento funcione. Consulte Ativar o monitoramento de produção.

Iniciar o monitoramento da produção

Esta seção inclui um exemplo de código que mostra como criar os diferentes tipos de marcadores.

Para mais informações sobre os pontuadores, veja o seguinte:

nota

A qualquer momento, no máximo 20 avaliadores podem estar associados a um experimento para monitoramento contínuo da qualidade.

Crie e programe juízes LLM usando a interface do usuário.

Você pode usar a interface do usuário do MLflow para criar e testar avaliadores com base em juízes de mestrado em direito (LLM).

avaliadores registrados

  1. Acesse a tab "Scorers" na interface do usuário do experimento MLflow .
  2. Clique em Novo Marcador .
  3. Selecione o seu juiz integrado LLM no menu suspenso LLM padrão .
  4. (Opcional) Clique em Pontuador de execução para executar um subconjunto de seus rastreamentos.
  5. (Opcional) Ajuste as configurações de avaliação para monitoramento da produção em rastreamentos futuros.
  6. Clique em Criar marcador .

Use juízes LLM integrados

MLflow fornece vários juízes LLM integrados que você pode usar imediatamente para monitoramento.

Python
from mlflow.genai.scorers import Safety, ScorerSamplingConfig

# Register the scorer with a name and start monitoring
safety_judge = Safety().register(name="my_safety_judge") # name must be unique to experiment
safety_judge = safety_judge.start(sampling_config=ScorerSamplingConfig(sample_rate=0.7))

Por default, cada juiz usa um LLM hospedado Databricks , projetado para realizar avaliações de qualidade do GenAI. Você pode alterar o modelo do juiz para usar um endpoint do modelo de atendimento Databricks usando o argumento model na definição do pontuador. O modelo deve ser especificado no formato databricks:/<databricks-serving-endpoint-name>.

Python
safety_judge = Safety(model="databricks:/databricks-gpt-oss-20b").register(name="my_custom_safety_judge")

Diretrizes de uso para juízes do LLM

As diretrizes para o exame LLM definem que os avaliadores devem analisar as entradas e saídas usando critérios de linguagem natural de aprovação/reprovação.

Python
from mlflow.genai.scorers import Guidelines

# Create and register the guidelines scorer
english_judge = Guidelines(
name="english",
guidelines=["The response must be in English"]
).register(name="is_english") # name must be unique to experiment

# Start monitoring with the specified sample rate
english_judge = english_judge.start(sampling_config=ScorerSamplingConfig(sample_rate=0.7))

Assim como os juízes integrados, você pode alterar o modelo do juiz para usar um endpoint do modelo servindo Databricks .

Python
english_judge = Guidelines(
name="english",
guidelines=["The response must be in English"],
model="databricks:/databricks-gpt-oss-20b",
).register(name="custom_is_english")

Use juízes LLM com prompts personalizados

Para maior flexibilidade do que os avaliadores das Diretrizes, utilize os Avaliadores LLM com instruções personalizadas , que permitem uma avaliação de qualidade em vários níveis com categorias de escolha personalizáveis e pontuação numérica.

Python
from mlflow.genai.scorers import scorer, ScorerSamplingConfig


@scorer
def formality(inputs, outputs, trace):
# Must be imported inline within the scorer function body
from mlflow.genai.judges import custom_prompt_judge
from mlflow.entities.assessment import DEFAULT_FEEDBACK_NAME

formality_prompt = """
You will look at the response and determine the formality of the response.

<request>{{request}}</request>
<response>{{response}}</response>

You must choose one of the following categories.

[[formal]]: The response is very formal.
[[semi_formal]]: The response is somewhat formal. The response is somewhat formal if the response mentions friendship, etc.
[[not_formal]]: The response is not formal.
"""

my_prompt_judge = custom_prompt_judge(
name="formality",
prompt_template=formality_prompt,
numeric_values={
"formal": 1,
"semi_formal": 0.5,
"not_formal": 0,
},
model="databricks:/databricks-gpt-oss-20b", # optional
)

result = my_prompt_judge(request=inputs, response=inputs)
if hasattr(result, "name"):
result.name = DEFAULT_FEEDBACK_NAME
return result

# Register the custom judge and start monitoring
formality_judge = formality.register(name="my_formality_judge") # name must be unique to experiment
formality_judge = formality_judge.start(sampling_config=ScorerSamplingConfig(sample_rate=0.1))

Use funções personalizadas de pontuação

Para máxima flexibilidade, defina e utilize uma função de pontuação personalizada.

Ao definir avaliadores personalizados, não utilize dicas de tipo que precisem ser importadas na assinatura da função. Se o corpo da função de avaliação usar pacotes que precisam ser importados, importe-os diretamente na função para garantir a serialização correta.

Alguns pacotes estão disponíveis em default sem a necessidade de uma importação inline. Estes incluem databricks-agents, mlflow-skinny, openai e todos os pacotes incluídos na versão 2 do ambiente sem servidor.

Python
from mlflow.genai.scorers import scorer, ScorerSamplingConfig


# Custom metric: Check if response mentions Databricks
@scorer
def mentions_databricks(outputs):
"""Check if the response mentions Databricks"""
return "databricks" in str(outputs.get("response", "")).lower()

# Custom metric: Response length check
@scorer(aggregations=["mean", "min", "max"])
def response_length(outputs):
"""Measure response length in characters"""
return len(str(outputs.get("response", "")))

# Custom metric with multiple inputs
@scorer
def response_relevance_score(inputs, outputs):
"""Score relevance based on keyword matching"""
query = str(inputs.get("query", "")).lower()
response = str(outputs.get("response", "")).lower()

# Simple keyword matching (replace with your logic)
query_words = set(query.split())
response_words = set(response.split())

if not query_words:
return 0.0

overlap = len(query_words & response_words)
return overlap / len(query_words)

# Register and start monitoring custom scorers
databricks_scorer = mentions_databricks.register(name="databricks_mentions")
databricks_scorer = databricks_scorer.start(sampling_config=ScorerSamplingConfig(sample_rate=0.5))

length_scorer = response_length.register(name="response_length")
length_scorer = length_scorer.start(sampling_config=ScorerSamplingConfig(sample_rate=1.0))

relevance_scorer = response_relevance_score.register(name="response_relevance_score") # name must be unique to experiment
relevance_scorer = relevance_scorer.start(sampling_config=ScorerSamplingConfig(sample_rate=1.0))

Configuração de vários marcadores

Para uma configuração de monitoramento abrangente, registre-se e comece vários marcadores individualmente.

Python
from mlflow.genai.scorers import Safety, Guidelines, ScorerSamplingConfig, list_scorers

# # Register multiple scorers for comprehensive monitoring
safety_judge = Safety().register(name="safety") # name must be unique within an MLflow experiment
safety_judge = safety_judge.start(
sampling_config=ScorerSamplingConfig(sample_rate=1.0), # Check all traces
)

guidelines_judge = Guidelines(
name="english",
guidelines=["Response must be in English"]
).register(name="english_check")
guidelines_judge = guidelines_judge.start(
sampling_config=ScorerSamplingConfig(sample_rate=0.5), # Sample 50%
)

# List and manage all scorers
all_scorers = list_scorers()
for scorer in all_scorers:
if scorer.sample_rate > 0:
print(f"{scorer.name} is active")
else:
print(f"{scorer.name} is stopped")

Ciclo de vida do marcador

Os ciclos de vida dos avaliadores são centrados em experimentos do MLflow. A tabela a seguir lista os estados do ciclo de vida do avaliador.

Os marcadores são imutáveis , portanto, uma operação de ciclo de vida não modifica o marcador original. Em vez disso, retorna uma nova instância de avaliador.

Status

Descrição

API

Não registrado

A função de pontuação está definida, mas não é conhecida pelo servidor.

Registrado

O avaliador está registrado no experimento MLflow ativo.

.register()

Ativas

O Scorer está sendo executado com uma taxa de amostragem > 0.

.start()

Parado

O sistema de pontuação está registrado, mas não está em execução (taxa de amostragem = 0).

.stop()

Excluído

O avaliador foi removido do servidor e não está mais associado ao experimento MLflow.

delete_scorer()

Ciclo de vida básico do scorer

Python
from mlflow.genai.scorers import Safety, scorer, ScorerSamplingConfig

# Built-in scorer lifecycle
safety_judge = Safety().register(name="safety_check")
safety_judge = safety_judge.start(
sampling_config=ScorerSamplingConfig(sample_rate=1.0),
)
safety_judge = safety_judge.update(
sampling_config=ScorerSamplingConfig(sample_rate=0.8),
)
safety_judge = safety_judge.stop()
delete_scorer(name="safety_check")

# Custom scorer lifecycle
@scorer
def response_length(outputs):
return len(str(outputs.get("response", "")))

length_scorer = response_length.register(name="length_check")
length_scorer = length_scorer.start(
sampling_config=ScorerSamplingConfig(sample_rate=0.5),
)

marcadores

As seguintes APIs estão disponíveis para gerenciar os avaliadores.

API

Descrição

Exemplo

list_scorers()

Liste todos os avaliadores registrados para o experimento atual.

Liste os pontuadores atuais

get_scorer()

Recupere o nome de um avaliador registrado.

Obtenha e atualize um marcador.

Scorer.update()

Modifique a configuração de amostragem de um avaliador ativo. Esta é uma operação imutável.

Obtenha e atualize um marcador.

backfill_scorer()

Aplicar retroativamente métricas novas ou atualizadas a registros históricos.

Avaliar traços históricos (preenchimento de métricas)

delete_scorer()

Excluir um avaliador registrado pelo nome.

Pare e exclua os marcadores

Liste os pontuadores atuais.

Para view todos os avaliadores registrados para o seu experimento:

Python
from mlflow.genai.scorers import list_scorers

# List all registered scorers
scorers = list_scorers()
for scorer in scorers:
print(f"Name: {scorer._server_name}")
print(f"Sample rate: {scorer.sample_rate}")
print(f"Filter: {scorer.filter_string}")
print("---")

Obtenha e atualize um marcador.

Para modificar as configurações existentes do marcador:

Python
from mlflow.genai.scorers import get_scorer

# Get existing scorer and update its configuration (immutable operation)
safety_judge = get_scorer(name="safety_monitor")
updated_judge = safety_judge.update(sampling_config=ScorerSamplingConfig(sample_rate=0.8)) # Increased from 0.5

# Note: The original scorer remains unchanged; update() returns a new scorer instance
print(f"Original sample rate: {safety_judge.sample_rate}") # Original rate
print(f"Updated sample rate: {updated_judge.sample_rate}") # New rate

Pare e exclua os marcadores

Para interromper o monitoramento ou remover um avaliador completamente:

Python
from mlflow.genai.scorers import get_scorer, delete_scorer

# Get existing scorer
databricks_scorer = get_scorer(name="databricks_mentions")

# Stop monitoring (sets sample_rate to 0, keeps scorer registered)
stopped_scorer = databricks_scorer.stop()
print(f"Sample rate after stop: {stopped_scorer.sample_rate}") # 0

# Remove scorer entirely from the server
delete_scorer(name=databricks_scorer.name)

# Or restart monitoring from a stopped scorer
restarted_scorer = stopped_scorer.start(sampling_config=ScorerSamplingConfig(sample_rate=0.5))

Atualizações imutáveis

Os avaliadores, incluindo os juízes do LLM, são objetos imutáveis. Ao atualizar um marcador de pontuação, você não modifica o marcador de pontuação original. Em vez disso, é criada uma cópia atualizada do marcador. Essa imutabilidade ajuda a garantir que os marcadores destinados à produção não sejam modificados acidentalmente. O trecho de código a seguir mostra como funcionam as atualizações imutáveis.

Python
# Demonstrate immutability
original_judge = Safety().register(name="safety")
original_judge = original_judge.start(
sampling_config=ScorerSamplingConfig(sample_rate=0.3),
)

# Update returns new instance
updated_judge = original_judge.update(
sampling_config=ScorerSamplingConfig(sample_rate=0.8),
)

# Original remains unchanged
print(f"Original: {original_judge.sample_rate}") # 0.3
print(f"Updated: {updated_judge.sample_rate}") # 0.8

Avaliar traços históricos (preenchimento de métricas)

É possível aplicar retroativamente métricas novas ou atualizadas a rastreamentos históricos.

Preenchimento básico de métricas utilizando taxas de amostragem atuais

Python
from databricks.agents.scorers import backfill_scorers

safety_judge = Safety()
safety_judge.register(name="safety_check")
safety_judge.start(sampling_config=ScorerSamplingConfig(sample_rate=0.5))

#custom scorer
@scorer(aggregations=["mean", "min", "max"])
def response_length(outputs):
"""Measure response length in characters"""
return len(outputs)

response_length.register(name="response_length")
response_length.start(sampling_config=ScorerSamplingConfig(sample_rate=0.5))

# Use existing sample rates for specified scorers
job_id = backfill_scorers(
scorers=["safety_check", "response_length"]
)

Preenchimento de métricas utilizando taxas de amostragem e intervalos de tempo personalizados

Python
from databricks.agents.scorers import backfill_scorers, BackfillScorerConfig
from datetime import datetime
from mlflow.genai.scorers import Safety, Correctness

safety_judge = Safety()
safety_judge.register(name="safety_check")
safety_judge.start(sampling_config=ScorerSamplingConfig(sample_rate=0.5))

#custom scorer
@scorer(aggregations=["mean", "min", "max"])
def response_length(outputs):
"""Measure response length in characters"""
return len(outputs)

response_length.register(name="response_length")
response_length.start(sampling_config=ScorerSamplingConfig(sample_rate=0.5))

# Define custom sample rates for backfill
custom_scorers = [
BackfillScorerConfig(scorer=safety_judge, sample_rate=0.8),
BackfillScorerConfig(scorer=response_length, sample_rate=0.9)
]

job_id = backfill_scorers(
experiment_id=YOUR_EXPERIMENT_ID,
scorers=custom_scorers,
start_time=datetime(2024, 6, 1),
end_time=datetime(2024, 6, 30)
)

Preenchimento de dados recentes

Python
from datetime import datetime, timedelta

# Backfill last week's data with higher sample rates
one_week_ago = datetime.now() - timedelta(days=7)

job_id = backfill_scorers(
scorers=[
BackfillScorerConfig(scorer=safety_judge, sample_rate=0.8),
BackfillScorerConfig(scorer=response_length, sample_rate=0.9)
],
start_time=one_week_ago
)

visualizar resultados

Após programar os avaliadores, aguarde 15 a 20 minutos para o processamento inicial. Então:

  1. Navegue até o seu experimento MLflow.
  2. Abra o Traces tab para visualizar as avaliações anexadas aos traços.
  3. Utilize os painéis de monitoramento para acompanhar as tendências de qualidade.

Melhores práticas

Gestão do estado do marcador

  • Verifique o estado do avaliador antes das operações usando sample_rate.
  • Utilize o padrão imutável. Atribua os resultados de .start(), .update(), .stop() às variáveis.
  • Entenda o ciclo de vida do marcador. .stop() preserva o registro, delete_scorer() remove o marcador completamente.

métricas de preenchimento

  • começar pequeno. Comece com intervalos de tempo menores para estimar a duração do trabalho e a utilização dos recursos.
  • Use taxas de amostragem apropriadas. Considere as implicações de custo e tempo do uso de altas taxas de amostragem.

Estratégia de amostragem

  • Para pontuações críticas, como verificações de segurança, use sample_rate=1.0.

  • Para avaliadores caros, como juízes LLM complexos, use taxas de amostragem mais baixas (0,05-0,2).

  • Para melhoria iterativa durante o desenvolvimento, use taxas moderadas (0,3-0,5).

  • Equilibre a cobertura com o custo, conforme mostrado nos exemplos a seguir:

    Python
    # High-priority scorers: higher sampling
    safety_judge = Safety().register(name="safety")
    safety_judge = safety_judge.start(sampling_config=ScorerSamplingConfig(sample_rate=1.0)) # 100% coverage for critical safety

    # Expensive scorers: lower sampling
    complex_scorer = ComplexCustomScorer().register(name="complex_analysis")
    complex_scorer = complex_scorer.start(sampling_config=ScorerSamplingConfig(sample_rate=0.05)) # 5% for expensive operations

Design de marcador personalizado

Mantenha os marcadores personalizados independentes, conforme mostrado no exemplo a seguir:

Python
@scorer
def well_designed_scorer(inputs, outputs):
# All imports inside the function
import re
import json

# Handle missing data gracefully
response = outputs.get("response", "")
if not response:
return 0.0

# Return consistent types
return float(len(response) > 100)

Solução de problemas

Os marcadores não estão correndo

Se os marcadores não estiverem em execução, verifique o seguinte:

  1. Verifique o experimento : certifique-se de que os rastreamentos são registros do experimento, e não de execuções individuais.
  2. Taxa de amostragem : Com taxas de amostragem baixas, pode demorar para ver os resultados.
  3. Verifique as strings de filtro : Certifique-se de que seu filter_string corresponda aos rastreamentos reais.

Problemas de serialização

Ao criar um marcador personalizado, inclua as importações na definição da função.

Python
# ❌ Avoid external dependencies
import external_library # Outside function

@scorer
def bad_scorer(outputs):
return external_library.process(outputs)

# ✅ Include imports in the function definition
@scorer
def good_scorer(outputs):
import json # Inside function
return len(json.dumps(outputs))

# ❌ Avoid using type hints in scorer function signature that requires imports
from typing import List

@scorer
def scorer_with_bad_types(outputs: List[str]):
return False

problemas de preenchimento de métricas

" Marcador programado 'X' não encontrado no experimento "

  • Certifique-se de que o nome do avaliador corresponda a um avaliador registrado em seu experimento.
  • Verifique os avaliadores disponíveis usando o método list_scorers .

Rastros de arquivo

O senhor pode salvar traços e suas avaliações associadas em uma tabela Delta do Unity Catalog para armazenamento de longo prazo e análise avançada. Isso é útil para criar painéis personalizados, realizar análises detalhadas dos dados de rastreamento e manter um registro duradouro do comportamento do seu aplicativo.

nota

O senhor deve ter as permissões necessárias para gravar na tabela Delta do Unity Catalog especificada. A tabela de destino será criada se ainda não existir.

Se a tabela já existir, os traços serão anexados a ela.

Habilitar rastreamentos de arquivamento

Para começar a arquivar rastreamentos para um experimento, use a função enable_databricks_trace_archival. O senhor deve especificar o nome completo da tabela Delta de destino, incluindo o catálogo e o esquema. Se você não fornecer um experiment_id, o arquivamento de rastreamentos será habilitado para o experimento atualmente ativo.

Python
from mlflow.tracing.archival import enable_databricks_trace_archival

# Archive traces from a specific experiment to a Unity Catalog Delta table
enable_databricks_trace_archival(
delta_table_fullname="my_catalog.my_schema.archived_traces",
experiment_id="YOUR_EXPERIMENT_ID",
)

Pare de arquivar rastros para um experimento a qualquer momento usando a função disable_databricks_trace_archival .

Python
from mlflow.tracing.archival import disable_databricks_trace_archival

# Stop archiving traces for the specified experiment
disable_databricks_trace_archival(experiment_id="YOUR_EXPERIMENT_ID")

Próximos passos

Guia de referência