Automatiseer de basis: gebruik code om simpele fouten op te vangen.
Nu je weet welke fouten je wilt opvangen met op regels gebaseerde evaluaties, is het tijd om de bijbehorende evaluatiefuncties te implementeren:
-
evalDataFormat(): Controleert of het gegevensformaat correct is. Dit omvat geldige JSON, alle sleutels aanwezig, geen lege waarden, motto mag niet meer dan zes woorden bevatten, hexadecimale kleuren. -
evalContrastRatio(): Controleert of de contrastverhouding tussen tekst en achtergrondkleur beschikbaar is.
Implementeer op regels gebaseerde evaluaties.
Kies een scoringsmethode
De evaluatiecriteria zijn binair. Uw op regels gebaseerde evaluatiefuncties moeten een binaire uitvoer produceren, zoals een label PASS of FAIL .
- Uitvoer van de ThemeBuilder-app (volledig thema-object) →
evalDataFormat()→ labelPASSofFAIL.PASSals het gegevensformaat aan alle beperkingen voldoet.FAILanders. - Uitvoer van de ThemeBuilder-app (kleurpaletobject) →
evalContrastRatio()→ labelPASSofFAIL.PASSals de verhouding > 4,5 is.FAILanders.
Definieer een evaluatietype
De PASS of FAIL indicator is een booleaanse waarde, maar je kunt ervoor kiezen om deze voor de leesbaarheid als een tekenreekslabel (categorie) te implementeren.
Om het overzichtelijk te houden, kun je hetzelfde TypeScript-type gebruiken voor zowel je op regels gebaseerde evaluaties als de LLM-beoordelingsevaluaties die je later implementeert. Maak een EvalResult -type aan dat een binaire EvalLabel -categorie en een rationale veld voor het beoordelingsmodel om de score toe te lichten omvat.
enum EvalLabel {
PASS = "PASS",
FAIL = "FAIL"
}
interface EvalResult {
label: EvalLabel;
rationale?: string;
}
Implementeer evaluatoren
Zod is een uitstekend hulpmiddel voor schemavalidatie, omdat het zowel de JSON-structuur als aangepaste regels verwerkt. Het is declaratief, waardoor de validatiecode leesbaar is. Definieer gedetailleerde foutrapporten met specifieke paden en redenen voor fouten, voor eenvoudigere probleemoplossing.
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)
});
Contrastverhouding
Houd domeinlogica, zoals de berekeningen van de contrastverhouding, in aparte hulpprogramma's.
/*
* 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?)." };
}
}
Bekijk onze evaluatiecode voor evalDataFormat() en evalContrastRatio() .
Test regelgebaseerde evaluaties
Op regels gebaseerde evaluaties zijn deterministisch, dus je kunt klassieke unit tests implementeren om hun gedrag te controleren. Bouw je tests zo dat ze verschillende outputs door de evaluatoren laten lopen en controleer of ze het verwachte PASS of FAIL label retourneren.
Als een testcase verwacht dat de evaluator een FAIL retourneert en dat ook doet, dan geeft de test een PASS als uitvoer, omdat de evaluator zich naar behoren heeft gedragen.
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;
// ...
});