Conjuntos de avaliação

Prévia

Este recurso está em Prévia pública.

Para medir a qualidade de um aplicativo agêntico, o senhor precisa ser capaz de definir o que é uma resposta precisa e de alta qualidade. O senhor faz isso fornecendo um conjunto de avaliação. Este artigo aborda o esquema necessário do conjunto de avaliação, quais métricas são calculadas com base em quais dados estão presentes no conjunto de avaliação e algumas práticas recomendadas para a criação de um conjunto de avaliação.

Databricks recomenda a criação de um conjunto de avaliação de rótulo humano. Esse é um conjunto de perguntas representativas e respostas verdadeiras. Opcionalmente, o senhor também pode fornecer os documentos de apoio nos quais espera que a resposta se baseie, caso sua solicitação inclua um passo a passo de recuperação.

Um bom conjunto de avaliação tem as seguintes características:

  • Representativo: deve refletir com precisão o intervalo de solicitações que o aplicativo encontrará na produção.

  • Desafiador: Deve incluir casos difíceis e diversos para testar efetivamente toda a gama de recursos do aplicativo.

  • Atualizada continuamente: deve ser atualizado regularmente para refletir como o aplicativo é usado e as mudanças nos padrões de tráfego de produção.

Para saber como executar uma avaliação utilizando o conjunto de avaliações, consulte Como executar uma avaliação e exibir os resultados.

Esquema do conjunto de avaliação

A tabela a seguir apresenta o esquema necessário para o DataFrame fornecido na chamada mlflow.evaluate().

Coluna

Tipo de dados

Descrição

Aplicativo passado como argumento de entrada

Saídas geradas fornecidas anteriormente

request_id

string

Identificador único da solicitação.

Opcional

Opcional

Solicitado

string

Entrada para o aplicativo avaliar, pergunta ou consulta do usuário. Por exemplo, "What is RAG?" (O que é RAG?). Consulte Esquema para solicitação.

Obrigatório

Obrigatório

expected_retrieved_context

array

Matriz de objetos que contém o contexto recuperado esperado para a solicitação (se o aplicativo incluir um passo de recuperação). Esquema de matriz

Opcional

Opcional

expected_response

string

Resposta (correta) da verdade fundamental para a solicitação de entrada.

Opcional

Opcional

Resposta

string

Resposta gerada pelo aplicativo que está sendo avaliado.

Gerado pela avaliação do agente

Opcional. Se não for fornecido, será derivado do Trace. É necessário response ou trace.

retrieved_context

array

Resultados de recuperação gerados pelo recuperador no aplicativo que está sendo avaliado. Se houver vários passos de recuperação no aplicativo, este será o resultado da recuperação do último passo (cronologicamente no rastreamento). Esquema de matriz

Gerado pela avaliação do agente

Opcional. Se não for fornecido, será derivado do rastreamento fornecido.

trace

Cadeia de caracteres JSON do MLflow Trace

MLflow Trace da execução do aplicativo na solicitação correspondente.

Gerado pela avaliação do agente

Opcional. É necessário response ou trace.

Esquema para solicitação

O esquema de solicitação pode ser um dos seguintes:

  • Uma corda simples. Esse formato é compatível apenas com conversas de turno único.

  • Um campo messages que segue o esquema de conclusão de bate-papo da OpenAI e pode codificar a conversa completa.

  • Um campo de cadeias de caracteres query para a solicitação mais recente e um campo history opcional que codifica os turnos anteriores da conversa.

Para aplicativos de bate-papo com várias voltas, use a segunda ou terceira opção acima.

O exemplo a seguir mostra todas as três opções na mesma coluna request da avaliação dataset:

import pandas as pd

data = {
  "request": [

      # Plain string
      "What is the difference between reduceByKey and groupByKey in Spark?",

      # Using the `messages` field for a single- or multi-turn chat
      {
          "messages": [
              {
                  "role": "user",
                  "content": "How can you minimize data shuffling in Spark?"
              }
          ]
      },

      # Using the query and history fields for a single- or multi-turn chat
      {
          "query": "Explain broadcast variables in Spark. How do they enhance performance?",
          "history": [
              {
                  "role": "user",
                  "content": "What are broadcast variables?"
              },
              {
                  "role": "assistant",
                  "content": "Broadcast variables allow the programmer to keep a read-only variable cached on each machine."
              }
          ]
      }
  ],

  "expected_response": [
    "expected response for first question",
    "expected response for second question",
    "expected response for third question"
  ]
}

eval_dataset = pd.DataFrame(data)

Esquema para matrizes no conjunto de avaliação

O esquema das matrizes expected_retrieved_context e retrieved_context é apresentado na tabela a seguir:

Coluna

Tipo de dados

Descrição

Aplicativo passado como argumento de entrada

Saídas geradas fornecidas anteriormente

conteúdo

string

Conteúdo do contexto recuperado. Cadeia de caracteres em qualquer formato, como HTML, texto sem formatação ou Markdown.

Opcional

Opcional

doc_uri

string

Identificador exclusivo (URI) do documento pai de onde veio a parte.

Obrigatório

Obrigatório

métricas disponíveis quando o aplicativo é passado por meio do argumento de entrada model

As métricas calculadas são determinadas pelos dados que o senhor fornece no conjunto de avaliação. A tabela mostra as dependências das avaliações que usam o aplicativo como argumento de entrada. As colunas indicam os dados incluídos no conjunto de avaliação, e um X indica que a métrica é suportada quando esses dados são fornecidos.

Para obter detalhes sobre o que essas métricas medem, consulte Usar métricas do agente & LLM judges para avaliar o desempenho do aplicativo.

Métricas calculadas

request

request e expected_response

request, expected_response, e expected_retrieved_context

response/llm_judged/relevance_to_query/rating

response/llm_judged/safety/rating

response/llm_judged/groundedness/rating

retrieval/llm_judged/chunk_relevance_precision

agent/total_token_count

agent/input_token_count

agent/output_token_count

response/llm_judged/correctness/rating

retrieval/ground_truth/document_recall

Exemplo de avaliação definido somente com request

eval_set = [
    {
        "request": "What is the difference between reduceByKey and groupByKey in Spark?",
    }
]

Exemplo de avaliação definido com request e expected_response

eval_set  = [
    {
        "request_id": "request-id",
        "request": "What is the difference between reduceByKey and groupByKey in Spark?",
        "expected_response": "There's no significant difference.",
    }
]

Exemplo de avaliação definido com request, expected_response e expected_retrieved_content

eval_set  = [
    {
        "request_id": "request-id",
        "request": "What is the difference between reduceByKey and groupByKey in Spark?",
        "expected_retrieved_context": [
            {
                "doc_uri": "doc_uri_1",
            },
            {
                "doc_uri": "doc_uri_2",
            },
        ],
        "expected_response": "There's no significant difference.",
    }
]

métricas disponíveis quando as saídas de aplicativos são fornecidas

As métricas calculadas são determinadas pelos dados que o senhor fornece no conjunto de avaliação. A tabela mostra as dependências para avaliações em que o senhor fornece um Dataframe com o conjunto de análise e os outputs do aplicativo. As colunas indicam os dados incluídos no conjunto de avaliação, e um X indica que a métrica é suportada quando esses dados são fornecidos.

Métricas calculadas

request e response

request, response, e retrieved_context

request, response, retrieved_context, e expected_response

request, response, retrieved_context, expected_response e expected_retrieved_context

response/llm_judged/relevance_to_query/rating

response/llm_judged/safety/rating

agent/request_token_count

agent/response_token_count

Juízes de LLM definidos pelo cliente

retrieval/llm_judged/chunk_relevance/precision

response/llm_judged/groundedness/rating

response/llm_judged/correctness/rating

retrieval/ground_truth/document_recall

Exemplo de avaliação definido somente comrequeste response

eval_set = [
    {
        "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.",
    }
]

Exemplo de avaliação definido com request, response e retrieved_context

eval_set = [
    {
        "request_id": "request-id", # optional, but useful for tracking
        "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.",
        "retrieved_context": [
            {
                # In `retrieved_context`, `content` is optional, but delivers additional functionality if provided (the Databricks Context Relevance LLM judge runs to check the relevance of the provided content 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",
            },
        ],
    }
]

Exemplo de avaliação definido com request, response, retrieved_context e expected_response

eval_set  = [
    {
        "request_id": "request-id",
        "request": "What is the difference between reduceByKey and groupByKey in Spark?",
        "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, but delivers additional functionality if provided (the Databricks Context Relevance LLM judge runs to check the relevance of the provided content 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",
            },
        ],
    }
]

Conjunto de avaliação de amostras com request, response, retrieved_context, expected_response e expected_retrieved_context

level_4_data  = [
    {
        "request_id": "request-id",
        "request": "What is the difference between reduceByKey and groupByKey in Spark?",
        "expected_retrieved_context": [
            {
                "doc_uri": "doc_uri_2_1",
            },
            {
                "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, but delivers additional functionality if provided (the Databricks Context Relevance LLM judge runs to check the relevance of the provided content 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",
            },
        ],
    }
]

Práticas recomendadas para desenvolver um conjunto de avaliação

  • Considere cada amostra, ou grupo de amostras, no conjunto de avaliação como um teste de unidade. Ou seja, cada amostra deve corresponder a um cenário específico com um resultado esperado explícito. Por exemplo, pense na possibilidade de testar contextos mais longos, raciocínio multihop e capacidade de inferir respostas a partir de evidências indiretas.

  • Você pode testar cenários adversos de usuários mal-intencionados.

  • Não há uma diretriz específica sobre o número de perguntas a serem incluídas em um conjunto de avaliação, mas sinais claros de dados de alta qualidade geralmente têm melhor desempenho do que sinais ruidosos de dados fracos.

  • Você pode incluir exemplos muito difíceis, até mesmo para os humanos responderem.

  • Quer você esteja criando um aplicativo de uso geral ou voltado para um domínio específico, seu aplicativo provavelmente encontrará uma grande variedade de perguntas. O conjunto de avaliação deve refletir isso. Por exemplo, se você for criar um aplicativo para responder a perguntas específicas de RH, ainda assim deve pensar em testar outros domínios (por exemplo, operações) para garantir que o aplicativo não tenha alucinações ou forneça respostas prejudiciais.

  • Os rótulos gerados por humanos, consistentes e de alta qualidade, são a melhor maneira de garantir que os valores da verdade básica que o senhor fornece ao aplicativo reflitam com precisão o comportamento desejado. Alguns dos passos para garantir um rótulo humano de alta qualidade são os seguintes:

    • Respostas agregadas (rótulos) de vários rotuladores humanos para a mesma pergunta.

    • Certifique-se de que as instruções de rotulagem sejam claras e que os rotuladores humanos sejam consistentes.

    • Assegurar que as condições para o processo de título humano sejam idênticas ao formato das solicitações enviadas para o aplicativo RAG.

  • Os rotuladores humanos são, por natureza, ruidosos e inconsistentes, por exemplo, devido a interpretações diferentes da pergunta. Isso é uma parte importante do processo. O uso da rotulagem humana pode revelar interpretações de questões que você não considerou e isso pode fornecer entendimento sobre o comportamento que você observa em sua aplicação.