Avaliação

A avaliaçã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.

Tipos de avaliação

O Genkit oferece suporte a dois tipos de avaliação:

  • Avaliação baseada em inferência: esse tipo de avaliação é executado em uma coleção de entradas predeterminadas, avaliando a qualidade das saídas correspondentes.

    Esse é o tipo de avaliação mais comum, adequado para a maioria dos casos de uso. Essa abordagem testa a saída real de um sistema para cada execução de avaliação.

    É possível realizar a avaliação de qualidade manualmente, inspecionando visualmente os resultados. Como alternativa, é possível automatizar a avaliação usando uma métrica de avaliação.

  • Avaliação bruta: esse tipo de avaliação avalia diretamente a qualidade das entradas sem nenhuma inferência. Essa abordagem geralmente é usada com a avaliação automatizada usando métricas. Todos os campos obrigatórios para avaliação (por exemplo, input, context, output e reference) precisam estar presentes no conjunto de dados de entrada. Isso é útil quando você tem dados de uma fonte externa (por exemplo, coletados dos seus rastros de produção) e quer ter uma medição objetiva da qualidade dos dados coletados.

    Para mais informações, consulte a seção Uso avançado desta página.

Esta seção explica como realizar uma avaliação baseada em inferência usando o Genkit.

Início rápido

Configuração

  1. Use um app Genkit existente ou crie um novo seguindo nosso guia [Introdução](get-started).
  2. Adicione o código abaixo para definir uma aplicação simples de RAG para avaliação. Neste guia, usamos um extrator fictício que sempre retorna os mesmos documentos. ```js import { genkit, z, Document } from "genkit"; import { googleAI, gemini15Flash, gemini15Pro, } from "@genkit-ai/googleai"; // Inicialize o Genkit export const ai = genkit ({ plugins: [ googleAI(), ] }); // Extrator simulado que sempre retorna os mesmos documentos export const dummyRetriever = ai.defineRetriever( { name: "dummyRetriever", }, async (i) => { const facts = [ "Dog is man's best friend", "Dogs have evolved and were domesticated from wolves", ]; // Apenas retorne fatos como documentos. return { documents: facts.map((t) => Document.fromText(t)) }; } ); // Um fluxo simples de perguntas e respostas export const qaFlow = ai.defineFlow({ name: 'qaFlow', inputSchema: z.string(), outputSchema: z.string(), }, async (query) => { const factDocs = await ai.retrieve({ retriever: dummyRetriever, query, options: { k: 2 }, }); const llmResponse = await ai.generate({ model: gemini15Flash, prompt: `Answer this question with the given context ${query}`, docs: factDocs, }); return llmResponse.text; } ); ```
  3. (Opcional) Adicione métricas de avaliação ao seu aplicativo para usar durante a avaliação. Este guia usa a métrica "MALICIOUSNESS" do plug-in "genkitEval". ```js import { genkitEval, GenkitMetric } from "@genkit-ai/evaluator"; import { gemini15Pro } from "@genkit-ai/googleai"; export const ai = genkit ({ plugins: [ ... // Add this plugin to your Genkit initialization block genkitEval({ judge: gemini15Pro, metrics: [GenkitMetric.MALICIOUSNESS], }), ] }); ``` **Observação:** a configuração acima requer a instalação do pacote [`@genkit-ai/evaluator`](https://www.npmjs.com/package/@genkit-ai/evaluator). ```posix-terminal npm install @genkit-ai/evaluator ```
  4. Inicie seu aplicativo Genkit ```posix-terminal genkit start -- ```

Criar um conjunto de dados

Crie um conjunto de dados para definir os exemplos que você quer usar para avaliar o fluxo.

  1. Acesse a interface do desenvolvedor em http://localhost:4000 e clique no botão Datasets para abrir a página "Datasets".

  2. Clique no botão Criar conjunto de dados para abrir a caixa de diálogo de criação de conjuntos de dados.

    a. Forneça um datasetId para o novo conjunto de dados. Este guia usa myFactsQaDataset.

    b. Selecione o tipo de conjunto de dados Flow.

    c. Deixe o campo de destino da validação em branco e clique em Salvar.

  3. A página do novo conjunto de dados aparece com um conjunto vazio. Adicione exemplos a ele seguindo estas etapas:

    a. Clique no botão Adicionar exemplo para abrir o painel do editor de exemplo.

    b. Apenas o campo input é obrigatório. Insira "Who is man's best friend?" no campo input e clique em Salvar para adicionar o exemplo ao seu conjunto de dados.

    c. Repita as etapas (a) e (b) mais algumas vezes para adicionar mais exemplos. Este guia adiciona os seguintes exemplos de entradas ao conjunto de dados:

    "Can I give milk to my cats?"
    "From which animals did dogs evolve?"
    

    Ao final desta etapa, seu conjunto de dados terá três exemplos com os valores mencionados acima.

Executar a avaliação e conferir os resultados

Para começar a avaliar o fluxo, clique na guia Evaluations na interface para desenvolvedores e clique no botão Run new evaluation para começar.

  1. Selecione o botão de opção Flow para avaliar um fluxo.

  2. Selecione qaFlow como o fluxo de destino a ser avaliado.

  3. Selecione myFactsQaDataset como o conjunto de dados de destino a ser usado para avaliação.

  4. (Opcional) Se você instalou uma métrica de avaliador usando plug-ins do Genkit, confira essas métricas nesta página. Selecione as métricas que você quer usar com essa execução de avaliação. Isso é totalmente opcional: omitir essa etapa ainda vai retornar os resultados na execução de avaliação, mas sem nenhuma métrica associada.

  5. Por fim, clique em Executar avaliação para iniciar a avaliação. Dependendo do fluxo que você está testando, isso pode demorar um pouco. Quando a avaliação for concluída, uma mensagem de sucesso vai aparecer com um link para conferir os resultados. Clique no link para acessar a página Detalhes da avaliação.

Você pode conferir os detalhes da sua avaliação nesta página, incluindo a entrada original, o contexto extraído e as métricas (se houver).

Principais conceitos

Terminologia

  • Avaliação: é um processo que avalia o desempenho do sistema. No Genkit, esse sistema geralmente é uma primitiva do Genkit, como um fluxo ou um modelo. Uma avaliação pode ser automatizada ou manual (avaliação humana).

  • Inferência em massa: a inferência é o ato de executar uma entrada em um fluxo ou modelo para receber a saída correspondente. A inferência em massa envolve a execução de inferência em várias entradas simultaneamente.

  • Métrica: uma métrica de avaliação é um critério em que uma inferência é pontuada. Exemplos incluem precisão, fidelidade, malícia, se a saída está em inglês etc.

  • Conjunto de dados: é uma coleção de exemplos para usar na avaliação com base em inferência. Um conjunto de dados geralmente consiste em campos input e reference opcionais. O campo reference não afeta a etapa de inferência da avaliação, mas é transmitido literalmente para todas as métricas de avaliação. No Genkit, é possível criar um conjunto de dados pela interface do desenvolvedor. Há dois tipos de conjuntos de dados no Genkit: Flow e Model.

Validação do esquema

Dependendo do tipo, os conjuntos de dados têm suporte à validação de esquema na interface para desenvolvedores:

  • Os conjuntos de dados de fluxo oferecem suporte à validação dos campos input e reference do conjunto de dados em relação a um fluxo no aplicativo do Genkit. A validação de esquema é opcional e só é aplicada se um esquema for especificado no fluxo de destino.

  • Os conjuntos de dados de modelos têm um esquema implícito, com suporte para os tipos de entrada string e GenerateRequest. A validação de string oferece uma maneira conveniente de avaliar comandos de texto simples, enquanto GenerateRequest oferece controle completo para casos de uso avançados (por exemplo, fornecendo parâmetros de modelo, histórico de mensagens, ferramentas etc.). Você pode encontrar o esquema completo de GenerateRequest nos documentos de referência da API.

Avaliadores com suporte

Avaliadores do Genkit

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

  • Fidelidade: mede a consistência factual da resposta gerada em relação ao contexto fornecido.
  • Relevância da resposta: avalia a pertinência da resposta gerada para a pergunta.
  • Malícia: mede se a saída gerada tem a intenção de enganar, prejudicar ou explorar.

Plug-ins de avaliação

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

Uso avançado

Avaliação usando a CLI

A CLI do Genkit oferece uma API avançada para realizar avaliações. Isso é especialmente útil em ambientes em que a interface para desenvolvedores não está disponível (por exemplo, em um fluxo de trabalho CI/CD).

A CLI do Genkit fornece três comandos principais de avaliação: eval:flow, eval:extractData e eval:run.

Comando eval:flow

O comando eval:flow executa a avaliação baseada em inferência em um conjunto de dados de entrada. Esse conjunto de dados pode ser fornecido como um arquivo JSON ou referenciando um conjunto de dados existente no ambiente de execução do Genkit.

# Referencing an existing dataset
genkit eval:flow qaFlow --input myFactsQaDataset
# or, using a dataset from a file
genkit eval:flow qaFlow --input testInputs.json

Aqui, testInputs.json precisa ser uma matriz de objetos que contenha um campo input e um campo reference opcional, como abaixo:

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

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

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

Por padrão, os comandos eval:flow e eval:run usam todas as métricas disponíveis para avaliação. 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:flow qaFlow --input testInputs.json --evaluators=genkit/faithfulness,genkit/answer_relevancy

É possível conferir os resultados da execução da avaliação na interface para desenvolvedores em localhost:4000/evaluate.

Comandos eval:extractData e eval:run

Para oferecer suporte à avaliação bruta, o Genkit fornece ferramentas para extrair dados de rastros e executar métricas de avaliação nos dados extraídos. Isso é útil, por exemplo, se você estiver usando um framework diferente para avaliação ou se estiver coletando inferências de um ambiente diferente para testar localmente a qualidade da saída.

Você pode executar em lote seu fluxo do Genkit e adicionar um rótulo exclusivo à execução, que pode ser usado para extrair um conjunto de dados de avaliação. Um conjunto de dados de avaliação bruto é uma coleção de entradas para métricas de avaliação, sem executar nenhuma inferência anterior.

Execute o fluxo nas entradas de teste:

genkit flow:batchRun qaFlow testInputs.json --label firstRunSimple

Extraia os dados de avaliação:

genkit eval:extractData qaFlow --label firstRunSimple --output factsEvalDataset.json

Os dados exportados têm um formato diferente do conjunto de dados apresentado anteriormente. Isso ocorre porque esses dados são destinados a serem usados diretamente com as métricas de avaliação, sem nenhuma etapa de inferência. Confira a sintaxe dos dados extraídos.

Array<{
  "testCaseId": string,
  "input": any,
  "output": any,
  "context": any[],
  "traceIds": string[],
}>;

O extrator de dados localiza automaticamente os extratores e adiciona os documentos produzidos à matriz de contexto. É possível executar métricas de avaliação nesse conjunto de dados extraído usando o comando eval:run.

genkit eval:run factsEvalDataset.json

Por padrão, eval:run é executado em todos os avaliadores configurados. Assim como em eval:flow, os resultados de eval:run aparecem na página de avaliação da IU do desenvolvedor, localizada em localhost:4000/evaluate.

Extratores personalizados

O Genkit oferece uma lógica padrão razoável para extrair os campos necessários (input, output e context) durante uma avaliação. No entanto, talvez você precise de mais controle sobre a lógica de extração desses campos. O Genkit oferece suporte a extratores personalizados para isso. É possível fornecer extratores personalizados para serem usados nos comandos eval:extractData e eval:flow.

Primeiro, como uma etapa preparatória, apresente uma etapa auxiliar no nosso exemplo de qaFlow:

export const qaFlow = ai.defineFlow({
    name: 'qaFlow',
    inputSchema: z.string(),
    outputSchema: z.string(),
  },
  async (query) => {
    const factDocs = await ai.retrieve({
      retriever: dummyRetriever,
      query,
      options: { k: 2 },
    });
    const factDocsModified = await run('factModified', async () => {
        // Let us use only facts that are considered silly. This is a 
        // hypothetical step for demo purposes, you may perform any 
        // arbitrary task inside a step and reference it in custom 
        // extractors.
        //
        // Assume you have a method that checks if a fact is silly
        return factDocs.filter(d => isSillyFact(d.text));
    });

    const llmResponse = await ai.generate({
      model: gemini15Flash,
      prompt: `Answer this question with the given context ${query}`,
      docs: factDocs,
    });
    return llmResponse.text;
  }
);

Em seguida, configure um extrator personalizado para usar a saída da etapa factModified ao avaliar esse fluxo.

Se você não tiver um arquivo tools-config para configurar extratores personalizados, adicione um chamado genkit-tools.conf.js à raiz do projeto.

cd /path/to/your/genkit/app
touch genkit-tools.conf.js

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

module.exports = {
  evaluators: [
    {
      actionRef: '/flow/qaFlow',
      extractors: {
        context: { outputOf: 'factModified' },
      },
    },
  ],
};

Essa configuração substitui os extratores padrão das ferramentas do Genkit, especificamente mudando o que é considerado como context ao avaliar esse fluxo.

A execução da avaliação novamente revela que o contexto agora é preenchido como a saída da etapa factModified.

genkit eval:flow qaFlow --input testInputs.json

Os extratores de avaliação são especificados da seguinte maneira:

  • 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 valor do tipo any, 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 todos esses extratores são do tipo correspondente ao extrator. Por exemplo, se você usar context: { outputOf: 'foo-step' } e foo-step retornar uma matriz de objetos, o contexto extraído também será uma matriz de objetos.

Sintetizar dados de teste usando um LLM

Confira um exemplo de fluxo que usa um arquivo PDF para gerar possíveis perguntas do usuário.

import { genkit, run, z } from "genkit";
import { googleAI, gemini15Flash } from "@genkit-ai/googleai";
import { chunk } from "llm-chunk"; // npm i llm-chunk
import path from "path";
import { readFile } from "fs/promises";
import pdf from "pdf-parse"; // npm i pdf-parse

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;

async function extractText(filePath: string) {
  const pdfFile = path.resolve(filePath);
  const dataBuffer = await readFile(pdfFile);
  const data = await pdf(dataBuffer);
  return data.text;
}

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.
    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