기본사항 자동화: 코드를 사용하여 간단한 오류를 포착합니다.
규칙 기반 평가로 포착할 실패를 파악했으므로 이제 상응하는 평가자 함수를 구현할 차례입니다.
evalDataFormat(): 데이터 형식이 올바른지 확인합니다. 여기에는 유효한 JSON, 모든 키 존재, 빈 값 없음, 모토가 6단어 미만, 16진수 색상이 포함됩니다.evalContrastRatio(): 텍스트-배경 색상 대비율에 액세스할 수 있는지 확인합니다.
규칙 기반 평가 구현
점수 매기기 방법 선택
평가 기준은 바이너리입니다. 규칙 기반 평가 함수는 PASS 또는 FAIL 라벨과 같은 바이너리 출력을 생성해야 합니다.
- ThemeBuilder 앱 출력 (전체 테마 객체) →
evalDataFormat()→PASS또는FAIL라벨. 데이터 형식이 모든 제약 조건을 충족하는 경우PASS입니다. 그렇지 않으면FAIL입니다. - ThemeBuilder 앱 출력 (색상 팔레트 객체) →
evalContrastRatio()→PASS또는FAIL라벨 .비율이 4.5보다 큰 경우PASS입니다. 그렇지 않으면FAIL입니다.
평가 유형 정의
PASS 또는 FAIL 측정항목은 불리언이지만 가독성을 위해 문자열 라벨 (카테고리)로 구현할 수 있습니다.
간단하게 유지하기 위해 규칙 기반 평가와 나중에 구현할 LLM 평가자 평가 모두에 동일한 TypeScript 유형을 사용할 수 있습니다. 바이너리 EvalLabel 카테고리를 래핑하는 EvalResult 유형과 평가자 모델이 등급을 설명하는 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?)." };
}
}
rationale
평가자 코드
의 evalDataFormat() 및 evalContrastRatio()을 살펴보세요.
규칙 기반 평가 테스트
규칙 기반 평가는 결정적이므로 클래식 단위 테스트를 구현하여 동작을 확인할 수 있습니다. 평가자를 통해 다양한 출력을 실행하고 예상한 PASS 또는 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;
// ...
});
사용해 보기
- evals-course 프로젝트를 클론합니다.
- 설정합니다.
- 규칙 기반 평가자 테스트를 직접 실행합니다.