Firebase Genkit dapat diperluas untuk mendukung evaluasi kustom output kasus pengujian, baik dengan menggunakan LLM sebagai hakim, atau sepenuhnya secara terprogram.
Definisi evaluator
Evaluator adalah fungsi yang menilai konten yang diberikan ke dan dihasilkan oleh LLM. Ada dua pendekatan utama untuk evaluasi otomatis (pengujian): penilaian heuristik dan penilaian berbasis LLM. Dalam pendekatan heuristik, Anda menentukan fungsi deterministik seperti pengembangan software tradisional. Dalam penilaian berbasis LLM, konten akan dimasukkan kembali ke LLM dan LLM diminta untuk menilai output sesuai dengan kriteria yang ditetapkan dalam perintah.
Evaluator berbasis LLM
Evaluator berbasis LLM memanfaatkan LLM untuk mengevaluasi input, konteks, atau output fitur AI generatif Anda.
Evaluator berbasis LLM di Genkit terdiri dari 3 komponen:
- Perintah
- Fungsi penskoran
- Tindakan evaluator
Menentukan perintah
Untuk contoh ini, perintah akan meminta LLM untuk menilai seberapa lezat output-nya. Pertama, berikan konteks ke LLM, lalu jelaskan apa yang Anda inginkan, dan terakhir, berikan beberapa contoh untuk mendasarkan responsnya.
Utilitas definePrompt
Genkit menyediakan cara mudah untuk menentukan perintah dengan validasi input dan output. Berikut cara menyiapkan perintah evaluasi dengan definePrompt
.
const DELICIOUSNESS_VALUES = ['yes', 'no', 'maybe'] as const;
const DeliciousnessDetectionResponseSchema = z.object({
reason: z.string(),
verdict: z.enum(DELICIOUSNESS_VALUES),
});
type DeliciousnessDetectionResponse = z.infer<typeof DeliciousnessDetectionResponseSchema>;
const DELICIOUSNESS_PROMPT = ai.definePrompt(
{
name: 'deliciousnessPrompt',
inputSchema: z.object({
output: z.string(),
}),
outputSchema: DeliciousnessDetectionResponseSchema,
},
`You are a food critic. Assess whether the provided output sounds delicious, giving only "yes" (delicious), "no" (not delicious), or "maybe" (undecided) as the verdict.
Examples:
Output: Chicken parm sandwich
Response: { "reason": "A classic and beloved dish.", "verdict": "yes" }
Output: Boston Logan Airport tarmac
Response: { "reason": "Not edible.", "verdict": "no" }
Output: A juicy piece of gossip
Response: { "reason": "Metaphorically 'tasty' but not food.", "verdict": "maybe" }
New Output:
{{output}}
Response:
`
);
Menentukan fungsi penskoran
Sekarang, tentukan fungsi yang akan mengambil contoh yang menyertakan output
seperti yang diperlukan oleh perintah dan beri skor pada hasilnya. Kasus pengujian Genkit menyertakan input
sebagai kolom wajib diisi, dengan kolom opsional untuk output
dan context
. Evaluator bertanggung jawab untuk memvalidasi bahwa semua kolom yang diperlukan untuk evaluasi sudah ada.
import { BaseEvalDataPoint, Score } from 'genkit/evaluator';
/**
* Score an individual test case for delciousness.
*/
export async function deliciousnessScore<
CustomModelOptions extends z.ZodTypeAny,
>(
judgeLlm: ModelArgument<CustomModelOptions>,
dataPoint: BaseEvalDataPoint,
judgeConfig?: CustomModelOptions
): Promise<Score> {
const d = dataPoint;
// Validate the input has required fields
if (!d.output) {
throw new Error('Output is required for Deliciousness detection');
}
//Hydrate the prompt
const finalPrompt = DELICIOUSNESS_PROMPT.renderText({
output: d.output as string,
});
// Call the LLM to generate an evaluation result
const response = await generate({
model: judgeLlm,
prompt: finalPrompt,
config: judgeConfig,
});
// Parse the output
const parsedResponse = response.output;
if (!parsedResponse) {
throw new Error(`Unable to parse evaluator response: ${response.text}`);
}
// Return a scored response
return {
score: parsedResponse.verdict,
details: { reasoning: parsedResponse.reason },
};
}
Menentukan tindakan evaluator
Langkah terakhir adalah menulis fungsi yang menentukan tindakan evaluator itu sendiri.
import { BaseEvalDataPoint, EvaluatorAction } from 'genkit/evaluator';
/**
* Create the Deliciousness evaluator action.
*/
export function createDeliciousnessEvaluator<
ModelCustomOptions extends z.ZodTypeAny,
>(
judge: ModelReference<ModelCustomOptions>,
judgeConfig: z.infer<ModelCustomOptions>
): EvaluatorAction {
return defineEvaluator(
{
name: `myAwesomeEval/deliciousness`,
displayName: 'Deliciousness',
definition: 'Determines if output is considered delicous.',
},
async (datapoint: BaseEvalDataPoint) => {
const score = await deliciousnessScore(judge, datapoint, judgeConfig);
return {
testCaseId: datapoint.testCaseId,
evaluation: score,
};
}
);
}
Evaluator Heuristik
Evaluator heuristik dapat berupa fungsi apa pun yang digunakan untuk mengevaluasi input, konteks, atau output fitur AI generatif Anda.
Evaluator heuristik di Genkit terdiri dari 2 komponen:
- Fungsi penskoran
- Tindakan evaluator
Menentukan fungsi penskoran
Sama seperti evaluator berbasis LLM, tentukan fungsi penskoran. Dalam hal ini, fungsi penskoran tidak perlu mengetahui LLM hakim atau konfigurasinya.
import { BaseEvalDataPoint, Score } from 'genkit/evaluator';
const US_PHONE_REGEX =
/^[\+]?[(]?[0-9]{3}[)]?[-\s\.]?[0-9]{3}[-\s\.]?[0-9]{4}$/i;
/**
* Scores whether an individual datapoint matches a US Phone Regex.
*/
export async function usPhoneRegexScore(
dataPoint: BaseEvalDataPoint
): Promise<Score> {
const d = dataPoint;
if (!d.output || typeof d.output !== 'string') {
throw new Error('String output is required for regex matching');
}
const matches = US_PHONE_REGEX.test(d.output as string);
const reasoning = matches
? `Output matched regex ${regex.source}`
: `Output did not match regex ${regex.source}`;
return {
score: matches,
details: { reasoning },
};
}
Menentukan tindakan evaluator
import { BaseEvalDataPoint, EvaluatorAction } from 'genkit/evaluator';
/**
* Configures a regex evaluator to match a US phone number.
*/
export function createUSPhoneRegexEvaluator(
metrics: RegexMetric[]
): EvaluatorAction[] {
return metrics.map((metric) => {
const regexMetric = metric as RegexMetric;
return defineEvaluator(
{
name: `myAwesomeEval/${metric.name.toLocaleLowerCase()}`,
displayName: 'Regex Match',
definition:
'Runs the output against a regex and responds with 1 if a match is found and 0 otherwise.',
isBilled: false,
},
async (datapoint: BaseEvalDataPoint) => {
const score = await regexMatchScore(datapoint, regexMetric.regex);
return fillScores(datapoint, score);
}
);
});
}
Konfigurasi
Opsi Plugin
Tentukan PluginOptions
yang akan digunakan plugin evaluator kustom. Objek ini tidak memiliki persyaratan ketat dan bergantung pada jenis evaluator yang ditentukan.
Setidaknya, metrik ini harus mengambil definisi metrik yang akan didaftarkan.
export enum MyAwesomeMetric {
WORD_COUNT = 'WORD_COUNT',
US_PHONE_REGEX_MATCH = 'US_PHONE_REGEX_MATCH',
}
export interface PluginOptions {
metrics?: Array<MyAwesomeMetric>;
}
Jika plugin baru ini menggunakan LLM sebagai hakim dan plugin mendukung penggantian LLM yang akan digunakan, tentukan parameter tambahan dalam objek PluginOptions
.
export enum MyAwesomeMetric {
DELICIOUSNESS = 'DELICIOUSNESS',
US_PHONE_REGEX_MATCH = 'US_PHONE_REGEX_MATCH',
}
export interface PluginOptions<ModelCustomOptions extends z.ZodTypeAny> {
judge: ModelReference<ModelCustomOptions>;
judgeConfig?: z.infer<ModelCustomOptions>;
metrics?: Array<MyAwesomeMetric>;
}
Definisi plugin
Plugin didaftarkan dengan framework melalui file genkit.config.ts
dalam project. Agar dapat mengonfigurasi plugin baru, tentukan fungsi yang menentukan GenkitPlugin
dan mengonfigurasinya dengan PluginOptions
yang ditentukan di atas.
Dalam hal ini, kita memiliki dua evaluator DELICIOUSNESS
dan US_PHONE_REGEX_MATCH
. Di sinilah evaluator tersebut terdaftar dengan plugin dan dengan Firebase Genkit.
export function myAwesomeEval<ModelCustomOptions extends z.ZodTypeAny>(
options: PluginOptions<ModelCustomOptions>
): PluginProvider {
// Define the new plugin
const plugin = (options?: MyPluginOptions<ModelCustomOptions>) => {
return genkitPlugin(
'myAwesomeEval',
async (ai: Genkit) => {
const { judge, judgeConfig, metrics } = options;
const evaluators: EvaluatorAction[] = metrics.map((metric) => {
switch (metric) {
case DELICIOUSNESS:
// This evaluator requires an LLM as judge
return createDeliciousnessEvaluator(ai, judge, judgeConfig);
case US_PHONE_REGEX_MATCH:
// This evaluator does not require an LLM
return createUSPhoneRegexEvaluator();
}
});
return { evaluators };
})
}
// Create the plugin with the passed options
return plugin(options);
}
export default myAwesomeEval;
Mengonfigurasi Genkit
Tambahkan plugin yang baru ditentukan ke konfigurasi Genkit Anda.
Untuk evaluasi dengan Gemini, nonaktifkan setelan keamanan agar evaluator dapat menerima, mendeteksi, dan memberi skor konten yang berpotensi berbahaya.
import { gemini15Flash } from '@genkit-ai/googleai';
const ai = genkit({
plugins: [
...
myAwesomeEval({
judge: gemini15Flash,
judgeConfig: {
safetySettings: [
{
category: 'HARM_CATEGORY_HATE_SPEECH',
threshold: 'BLOCK_NONE',
},
{
category: 'HARM_CATEGORY_DANGEROUS_CONTENT',
threshold: 'BLOCK_NONE',
},
{
category: 'HARM_CATEGORY_HARASSMENT',
threshold: 'BLOCK_NONE',
},
{
category: 'HARM_CATEGORY_SEXUALLY_EXPLICIT',
threshold: 'BLOCK_NONE',
},
],
},
metrics: [
MyAwesomeMetric.DELICIOUSNESS,
MyAwesomeMetric.US_PHONE_REGEX_MATCH
],
}),
],
...
});
Pengujian
Masalah yang sama yang berlaku untuk mengevaluasi kualitas output fitur AI generatif juga berlaku untuk mengevaluasi kapasitas penilaian evaluator berbasis LLM.
Untuk mengetahui apakah evaluator kustom berperforma sesuai dengan tingkat yang diharapkan, buat serangkaian kasus pengujian yang memiliki jawaban benar dan salah yang jelas.
Sebagai contoh untuk kelezatan, yang mungkin terlihat seperti file json deliciousness_dataset.json
:
[
{
"testCaseId": "delicous_mango",
"input": "What is a super delicious fruit",
"output": "A perfectly ripe mango – sweet, juicy, and with a hint of tropical sunshine."
},
{
"testCaseId": "disgusting_soggy_cereal",
"input": "What is something that is tasty when fresh but less tasty after some time?",
"output": "Stale, flavorless cereal that's been sitting in the box too long."
}
]
Contoh ini dapat dibuat oleh manusia atau Anda dapat meminta LLM untuk membantu membuat serangkaian kasus pengujian yang dapat diseleksi. Ada banyak set data benchmark yang tersedia dan juga dapat digunakan.
Kemudian, gunakan Genkit CLI untuk menjalankan evaluator terhadap kasus pengujian ini.
genkit eval:run deliciousness_dataset.json
Lihat hasil Anda di UI Genkit.
genkit start
Buka localhost:4000/evaluate
.