Bạn có thể mở rộng Firebase Genkit để hỗ trợ hoạt động đánh giá tuỳ chỉnh kết quả của trường hợp kiểm thử, bằng cách sử dụng LLM làm người đánh giá hoặc bằng cách sử dụng phương thức lập trình.
Định nghĩa về người đánh giá
Bên đánh giá là các chức năng đánh giá nội dung được một LLM cung cấp và tạo ra. Có hai phương pháp chính để đánh giá tự động (kiểm thử): đánh giá dựa trên phương pháp phỏng đoán và đánh giá dựa trên mô hình ngôn ngữ lớn (LLM). Trong phương pháp phỏng đoán, bạn xác định hàm tất định giống như các hàm trong quá trình phát triển phần mềm truyền thống. Trong bài đánh giá dựa trên mô hình ngôn ngữ lớn (LLM), nội dung được đưa trở lại cho một LLM và LLM được yêu cầu tính điểm kết quả theo tiêu chí được đặt ra trong câu lệnh.
Bên đánh giá dựa trên LLM
Người đánh giá theo mô hình ngôn ngữ lớn (LLM) sẽ sử dụng một LLM để đánh giá dữ liệu đầu vào, bối cảnh hoặc đầu ra của tính năng AI tạo sinh.
Nhân viên đánh giá dựa trên LLM trong Genkit bao gồm 3 thành phần:
- Lời nhắc
- Chức năng tính điểm
- Hành động của người đánh giá
Xác định lời nhắc
Đối với ví dụ này, câu lệnh sẽ yêu cầu LLM đánh giá độ ngon của kết quả. Trước tiên, hãy cung cấp ngữ cảnh cho LLM, sau đó mô tả việc bạn muốn LLM thực hiện và cuối cùng là đưa ra một vài ví dụ để làm cơ sở cho câu trả lời.
Genkit đi kèm với dotprompt
, giúp bạn dễ dàng xác định và quản lý lời nhắc có các tính năng như xác thực giản đồ đầu vào/đầu ra. Dưới đây là cách bạn có thể sử dụng dotprompt
để xác định lời nhắc đánh giá.
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:
`
);
Xác định hàm tính điểm
Bây giờ, hãy định nghĩa hàm để lấy ví dụ bao gồm output
theo yêu cầu của câu lệnh và tính điểm kết quả. Các trường hợp thử nghiệm bộ công cụ tạo sinh bao gồm input
theo trường bắt buộc, với các trường không bắt buộc cho output
và context
. Nhân viên đánh giá có trách nhiệm xác thực rằng tất cả các trường bắt buộc để đánh giá đều xuất hiện.
/**
* 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 },
};
}
Xác định thao tác của người đánh giá
Bước cuối cùng là viết một hàm tự xác định thao tác của trình đánh giá.
/**
* 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,
};
}
);
}
Người đánh giá Heuristic
Bên đánh giá phương pháp phỏng đoán có thể là bất kỳ chức năng nào dùng để đánh giá dữ liệu đầu vào, bối cảnh hoặc đầu ra của tính năng AI tạo sinh.
Nhân viên đánh giá chẩn đoán trong Genkit bao gồm 2 thành phần:
- Chức năng tính điểm
- Hành động của người đánh giá
Xác định hàm tính điểm
Cũng giống như trình đánh giá dựa trên LLM, hãy xác định hàm tính điểm. Trong trường hợp này, hàm tính điểm không cần phải biết về LLM của đối tượng đánh giá hoặc cấu hình của mô hình đó.
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 },
};
}
Xác định thao tác của người đánh giá
/**
* 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);
}
);
});
}
Cấu hình
Tùy chọn trình bổ trợ
Xác định PluginOptions
mà trình bổ trợ trình đánh giá tuỳ chỉnh sẽ sử dụng. Đối tượng này không có yêu cầu nghiêm ngặt và phụ thuộc vào loại trình đánh giá được xác định.
Ít nhất, Trình quản lý thẻ phải xác định được chỉ số nào cần đăng ký.
export enum MyAwesomeMetric {
WORD_COUNT = 'WORD_COUNT',
US_PHONE_REGEX_MATCH = 'US_PHONE_REGEX_MATCH',
}
export interface PluginOptions {
metrics?: Array<MyAwesomeMetric>;
}
Nếu trình bổ trợ mới này sử dụng một LLM làm giá trị đánh giá và trình bổ trợ hỗ trợ hoán đổi LLM nào sẽ sử dụng, hãy xác định các tham số bổ sung trong đối tượng 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>;
}
Định nghĩa trình bổ trợ
Các trình bổ trợ được đăng ký với khung thông qua tệp genkit.config.ts
trong một dự án. Để có thể định cấu hình một trình bổ trợ mới, hãy xác định một hàm xác định GenkitPlugin
và định cấu hình hàm đó bằng PluginOptions
được xác định ở trên.
Trong trường hợp này, chúng ta có 2 nhân viên đánh giá là DELICIOUSNESS
và US_PHONE_REGEX_MATCH
. Đây là nơi những người đánh giá đó được đăng ký với trình bổ trợ và với Firebase Genkit.
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;
Định cấu hình Genkit
Thêm trình bổ trợ mới xác định vào cấu hình Genkit.
Để đánh giá bằng Gemini, hãy tắt các chế độ cài đặt an toàn để người đánh giá có thể chấp nhận, phát hiện và cho điểm nội dung có khả năng gây hại.
import { geminiPro } from '@genkit-ai/googleai';
export default configureGenkit({
plugins: [
...
myAwesomeEval({
judge: geminiPro,
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
],
}),
],
...
});
Thử nghiệm
Các vấn đề tương tự áp dụng cho việc đánh giá chất lượng đầu ra của một tính năng AI tạo sinh cũng áp dụng cho việc đánh giá năng lực đánh giá của một người đánh giá dựa trên mô hình ngôn ngữ lớn (LLM).
Để biết công cụ đánh giá tuỳ chỉnh có hoạt động ở cấp độ dự kiến hay không, hãy tạo một tập hợp các trường hợp kiểm thử có câu trả lời đúng và sai rõ ràng.
Ví dụ về độ ngon, có thể trông giống như tệp 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."
}
]
Những ví dụ này có thể do con người tạo ra hoặc bạn có thể yêu cầu một LLM giúp tạo một tập hợp trường hợp kiểm thử có thể tuyển chọn. Cũng có nhiều tập dữ liệu điểm chuẩn có sẵn để bạn sử dụng.
Sau đó, sử dụng Genkit CLI để chạy công cụ đánh giá theo các trường hợp kiểm thử này.
genkit eval:run deliciousness_dataset.json
Xem kết quả trong giao diện người dùng Genkit.
genkit start
Chuyển đến localhost:4000/evaluate
.