Évaluation

Les évaluations sont une forme de test qui vous aide à valider les réponses de votre LLM et à vous assurer qu'elles répondent à vos critères de qualité.

Firebase Genkit est compatible avec les outils d'évaluation tiers via des plug-ins, associés à de puissantes fonctionnalités d'observabilité qui fournissent des insights sur l'état d'exécution de vos applications LLM. Les outils Genkit vous aident à extraire automatiquement des données, y compris des entrées, des sorties et des informations à partir d'étapes intermédiaires, afin d'évaluer la qualité de bout en bout des réponses du LLM, ainsi que de comprendre les performances des composants de votre système.

Par exemple, si vous disposez d'un flux RAG, Genkit extrait l'ensemble de documents renvoyés par le récupérateur afin que vous puissiez évaluer la qualité de votre récupérateur pendant son exécution dans le contexte du flux, comme indiqué ci-dessous avec les métriques de fidélité et de pertinence des réponses Genkit:

import { genkit } from 'genkit';
import { genkitEval, GenkitMetric } from '@genkit-ai/evaluator';
import { vertexAI, textEmbedding004, gemini15Flash } from '@genkit-ai/vertexai';

const ai = genkit({
  plugins: [
    vertexAI(),
    genkitEval({
      judge: gemini15Flash,
      metrics: [GenkitMetric.FAITHFULNESS, GenkitMetric.ANSWER_RELEVANCY],
      embedder: textEmbedding004, // GenkitMetric.ANSWER_RELEVANCY requires an embedder
    }),
  ],
  // ...
});

Remarque:La configuration ci-dessus nécessite d'installer les packages genkit, @genkit-ai/google-ai, @genkit-ai/evaluator et @genkit-ai/vertexai.

  npm install @genkit-ai/evaluator @genkit-ai/vertexai

Commencez par définir un ensemble d'entrées que vous souhaitez utiliser comme ensemble de données d'entrée appelé testInputs.json. Cet ensemble de données d'entrée représente les cas de test que vous utiliserez pour générer une sortie à des fins d'évaluation.

["Cheese", "Broccoli", "Spinach and Kale"]

Vous pouvez ensuite utiliser la commande eval:flow pour évaluer votre flux par rapport aux scénarios de test fournis dans testInputs.json.

genkit eval:flow menuSuggestionFlow --input testInputs.json

Vous pouvez ensuite consulter les résultats de l'évaluation dans l'UI du développeur en exécutant la commande suivante:

genkit start

Accédez ensuite à localhost:4000/evaluate.

Vous pouvez également fournir un fichier de sortie pour inspecter la sortie dans un fichier JSON.

genkit eval:flow menuSuggestionFlow --input testInputs.json --output eval-result.json

Remarque:Vous trouverez ci-dessous un exemple de la façon dont un LLM peut vous aider à générer des cas de test.

Évaluateurs acceptés

Évaluateurs Genkit

Genkit inclut un petit nombre d'évaluateurs natifs, inspirés de RAGAS, pour vous aider à vous lancer:

  • Fidélité
  • Pertinence des réponses
  • Malveillance

Plug-ins d'évaluation

Genkit est compatible avec d'autres évaluateurs via des plug-ins:

Utilisation avancée

eval:flow est un moyen pratique d'évaluer rapidement le flux, mais vous devrez peut-être parfois avoir plus de contrôle sur les étapes d'évaluation. Cela peut se produire si vous utilisez un autre framework et que vous disposez déjà d'une sortie que vous souhaitez évaluer. Vous pouvez effectuer toutes les étapes que eval:flow effectue de manière semi-manuelle.

Vous pouvez exécuter votre flux Genkit par lot et ajouter un libellé unique à l'exécution, qui sera ensuite utilisé pour extraire un ensemble de données d'évaluation (un ensemble d'entrées, de sorties et de contextes).

Exécutez le flux sur vos entrées de test:

genkit flow:batchRun myRagFlow test_inputs.json --output flow_outputs.json --label customLabel

Extrayez les données d'évaluation:

genkit eval:extractData myRagFlow --label customLabel --output customLabel_dataset.json

Les données exportées seront générées au format JSON, avec chaque testCase au format suivant:

[
  {
    "testCaseId": string,
    "input": string,
    "output": string,
    "context": array of strings,
    "traceIds": array of strings,
  }
]

L'extracteur de données localise automatiquement les récupérateurs et ajoute les documents produits au tableau de contexte. Par défaut, eval:run s'exécute sur tous les évaluateurs configurés. Comme pour eval:flow, les résultats de eval:run s'affichent sur la page d'évaluation de l'UI du développeur, située à l'adresse localhost:4000/evaluate.

Extracteurs personnalisés

Vous pouvez également fournir des extracteurs personnalisés à utiliser dans les commandes eval:extractData et eval:flow. Les extracteurs personnalisés vous permettent de remplacer la logique d'extraction par défaut, ce qui vous permet de créer et d'évaluer plus facilement des ensembles de données.

Pour configurer des extracteurs personnalisés, ajoutez un fichier de configuration d'outils nommé genkit-tools.conf.js à la racine de votre projet s'il n'en existe pas déjà un.

cd $GENKIT_PROJECT_HOME
touch genkit-tools.conf.js

Dans le fichier de configuration des outils, ajoutez le code suivant:

module.exports = {
  evaluators: [
    {
      actionRef: '/flow/myFlow',
      extractors: {
        context: { outputOf: 'foo-step' },
        output: 'bar-step',
      },
    },
  ],
};

Dans cet exemple, vous allez configurer un extracteur pour le flux myFlow. La configuration remplace les extracteurs pour les champs context et output, et utilise la logique par défaut pour le champ input.

La spécification des extracteurs d'évaluation est la suivante:

  • Le champ evaluators accepte un tableau d'objets EvaluatorConfig, qui sont définis par flowName.
  • extractors est un objet qui spécifie les forçages de l'extracteur. Les clés actuellement acceptées dans extractors sont [input, output, context]. Voici les types de valeurs acceptés :
    • string : doit être un nom d'étape, spécifié sous forme de chaîne. La sortie de cette étape est extraite pour cette clé.
    • { inputOf: string } ou { outputOf: string } : ces objets représentent des canaux spécifiques (entrée ou sortie) d'une étape. Par exemple, { inputOf: 'foo-step' } extrait l'entrée de l'étape foo-step pour cette clé.
    • (trace) => string; : pour plus de flexibilité, vous pouvez fournir une fonction qui accepte une trace Genkit et renvoie un string, et spécifier la logique d'extraction dans cette fonction. Consultez genkit/genkit-tools/common/src/types/trace.ts pour connaître le schéma TraceData exact.

Remarque:Les données extraites pour toutes ces étapes seront une chaîne JSON. Les outils analysent automatiquement cette chaîne JSON au moment de l'évaluation. Si vous fournissez un extracteur de fonction, assurez-vous que la sortie est une chaîne JSON valide. Par exemple, "Hello, world!" n'est pas un fichier JSON valide, mais "\"Hello, world!\"" l'est.

Exécuter sur des ensembles de données existants

Pour exécuter une évaluation sur un ensemble de données déjà extrait:

genkit eval:run customLabel_dataset.json

Pour effectuer la sortie dans un autre emplacement, utilisez l'option --output.

genkit eval:flow menuSuggestionFlow --input testInputs.json --output customLabel_evalresult.json

Pour exécuter sur un sous-ensemble des évaluateurs configurés, utilisez l'indicateur --evaluators et fournissez une liste d'évaluateurs par nom, séparés par une virgule:

genkit eval:run customLabel_dataset.json --evaluators=genkit/faithfulness,genkit/answer_relevancy

Synthétiser des données de test à l'aide d'un LLM

Voici un exemple de flux qui utilise un fichier PDF pour générer les questions que les utilisateurs pourraient se poser à son sujet.

import { genkit, run, z } from "genkit";
import { googleAI, gemini15Flash } from "@genkit-ai/googleai";
import { chunk } from "llm-chunk";

const ai = genkit({ plugins: [googleAI()] });

export const synthesizeQuestions = ai.defineFlow(
  {
    name: "synthesizeQuestions",
    inputSchema: z.string().describe("PDF file path"),
    outputSchema: z.array(z.string()),
  },
  async (filePath) => {
    filePath = path.resolve(filePath);
    const pdfTxt = await run("extract-text", () => extractText(filePath));

    const chunks = await run("chunk-it", async () =>
      chunk(pdfTxt, chunkingConfig)
    );

    const questions: string[] = [];
    for (var i = 0; i < chunks.length; i++) {
      const qResponse = await ai.generate({
        model: gemini15Flash,
        prompt: {
          text: `Generate one question about the text below: ${chunks[i]}`,
        },
      });
      questions.push(qResponse.text);
    }
    return questions;
  }
);

Vous pouvez ensuite utiliser cette commande pour exporter les données dans un fichier et les utiliser à des fins d'évaluation.

genkit flow:run synthesizeQuestions '"my_input.pdf"' --output synthesizedQuestions.json