הערכה היא סוג של בדיקה שעוזרת לאמת את התשובות של ה-LLM ולוודא שהן עומדות בסטנדרט האיכות שלכם.
Firebase Genkit תומך בכלי הערכה של צד שלישי באמצעות יישומי פלאגין, בשילוב עם תכונות מתקדמות של יכולת תצפית שמספקות תובנות לגבי מצב זמן הריצה של האפליקציות שמבוססות על LLM. כלי Genkit עוזרים לחלץ באופן אוטומטי נתונים, כולל קלט, פלט ומידע משלב ביניים, כדי להעריך את האיכות מקצה לקצה של התשובות של LLM, וגם כדי להבין את הביצועים של אבני הבניין של המערכת.
סוגי הבדיקות
ב-Genkit יש תמיכה בשני סוגים של הערכה:
הערכה מבוססת-הסקה: סוג ההערכה הזה פועל על סמך אוסף של נתוני קלט שהוגדרו מראש, ומעריך את האיכות של הפלט המתאים.
זהו סוג ההערכה הנפוץ ביותר, והוא מתאים לרוב התרחישים לדוגמה. הגישה הזו מאפשרת לבדוק את הפלט בפועל של המערכת בכל הפעלה של הבדיקה.
אפשר לבצע את הערכת האיכות באופן ידני על ידי בדיקה חזותית של התוצאות. לחלופין, אפשר להפוך את הבדיקה לאוטומטית באמצעות מדד הערכה.
הערכה גולמית: סוג ההערכה הזה מעריך ישירות את איכות הקלט ללא כל היסק. בדרך כלל משתמשים בגישה הזו עם הערכה אוטומטית באמצעות מדדים. כל השדות הנדרשים לצורך הערכה (למשל,
input
,context
, output
ו-reference
) חייבים להופיע במערך הנתונים של הקלט. האפשרות הזו שימושית כשיש לכם נתונים שמגיעים ממקור חיצוני (למשל, שנאספו מהטראקים שלכם בסביבת הייצור) ואתם רוצים לבצע מדידה אובייקטיבית של איכות הנתונים שנאספו.מידע נוסף זמין בקטע שימוש מתקדם בדף הזה.
בקטע הזה נסביר איך לבצע הערכה מבוססת-הסקה באמצעות Genkit.
התחלה מהירה
הגדרה
- אפשר להשתמש באפליקציה קיימת של Genkit או ליצור אפליקציה חדשה לפי ההוראות במדריך [תחילת העבודה](תחילת העבודה).
- מוסיפים את הקוד הבא כדי להגדיר אפליקציית RAG פשוטה לצורך הערכה. במדריך הזה אנחנו משתמשים בשירות אחזור דמי שמחזיר תמיד את אותם מסמכים. ```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)) }; } ); // תהליך פשוט של מענה על שאלות 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; } ); ```
- (אופציונלי) מוסיפים מדדי הערכה לאפליקציה לשימוש במהלך ההערכה. במדריך הזה נעשה שימוש במדד 'MALICIOUSNESS' מהתוסף 'genkitEval'. ```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], }), ] }); ``` **הערה:** כדי להשתמש בתצורה שלמעלה, צריך להתקין את החבילה [`@genkit-ai/evaluator`](https://www.npmjs.com/package/@genkit-ai/evaluator). ```posix-terminal npm install @genkit-ai/evaluator ```
- מפעילים את אפליקציית Genkit
```posix-terminal
genkit start --
```
יצירת מערך נתונים
יוצרים מערך נתונים כדי להגדיר את הדוגמאות שבהן אנחנו רוצים להשתמש כדי להעריך את התהליך.
עוברים לממשק המשתמש של הפיתוח בכתובת
http://localhost:4000
ולוחצים על הלחצן Datasets כדי לפתוח את הדף Datasets.לוחצים על הלחצן Create Dataset כדי לפתוח את תיבת הדו-שיח ליצירת מערך נתונים.
א. נותנים שם
datasetId
למערך הנתונים החדש. במדריך הזה נעשה שימוש ב-myFactsQaDataset
.ב. בוחרים את סוג מערך הנתונים
Flow
.ג. משאירים את השדה validation target ריק ולוחצים על Save.
יופיע הדף של מערך הנתונים החדש, שבו מוצג מערך נתונים ריק. כדי להוסיף דוגמאות:
א. לוחצים על הלחצן Add example כדי לפתוח את חלונית העריכה של הדוגמה.
ב. רק השדה
input
הוא חובה. מזינים"Who is man's best friend?"
בשדהinput
ולוחצים על שמירה כדי להוסיף את ה-has לדוגמה למערך הנתונים.ג. חוזרים על שלבים (א) ו-(ב) עוד כמה פעמים כדי להוסיף עוד דוגמאות. במדריך הזה מתווספים למערך הנתונים דוגמאות של קלט:
"Can I give milk to my cats?" "From which animals did dogs evolve?"
בסיום השלב הזה, מערך הנתונים אמור לכלול 3 דוגמאות עם הערכים שצוינו למעלה.
הפעלת ההערכה והצגת התוצאות
כדי להתחיל להעריך את התהליך, לוחצים על הכרטיסייה Evaluations
בממשק המשתמש למפתחים ואז על הלחצן Run new evaluation.
בוחרים בלחצן הבחירה
Flow
כדי להעריך תהליך.בוחרים ב-
qaFlow
בתור תהליך היעד לבדיקה.בוחרים את
myFactsQaDataset
כמערך הנתונים היעד לצורך הערכה.(אופציונלי) אם התקנתם מדד הערכה באמצעות יישומי פלאגין של Genkit, תוכלו לראות את המדדים האלה בדף הזה. בוחרים את המדדים שרוצים להשתמש בהם במהלך ההרצה של הבדיקה. השלב הזה הוא אופציונלי לחלוטין: אם תדלגו עליו, עדיין יוצגו התוצאות של הרצה של הערכה, אבל בלי מדדים משויכים.
לבסוף, לוחצים על הפעלת הבדיקה כדי להתחיל את הבדיקה. התהליך עשוי להימשך זמן מה, בהתאם לתהליך שאתם בודקים. בסיום ההערכה תוצג הודעה על הצלחה עם קישור להצגת התוצאות. לוחצים על הקישור כדי לעבור לדף פרטי הבדיקה.
בדף הזה אפשר לראות את פרטי הבדיקה, כולל הקלט המקורי, ההקשר שחולץ והמדדים (אם יש).
מושגי ליבה
הסברים על המונחים
הערכה: הערכה היא תהליך להערכת ביצועי המערכת. ב-Genkit, מערכת כזו היא בדרך כלל רכיב פרימיטיבי של Genkit, כמו תהליך או מודל. ההערכה יכולה להיות אוטומטית או ידנית (הערכה אנושית).
הסקת מסקנות בכמות גדולה: פעולת ההסקה היא הפעלת קלט בתהליך או במודל כדי לקבל את הפלט המתאים. הסקת מסקנות בכמות גדולה כוללת ביצוע של הסקה על מספר מקורות קלט בו-זמנית.
מדד מדד הערכה הוא קריטריון שממנו נקבע הדירוג של ההסקה. דוגמאות לכך הן: דיוק, נאמנות, זדוניות, האם הפלט הוא באנגלית ועוד.
מערך נתונים: מערך נתונים הוא אוסף של דוגמאות לשימוש בהערכה מבוססת-הסקה. בדרך כלל, מערך נתונים מורכב משדות
input
ושדותreference
אופציונליים. השדהreference
לא משפיע על שלב ההסקה של ההערכה, אבל הוא מועבר ללא שינוי לכל מדדי ההערכה. ב-Genkit אפשר ליצור מערך נתונים דרך ממשק המשתמש למפתחים. יש שני סוגים של מערכי נתונים ב-Genkit: מערכי נתונים של תהליכים ומערכי נתונים של מודלים.
אימות סכימה
בהתאם לסוג, למערכי נתונים יש תמיכה באימות סכימה בממשק המשתמש למפתחים:
מערכי נתונים של תהליכים תומכים באימות של השדות
input
ו-reference
של מערך הנתונים מול תהליך באפליקציית Genkit. אימות הסכימה הוא אופציונלי, והוא נאכף רק אם סכימה מצוינה בתהליך היעד.למערכי נתונים של מודלים יש סכימה משתמעת, שתומכת גם בסוגים
string
וגם בסוגיםGenerateRequest
של קלט. אימות מחרוזות הוא דרך נוחה להעריך הנחיות טקסט פשוטות, בעוד ש-GenerateRequest
מספק שליטה מלאה בתרחישי שימוש מתקדמים (למשל, מתן פרמטרים של מודל, היסטוריית הודעות, כלים וכו'). אפשר למצוא את הסכימה המלאה שלGenerateRequest
במסמכי העזר של ה-API.
גורמי הערכה נתמכים
בודקי Genkit
כדי לעזור לכם להתחיל, Genkit כולל מספר קטן של מודלים מקומיים להערכה, בהשראת RAGAS:
- נאמנות – מדידת העקביות העובדתית של התשובה שנוצרה בהתאם להקשר הנתון
- רלוונטיות התשובה – הערכה של מידת הרלוונטיות של התשובה שנוצרה להנחיה הנתונה
- זדון – המערכת בודקת אם הפלט שנוצר נועד להטעות, להזיק או לנצל לרעה
פלאגינים של כלי הערכה
Genkit תומך במודולים נוספים להערכה באמצעות פלאגינים, כמו Vertex Rapid Evaluators, שאפשר לגשת אליהם דרך הפלאגין של VertexAI.
שימוש מתקדם
הערכה באמצעות CLI
ה-CLI של Genkit מספק ממשק API עשיר לביצוע הערכה. האפשרות הזו שימושית במיוחד בסביבות שבהן ממשק המשתמש של הפיתוח לא זמין (למשל בתהליך עבודה של 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"
}
]
אם התהליך דורש אימות, אפשר לציין אותו באמצעות הארגומנט --auth
:
genkit eval:flow qaFlow --input testInputs.json --auth "{\"email_verified\": true}"
כברירת מחדל, הפקודות eval:flow
ו-eval:run
משתמשות בכל המדדים הזמינים לצורך הערכה. כדי להריץ על קבוצת משנה של הבודקים שהוגדרו, משתמשים בדגל --evaluators
ומספקים רשימה של הבודקים לפי שם, מופרדת בפסיקים:
genkit eval:flow qaFlow --input testInputs.json --evaluators=genkit/faithfulness,genkit/answer_relevancy
אפשר לראות את התוצאות של הרצת ההערכה בממשק המשתמש של הפיתוח בכתובת localhost:4000/evaluate
.
הפקודות 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
.
חילוצי נתונים בהתאמה אישית
Genkit מספק לוגיקה סבירה של ברירת מחדל לחילוץ השדות הנחוצים (input
, output
ו-context
) במהלך הערכה. עם זאת, יכול להיות שתצטרכו יותר שליטה על הלוגיקה של החילוץ של השדות האלה.
כדי לעשות זאת, Genkit תומך ב-extractors מותאמים אישית. אפשר לספק מחלצים מותאמים אישית לשימוש בפקודות 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,
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;
}
);
בשלב הבא, מגדירים חילוץ מותאם אישית כך שישתמש בפלט של שלב factModified
במהלך הערכת התהליך.
אם אין לכם קובץ tools-config להגדרת חילוצי נתונים מותאמים אישית, מוסיפים קובץ בשם 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
כשבודקים את התהליך הזה.
הפעלה חוזרת של ההערכה מראה שההקשר מאוכלס עכשיו כפלט של השלב 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, 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;
}
);
לאחר מכן תוכלו להשתמש בפקודה הזו כדי לייצא את הנתונים לקובץ ולהשתמש בהם לצורך הערכה.
genkit flow:run synthesizeQuestions '"my_input.pdf"' --output synthesizedQuestions.json