ทำให้พื้นฐานเป็นเรื่องง่าย: ใช้โค้ดเพื่อตรวจจับข้อผิดพลาดเล็กๆ น้อยๆ
เมื่อทราบแล้วว่าต้องการตรวจจับความล้มเหลวใดด้วยฟังก์ชันการประเมินตามกฎ ก็ถึงเวลาใช้ฟังก์ชันการประเมินที่เกี่ยวข้อง
evalDataFormat(): ตรวจสอบว่ารูปแบบข้อมูลถูกต้อง ซึ่งรวมถึง JSON ที่ถูกต้อง คีย์ทั้งหมดอยู่ครบ ไม่มีค่าว่างเปล่า สโลแกนไม่เกิน 6 คำ และสีฐานสิบหกevalContrastRatio(): ตรวจสอบว่าอัตราส่วนความคมชัดของสีข้อความกับสีพื้นหลังเข้าถึงได้
ใช้ฟังก์ชันการประเมินตามกฎ
เลือกวิธีการให้คะแนน
เกณฑ์การประเมินเป็นแบบไบนารี ฟังก์ชันการประเมินตามกฎควรสร้างเอาต์พุตแบบไบนารี เช่น ป้ายกำกับ PASS หรือ FAIL
- เอาต์พุตของแอป ThemeBuilder (ออบเจ็กต์ธีมแบบเต็ม) →
evalDataFormat()→ ป้ายกำกับPASSหรือFAILPASSหากรูปแบบข้อมูลเป็นไปตามข้อจำกัดทั้งหมดFAILในกรณีอื่นๆ - เอาต์พุตของแอป ThemeBuilder (ออบเจ็กต์ชุดสี) →
evalContrastRatio()→ ป้ายกำกับPASSหรือFAILPASSหากอัตราส่วน > 4.5FAILในกรณีอื่นๆ
กำหนดประเภทฟังก์ชันการประเมิน
เมตริก PASS หรือ FAIL เป็นบูลีน แต่คุณเลือกใช้เป็นป้ายกำกับสตริง (หมวดหมู่) เพื่อให้อ่านง่ายขึ้นได้
คุณสามารถใช้ประเภท TypeScript เดียวกันสำหรับฟังก์ชันการประเมินตามกฎและฟังก์ชันการประเมินของโมเดลภาษาขนาดใหญ่ (LLM) ที่คุณจะใช้ในภายหลังได้ สร้างประเภท 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?)." };
}
}
ดูโค้ดฟังก์ชันการประเมิน
สำหรับ evalDataFormat() และ evalContrastRatio()
ทดสอบฟังก์ชันการประเมินตามกฎ
การประเมินตามกฎเป็นแบบดีเทอร์มินิสติก คุณจึงใช้การทดสอบหน่วยแบบคลาสสิกเพื่อตรวจสอบลักษณะการทำงานได้ สร้างการทดสอบเพื่อเรียกใช้เอาต์พุตต่างๆ ผ่านฟังก์ชันการประเมิน และยืนยันว่าฟังก์ชันการประเมินแสดงป้ายกำกับ PASS หรือ FAIL ตามที่คุณคาดไว้
หากกรณีทดสอบคาดว่าฟังก์ชันการประเมินจะแสดง FAIL และฟังก์ชันการประเมินก็แสดง FAIL จริงๆ การทดสอบจะแสดง PASS เนื่องจากฟังก์ชันการประเมินทำงานตามที่ตั้งใจไว้
import { MIN_CONTRAST_RATIO } from '../src/app.config'; // 4.5
const testCases = [
{
// ...
appOutput: {
motto: "Test motto",
colorPalette: {
textColor: "#333333",
backgroundColor: "#000000",
primary: "#FF0000",
secondary: "#333333"
}
},
expected: {
// Dark grey on black (low contrast): FAIL
contrast: EvalLabel.FAIL
}
}
// ... more test cases
];
testCases.forEach((testCase) => {
const result = evalContrastRatio(
testCase.appOutput.colorPalette as any, MIN_CONTRAST_RATIO
);
const actualEvalLabel = result.label;
const expectedEvalLabel = testCase.expected.contrast;
const isSuccess = actualEvalLabel === expectedEvalLabel;
// ...
});