Avaliação

As avaliações são uma forma de teste que ajuda a validar as respostas do LLM e garantir que elas atendam ao seu nível de qualidade.

O Firebase Genkit oferece suporte a ferramentas de avaliação de terceiros por meio de plug-ins, com recursos de observabilidade poderosos que fornecem insights sobre o estado de execução dos aplicativos com LLM. As ferramentas do Genkit ajudam a extrair automaticamente dados, incluindo entradas, saídas e informações de etapas intermediárias para avaliar a qualidade de ponta a ponta das respostas do LLM e entender o desempenho dos elementos básicos do sistema.

Por exemplo, se você tiver um fluxo RAG, o Genkit vai extrair o conjunto de documentos que foi retornado pelo retriever para que você possa avaliar a qualidade do retriever enquanto ele é executado no contexto do fluxo, conforme mostrado abaixo com as métricas de fidelidade e relevância da resposta do 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
    }),
  ],
  // ...
});

Observação:a configuração acima requer a instalação dos pacotes genkit, @genkit-ai/googleai, @genkit-ai/evaluator e @genkit-ai/vertexai.

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

Comece definindo um conjunto de entradas que você quer usar como um conjunto de dados de entrada chamado testInputs.json. Esse conjunto de dados de entrada representa os casos de teste que você vai usar para gerar saídas para avaliação.

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

Se o avaliador exigir uma saída de referência para avaliar um fluxo, você poderá transmitir a entrada e a saída de referência usando este formato:

{
  "samples": [
    {
      "input": "What is the French word for Cheese?",
      "reference": "Fromage"
    },
    {
      "input": "What green vegetable looks like cauliflower?",
      "reference": "Broccoli"
    }
  ]
}

Você pode usar qualquer tipo de dados JSON no arquivo JSON de entrada. O Genkit vai transmiti-los ao fluxo com o mesmo tipo de dados.

Em seguida, use o comando eval:flow para avaliar seu fluxo em relação aos casos de teste fornecidos em testInputs.json.

genkit eval:flow menuSuggestionFlow --input testInputs.json

Se o fluxo exigir autenticação, especifique-o usando o argumento --auth:

genkit eval:flow menuSuggestionFlow --input testInputs.json --auth "{\"email_verified\": true}"

Para conferir os resultados da avaliação na interface do desenvolvedor, execute:

genkit start

Depois, navegue até localhost:4000/evaluate.

Como alternativa, você pode fornecer um arquivo de saída para inspecionar a saída em um arquivo JSON.

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

Observação:abaixo, você pode conferir um exemplo de como um LLM pode ajudar a gerar os casos de teste.

Avaliadores com suporte

Avaliadores do Genkit

O Genkit inclui um pequeno número de avaliadores nativos, inspirados pelo RAGAS, para ajudar você a começar:

  • Fidelidade
  • Relevância da resposta
  • Malícia

Plug-ins de avaliação

O Genkit oferece suporte a outros avaliadores por meio de plug-ins, como os avaliadores rápidos da VertexAI, pelo VertexAI Plugin.

Uso avançado

eval:flow é uma maneira conveniente de avaliar rapidamente o fluxo, mas às vezes você precisa de mais controle sobre as etapas de avaliação. Isso pode ocorrer se você estiver usando uma framework diferente e já tiver alguma saída que gostaria de avaliar. Você pode realizar todas as etapas que o eval:flow executa de forma semimanual.

Você pode executar o fluxo do Genkit em lote e adicionar um rótulo exclusivo à execução, que será usado para extrair um conjunto de dados de avaliação (um conjunto de entradas, saídas e contextos).

Execute o fluxo nas entradas de teste:

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

Extraia os dados de avaliação:

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

Os dados exportados serão gerados como um arquivo JSON com cada testCase no formato a seguir:

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

O extrator de dados localiza automaticamente os extratores e adiciona os documentos produzidos à matriz de contexto. Por padrão, eval:run será executado em todos os avaliadores configurados. Assim como eval:flow, os resultados de eval:run vão aparecer na página de avaliação da interface para desenvolvedores, localizada em localhost:4000/evaluate.

Extratores personalizados

Também é possível fornecer extratores personalizados para serem usados nos comandos eval:extractData e eval:flow. Os extratores personalizados permitem que você substitua a lógica de extração padrão, dando mais poder na criação e avaliação de conjuntos de dados.

Para configurar extratores personalizados, adicione um arquivo de configuração de ferramentas chamado genkit-tools.conf.js à raiz do projeto, se ainda não tiver um.

cd $GENKIT_PROJECT_HOME
touch genkit-tools.conf.js

No arquivo de configuração de ferramentas, adicione este código:

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

Neste exemplo, você vai configurar um extrator para o fluxo myFlow. A configuração substitui os extratores dos campos context e output e usa a lógica padrão do campo input.

A especificação dos extratores de avaliação é a seguinte:

  • O campo evaluators aceita uma matriz de objetos EvaluatorConfig, que são limitados por flowName.
  • extractors é um objeto que especifica as substituições do extrator. As chaves atuais com suporte em extractors são [input, output, context]. Os tipos de valor aceitáveis são:
    • string: precisa ser o nome de uma etapa, especificado como uma string. A saída desta etapa é extraída para essa chave.
    • { inputOf: string } ou { outputOf: string }: esses objetos representam canais específicos (entrada ou saída) de uma etapa. Por exemplo, { inputOf: 'foo-step' } extrairia a entrada da etapa foo-step para essa chave.
    • (trace) => string;: para mais flexibilidade, você pode fornecer uma função que aceite um rastro do Genkit e retorne um string, além de especificar a lógica de extração dentro dessa função. Consulte genkit/genkit-tools/common/src/types/trace.ts para conferir o esquema exato do TraceData.

Observação:os dados extraídos para todas essas etapas serão uma string JSON. A ferramenta vai analisar essa string JSON automaticamente no momento da avaliação. Se você estiver fornecendo um extrator de função, verifique se a saída é uma string JSON válida. Por exemplo: "Hello, world!" não é um JSON válido; "\"Hello, world!\"" é válido.

Execução em conjuntos de dados

Para executar a avaliação em um conjunto de dados já extraído, faça o seguinte:

genkit eval:run customLabel_dataset.json

Para gerar saída em um local diferente, use a flag --output.

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

Para executar em um subconjunto dos avaliadores configurados, use a flag --evaluators e forneça uma lista separada por vírgulas de avaliadores por nome:

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

Sintetizar dados de teste usando um LLM

Confira um exemplo de fluxo que usa um arquivo PDF para gerar possíveis perguntas que os usuários podem fazer sobre ele.

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

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

const chunkingConfig = {
  minLength: 1000, // number of minimum characters into chunk
  maxLength: 2000, // number of maximum characters into chunk
  splitter: 'sentence', // paragraph | sentence
  overlap: 100, // number of overlap chracters
  delimiters: '', // regex for base split method
} as any;

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);
    // `extractText` loads the PDF and extracts its contents as text.
    // See our RAG documentation for more details. 
    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;
  }
);

Em seguida, use esse comando para exportar os dados para um arquivo e usar para avaliação.

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