Đánh giá

Đánh giá là một hình thức kiểm thử giúp bạn xác thực các câu trả lời của LLM và đảm bảo rằng các câu trả lời đó đáp ứng tiêu chuẩn chất lượng của bạn.

Firebase Genkit hỗ trợ các công cụ đánh giá của bên thứ ba thông qua các trình bổ trợ, kết hợp với các tính năng quan sát mạnh mẽ cung cấp thông tin chi tiết về trạng thái thời gian chạy của các ứng dụng sử dụng LLM. Bộ công cụ Genkit giúp bạn tự động trích xuất dữ liệu bao gồm dữ liệu đầu vào, đầu ra và thông tin từ các bước trung gian để đánh giá chất lượng toàn diện của các phản hồi LLM cũng như hiểu được hiệu suất của các khối xây dựng của hệ thống.

Ví dụ: nếu bạn có luồng RAG, Genkit sẽ trích xuất tập hợp tài liệu mà trình truy xuất trả về để bạn có thể đánh giá chất lượng của trình truy xuất trong khi trình truy xuất chạy trong ngữ cảnh của luồng như minh hoạ bên dưới với các chỉ số về độ trung thực và mức độ liên quan của câu trả lời 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
    }),
  ],
  // ...
});

Lưu ý: Cấu hình ở trên yêu cầu cài đặt các gói genkit, @genkit-ai/googleai, @genkit-ai/evaluator@genkit-ai/vertexai.

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

Bắt đầu bằng cách xác định một tập hợp dữ liệu đầu vào mà bạn muốn sử dụng làm tập dữ liệu đầu vào có tên là testInputs.json. Tập dữ liệu đầu vào này đại diện cho các trường hợp kiểm thử mà bạn sẽ sử dụng để tạo đầu ra cho quá trình đánh giá.

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

Nếu trình đánh giá yêu cầu đầu ra tham chiếu để đánh giá một flow, bạn có thể truyền cả đầu vào và đầu ra tham chiếu bằng định dạng này:

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

Xin lưu ý rằng bạn có thể sử dụng bất kỳ loại dữ liệu JSON nào trong tệp JSON đầu vào. Genkit sẽ truyền các giá trị này cùng với cùng một loại dữ liệu đến flow của bạn.

Sau đó, bạn có thể sử dụng lệnh eval:flow để đánh giá luồng của mình dựa trên các trường hợp kiểm thử được cung cấp trong testInputs.json.

genkit eval:flow menuSuggestionFlow --input testInputs.json

Nếu luồng của bạn yêu cầu xác thực, bạn có thể chỉ định luồng đó bằng đối số --auth:

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

Sau đó, bạn có thể xem kết quả đánh giá trong Giao diện người dùng dành cho nhà phát triển bằng cách chạy:

genkit start

Sau đó, hãy chuyển đến localhost:4000/evaluate.

Ngoài ra, bạn có thể cung cấp một tệp đầu ra để kiểm tra đầu ra trong tệp JSON.

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

Lưu ý: Dưới đây là ví dụ về cách LLM có thể giúp bạn tạo các trường hợp kiểm thử.

Trình đánh giá được hỗ trợ

Trình đánh giá Genkit

Genkit bao gồm một số ít trình đánh giá gốc, lấy cảm hứng từ RAGAS, để giúp bạn bắt đầu:

  • Trung thành
  • Mức độ liên quan của câu trả lời
  • Độc hại

Trình bổ trợ trình đánh giá

Genkit hỗ trợ các trình đánh giá bổ sung thông qua các trình bổ trợ như Trình đánh giá nhanh VertexAI thông qua Trình bổ trợ VertexAI.

Sử dụng nâng cao

eval:flow là một cách thuận tiện để nhanh chóng đánh giá luồng, nhưng đôi khi bạn có thể cần kiểm soát nhiều hơn các bước đánh giá. Điều này có thể xảy ra nếu bạn đang sử dụng một khung khác và đã có một số kết quả mà bạn muốn đánh giá. Bạn có thể thực hiện tất cả các bước mà eval:flow thực hiện một cách bán thủ công.

Bạn có thể chạy quy trình Genkit theo lô và thêm một nhãn duy nhất vào quy trình chạy. Sau đó, quy trình này sẽ được dùng để trích xuất tập dữ liệu đánh giá (một tập hợp đầu vào, đầu ra và ngữ cảnh).

Chạy quy trình trên dữ liệu đầu vào kiểm thử:

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

Trích xuất dữ liệu đánh giá:

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

Dữ liệu đã xuất sẽ được xuất dưới dạng tệp JSON với mỗi testCase ở định dạng sau:

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

Trình trích xuất dữ liệu sẽ tự động xác định vị trí trình truy xuất và thêm các tài liệu đã tạo vào mảng ngữ cảnh. Theo mặc định, eval:run sẽ chạy trên tất cả các trình đánh giá đã định cấu hình và giống như eval:flow, kết quả cho eval:run sẽ xuất hiện trên trang đánh giá của Giao diện người dùng dành cho nhà phát triển, nằm ở localhost:4000/evaluate.

Trình trích xuất tuỳ chỉnh

Bạn cũng có thể cung cấp trình trích xuất tuỳ chỉnh để sử dụng trong các lệnh eval:extractDataeval:flow. Trình trích xuất tuỳ chỉnh cho phép bạn ghi đè logic trích xuất mặc định, giúp bạn có nhiều quyền hơn trong việc tạo và đánh giá các tập dữ liệu.

Để định cấu hình trình trích xuất tuỳ chỉnh, hãy thêm tệp cấu hình công cụ có tên genkit-tools.conf.js vào thư mục gốc của dự án nếu bạn chưa có.

cd $GENKIT_PROJECT_HOME
touch genkit-tools.conf.js

Trong tệp cấu hình công cụ, hãy thêm mã sau:

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

Trong mẫu này, bạn định cấu hình trình trích xuất cho luồng myFlow. Cấu hình này ghi đè các trình trích xuất cho các trường contextoutput, đồng thời sử dụng logic mặc định cho trường input.

Thông số kỹ thuật của trình trích xuất đánh giá như sau:

  • Trường evaluators chấp nhận một mảng các đối tượng EvaluatorConfig, được flowName xác định phạm vi
  • extractors là một đối tượng chỉ định các cơ chế ghi đè trình trích xuất. Các khoá được hỗ trợ hiện tại trong extractors[input, output, context]. Các loại giá trị được chấp nhận là:
    • string – đây phải là tên bước, được chỉ định dưới dạng chuỗi. Đầu ra của bước này được trích xuất cho khoá này.
    • { inputOf: string } hoặc { outputOf: string } – Các đối tượng này đại diện cho các kênh cụ thể (đầu vào hoặc đầu ra) của một bước. Ví dụ: { inputOf: 'foo-step' } sẽ trích xuất dữ liệu đầu vào của bước foo-step cho khoá này.
    • (trace) => string; – Để linh hoạt hơn, bạn có thể cung cấp một hàm chấp nhận dấu vết Genkit và trả về string, đồng thời chỉ định logic trích xuất bên trong hàm này. Tham khảo genkit/genkit-tools/common/src/types/trace.ts để biết giản đồ TraceData chính xác.

Lưu ý: Dữ liệu được trích xuất cho tất cả các bước này sẽ là một chuỗi JSON. Công cụ sẽ tự động phân tích cú pháp chuỗi JSON này tại thời điểm đánh giá. Nếu cung cấp trình trích xuất hàm, hãy đảm bảo rằng kết quả là một chuỗi JSON hợp lệ. Ví dụ: "Hello, world!" không phải là JSON hợp lệ; "\"Hello, world!\"" là hợp lệ.

Chạy trên các tập dữ liệu hiện có

Cách chạy quy trình đánh giá trên một tập dữ liệu đã được trích xuất:

genkit eval:run customLabel_dataset.json

Để xuất ra một vị trí khác, hãy sử dụng cờ --output.

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

Để chạy trên một nhóm nhỏ các trình đánh giá đã định cấu hình, hãy sử dụng cờ --evaluators và cung cấp danh sách trình đánh giá được phân tách bằng dấu phẩy theo tên:

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

Tổng hợp dữ liệu kiểm thử bằng LLM

Dưới đây là một luồng ví dụ sử dụng tệp PDF để tạo các câu hỏi mà người dùng có thể đặt về tệp đó.

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

Sau đó, bạn có thể sử dụng lệnh này để xuất dữ liệu vào một tệp và sử dụng để đánh giá.

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