Firebase Genkit, test durumu çıktılarının özel olarak değerlendirilmesini destekleyecek şekilde genişletilebilir. Bunun için LLM'yi yargılama amacıyla veya yalnızca programatik olarak kullanabilirsiniz.
Değerlendirici tanımı
Değerlendiriciler, bir LLM'ye verilen ve LLM tarafından oluşturulan içeriği değerlendiren işlevlerdir. Otomatik değerlendirme (test) için iki temel yaklaşım vardır: bulgusal değerlendirme ve LLM tabanlı değerlendirme. Sezgisel yaklaşımda, geleneksel yazılım geliştirmede olduğu gibi deterministik bir işlev tanımlarsınız. LLM tabanlı bir değerlendirmede içerik bir LLM'ye geri beslenir ve LLM'den sonucu, istemde belirlenen ölçütlere göre puanlaması istenir.
LLM tabanlı Değerlendirme Araçları
LLM tabanlı bir değerlendirme uzmanı, üretken yapay zeka özelliğinizin girdisini, bağlamını veya çıktısını değerlendirmek için LLM'den yararlanır.
Genkit'teki LLM tabanlı değerlendirmeciler 3 bileşenden oluşur:
- İstem
- Puanlama işlevi
- Bir değerlendirmeci işlemi
İstemi tanımlama
Bu örnekte istem, LLM'den sonucun ne kadar lezzetli olduğunu değerlendirmesini isteyecektir. Öncelikle LLM'ye bağlam bilgisi sağlayın, ardından ne yapmasını istediğinizi açıklayın ve son olarak da yanıtını dayandırabileceği birkaç örnek verin.
Genkit, giriş/çıkış şeması doğrulaması gibi özelliklerle istemleri tanımlamanın ve yönetmenin kolay bir yolunu sunan dotprompt
içerir. Değerlendirme istemi tanımlamak için dotprompt
aracını nasıl kullanabileceğiniz aşağıda açıklanmıştır.
import { defineDotprompt } from '@genkit-ai/dotprompt';
// Define the expected output values
const DELICIOUSNESS_VALUES = ['yes', 'no', 'maybe'] as const;
// Define the response schema expected from the LLM
const DeliciousnessDetectionResponseSchema = z.object({
reason: z.string(),
verdict: z.enum(DELICIOUSNESS_VALUES),
});
type DeliciousnessDetectionResponse = z.infer<
typeof DeliciousnessDetectionResponseSchema
>;
const DELICIOUSNESS_PROMPT = defineDotprompt(
{
input: {
schema: z.object({
output: z.string(),
}),
},
output: {
schema: DeliciousnessDetectionResponseSchema,
},
},
`You are a food critic with a wide range in taste. Given the output, decide if it sounds delicious and provide your reasoning. Use only "yes" (if delicous), "no" (if not delicious), "maybe" (if you can't decide) as the verdict.
Here are a few examples:
Output:
Chicken parm sandwich
Response:
{ "reason": "This is a classic sandwich enjoyed by many - totally delicious", "verdict":"yes"}
Output:
Boston logan international airport tarmac
Response:
{ "reason": "This is not edible and definitely not delicious.", "verdict":"no"}
Output:
A juicy piece of gossip
Response:
{ "reason": "Gossip is sometimes metaphorically referred to as tasty.", "verdict":"maybe"}
Here is a new submission to assess:
Output:
{{output}}
Response:
`
);
Puanlama işlevini tanımlama
Şimdi, istemin gerektirdiği şekilde output
öğesini içeren bir örnek alacak işlevi tanımlayıp sonucu puanlayın. Genkit test durumlarında zorunlu bir alan olarak input
, output
ve context
için isteğe bağlı alanlar bulunur. Değerlendirme için gerekli tüm alanların mevcut olduğunu doğrulamak değerlendirmecinin sorumluluğundadır.
/**
* Score an individual test case for delciousness.
*/
export async function deliciousnessScore<
CustomModelOptions extends z.ZodTypeAny,
>(
judgeLlm: ModelArgument<CustomModelOptions>,
dataPoint: BaseDataPoint,
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 },
};
}
Değerlendirmeci işlemini tanımlama
Son adım, değerlendirici işleminin kendisini tanımlayan bir fonksiyon yazmaktır.
/**
* 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: BaseDataPoint) => {
const score = await deliciousnessScore(judge, datapoint, judgeConfig);
return {
testCaseId: datapoint.testCaseId,
evaluation: score,
};
}
);
}
Sezgisel Değerlendirme Araçları
Sezgisel değerlendirme aracı, üretken yapay zeka özelliğinizin girdisini, bağlamını veya çıkışını değerlendirmek için kullanılan herhangi bir fonksiyon olabilir.
Genkit'teki bulgusal değerlendirmeciler 2 bileşenden oluşur:
- Puanlama işlevi
- Bir değerlendirmeci işlemi
Puanlama işlevini tanımlama
Tıpkı LLM tabanlı değerlendirme uzmanı gibi puanlama işlevini tanımlayın. Bu durumda, puanlama işlevinin jüri LLM'si veya yapılandırması hakkında bilgi sahibi olmasına gerek yoktur.
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: BaseDataPoint
): 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 },
};
}
Değerlendirmeci işlemini tanımlama
/**
* 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: BaseDataPoint) => {
const score = await regexMatchScore(datapoint, regexMetric.regex);
return fillScores(datapoint, score);
}
);
});
}
Yapılandırma
Eklenti Seçenekleri
Özel değerlendirici eklentisinin kullanacağı PluginOptions
öğesini tanımlayın. Bu nesnenin katı bir gereksinimi yoktur ve tanımlanan değerlendirici türlerine bağlıdır.
En azından hangi metriklerin kaydedileceğini tanımlamak gerekir.
export enum MyAwesomeMetric {
WORD_COUNT = 'WORD_COUNT',
US_PHONE_REGEX_MATCH = 'US_PHONE_REGEX_MATCH',
}
export interface PluginOptions {
metrics?: Array<MyAwesomeMetric>;
}
Bu yeni eklenti, hakim olarak bir LLM kullanıyorsa ve eklenti, kullanılacak LLM'nin değiştirilmesini destekliyorsa PluginOptions
nesnesinde ek parametreler tanımlayın.
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>;
}
Eklenti tanımı
Eklentiler, projedeki genkit.config.ts
dosyası aracılığıyla çerçeveye kaydedilir. Yeni bir eklenti yapılandırabilmek için GenkitPlugin
tanımlayan ve yukarıda tanımlanan PluginOptions
ile yapılandıran bir işlev tanımlayın.
Bu örnekte DELICIOUSNESS
ve US_PHONE_REGEX_MATCH
adlı iki değerlendirme uzmanımız var. Bu değerlendirmeciler, eklentiye ve Firebase Genkit'e burada kayıtlıdır.
export function myAwesomeEval<ModelCustomOptions extends z.ZodTypeAny>(
params: PluginOptions<ModelCustomOptions>
): PluginProvider {
// Define the new plugin
const plugin = genkitPlugin(
'myAwesomeEval',
async (params: PluginOptions<ModelCustomOptions>) => {
const { judge, judgeConfig, metrics } = params;
const evaluators: EvaluatorAction[] = metrics.map((metric) => {
// We'll create these functions in the next step
switch (metric) {
case DELICIOUSNESS:
// This evaluator requires an LLM as judge
return createDeliciousnessEvaluator(judge, judgeConfig);
case US_PHONE_REGEX_MATCH:
// This evaluator does not require an LLM
return createUSPhoneRegexEvaluator();
}
});
return { evaluators };
}
);
// Create the plugin with the passed params
return plugin(params);
}
export default myAwesomeEval;
Genkit'i yapılandırma
Yeni tanımlanan eklentiyi Genkit yapılandırmanıza ekleyin.
Gemini ile değerlendirme yaparken güvenlik ayarlarını devre dışı bırakın. Böylece değerlendirici, zararlı olabilecek içerikleri kabul edebilir, tespit edebilir ve puanlayabilir.
import { gemini15Flash } from '@genkit-ai/googleai';
export default configureGenkit({
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
],
}),
],
...
});
Test
Üretken yapay zeka özelliğinin çıktılarının kalitesini değerlendirmede geçerli olan sorunlar, LLM tabanlı bir değerlendirmecinin değerlendirme kapasitesinin değerlendirilmesi için de geçerlidir.
Özel değerlendiricinin beklenen düzeyde performans gösterip göstermediğine dair fikir edinmek için net bir doğru ve yanlış cevabı olan bir dizi test durumu oluşturun.
Lezzet konusuna örnek olarak şu json dosyasına benzer: 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."
}
]
Bu örnekler gerçek kişiler tarafından oluşturulabilir veya LLM'den (büyük dil modeli) seçilebilecek bir test durumu grubu oluşturmaya yardımcı olmasını isteyebilirsiniz. Kullanabileceğiniz birçok karşılaştırma veri kümesi de vardır.
Ardından, değerlendiriciyi bu test durumlarında çalıştırmak için Genkit KSA'yı kullanın.
genkit eval:run deliciousness_dataset.json
Sonuçlarınızı Genkit kullanıcı arayüzünde görüntüleyin.
genkit start
localhost:4000/evaluate
adresine gidiş rotasını izle.