评估

评估是一种测试形式,可帮助您验证 LLM 的回答并确保其符合您的质量标准。

Firebase Genkit 通过插件支持第三方评估工具,并搭配强大的可观测性功能,可深入了解采用 LLM 的应用的运行时状态。Genkit 工具可帮助您自动从中间步骤中提取数据(包括输入、输出和信息),以评估 LLM 回答的端到端质量,以及了解系统构建块的性能。

例如,如果您有一个 RAG 流程,Genkit 将提取检索器返回的一组文档,以便您评估检索器在流程上下文中运行时的质量,如下所示,使用 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
    }),
  ],
  // ...
});

注意:上述配置需要安装 genkit@genkit-ai/googleai@genkit-ai/evaluator@genkit-ai/vertexai 软件包。

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

首先,定义一组要用作输入数据集的输入(称为 testInputs.json)。此输入数据集代表您将用于生成输出以进行评估的测试用例。

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

如果评估器需要参考输出来评估流程,您可以改用以下格式同时传递输入和参考输出:

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

请注意,您可以在输入 JSON 文件中使用任何 JSON 数据类型。Genkit 会将它们及其数据类型一起传递给您的数据流。

然后,您可以使用 eval:flow 命令根据 testInputs.json 中提供的测试用例评估您的流程。

genkit eval:flow menuSuggestionFlow --input testInputs.json

如果您的流程需要身份验证,您可以使用 --auth 参数指定它:

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

然后,您可以通过运行以下命令在开发者界面中查看评估结果:

genkit start

然后,前往 localhost:4000/evaluate

或者,您也可以提供输出文件,以便在 JSON 文件中检查输出。

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

注意:下面的示例展示了 LLM 如何帮助您生成测试用例。

支持的评估器

Genkit 评估程序

Genkit 包含少数几个受 RAGAS 启发的原生评估器,可帮助您上手:

  • 忠诚
  • 回答相关性
  • 恶意

评估器插件

Genkit 通过 VertexAI 插件支持 VertexAI Rapid 评估器等插件提供的其他评估器。

高级用法

eval:flow 是一种快速评估流程的便捷方式,但有时您可能需要更好地控制评估步骤。如果您使用的是其他框架,并且已经有了要评估的输出,就可能会出现这种情况。您可以半自动执行 eval:flow 执行的所有步骤。

您可以批量运行 Genkit 流程,并为运行添加唯一标签,该标签将用于提取评估数据集(一组输入、输出和上下文)。

针对测试输入运行流程:

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

提取评估数据:

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

导出的数据将以 JSON 文件的形式输出,其中每个 testCase 均采用以下格式:

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

数据提取器会自动定位检索器,并将生成的文档添加到上下文数组。默认情况下,eval:run 将针对所有已配置的评估器运行,并且与 eval:flow 一样,eval:run 的结果将显示在位于 localhost:4000/evaluate 的开发者界面的评估页面中。

自定义提取器

您还可以提供要在 eval:extractDataeval:flow 命令中使用的自定义提取器。借助自定义提取器,您可以替换默认的提取逻辑,从而更轻松地创建数据集并对其进行评估。

如需配置自定义提取器,请在项目根目录中添加一个名为 genkit-tools.conf.js 的工具配置文件(如果尚无)。

cd $GENKIT_PROJECT_HOME
touch genkit-tools.conf.js

在 tools 配置文件中,添加以下代码:

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

在此示例中,您将为 myFlow 流配置提取器。该配置会替换 contextoutput 字段的提取器,并对 input 字段使用默认逻辑。

评估提取器的规范如下:

  • evaluators 字段接受一个 EvaluatorConfig 对象数组,这些对象受 flowName 的作用域控制
  • extractors 是一个对象,用于指定提取器替换项。extractors 中当前支持的键为 [input, output, context]。可接受的值类型包括:
    • string - 这应为步骤名称,以字符串形式指定。系统会为此键提取此步骤的输出。
    • { inputOf: string }{ outputOf: string } - 这些对象代表步骤的特定渠道(输入或输出)。例如,{ inputOf: 'foo-step' } 会提取此键对应的步骤 foo-step 的输入。
    • (trace) => string; - 为了进一步提高灵活性,您可以提供一个接受 Genkit 轨迹并返回 string 的函数,并在此函数内指定提取逻辑。如需了解确切的 TraceData 架构,请参阅 genkit/genkit-tools/common/src/types/trace.ts

注意:所有这些步骤的提取数据都将是 JSON 字符串。工具会在评估时自动解析此 JSON 字符串。如果提供函数提取器,请确保输出是有效的 JSON 字符串。例如:"Hello, world!" 不是有效的 JSON;"\"Hello, world!\"" 是有效的。

在现有数据集上运行

如需对已提取的数据集运行评估,请执行以下操作:

genkit eval:run customLabel_dataset.json

如需输出到其他位置,请使用 --output 标志。

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

如需在部分配置的评估器上运行,请使用 --evaluators 标志,并按名称提供以英文逗号分隔的评估器列表:

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

使用 LLM 合成测试数据

以下示例流程使用 PDF 文件生成用户可能会询问的相关问题。

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;
  }
);

然后,您可以使用此命令将数据导出到文件中,以供评估。

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