Partager via


Jeux d’évaluation (MLflow 2)

Importante

Databricks recommande d’utiliser MLflow 3 pour évaluer et surveiller les applications GenAI. Cette page décrit l’évaluation de l’agent MLflow 2.

Pour mesurer la qualité d’un agent IA, vous devez être en mesure de définir un ensemble représentatif de requêtes, ainsi que des critères qui caractérisent des réponses de haute qualité. Vous faites cela en fournissant un jeu d’évaluation. Cet article décrit les différentes options de votre jeu d’évaluation et certaines bonnes pratiques pour la création d’un jeu d’évaluation.

Databricks recommande de créer un jeu d’évaluation étiqueté par l’homme, qui se compose de questions représentatives et de réponses de base. Si votre application inclut une étape de récupération, vous pouvez éventuellement fournir les documents de prise en charge sur lesquels vous attendez que la réponse soit basée. Pour vous aider à commencer à créer un jeu d’évaluation, Databricks fournit un Kit de développement logiciel (SDK) pour générer des questions synthétiques de haute qualité et des réponses de base qui peuvent être utilisées directement dans l’évaluation de l’agent, ou envoyées à des experts en matière à des fins de révision. Consultez Synthétiser des ensembles d’évaluation.

Un bon jeu d’évaluation présente les caractéristiques suivantes :

  • Représentatif : il doit refléter avec précision la plage de demandes que l’application rencontrera en production.
  • Difficile : il doit inclure des cas difficiles et variés pour tester efficacement la gamme complète des fonctionnalités de l’application.
  • Mise à jour continue : il doit être mis à jour régulièrement pour refléter l’utilisation de l’application et les modèles de changements de trafic de production.

Pour connaître le schéma requis d’un jeu d’évaluation, consultez Le schéma d’entrée d’évaluation de l’agent (MLflow 2).

Exemples de jeux d’évaluations

Cette section inclut des exemples simples de jeux d’évaluations.

Exemple de jeu d’évaluations avec uniquement request

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

Exemple de jeu d’évaluations avec request et 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.",
    }
]

Exemple de jeu d’évaluations avec request, expected_response et 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.",
    }
]

Exemple de jeu d’évaluations avec uniquement request etresponse

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.",
    }
]

Exemple de jeux d’évaluations avec un request formaté arbitrairement et response

eval_set = [
    {
        "request": {"query": "Difference between", "item_a": "reduceByKey", "item_b": "groupByKey"},
        "response": {
            "differences": [
                "reduceByKey aggregates data before shuffling",
                "groupByKey shuffles all data",
                "reduceByKey is more efficient",
            ]
        }
    }
]

Exemple de jeu d’évaluations avec request, response et guidelines

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.",
        # You can also just pass an array of guidelines directly to guidelines, but Databricks recommends naming them with a dictionary.
        "guidelines": {
            "english": ["The response must be in English"],
            "clarity": ["The response must be clear, coherent, and concise"],
        }
    }
]

Exemple d’ensemble d’évaluation avec request, response, guidelineset expected_facts

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.",
        "expected_facts": [
            "There's no significant difference.",
        ],
        # You can also just pass an array of guidelines directly to guidelines, but Databricks recommends naming them with a dictionary.
        "guidelines": {
            "english": ["The response must be in English"],
            "clarity": ["The response must be clear, coherent, and concise"],
        }
    }
]

Exemple de jeu d’évaluations avec request, response et 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",
            },
        ],
    }
]

Exemple de jeu d’évaluations avec request, response, retrieved_context, et expected_facts

eval_set  = [
    {
        "request_id": "request-id",
        "request": "What is the difference between reduceByKey and groupByKey in Spark?",
        "expected_facts": [
            "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",
            },
        ],
    }
]

Exemple de jeu d’évaluations avec request, response, retrieved_context, expected_facts, et expected_retrieved_context

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

Meilleures pratiques pour le développement d’un jeu d’évaluation

  • Considérez chaque exemple, ou groupe d’exemples, dans le jeu d’évaluations comme un test unitaire. Autrement dit, chaque exemple doit correspondre à un scénario spécifique avec un résultat attendu explicite. Par exemple, envisagez de tester des contextes plus longs, un raisonnement à plusieurs tronçons et le capacité à déduire des réponses à partir de preuves indirectes.
  • Envisagez de tester des scénarios contradictoires à partir d’utilisateurs malveillants.
  • Il n’existe aucune directive spécifique sur le nombre de questions à inclure dans un jeu d’évaluations, mais des signaux clairs provenant de données de haute qualité donnent généralement de meilleurs résultats que des signaux bruyants provenant de données de faible qualité.
  • Envisagez d’inclure des exemples auxquels il est très difficile, même pour les humains, de répondre.
  • Que vous développiez une application à usage général ou que vous cibliez un domaine spécifique, votre application rencontrera probablement un large éventail de questions. Le jeu d’évaluations devrait en tenir compte. Par exemple, si vous créez une application pour répondre à des questions RH spécifiques, vous devriez tout de même envisager de tester d’autres domaines (par exemple, les opérations) afin de vous assurer que l’application n'hallucine pas ou ne fournit pas de réponses nuisibles.
  • Des étiquettes cohérentes et de haute qualité générées par des humains sont le meilleur moyen de garantir que les valeurs de réalité du terrain que vous fournissez à l’application reflètent avec précision le comportement souhaité. Voici quelques étapes pour garantir des étiquettes humaines de grande qualité :
    • Agrégez les réponses (étiquettes) de plusieurs étiqueteurs humains pour la même question.
    • Assurez-vous que les instructions d’étiquetage sont claires et que les étiqueteurs humains sont cohérents.
    • Veillez à que les conditions du processus d’étiquetage humain sont identiques au format des requêtes soumises à l’application RAG.
  • Les étiqueteurs humains sont par nature bruyants et incohérents, par exemple en raison de différentes interprétations de la question. Il s’agit d’une partie importante du processus. L’utilisation de l’étiquetage humain peut révéler des interprétations de questions que vous n’aviez pas imaginées et qui pourraient fournir des informations de comportement que vous observez dans votre application.