يمكنك توسيع نطاق Firebase Genkit لتتوافق مع التقييم المخصّص، وذلك باستخدام نموذج تعلم لغوي كبير (LLM) كمحكّم أو من خلال التقييم الآلي (التخميني).
تعريف المقيّم
التقييمات هي دوالّ تقيِّم ردّ نموذج اللغة الضخمة. هناك طريقتان رئيسيتان للتقييم الآلي: التقييم الاستقرائي والتقييم استنادًا إلى نموذج اللغة الضخمة. في المنهج الاستكشافي، يمكنك تحديد دالة حتمية. في المقابل، في التقييم المستنِد إلى النماذج اللغوية الكبيرة، تتم إعادة تقديم المحتوى إلى نموذج لغوي كبير، ويُطلب من النموذج اللغوي الكبير تقييم النتيجة وفقًا للمعايير المحدّدة في طلب.
تتيح لك الطريقة ai.defineEvaluator
، التي تستخدمها لتحديد ai.defineEvaluator
إجراء تقييم في Genkit، استخدام أي من الطريقتَين. يستكشف هذا
المستند بعض الأمثلة على كيفية استخدام هذه
الطريقة للتقييمات المستندة إلى الأساليب الاستقرائية ونموذج اللغة الضخمة.
المقيّمون المستندون إلى نموذج اللغة الضخمة
يستفيد التقييم المستنِد إلى نموذج لغوي كبير من نموذج لغوي كبير لتقييم
input
وcontext
وoutput
لميزة الذكاء الاصطناعي التوليدي.
تتكوّن أدوات التقييم المستندة إلى النماذج اللغوية الكبيرة (LLM) في Genkit من 3 مكوّنات:
- طلب
- دالة تسجيل النقاط
- إجراء تقييم
تحديد الطلب
في هذا المثال، يستفيد المُقيّم من نموذج تعلُّم لغوي كبير (LLM) لتحديد ما إذا كان أحد أطباق
الطعام (output
) لذيذًا أم لا. أولاً، قدِّم سياقًا للنموذج اللغوي الكبير، ثم صف ما تريده منه أن يفعله، وأخيراً، قدِّم له بعض الأمثلة التي يستند إليها في ردّه.
توفّر الأداة definePrompt
في Genkit طريقة سهلة لتحديد طلبات المستخدمين مع
التحقّق من الإدخال والإخراج. التعليمة البرمجية التالية هي مثال على
إعداد طلب تقييم باستخدام definePrompt
.
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:
`
);
}
تحديد وظيفة التسجيل
حدِّد دالة تأخذ مثالاً يتضمّن output
كما هو مطلوب في الطلب، وتُحسِّن النتيجة. تتضمّن اختبارات Genkit input
كحقل مطلوب، مع output
وcontext
كحقول اختيارية. تقع على عاتق المقيّم مهمة التحقّق من توفّر جميع الحقول المطلوبة لتقييم الأداء.
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 },
};
}
تحديد إجراء المُقيِّم
الخطوة الأخيرة هي كتابة دالة تحدِّد EvaluatorAction
.
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
أدوات إنشاء Genkit الأخرى، مثل
defineFlow
وdefineRetriever
. تتطلّب هذه الطريقة تقديم EvaluatorFn
كوسيطة ردّ اتصال. تقبل طريقة EvaluatorFn
كائنًا من نوع
BaseEvalDataPoint
، والذي يتوافق مع إدخال واحد في مجموعة
بيانات قيد التقييم، بالإضافة إلى مَعلمة خيارات مخصّصة
اختيارية إذا تم تحديدها. تعالج الدالة نقطة البيانات
وتُرجع عنصرًا من النوع EvalResponse
.
في ما يلي مخطّطات Zod لكلّ من BaseEvalDataPoint
وEvalResponse
:
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
للمستخدم تقديم اسم واسم معروض يسهل على المستخدم قراءته
وتعريف للمقيّم. يتم عرض الاسم المعروض و
التعريف مع نتائج التقييم في واجهة مستخدم المطوّر.
يتضمّن أيضًا حقل isBilled
اختياريًا يحدِّد ما إذا كان هذا المُقيِّم
يمكن أن يؤدّي إلى الفوترة (على سبيل المثال، إذا كان يستخدم نموذجًا لغويًا كبيرًا أو واجهة برمجة تطبيقات يتم تحصيل رسوم استخدامها). إذا تم تحصيل رسوم من أحد المقيمين، تطلب واجهة المستخدم من المستخدم تأكيدًا في سطر الأوامر قبل السماح له بإجراء تقييم. تساعد هذه الخطوة في تجنُّب
النفقات غير المقصودة.
أدوات التقييم المستندة إلى الإعدادات الإرشادية
يمكن أن يكون المُقيّم الاستقرائي أيّ دالة تُستخدَم لتقييم input
أو context
أو
أو output
لميزة الذكاء الاصطناعي التوليدي.
تتألف أدوات التقييم الاستكشافي في Genkit من مكوّنين:
- دالة تسجيل النقاط
- إجراء تقييم
تحديد وظيفة التسجيل
كما هو الحال مع المُقيِّم المستنِد إلى نموذج اللغة الضخمة، حدِّد دالة التقييم. في هذه الحالة، لا تحتاج دالة التسجيل إلى نموذج لغة طبيعية لمحكّم.
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 },
};
}
تحديد إجراء المُقيِّم
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,
};
}
);
}
تجميع العناصر معًا
تعريف المكوّن الإضافي
يتم تسجيل المكوّنات الإضافية في إطار العمل من خلال تثبيتها في وقت
بدء Genkit. لتحديد مكوّن إضافي جديد، استخدِم genkitPlugin
طريقة لإنشاء مثيل لجميع إجراءات Genkit ضمن سياق المكوّن الإضافي.
يعرض نموذج الرمز هذا اثنين من المقيّمين: مقيّم الطعم المستنِد إلى نموذج اللغة الكبيرة، ومقيّم رقم الهاتف في الولايات المتحدة المستنِد إلى التعبير العادي. يؤدي إنشاء مثيل لهذه التقييمات ضمن سياق المكوّن الإضافي إلى تسجيلها في المكوّن الإضافي.
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
أضِف المكوّن الإضافي myCustomEvals
إلى إعدادات Genkit.
لإجراء التقييم باستخدام Gemini، أوقِف إعدادات السلامة كي يتمكّن المُقيّم من قبول المحتوى الذي يُحتمل أن يكون ضارًا ورصده وتقييمه.
import { gemini15Pro } from '@genkit-ai/googleai';
const ai = genkit({
plugins: [
vertexAI(),
...
myCustomEvals({
judge: gemini15Pro,
}),
],
...
});
استخدام المقيّمين المخصّصين
بعد إنشاء مثيل للمقيّمين المخصّصين في سياق تطبيق Genkit (إما من خلال مكوّن إضافي أو مباشرةً)، يصبحون جاهزين للاستخدام. يوضّح المثال التالي كيفية تجربة أداة تقييم اللذة باستخدام بعض نماذج المدخلات والمخرجات.
- 1. أنشئ ملفًا بتنسيق 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."
}
]
- 2- استخدِم Genkit CLI لتشغيل أداة التقييم على حالات الاختبار هذه.
# Start your genkit runtime genkit start -- <command to start your app>
genkit eval:run deliciousness_dataset.json --evaluators=myCustomEvals/deliciousnessEvaluator
- 3- انتقِل إلى localhost:4000/evaluate لعرض النتائج في واجهة مستخدم Genkit.
من المهمّ ملاحظة أنّ الثقة في المقيّمين المخصّصين تزداد مع مقارنة أدائهم بمجموعات البيانات أو الأساليب العادية. كرِّر تقييم نتائج هذه المقاييس لتحسين أداء المقيّمين إلى أن يتم بلوغ المستوى المستهدف من الجودة.