Bewertung

Die Bewertung ist eine Form des Tests, mit der Sie die Antworten Ihres LLM validieren und dafür sorgen können, dass sie Ihre Qualitätsanforderungen erfüllen.

Firebase Genkit unterstützt Bewertungstools von Drittanbietern über Plug-ins, kombiniert mit leistungsstarken Observability-Funktionen, die Einblicke in den Laufzeitstatus Ihrer LLM-gestützten Anwendungen bieten. Mit Genkit-Tools können Sie automatisch Daten wie Eingaben, Ausgaben und Informationen aus Zwischenschritten extrahieren, um die End-to-End-Qualität von LLM-Antworten zu bewerten und die Leistung der Bausteine Ihres Systems zu verstehen.

Arten der Bewertung

Genkit unterstützt zwei Arten der Bewertung:

  • Inferenzbasierte Bewertung: Bei dieser Art der Bewertung werden eine Reihe von vorab festgelegten Eingaben ausgeführt und die entsprechenden Ausgaben auf Qualität geprüft.

    Dies ist der häufigste Bewertungstyp, der für die meisten Anwendungsfälle geeignet ist. Bei diesem Ansatz wird die tatsächliche Ausgabe eines Systems bei jedem Bewertungslauf getestet.

    Sie können die Qualitätsprüfung manuell durchführen, indem Sie die Ergebnisse visuell prüfen. Alternativ können Sie die Bewertung mithilfe eines Bewertungsmesswerts automatisieren.

  • Unbehandelte Bewertung: Bei dieser Art der Bewertung wird die Qualität der Eingaben direkt und ohne Inferenz bewertet. Dieser Ansatz wird in der Regel mit einer automatisierten Bewertung anhand von Messwerten verwendet. Alle für die Bewertung erforderlichen Felder (z.B. input, context, output und reference) müssen im Eingabedatensatz vorhanden sein. Das ist nützlich, wenn Sie Daten aus einer externen Quelle haben (z.B. aus Ihren Produktions-Traces), und eine objektive Messung der Qualität der erfassten Daten wünschen.

    Weitere Informationen finden Sie auf dieser Seite im Abschnitt Erweiterte Verwendung.

In diesem Abschnitt wird erläutert, wie Sie eine inferenzbasierte Bewertung mit Genkit durchführen.

Kurzanleitung

Einrichtung

  1. Sie können eine vorhandene Genkit-App verwenden oder eine neue erstellen. Folgen Sie dazu der Anleitung unter [Einstieg](get-started).
  2. Fügen Sie den folgenden Code hinzu, um eine einfache RAG-Anwendung zum Bewerten zu definieren. In diesem Leitfaden verwenden wir einen Dummy-Abruf, der immer dieselben Dokumente zurückgibt. ```js import { genkit, z, Document } from "genkit"; import { googleAI, gemini15Flash, gemini15Pro, } from "@genkit-ai/googleai"; // Initialize Genkit export const ai = genkit ({ plugins: [ googleAI(), ] }); // Dummy retriever that always returns the same docs 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", ]; // Just return facts as documents. return { documents: facts.map((t) => Document.fromText(t)) }; } ); // Ein einfacher Ablauf zum Beantworten von Fragen 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. Optional: Fügen Sie Ihrer Anwendung Bewertungsmesswerte hinzu, die bei der Bewertung verwendet werden sollen. In diesem Leitfaden wird der Messwert „MALICIOUSNESS“ aus dem Plug-in „genkitEval“ verwendet. ```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], }), ] }); ``` **Hinweis:** Für die oben stehende Konfiguration muss das Paket [`@genkit-ai/evaluator`](https://www.npmjs.com/package/@genkit-ai/evaluator) installiert sein. ```posix-terminal npm install @genkit-ai/evaluator ```
  4. Starten Sie Ihre Genkit-Anwendung: ```posix-terminal genkit start -- ```

Dataset erstellen

Erstellen Sie ein Dataset, um die Beispiele zu definieren, die wir zur Bewertung des Ablaufs verwenden möchten.

  1. Rufen Sie die Entwickler-Benutzeroberfläche unter http://localhost:4000 auf und klicken Sie auf die Schaltfläche Datasets, um die Seite „Datasets“ zu öffnen.

  2. Klicken Sie auf die Schaltfläche Dataset erstellen, um das Dialogfeld „Dataset erstellen“ zu öffnen.

    a. Geben Sie einen datasetId für den neuen Datensatz an. In dieser Anleitung wird myFactsQaDataset verwendet.

    b. Wählen Sie den Datensatztyp Flow aus.

    c. Lassen Sie das Feld für das Validierungsziel leer und klicken Sie auf Speichern.

  3. Die Seite des neuen Datensatzes wird angezeigt. Er ist noch leer. So fügen Sie Beispiele hinzu:

    a. Klicken Sie auf die Schaltfläche Beispiel hinzufügen, um den Beispieleditor zu öffnen.

    b. Nur das Feld input ist erforderlich. Geben Sie "Who is man's best friend?" in das Feld input ein und klicken Sie auf Speichern, um das Beispiel dem Datensatz hinzuzufügen.

    c. Wiederholen Sie die Schritte (a) und (b) noch einige Male, um weitere Beispiele hinzuzufügen. In diesem Leitfaden werden dem Datensatz die folgenden Beispielinputs hinzugefügt:

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

    Am Ende dieses Schritts sollte Ihr Datensatz drei Beispiele mit den oben genannten Werten enthalten.

Bewertung ausführen und Ergebnisse ansehen

Klicken Sie in der Entwickleroberfläche auf den Tab Evaluations und dann auf die Schaltfläche Neue Bewertung ausführen, um mit der Bewertung des Ablaufs zu beginnen.

  1. Wählen Sie das Optionsfeld Flow aus, um einen Ablauf zu bewerten.

  2. Wählen Sie qaFlow als Zielfluss aus, der ausgewertet werden soll.

  3. Wählen Sie myFactsQaDataset als Ziel-Dataset für die Bewertung aus.

  4. Optional: Wenn Sie einen Bewertungsmesswert mit Genkit-Plug-ins installiert haben, sehen Sie diese Messwerte auf dieser Seite. Wählen Sie die Messwerte aus, die Sie für diesen Bewertungslauf verwenden möchten. Dieser Schritt ist völlig optional: Wenn Sie ihn überspringen, werden die Ergebnisse der Bewertungsausführung zwar zurückgegeben, aber ohne zugehörige Messwerte.

  5. Klicken Sie abschließend auf Bewertung ausführen, um die Bewertung zu starten. Je nach getestetem Ablauf kann dies einige Zeit dauern. Nach Abschluss der Bewertung wird eine Erfolgsmeldung mit einem Link zu den Ergebnissen angezeigt. Klicken Sie auf den Link, um die Seite Details zur Evaluierung aufzurufen.

Auf dieser Seite finden Sie die Details Ihrer Bewertung, einschließlich des ursprünglichen Eingabetexts, des extrahierten Kontexts und der Messwerte (falls vorhanden).

Wichtige Konzepte

Terminologie

  • Bewertung: Bei einer Bewertung wird die Systemleistung beurteilt. In Genkit ist ein solches System in der Regel eine Genkit-Primitivstruktur wie ein Flow oder ein Modell. Eine Bewertung kann automatisiert oder manuell (menschliche Bewertung) erfolgen.

  • Bulk-Inferenz: Bei der Inferenz wird eine Eingabe in einem Workflow oder Modell ausgeführt, um die entsprechende Ausgabe zu erhalten. Bei der Bulk-Inferenz werden mehrere Eingaben gleichzeitig verarbeitet.

  • Messwert: Ein Bewertungsmesswert ist ein Kriterium, anhand dessen eine Inferenz bewertet wird. Beispiele sind Genauigkeit, Treue, Böswilligkeit und ob die Ausgabe auf Englisch ist.

  • Dataset: Ein Dataset ist eine Sammlung von Beispielen, die für die inferenzbasierte Bewertung verwendet werden. Ein Datensatz besteht in der Regel aus input- und optionalen reference-Feldern. Das Feld reference hat keine Auswirkungen auf den Inferenzschritt der Bewertung, wird aber unverändert an alle Bewertungsmesswerte übergeben. In Genkit können Sie einen Datensatz über die Entwickleroberfläche erstellen. In Genkit gibt es zwei Arten von Datensätzen: Flow- und Modell-Datensätze.

Schemavalidierung

Je nach Typ wird die Schemaüberprüfung für Datensätze in der Entwicklungs-UI unterstützt:

  • Ablauf-Datasets unterstützen die Validierung der Felder input und reference des Datasets anhand eines Ablaufs in der Genkit-Anwendung. Die Schemaüberprüfung ist optional und wird nur erzwungen, wenn für den Zielfluss ein Schema angegeben ist.

  • Modelldatensätze haben ein implizites Schema, das sowohl string- als auch GenerateRequest-Eingabetypen unterstützt. Die Stringvalidierung bietet eine praktische Möglichkeit, einfache Textprompts zu bewerten. GenerateRequest bietet hingegen eine vollständige Kontrolle für erweiterte Anwendungsfälle (z. B. Bereitstellung von Modellparametern, Nachrichtenverlauf, Tools usw.). Das vollständige Schema für GenerateRequest finden Sie in unseren API-Referenzdokumenten.

Unterstützte Prüfer

Genkit-Bewerter

Genkit enthält eine kleine Anzahl von nativen Bewertern, die von RAGAS inspiriert sind, um Ihnen den Einstieg zu erleichtern:

  • Treue: Misst die sachliche Konsistenz der generierten Antwort im Vergleich zum gegebenen Kontext.
  • Relevanz der Antwort: Bewertet, wie relevant die generierte Antwort für den jeweiligen Prompt ist.
  • Böswilligkeit: Gibt an, ob die generierte Ausgabe beabsichtigt ist, um zu täuschen, zu schädigen oder auszunutzen.

Plug-ins für Bewerter

Genkit unterstützt zusätzliche Evaluatoren über Plug-ins, z. B. die Vertex Rapid Evaluators, auf die Sie über das VertexAI-Plug-in zugreifen.

Erweiterte Nutzung

Bewertung über die Befehlszeile

Die Genkit-Befehlszeile bietet eine umfangreiche API für die Durchführung von Bewertungen. Das ist besonders nützlich in Umgebungen, in denen die Dev-Benutzeroberfläche nicht verfügbar ist (z.B. in einem CI/CD-Workflow).

Die Genkit-Befehlszeile bietet drei Hauptbewertungsbefehle: eval:flow, eval:extractData und eval:run.

Befehl eval:flow

Mit dem Befehl eval:flow wird eine inferenzbasierte Bewertung für einen Eingabedatensatz ausgeführt. Dieser Datensatz kann entweder als JSON-Datei oder durch Verweisen auf einen vorhandenen Datensatz in Ihrer Genkit-Laufzeit bereitgestellt werden.

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

Hier sollte testInputs.json ein Array von Objekten mit einem input-Feld und einem optionalen reference-Feld sein, wie unten dargestellt:

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

Wenn für deinen Ablauf eine Authentifizierung erforderlich ist, kannst du sie mit dem Argument --auth angeben:

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

Standardmäßig werden bei den Befehlen eval:flow und eval:run alle verfügbaren Messwerte für die Bewertung verwendet. Wenn Sie die Ausführung auf einen Teil der konfigurierten Bewerter beschränken möchten, verwenden Sie das Flag --evaluators und geben Sie eine durch Kommas getrennte Liste der Bewerter nach Namen an:

genkit eval:flow qaFlow --input testInputs.json --evaluators=genkit/faithfulness,genkit/answer_relevancy

Die Ergebnisse des Bewertungslaufs können Sie in der Dev-Benutzeroberfläche unter localhost:4000/evaluate einsehen.

Befehle eval:extractData und eval:run

Zur Unterstützung der unbehandelten Auswertung bietet Genkit Tools zum Extrahieren von Daten aus Traces und zum Ausführen von Bewertungsmesswerten auf extrahierten Daten. Das ist beispielsweise nützlich, wenn Sie ein anderes Framework für die Bewertung verwenden oder Inferenzen aus einer anderen Umgebung erfassen, um die Ausgabequalität lokal zu testen.

Sie können Ihren Genkit-Ablauf im Batch ausführen und der Ausführung ein eindeutiges Label hinzufügen, mit dem dann ein Evaluierungs-Dataset extrahiert werden kann. Ein Rohdatensatz für die Bewertung ist eine Sammlung von Eingaben für Bewertungsmesswerte, ohne dass zuvor eine Inferenz ausgeführt wurde.

Führen Sie den Ablauf mit Ihren Testinputs aus:

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

Bewertungsdaten extrahieren:

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

Die exportierten Daten haben ein anderes Format als das zuvor angegebene Dataset-Format. Das liegt daran, dass diese Daten direkt für Bewertungsmesswerte verwendet werden sollen, ohne Inferenzschritt. Hier ist die Syntax der extrahierten Daten.

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

Der Datenextractor sucht automatisch nach Retrievern und fügt die erstellten Dokumente dem Kontextarray hinzu. Mit dem Befehl eval:run können Sie Bewertungsmesswerte für diesen extrahierten Datensatz ausführen.

genkit eval:run factsEvalDataset.json

Standardmäßig wird eval:run für alle konfigurierten Evaluatoren ausgeführt. Wie bei eval:flow werden die Ergebnisse für eval:run auf der Bewertungsseite der Entwickler-UI unter localhost:4000/evaluate angezeigt.

Benutzerdefinierte Extrahierer

Genkit bietet eine angemessene Standardlogik zum Extrahieren der erforderlichen Felder (input, output und context) bei einer Bewertung. Möglicherweise benötigen Sie jedoch mehr Kontrolle über die Extraktionslogik für diese Felder. Genkit unterstützt benutzerdefinierte Extraktoren, um dies zu erreichen. Sie können benutzerdefinierte Extraktoren angeben, die in eval:extractData- und eval:flow-Befehlen verwendet werden sollen.

Führen Sie zuerst als Vorbereitungsschritt einen Hilfsschritt in unserem qaFlow-Beispiel ein:

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

Konfigurieren Sie als Nächstes einen benutzerdefinierten Extractor, um die Ausgabe des Schritts factModified bei der Auswertung dieses Ablaufs zu verwenden.

Wenn Sie keine tools-config-Datei zum Konfigurieren benutzerdefinierter Extraktoren haben, fügen Sie dem Projektstamm eine Datei mit dem Namen genkit-tools.conf.js hinzu.

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

Fügen Sie der Konfigurationsdatei für Tools den folgenden Code hinzu:

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

Mit dieser Konfiguration werden die Standard-Extractor der Genkit-Tools überschrieben. Insbesondere wird geändert, was bei der Auswertung dieses Ablaufs als context betrachtet wird.

Wenn Sie die Bewertung noch einmal ausführen, sehen Sie, dass der Kontext jetzt als Ausgabe des Schritts factModified eingefügt wird.

genkit eval:flow qaFlow --input testInputs.json

Bewertungsextractors werden so angegeben:

  • Das Feld evaluators akzeptiert ein Array von EvaluatorConfig-Objekten, die durch flowName begrenzt sind.
  • extractors ist ein Objekt, das die Extractor-Überschreibungen angibt. Die derzeit unterstützten Schlüssel in extractors sind [input, output, context]. Zulässige Werttypen sind:
    • string: Dies sollte der Name eines Schritts sein, der als String angegeben wird. Die Ausgabe dieses Schritts wird für diesen Schlüssel extrahiert.
    • { inputOf: string } oder { outputOf: string }: Diese Objekte stellen bestimmte Kanäle (Eingabe- oder Ausgabe) eines Schritts dar. Mit { inputOf: 'foo-step' } wird beispielsweise die Eingabe von Schritt foo-step für diesen Schlüssel extrahiert.
    • (trace) => string;: Für mehr Flexibilität können Sie eine Funktion angeben, die einen Genkit-Trace akzeptiert und einen Wert vom Typ any zurückgibt. Die Extraktionslogik können Sie in dieser Funktion angeben. Das genaue TraceData-Schema finden Sie unter genkit/genkit-tools/common/src/types/trace.ts.

Hinweis:Die extrahierten Daten für alle diese Extraktoren haben den Typ, der dem jeweiligen Extraktor entspricht. Wenn Sie beispielsweise „context: { outputOf: 'foo-step' }“ verwenden und foo-step ein Array von Objekten zurückgibt, ist der extrahierte Kontext ebenfalls ein Array von Objekten.

Testdaten mit einem LLM synthetisieren

Hier ist ein Beispiel für einen Ablauf, bei dem anhand einer PDF-Datei potenzielle Fragen von Nutzern generiert werden.

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

Mit diesem Befehl können Sie die Daten dann in eine Datei exportieren und zur Auswertung verwenden.

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