評価

評価は、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}"

次を実行すると、デベロッパー UI で評価結果を確認できます。

genkit start

次に、localhost:4000/evaluate に移動します。

または、出力ファイルを指定して、JSON ファイルで出力を検査することもできます。

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

注: LLM を使用してテストケースを生成する方法の例を以下に示します。

サポートされている評価ツール

Genkit エバリュエータ

Genkit には、RAGES にインスパイアされた少数のネイティブ評価ツールが用意されており、すぐに使用できます。

  • 忠実性
  • 回答の関連性
  • 悪意

評価プラグイン

Genkit は、VertexAI プラグインを介した VertexAI Rapid Evaluator などのプラグインを介して、追加の評価ツールをサポートしています。

高度な使用方法

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

エクスポートされたデータは、各 testCase が次の形式の JSON ファイルとして出力されます。

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

データ抽出ツールは、取得ツールを自動的に検出し、生成されたドキュメントをコンテキスト配列に追加します。デフォルトでは、eval:run は構成されたすべてのエバリュエータに対して実行されます。eval:flow と同様に、eval:run の結果は、デベロッパー UI の評価ページ(localhost:4000/evaluate)に表示されます。

カスタム エクストラクタ

eval:extractData コマンドと eval:flow コマンドで使用するカスタム抽出ツールを指定することもできます。カスタム エクストラクタを使用すると、デフォルトの抽出ロジックをオーバーライドして、データセットの作成と評価を強化できます。

カスタム抽出ツールを構成するには、genkit-tools.conf.js という名前のツール構成ファイルをプロジェクトのルートに追加します(まだない場合)。

cd $GENKIT_PROJECT_HOME
touch genkit-tools.conf.js

ツールの構成ファイルに、次のコードを追加します。

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

このサンプルでは、myFlow フローのエクストラクタを構成します。この構成は、context フィールドと output フィールドのエクストラクタをオーバーライドし、input フィールドにデフォルトのロジックを使用します。

評価エクストラクタの仕様は次のとおりです。

  • evaluators フィールドには、flowName によってスコープされた EvaluatorConfig オブジェクトの配列を指定します。
  • 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 ファイルを使用して、ユーザーが 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