Pular para o conteúdo principal

Enriquecer rastreamentos: tags, contexto e feedback

Depois de instrumentar o agente para emitir rastreamentos, você poderá enriquecer esses rastreamentos com informações adicionais que os tornam úteis para pesquisa, depuração e monitoramento de qualidade:

  • Tags e metadados — pares key-value para organizar, filtrar e anotar rastreamentos.
  • Contexto — ID do usuário, ID da sessão, ambiente e versão do agente para análise de coorte e depuração específica de implantação.
  • Feedback do usuário final — classificações e comentários capturados como avaliações em rastreamentos, fornecendo um sinal de qualidade de verdade fundamental (ground truth) da produção.

Um padrão de produção fundamental é o feedback do usuário final. Quando alguém clicar em polegar para cima ou para baixo, ou deixar um comentário no seu aplicativo implantado, registre-o como uma avaliação no rastreamento para essa interação. Manter o feedback anexado à execução de origem o torna imediatamente útil para fins posteriores — para depurar a solicitação específica e para criar datasets de avaliação a partir de sucessos e falhas reais.

Requisitos

Escolha o pacote adequado para o seu ambiente:

Bash
pip install --upgrade mlflow-tracing

O pacote mlflow-tracing tem dependências mínimas e é otimizado para uso em produção.

Crie um experimento do MLflow seguindo Set up your environment.


Tags e metadados

As tags são pares key-value mutáveis que você pode definir, atualizar ou excluir a qualquer momento — inclusive após o rastreamento ser registrado. Use tags para informações dinâmicas: status de revisão, rótulos de qualidade dos dados ou sinais de feedback do usuário.

Os metadados são imutáveis assim que o rastreamento é registrado. Use metadados para fatos estáveis capturados no momento da execução: versão do modelo, ambiente ou configuração.

API

Quando usar

mlflow.update_current_trace

Defina tags ou metadados em um rastreamento ativo durante a execução

mlflow.set_trace_tag

Definir ou atualizar uma tag em um rastreamento concluído

mlflow.delete_trace_tag

Remover uma tag de um rastreamento concluído

IU do MLflow

Defina ou atualize as tags em um rastreamento concluído de forma interativa

API

Quando usar

mlflow.update_current_trace

Defina tags ou metadados em um rastreamento ativo durante a execução

mlflow.set_trace_tag

Definir ou atualizar uma tag em um rastreamento concluído

mlflow.delete_trace_tag

Remover uma tag de um rastreamento concluído

IU do MLflow

Defina ou atualize as tags em um rastreamento concluído de forma interativa

Definir tags e metadados durante a execução

Chame mlflow.update_current_trace dentro de uma função rastreada para anexar tags ou metadados enquanto o rastreamento estiver ativo:

Python
import mlflow

@mlflow.trace
def my_func(x):
mlflow.update_current_trace(
metadata={"model_version": "v1.2.3", "environment": "production"},
tags={"fruit": "apple"}
)
return x + 1

my_func(10)
nota

update_current_trace adiciona uma nova key ou sobrescreve uma key existente para tags . Para metadados , tentar atualizar uma key existente é ignorado silenciosamente — os metadados são imutáveis após definidos.

Definir tags em um rastreamento concluído

Para atualizar ou remover tags após o registro de um rastreamento:

Python
import mlflow

@mlflow.trace
def process_data(data):
return data.upper()

result = process_data("hello world")

trace_id = mlflow.get_last_active_trace_id()

mlflow.set_trace_tag(trace_id=trace_id, key="review_status", value="approved")
mlflow.set_trace_tag(trace_id=trace_id, key="data_quality", value="high")
mlflow.delete_trace_tag(trace_id=trace_id, key="data_quality")

Definir tags na IU

Navegue até o rastreamento e clique no ícone de lápis ao lado de qualquer tag para editá-la ou excluí-la.

Atualização de tag de rastreamento


Adicionar contexto aos rastreamentos

O contexto vincula rastreamentos a usuários, sessões, implantações e código — permitindo o agrupamento de conversas com várias entradas, análise de coorte de usuários e depuração específica de ambiente.

Chame mlflow.update_current_trace dentro da lógica do seu agente rastreado para anexar o contexto:

Python
import mlflow

mlflow.update_current_trace(
metadata={
"mlflow.trace.user": user_id,
"mlflow.trace.session": session_id,
},
tags={
"query_category": "chat",
},
)

After logging, access context via mlflow.search_traces() (the metadata and tags columns in the returned DataFrame), or directly on Trace objects via Trace.info.trace_metadata and Trace.info.tags.

Consulte Enriquecer rastreamentos: tags, contexto e feedback para ver um exemplo prático completo.

Campos de contexto padrão

O MLflow define campos de metadados padronizados para os tipos de contexto mais comuns. Quando você os usa, a interface do usuário ativa automaticamente a filtragem e o agrupamento por esses campos.

Context type

Campo do MLflow

Casos de uso

ID do usuário

mlflow.trace.user

Associar rastreamentos a usuários específicos para personalização, análise de coorte e depuração específica do usuário

ID da sessão

mlflow.trace.session

Agrupe rastreamentos de conversas em vários turnos para analisar o fluxo conversacional completo

ID de solicitação do cliente

client_request_id no(a) TraceInfo

Link rastreia chamadas de API upstream para depuração de ponta a ponta

Ambiente / versão

mlflow.source.type + metadados personalizados

Rastreie o contexto de implantação em diferentes ambientes e versões de agentes

Custom fields

(as suas chaves de metadados)

Qualquer contexto específico do agente: ID de implantação, região, sinalizadores de recursos

Context type

Campo do MLflow

Casos de uso

ID do usuário

mlflow.trace.user

Associar rastreamentos a usuários específicos para personalização, análise de coorte e depuração específica do usuário

ID da sessão

mlflow.trace.session

Agrupe rastreamentos de conversas em vários turnos para analisar o fluxo conversacional completo

ID de solicitação do cliente

client_request_id no(a) TraceInfo

Link rastreia chamadas de API upstream para depuração de ponta a ponta

Ambiente / versão

mlflow.source.type + metadados personalizados

Rastreie o contexto de implantação em diferentes ambientes e versões de agentes

Custom fields

(as suas chaves de metadados)

Qualquer contexto específico do agente: ID de implantação, região, sinalizadores de recursos

Campos preenchidos automaticamente

O MLflow define automaticamente vários campos de metadados do seu ambiente de execução. Você pode substituir qualquer um deles por mlflow.update_current_trace quando a detecção default não atender aos seus requisitos.

Campo de metadados

Descrição

Definição automática a partir de

mlflow.source.name

Ponto de entrada ou nome do script

Nome do arquivo Python; nome do notebook do Databricks

mlflow.source.git.commit

Hash do commit do Git

Repositório git atual

mlflow.source.git.branch

Nome da branch do Git

Repositório git atual

mlflow.source.git.repoURL

URL do repositório do Git

Repositório git atual

mlflow.source.type

Ambiente de execução

NOTEBOOK (Jupyter/Databricks), LOCAL (script Python), UNKNOWN caso contrário

mlflow.sourceRun

ID de execução de origem

Execução ativa do MLflow

metadata.mlflow.modelId

ID do LoggedModel do MLflow

MLFLOW_ACTIVE_MODEL_ID variável de ambiente ou mlflow.set_active_model()

Campo de metadados

Descrição

Definição automática a partir de

mlflow.source.name

Ponto de entrada ou nome do script

Nome do arquivo Python; nome do notebook do Databricks

mlflow.source.git.commit

Hash do commit do Git

Repositório git atual

mlflow.source.git.branch

Nome da branch do Git

Repositório git atual

mlflow.source.git.repoURL

URL do repositório do Git

Repositório git atual

mlflow.source.type

Ambiente de execução

NOTEBOOK (Jupyter/Databricks), LOCAL (script Python), UNKNOWN caso contrário

mlflow.sourceRun

ID de execução de origem

Execução ativa do MLflow

metadata.mlflow.modelId

ID do LoggedModel do MLflow

MLFLOW_ACTIVE_MODEL_ID variável de ambiente ou mlflow.set_active_model()

Para metadados de implantação como ambiente e versão, extraia valores de variáveis de ambiente em vez de codificá-los rigidamente:

Python
import mlflow
import os

mlflow.update_current_trace(
metadata={
"mlflow.source.type": os.getenv("APP_ENVIRONMENT", "development"),
}
)

Práticas recomendadas

  1. Formatos de ID consistentes — Use formatos padronizados para IDs de usuário e de sessão em todo o agente.
  2. Limites de sessão — Defina regras claras para quando as sessões começam e terminam.
  3. Variáveis de ambiente — Preencha metadados a partir de variáveis de ambiente em vez de usar valores codificados rigidamente.
  4. Combine context types — Rastreie o contexto do usuário, da sessão e do ambiente juntos.
  5. Análise regular — Configure dashboards para monitorar o comportamento do usuário, os padrões de sessão e o desempenho da versão.
  6. Substituir os values default com cuidado — Só substitua metadados preenchidos automaticamente quando o valor detectado automaticamente não se adequar à sua implantação.

Coletar feedback do usuário

O feedback do usuário final fornece um sinal de verdade fundamental sobre a qualidade real do seu agente. O MLflow captura o feedback como avaliações — uma entidade estruturada permanentemente anexada a um rastreamento — para que cada classificação permaneça associada à interação exata que a motivou.

Avaliações de rastreamento

Tipos de feedback

Tipo de feedback

Descrição

Casos de uso comuns

binário

Polegar para cima/para baixo ou correto/incorreto

Sinais de satisfação rápidos

Numérico

Avaliações em uma escala (por exemplo, 1–5 estrelas)

Avaliação detalhada da qualidade

Categórico

Opções de múltipla escolha

Classificando problemas ou tipos de resposta

Texto

Comentários em formato livre

Explicações detalhadas do usuário

Tipo de feedback

Descrição

Casos de uso comuns

binário

Polegar para cima/para baixo ou correto/incorreto

Sinais de satisfação rápidos

Numérico

Avaliações em uma escala (por exemplo, 1–5 estrelas)

Avaliação detalhada da qualidade

Categórico

Opções de múltipla escolha

Classificando problemas ou tipos de resposta

Texto

Comentários em formato livre

Explicações detalhadas do usuário

Feedback data model

O feedback do usuário é capturado como uma entidade Feedback (um tipo de Avaliação) anexada a um rastreamento ou intervalo. Cada entidade de feedback armazena:

  • Valor — o sinal de feedback (booleano, numérico, texto ou dados estruturados)
  • Source — um AssessmentSource que identifica quem forneceu o feedback (consulte abaixo)
  • Rationale — explicação opcional para o feedback
  • Metadados — contexto adicional, como Timestamp ou atributos personalizados

Campos AssessmentSource

The AssessmentSource object on every feedback assessment identifies the origin of the feedback:

  • source_type"HUMAN" para feedback do usuário final, "LLM_JUDGE" para avaliação automatizada
  • source_id — o usuário ou sistema específico que forneceu o feedback (por exemplo, uma string de ID de usuário ou identificador de avaliador)

Passe ambos os campos ao chamar mlflow.log_feedback:

Python
from mlflow.entities import AssessmentSource

mlflow.log_feedback(
trace_id=trace_id,
name="user_feedback",
value=True,
source=AssessmentSource(source_type="HUMAN", source_id=user_id),
rationale="The answer was accurate and helpful.",
)

Para registrar o feedback, você precisa associar a resposta do usuário a um rastreamento específico. Duas abordagens:

Abordagem 1 — Usar o ID de rastreamento do MLflow (mais simples): recupere o ID de rastreamento gerado pelo MLflow durante a solicitação e retorne-o ao cliente. O cliente o envia de volta com o feedback.

Abordagem 2 — Usar um ID de solicitação do cliente (mais controle): gere seu próprio ID exclusivo por solicitação, anexe-o como uma tag de rastreamento e, em seguida, pesquise o rastreamento por essa tag quando o feedback chegar. Útil quando você já tem um sistema de acompanhamento de solicitações.

atenção

Se você implantar seu agente em um Endpoint do Databricks Model Serving, defina client_request_id como uma tag (e não como um atributo). Usar update_current_trace(client_request_id=...) como um atributo de metadados interrompe a exportação de rastreamentos em ambientes de serviço. Se você precisar usar o Model Serving, prefira a Abordagem 1 (IDs de rastreamento do MLflow) ou defina client_request_id por meio de update_current_trace(tags={"client_request_id": ...}).

Backend

Python
import mlflow
from fastapi import FastAPI, Query
from mlflow.entities import AssessmentSource
from pydantic import BaseModel
from typing import Optional

app = FastAPI()

class ChatRequest(BaseModel):
message: str

class ChatResponse(BaseModel):
response: str
trace_id: str # Return the trace ID so the client can reference it for feedback

@app.post("/chat", response_model=ChatResponse)
def chat(request: ChatRequest):
response = process_message(request.message) # Your agent logic here
trace_id = mlflow.get_current_active_span().trace_id
return ChatResponse(response=response, trace_id=trace_id)

class FeedbackRequest(BaseModel):
is_correct: bool
comment: Optional[str] = None

@app.post("/feedback")
def submit_feedback(
trace_id: str = Query(..., description="Trace ID from the chat response"),
feedback: FeedbackRequest = ...,
user_id: Optional[str] = Query(None)
):
mlflow.log_feedback(
trace_id=trace_id,
name="user_feedback",
value=feedback.is_correct,
source=AssessmentSource(source_type="HUMAN", source_id=user_id),
rationale=feedback.comment
)
return {"status": "success", "trace_id": trace_id}

Frontend (React)

JavaScript
import React, { useState } from 'react';

function ChatWithFeedback() {
const [message, setMessage] = useState('');
const [response, setResponse] = useState('');
const [traceId, setTraceId] = useState(null);
const [feedbackSubmitted, setFeedbackSubmitted] = useState(false);

const sendMessage = async () => {
const res = await fetch('/chat', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ message }),
});
const data = await res.json();
setResponse(data.response);
setTraceId(data.trace_id);
setFeedbackSubmitted(false);
};

const submitFeedback = async (isCorrect, comment = null) => {
if (!traceId || feedbackSubmitted) return;
const params = new URLSearchParams({ trace_id: traceId });
await fetch(`/feedback?${params}`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ is_correct: isCorrect, comment }),
});
setFeedbackSubmitted(true);
};

return (
<div>
<input value={message} onChange={(e) =&gt; setMessage(e.target.value)} placeholder="Ask a question..." />
<button onClick={sendMessage}>Send</button>
{response && (
<div>
<p>{response}</p>
<div>
<button onClick={() =&gt; submitFeedback(true)} disabled={feedbackSubmitted}>
👍
</button>
<button onClick={() =&gt; submitFeedback(false)} disabled={feedbackSubmitted}>
👎
</button>
</div>
{feedbackSubmitted && Thanks for your feedback!</span>}
</div>
)}
</div>
);
}

Feedback multidimensional

Registre várias avaliações nomeadas em um único rastreamento para capturar dimensões de qualidade separadas:

Python
from mlflow.entities import AssessmentSource

@app.post("/detailed-feedback")
def submit_detailed_feedback(
trace_id: str,
accuracy: int = Query(..., ge=1, le=5, description="Accuracy rating 1–5"),
helpfulness: int = Query(..., ge=1, le=5, description="Helpfulness rating 1–5"),
relevance: int = Query(..., ge=1, le=5, description="Relevance rating 1–5"),
user_id: str = Query(...),
comment: Optional[str] = None
):
dimensions = {"accuracy": accuracy, "helpfulness": helpfulness, "relevance": relevance}
for dimension, score in dimensions.items():
mlflow.log_feedback(
trace_id=trace_id,
name=f"user_{dimension}",
value=score / 5.0, # Normalize to 0–1 scale
source=AssessmentSource(source_type="HUMAN", source_id=user_id),
rationale=comment if dimension == "accuracy" else None
)
return {"status": "success", "trace_id": trace_id, "feedback_recorded": dimensions}

Respostas em transmissão

Com transmissão (SSE ou WebSockets), o ID de rastreamento não estará disponível até que a transmissão seja concluída. Retorne-o como um evento de transmissão final e desative os controles de feedback até que ele chegue.

Backend (FastAPI SSE)

Python
from fastapi import FastAPI
from fastapi.responses import StreamingResponse
import mlflow, json, asyncio
from typing import AsyncGenerator

@app.post("/chat/stream")
async def chat_stream(request: ChatRequest):
async def generate() -> AsyncGenerator[str, None]:
try:
with mlflow.start_span(name="streaming_chat") as span:
full_response = ""
async for token in your_llm_stream_function(request.message):
full_response += token
yield f"data: {json.dumps({'type': 'token', 'content': token})}\n\n"
await asyncio.sleep(0.01) # Prevent overwhelming the client
span.set_attribute("response", full_response)
span.set_attribute("token_count", len(full_response.split()))
# Send trace ID as the final event
yield f"data: {json.dumps({'type': 'done', 'trace_id': span.trace_id})}\n\n"
except Exception as e:
yield f"data: {json.dumps({'type': 'error', 'error': str(e)})}\n\n"

return StreamingResponse(
generate(),
media_type="text/event-stream",
headers={
&quot;Cache-Control&quot;: &quot;no-cache&quot;,
&quot;Connection&quot;: &quot;keep-alive&quot;,
&quot;X-Accel-Buffering&quot;: &quot;no&quot;, # Disable proxy buffering
},
)

No frontend, leia a transmissão, acumule token eventos no texto de resposta e capture a ID de rastreamento do evento done final. Use traceId && !isStreaming como a condição para habilitar os controles de feedback.

Notas de implementação principais:

  • O ID do rastreamento só fica disponível após a conclusão da transmissão — projete sua interface para desativar os controles de feedback até que ele chegue.
  • Use um formato de evento consistente com um campo type para distinguir tokens de conteúdo, eventos de conclusão e erros.
  • Defina X-Accel-Buffering: no para desativar o buffer de proxy.
  • Implemente o buffer de linha no frontend para lidar com mensagens SSE parciais.
  • Include error events in the transmissão so failures are logged to the trace and visible to the user.

Analisar feedback

Visualize o feedback na interface do usuário do MLflow abrindo qualquer rastreamento — as avaliações aparecem junto aos dados do intervalo.

IU de avaliações de rastreamento

Feedback do usuário sobre o rastreamento

Query e agregue o feedback programaticamente:

Python
from mlflow.client import MlflowClient
from datetime import datetime, timedelta

def analyze_user_feedback(experiment_name: str, hours: int = 24):
client = MlflowClient()
cutoff_ms = int((datetime.now() - timedelta(hours=hours)).timestamp() * 1000)
traces = client.search_traces(
experiment_names=[experiment_name],
filter_string=f"trace.timestamp_ms > {cutoff_ms}"
)

total = len(traces)
with_feedback = positive = negative = 0

for trace in traces:
detail = client.get_trace(trace.info.trace_id)
if detail.data.assessments:
with_feedback += 1
for a in detail.data.assessments:
if a.name == "user_feedback":
if a.value:
positive += 1
else:
negative += 1

feedback_rate = (with_feedback / total * 100) if total else 0
positive_rate = (positive / with_feedback * 100) if with_feedback else 0
print(f"Feedback rate: {feedback_rate:.1f}% Positive: {positive_rate:.1f}%")
print(f"Total feedback: {with_feedback} of {total} traces")

analyze_user_feedback("/Shared/production-genai-agent")

O mesmo padrão se estende ao feedback multidimensional: faça a iteração sobre as avaliações de cada rastreamento e agrupe a.value por a.name para calcular a média de cada dimensão de classificação separadamente.


Outros recursos

Próximo passo: Armazenar rastreamentos do OpenTelemetry no Unity Catalog