Firebase Genkit'i, özel değerlendirmeyi desteklemek için hakim olarak bir LLM kullanarak veya programatik (heuristic) değerlendirmeyle genişletebilirsiniz.
Değerlendirici tanımı
Değerlendiriciler, LLM'nin yanıtını değerlendiren işlevlerdir. Otomatik değerlendirmeye iki ana yaklaşım vardır: sezgisel değerlendirme ve LLM tabanlı değerlendirme. Heuristic yaklaşımda, deterministik bir işlev tanımlarsınız. Buna karşılık, LLM tabanlı bir değerlendirmede içerik bir LLM'ye geri beslenir ve LLM'den çıkışı bir istemde belirtilen ölçütlere göre puanlaması istenir.
Genkit'te bir değerlendirici işlemi tanımlamak için kullandığınız ai.defineEvaluator
yöntemi, her iki yaklaşımı da destekler. Bu dokümanda, bu yöntemin sezgisel ve LLM tabanlı değerlendirmeler için nasıl kullanılacağına dair birkaç örnek incelenmektedir.
LLM tabanlı değerlendirme araçları
LLM tabanlı bir değerlendirici, üretken yapay zeka özelliğinizin input
, context
ve output
özelliklerini değerlendirmek için LLM'den yararlanır.
Genkit'teki LLM tabanlı değerlendiriciler 3 bileşenden oluşur:
- İstem
- Puanlama işlevi
- Değerlendirici işlemi
İstemi tanımlama
Bu örnekte, değerlendirici bir yemeğin (output
) lezzetli olup olmadığını belirlemek için LLM'den yararlanır. Öncelikle LLM'ye bağlam bilgisi verin, ardından ne yapmasını istediğinizi açıklayın ve son olarak yanıtını temel alacağı birkaç örnek verin.
Genkit'in definePrompt
yardımcı programı, giriş ve çıkış doğrulamasıyla istemleri tanımlamanın kolay bir yolunu sunar. Aşağıdaki kod, definePrompt
ile değerlendirme istemi oluşturmaya dair bir örnektir.
import { z } from "genkit";
const DELICIOUSNESS_VALUES = ['yes', 'no', 'maybe'] as const;
const DeliciousnessDetectionResponseSchema = z.object({
reason: z.string(),
verdict: z.enum(DELICIOUSNESS_VALUES),
});
function getDeliciousnessPrompt(ai: Genkit) {
return ai.definePrompt({
name: 'deliciousnessPrompt',
input: {
schema: z.object({
responseToTest: z.string(),
}),
},
output: {
schema: 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: {{ responseToTest }}
Response:
`
);
}
Puanlama işlevini tanımlama
İstem tarafından gerektiği gibi output
içeren bir örnek alan ve sonucu puanlayan bir işlev tanımlayın. Genkit test örnekleri, zorunlu alan olarak input
ve isteğe bağlı alanlar olarak output
ve context
içerir. Değerlendirme için gerekli tüm alanların mevcut olduğunu doğrulamak değerlendirmecinin sorumluluğundadır.
import { ModelArgument, z } from 'genkit';
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 and generate an evaluation result
const deliciousnessPrompt = getDeliciousnessPrompt(ai);
const response = await deliciousnessPrompt(
{
responseToTest: d.output as string,
},
{
model: judgeLlm,
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ğerlendirici işlemini tanımlama
Son adım, EvaluatorAction
değerini tanımlayan bir işlev yazmaktır.
import { Genkit, z } from 'genkit';
import { BaseEvalDataPoint, EvaluatorAction } from 'genkit/evaluator';
/**
* Create the Deliciousness evaluator action.
*/
export function createDeliciousnessEvaluator<
ModelCustomOptions extends z.ZodTypeAny,
>(
ai: Genkit,
judge: ModelArgument<ModelCustomOptions>,
judgeConfig?: z.infer<ModelCustomOptions>
): EvaluatorAction {
return ai.defineEvaluator(
{
name: `myCustomEvals/deliciousnessEvaluator`,
displayName: 'Deliciousness',
definition: 'Determines if output is considered delicous.',
isBilled: true,
},
async (datapoint: BaseEvalDataPoint) => {
const score = await deliciousnessScore(judge, datapoint, judgeConfig);
return {
testCaseId: datapoint.testCaseId,
evaluation: score,
};
}
);
}
defineEvaluator
yöntemi, defineFlow
ve defineRetriever
gibi diğer Genkit kurucularına benzer. Bu yöntem için geri çağırma olarak bir EvaluatorFn
sağlanmalıdır. EvaluatorFn
yöntemi, değerlendirilmekte olan bir veri kümesinde tek bir girişe karşılık gelen bir BaseEvalDataPoint
nesnesini ve isteğe bağlı olarak belirtilmişse özel seçenekler parametresini kabul eder. İşlev, veri noktasını işler ve bir EvalResponse
nesnesi döndürür.
BaseEvalDataPoint
ve EvalResponse
için Zod şemaları aşağıdaki gibidir.
BaseEvalDataPoint
export const BaseEvalDataPoint = z.object({
testCaseId: z.string(),
input: z.unknown(),
output: z.unknown().optional(),
context: z.array(z.unknown()).optional(),
reference: z.unknown().optional(),
testCaseId: z.string().optional(),
traceIds: z.array(z.string()).optional(),
});
export const EvalResponse = z.object({
sampleIndex: z.number().optional(),
testCaseId: z.string(),
traceId: z.string().optional(),
spanId: z.string().optional(),
evaluation: z.union([ScoreSchema, z.array(ScoreSchema)]),
});
ScoreSchema
const ScoreSchema = z.object({
id: z.string().describe('Optional ID to differentiate multiple scores').optional(),
score: z.union([z.number(), z.string(), z.boolean()]).optional(),
error: z.string().optional(),
details: z
.object({
reasoning: z.string().optional(),
})
.passthrough()
.optional(),
});
defineEvaluator
nesnesi, kullanıcının değerlendirici için bir ad, kullanıcı tarafından okunabilen bir görünen ad ve bir tanım sağlamasına olanak tanır. Görünen ad ve tanım, değerlendirme sonuçlarıyla birlikte Geliştirici kullanıcı arayüzünde gösterilir.
Ayrıca, bu değerlendiricinin faturalandırmayla sonuçlanıp sonuçlanmayacağını (ör. faturalandırılan bir LLM veya API kullanıp kullanmadığını) belirten isteğe bağlı bir isBilled
alanı da vardır. Bir değerlendiriciye fatura gönderilirse kullanıcı arayüzü, değerlendirme yapmalarına izin vermeden önce kullanıcıdan CLI'de onay ister. Bu adım, istenmeyen harcamalardan korunmanıza yardımcı olur.
Buluşsal Yöntemlerle Değerlendirme Araçları
Heuristic evaluator, üretken yapay zeka özelliğinizin input
, context
veya output
değerini değerlendirmek için kullanılan herhangi bir işlev olabilir.
Genkit'teki sezgisel değerlendiriciler 2 bileşenden oluşur:
- Puanlama işlevi
- Değerlendirici işlemi
Puanlama işlevini tanımlama
LLM tabanlı değerlendiricide olduğu gibi puanlama işlevini tanımlayın. Bu durumda, puanlama işlevinin bir hakim LLM'ye ihtiyacı yoktur.
import { EvalResponses } from 'genkit';
import { BaseEvalDataPoint, Score } from 'genkit/evaluator';
const US_PHONE_REGEX =
/[\+]?[(]?[0-9]{3}[)]?[-\s\.]?[0-9]{3}[-\s\.]?[0-9]{4}/i;
/**
* Scores whether a datapoint output contains a US Phone number.
*/
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 US_PHONE_REGEX`
: `Output did not match US_PHONE_REGEX`;
return {
score: matches,
details: { reasoning },
};
}
Değerlendirici işlemini tanımlama
import { Genkit } from 'genkit';
import { BaseEvalDataPoint, EvaluatorAction } from 'genkit/evaluator';
/**
* Configures a regex evaluator to match a US phone number.
*/
export function createUSPhoneRegexEvaluator(ai: Genkit): EvaluatorAction {
return ai.defineEvaluator(
{
name: `myCustomEvals/usPhoneRegexEvaluator`,
displayName: "Regex Match for US PHONE NUMBER",
definition: "Uses Regex to check if output matches a US phone number",
isBilled: false,
},
async (datapoint: BaseEvalDataPoint) => {
const score = await usPhoneRegexScore(datapoint);
return {
testCaseId: datapoint.testCaseId,
evaluation: score,
};
}
);
}
Tümünü bir araya getirme
Eklenti tanımı
Genkit başlatılırken eklentiler çerçeveye kaydedilir. Yeni bir eklenti tanımlamak için genkitPlugin
yardımcı yöntemini kullanarak tüm Genkit işlemlerini eklenti bağlamında örnekleyin.
Bu kod örneğinde iki değerlendirici gösterilmektedir: LLM tabanlı lezzetlilik değerlendirici ve normal ifade tabanlı ABD telefon numarası değerlendirici. Bu değerlendirmecilerin eklenti bağlamında oluşturulması, bunları eklentiye kaydeder.
import { GenkitPlugin, genkitPlugin } from 'genkit/plugin';
export function myCustomEvals<
ModelCustomOptions extends z.ZodTypeAny
>(options: {
judge: ModelArgument<ModelCustomOptions>;
judgeConfig?: ModelCustomOptions;
}): GenkitPlugin {
// Define the new plugin
return genkitPlugin("myCustomEvals", async (ai: Genkit) => {
const { judge, judgeConfig } = options;
// The plugin instatiates our custom evaluators within the context
// of the `ai` object, making them available
// throughout our Genkit application.
createDeliciousnessEvaluator(ai, judge, judgeConfig);
createUSPhoneRegexEvaluator(ai);
});
}
export default myCustomEvals;
Genkit'i yapılandırma
myCustomEvals
eklentisini Genkit yapılandırmanıza ekleyin.
Gemini ile değerlendirme için güvenlik ayarlarını devre dışı bırakın. Böylece değerlendirici, zararlı olabilecek içerikleri kabul edebilir, algılayabilir ve puanlayabilir.
import { gemini15Pro } from '@genkit-ai/googleai';
const ai = genkit({
plugins: [
vertexAI(),
...
myCustomEvals({
judge: gemini15Pro,
}),
],
...
});
Özel değerlendiricilerinizi kullanma
Özel değerlendiricilerinizi Genkit uygulama bağlamında (bir eklenti aracılığıyla veya doğrudan) oluşturduktan sonra kullanılabilir hale gelirler. Aşağıdaki örnekte, lezzet değerlendirme aracının birkaç örnek giriş ve çıkışla nasıl deneneceği gösterilmektedir.
- 1. Aşağıdaki içeriğe sahip bir "deliciousness_dataset.json" JSON dosyası oluşturun:
[
{
"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."
}
]
- 2. Değerlendiriciyi bu test durumlarına karşı çalıştırmak için Genkit CLI'yi kullanın.
# Start your genkit runtime genkit start -- <command to start your app>
genkit eval:run deliciousness_dataset.json --evaluators=myCustomEvals/deliciousnessEvaluator
- 3. Sonuçlarınızı Genkit kullanıcı arayüzünde görüntülemek için "localhost:4000/evaluate" adresine gidin.
Özel değerlendiricileri standart veri kümeleriyle veya yaklaşımlarla karşılaştırdıkça özel değerlendiricilere olan güvenin arttığını unutmayın. Değerlendiricilerinizin performansını hedeflenen kalite düzeyine ulaşana kadar iyileştirmek için bu tür karşılaştırmaların sonuçlarını tekrarlayın.