評估是一種測試形式,可協助您驗證 LLM 的回覆,並確保回覆符合品質標準。
Firebase Genkit 可透過外掛程式支援第三方評估工具,並搭配強大的可觀察性功能,深入瞭解 LLM 支援應用程式的執行階段狀態。Genkit 工具可協助您自動擷取資料,包括中繼步驟的輸入內容、輸出內容和資訊,以評估 LLM 回應的端對端品質,並瞭解系統的構件效能。
評估類型
Genkit 支援兩種評估方式:
以推論為準的評估:這類評估會針對一組預先決定的輸入內容執行,評估對應輸出內容的品質。
這是最常見的評估類型,適用於多數用途。這種方法會針對每次評估作業測試系統的實際輸出內容。
您可以透過視覺檢查結果,手動執行品質評估。或者,您也可以使用評估指標自動執行評估作業。
原始評估:這類評估會直接評估輸入內容的品質,不進行任何推論。這種方法通常會搭配使用指標的自動評估機制。評估作業的所有必填欄位 (例如
input
、context
、output
和reference
) 必須出現在輸入資料集中。如果您有來自外部來源的資料 (例如從實際工作環境的追蹤記錄收集而來),且想要客觀評估所收集資料的品質,這項功能就非常實用。詳情請參閱本頁的「進階使用」一節。
本節說明如何使用 Genkit 執行以推論為基礎的評估作業。
快速入門導覽課程
設定
- 您可以使用現有的 Genkit 應用程式,也可以按照我們的 [入門指南](get-started.md)建立新的應用程式。
- 新增下列程式碼,定義要評估的簡易 RAG 應用程式。在本指南中,我們使用了一個一律傳回相同文件的虛擬擷取器。
import { genkit, z, Document } from "genkit"; import { googleAI, gemini15Flash, } 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)) }; } ); // A simple question-answering flow export const qaFlow = ai.defineFlow({ name: 'qaFlow', inputSchema: z.string(), outputSchema: z.string(), }, async (query) => { const factDocs = await ai.retrieve({ retriever: dummyRetriever, query, }); const llmResponse = await ai.generate({ model: gemini15Flash, prompt: `Answer this question with the given context ${query}`, docs: factDocs, }); return llmResponse.text; } );
- (選用) 在應用程式中加入評估指標,以便在評估時使用。本指南使用
genkitEval
外掛程式的MALICIOUSNESS
指標。 注意:上述設定需要安裝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], }), ] });
@genkit-ai/evaluator
套件。npm install @genkit-ai/evaluator
- 啟動 Genkit 應用程式。
genkit start --
建立資料集
建立資料集,定義要用於評估流程的範例。
前往
http://localhost:4000
的開發人員 UI,然後按一下「Datasets」按鈕,開啟「Datasets」頁面。按一下「Create Dataset」按鈕,開啟建立資料集對話方塊。
a. 為新資料集提供
datasetId
。本指南使用myFactsQaDataset
。b. 選取
Flow
資料集類型。c. 將驗證目標欄位留空,然後按一下「儲存」
新的資料集頁面隨即顯示,並顯示空白資料集。請按照下列步驟新增範例:
a. 按一下「新增範例」按鈕,開啟範例編輯器面板。
b. 您只需要提供
input
欄位。在input
欄位中輸入"Who is man's best friend?"
,然後按一下「儲存」,將範例 has 新增至資料集。c. 重複執行步驟 (a) 和 (b) 幾次,即可新增更多示例。本指南會在資料集中新增下列範例輸入內容:
"Can I give milk to my cats?" "From which animals did dogs evolve?"
完成這個步驟後,資料集應包含 3 個範例,並包含上述的值。
執行評估並查看結果
如要開始評估流程,請在資料集頁面中按一下「執行新評估」按鈕。您也可以透過「評估」分頁開始新的評估作業。
選取「
Flow
」圓形按鈕,即可評估流程。選取
qaFlow
做為要評估的目標流程。選取
myFactsQaDataset
做為評估用目標資料集。(選用) 如果您已使用 Genkit 外掛程式安裝評估指標,可以在這個頁面中查看這些指標。選取要用於這項評估作業的指標。這完全是可選步驟:省略這個步驟仍會在評估執行期間傳回結果,但不會傳回任何相關指標。
最後,按一下「Run evaluation」即可開始評估。視您要測試的流程而定,這可能需要一些時間。評估完成後,系統會顯示成功訊息,並附上可用來查看結果的連結。按一下連結即可前往「評估詳細資料」頁面。
您可以在這個頁面上查看評估結果的詳細資料,包括原始輸入內容、擷取的內容和指標 (如果有的話)。
核心概念
術語
評估:評估是一種評估系統效能的程序。在 Genkit 中,這類系統通常是 Genkit 基本元素,例如流程或模型。評估作業可以是自動評估或人工評估。
大量推論推論是指在資料流或模型上執行輸入內容,以取得相應輸出內容的行為。大量推論涉及同時對多個輸入內容執行推論。
指標:評估指標是評估推論分數的標準。例如準確度、忠實度、惡意性、輸出內容是否為英文等。
資料集:資料集是用於推論評估的範例集合。資料集通常包含
input
和選用的reference
欄位。reference
欄位不會影響評估的推論步驟,但會逐字傳遞至任何評估指標。在 Genkit 中,您可以透過開發人員 UI 建立資料集。Genkit 中有兩種類型的資料集:流程資料集和模型資料集。
結構定義驗證
視資料集類型而定,開發人員 UI 支援架構驗證:
流程資料集可針對 Genkit 應用程式中的流程,驗證資料集的
input
和reference
欄位。結構定義驗證為選用功能,只有在目標流程中指定結構定義時才會強制執行。模型資料集含有隱含的架構,同時支援
string
和GenerateRequest
輸入類型。字串驗證可讓您輕鬆評估簡單的文字提示,而GenerateRequest
則可提供完整的進階用途控制項 (例如提供模型參數、訊息記錄、工具等)。您可以在 API 參考文件中找到GenerateRequest
的完整結構定義。
支援的評估工具
Genkit 評估工具
Genkit 包含少數原生評估工具,這些工具的靈感來自 RAGAS,可協助您開始使用:
- 忠實度:評估生成答案與指定上下文的事實一致性
- 答案相關性:評估系統產生的答案與給定提示的相關程度
- 惡意性:評估產生的輸出內容是否意圖欺騙、傷害或濫用
評估工具外掛程式
Genkit 可透過外掛程式支援其他評估工具,例如 Vertex Rapid 評估工具,您可以透過 Vertex AI 外掛程式存取這些工具。
進階用途
使用 CLI 進行評估
Genkit CLI 提供豐富的 API 可用於執行評估。在無法使用開發人員 UI 的環境中 (例如 CI/CD 工作流程中),這項功能就特別實用。
Genkit CLI 提供 3 個主要評估指令:eval:flow
、eval:extractData
和 eval:run
。
eval:flow
指令
eval:flow
指令會對輸入資料集執行以推論為基礎的評估作業。您可以以 JSON 檔案的形式提供這項資料集,也可以在 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
在此,testInputs.json
應為物件陣列,其中包含 input
欄位和選用的 reference
欄位,如下所示:
[
{
"input": "What is the French word for Cheese?",
},
{
"input": "What green vegetable looks like cauliflower?",
"reference": "Broccoli"
}
]
如果流程需要驗證,您可以使用 --context
引數指定驗證:
genkit eval:flow qaFlow --input testInputs.json --context '{"auth": {"email_verified": true}}'
根據預設,eval:flow
和 eval:run
指令會使用所有可用的評估指標。如要針對已設定的評估工具子集執行,請使用 --evaluators
旗標,並以逗號分隔的清單提供評估工具名稱:
genkit eval:flow qaFlow --input testInputs.json --evaluators=genkitEval/maliciousness,genkitEval/answer_relevancy
您可以在 localhost:4000/evaluate
的開發人員 UI 中查看評估執行結果。
eval:extractData
和 eval:run
指令
為了支援原始評估,Genkit 提供工具,可從追蹤記錄中擷取資料,並針對擷取的資料執行評估指標。舉例來說,如果您使用其他評估架構,或是從其他環境收集推論,以便在本機測試輸出品質,這項功能就很實用。
您可以批次執行 Genkit 流程,並在執行時加入專屬標籤,然後用於擷取評估資料集。原始評估資料集是評估指標的輸入集合,不執行任何先前推論。
在測試輸入內容上執行流程:
genkit flow:batchRun qaFlow testInputs.json --label firstRunSimple
擷取評估資料:
genkit eval:extractData qaFlow --label firstRunSimple --output factsEvalDataset.json
匯出的資料格式與先前顯示的資料集格式不同。這是因為這類資料的用途是直接與評估指標搭配使用,不需任何推論步驟。以下是擷取資料的語法。
Array<{
"testCaseId": string,
"input": any,
"output": any,
"context": any[],
"traceIds": string[],
}>;
資料擷取器會自動尋找擷取器,並將產生的文件新增至內容陣列。您可以使用 eval:run
指令,對這個擷取的資料集執行評估指標。
genkit eval:run factsEvalDataset.json
根據預設,eval:run
會針對所有已設定的評估工具執行,而與 eval:flow
一樣,eval:run
的結果會顯示在位於 localhost:4000/evaluate
的開發人員 UI 評估頁面中。
自訂擷取器
Genkit 提供合理的預設邏輯,可在評估期間擷取必要欄位 (input
、output
和 context
)。不過,您可能需要對這些欄位的擷取邏輯進行更多控制。Genkit 支援自訂擷取器,可達成這項目標。您可以提供自訂擷取器,用於 eval:extractData
和 eval:flow
指令。
首先,我們在 qaFlow
範例中加入輔助步驟,做為準備步驟:
export const qaFlow = ai.defineFlow({
name: 'qaFlow',
inputSchema: z.string(),
outputSchema: z.string(),
},
async (query) => {
const factDocs = await ai.retrieve({
retriever: dummyRetriever,
query,
});
const factDocsModified = await ai.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: factDocsModified,
});
return llmResponse.text;
}
);
接下來,請設定自訂擷取器,在評估此流程時使用 factModified
步驟的輸出內容。
如果您沒有用來設定自訂擷取器的工具設定檔,請在專案根目錄中新增名為 genkit-tools.conf.js
的檔案。
cd /path/to/your/genkit/app
touch genkit-tools.conf.js
在工具設定檔案中新增下列程式碼:
module.exports = {
evaluators: [
{
actionRef: '/flow/qaFlow',
extractors: {
context: { outputOf: 'factModified' },
},
},
],
};
這項設定會覆寫 Genkit 工具的預設擷取工具,特別是變更評估此流程時視為 context
的內容。
再次執行評估作業,您會發現現在已將 context 填入做為步驟 factModified
的輸出內容。
genkit eval:flow qaFlow --input testInputs.json
評估擷取器的指定方式如下:
evaluators
欄位可接受 EvaluatorConfig 物件的陣列,其範圍由flowName
指定extractors
是用於指定擷取器覆寫值的物件。extractors
目前支援的鍵為[input, output, context]
。可接受的值類型如下:string
:應為步驟名稱,以字串形式指定。系統會為這個鍵擷取這個步驟的輸出內容。{ inputOf: string }
或{ outputOf: string }
:這些物件代表步驟的特定管道 (輸入或輸出)。舉例來說,{ inputOf: 'foo-step' }
會為這個鍵擷取步驟foo-step
的輸入內容。(trace) => string;
:為進一步提升彈性,您可以提供可接受 Genkit 追蹤記錄並傳回any
類型值的函式,並在該函式中指定擷取邏輯。如需確切的 TraceData 結構定義,請參閱genkit/genkit-tools/common/src/types/trace.ts
。
注意:所有擷取器的擷取資料都是對應擷取器的類型。舉例來說,如果您使用 context: { outputOf: 'foo-step' }
,而 foo-step
傳回物件的陣列,則擷取的內容也是物件的陣列。
使用 LLM 合成測試資料
以下是使用 PDF 檔案產生潛在使用者問題的流程範例。
import { genkit, 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 ai.run("extract-text", () => extractText(filePath));
const chunks = await ai.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