自动化基础知识:使用代码捕获简单错误。
现在,您已经知道要使用基于规则的评估捕获哪些失败,接下来需要实现相应的评估器函数:
evalDataFormat():检查数据格式是否正确。这包括有效的 JSON、所有键都存在、没有空值、格言不超过六个字、十六进制颜色。evalContrastRatio():检查文本与背景颜色对比度是否可访问。
实现基于规则的评估
评估标准是二进制的。基于规则的评估函数应生成二进制输出,例如 PASS 或 FAIL 标签。
- ThemeBuilder 应用输出(完整主题对象)→
evalDataFormat()→PASS或FAIL标签。如果数据格式满足所有约束条件,则为PASS。否则为FAIL。 - ThemeBuilder 应用输出(调色板对象)→
evalContrastRatio()→PASS或FAIL标签。如果比率大于 4.5,则为PASS。否则为FAIL。
定义评估类型
PASS 或 FAIL 指标是一个布尔值,但您可以选择将其实现为字符串标签(类别),以提高可读性。
为了保持简洁,您可以对基于规则的评估和稍后实现的 LLM 评判评估使用相同的 TypeScript 类型。创建一个 EvalResult 类型,用于封装二进制 EvalLabel 类别,以及一个 rationale 字段,供评判模型解释其评分。
enum EvalLabel {
PASS = "PASS",
FAIL = "FAIL"
}
interface EvalResult {
label: EvalLabel;
rationale?: string;
}
实现评估器
Zod 是一款出色的架构验证工具,因为它同时处理 JSON 结构和自定义规则。它是声明性的,这使得验证代码具有可读性。定义详细的错误报告,其中包含特定路径和失败原因,以便更轻松地进行问题排查。
import { z } from 'zod';
import { MAX_WORD_COUNT } from './app.config';
const hexColorRegex = /^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/;
// Reusable schema for hex colors
const HexColor = z.string().regex(hexColorRegex, { message: "Invalid hex color code" });
// zod schema definition for AppOutput
export const AppOutputSchema = z.object({
motto: z.string().min(1, { message: "Motto is missing or empty" }).refine((val) => {
const words = val.replace(/[^\w\s]|_/g, "").trim();
const count = words ? words.split(/\s+/).length : 0;
return count > 0 && count <= MAX_WORD_COUNT;
}, { message: `Motto must be between 1 and ${MAX_WORD_COUNT} words` }),
colorPalette: z.object({
textColor: HexColor,
backgroundColor: HexColor,
primary: HexColor,
secondary: HexColor
}).catchall(HexColor)
});
对比度
将对比度计算等网域逻辑保留在单独的实用程序函数中。
/*
* Input: ColorPalette {"textColor":"#333333","backgroundColor":"#000000", ...}
* Output: EvalResult {"status":"FAIL","rationale":"Contrast ratio is 1.66:1 (must be >= 4.5:1)."}
* minContrastRatio is an app config variable, MIN_CONTRAST_RATIO = 4.5
*/
export function evalContrastRatio(colorPalette: ColorPalette, minContrastRatio: number): EvalResult {
if (!colorPalette || !colorPalette.textColor || !colorPalette.backgroundColor) {
return { status: EvalLabel.FAIL, rationale: "Missing textColor or backgroundColor." };
}
try {
const ratio = getContrastRatio(colorPalette.textColor, colorPalette.backgroundColor);
const rationale = `Contrast ratio is ${ratio.toFixed(2)}:1 (must be >= ${minContrastRatio}:1).`;
if (ratio < minContrastRatio) {
return { status: EvalLabel.FAIL, rationale };
}
return { status: EvalLabel.PASS, rationale };
} catch (e) {
return { status: EvalLabel.FAIL, rationale: "Could not calculate contrast ratio (invalid hex?)." };
}
}
请查看我们的 评估器代码 ,了解