Xây dựng các tiêu chí đánh giá dựa trên quy tắc

Tự động hoá các thao tác cơ bản: sử dụng mã để phát hiện các lỗi đơn giản.

Giờ đây, khi bạn đã biết những lỗi mà bạn muốn phát hiện bằng các tiêu chí đánh giá dựa trên quy tắc, đã đến lúc triển khai các hàm tiêu chí đánh giá tương ứng:

  • evalDataFormat(): Kiểm tra để đảm bảo định dạng dữ liệu chính xác. Định dạng này bao gồm JSON hợp lệ, tất cả các khoá đều có mặt, không có giá trị trống, phương châm có dưới 6 từ, màu thập lục phân.
  • evalContrastRatio(): Kiểm tra để đảm bảo tỷ lệ tương phản giữa văn bản và màu nền có thể truy cập được.

Triển khai các tiêu chí đánh giá dựa trên quy tắc

Chọn phương thức tính điểm

Tiêu chí đánh giá là nhị phân. Các hàm tiêu chí đánh giá dựa trên quy tắc phải tạo ra kết quả nhị phân, chẳng hạn như nhãn PASS hoặc FAIL.

  • Kết quả của ứng dụng ThemeBuilder (đối tượng giao diện đầy đủ) → nhãn evalDataFormat()PASS hoặc FAIL. PASS nếu định dạng dữ liệu đáp ứng tất cả các ràng buộc. FAIL trong trường hợp khác.
  • Kết quả của ứng dụng ThemeBuilder (đối tượng bảng màu) → nhãn evalContrastRatio()PASS hoặc FAIL .PASS nếu tỷ lệ > 4,5. FAIL trong trường hợp khác.

Xác định loại tiêu chí đánh giá

Chỉ số PASS hoặc FAIL là một giá trị boolean, nhưng bạn có thể chọn triển khai chỉ số này dưới dạng nhãn chuỗi (danh mục) để dễ đọc.

Để giữ cho mọi thứ gọn gàng, bạn có thể sử dụng cùng một loại TypeScript cho cả tiêu chí đánh giá dựa trên quy tắc và tiêu chí đánh giá của mô hình ngôn ngữ lớn (LLM) mà bạn sẽ triển khai sau này. Tạo loại EvalResult bao bọc danh mục EvalLabel nhị phân và trường rationale để mô hình đánh giá giải thích xếp hạng của mô hình.

enum EvalLabel {
    PASS = "PASS",
    FAIL = "FAIL"
}

interface EvalResult {
    label: EvalLabel;
    rationale?: string;
}

Triển khai tiêu chí đánh giá

Zod là một công cụ tuyệt vời để xác thực giản đồ, vì công cụ này xử lý cả cấu trúc JSON và các quy tắc tuỳ chỉnh. Công cụ này có tính khai báo, giúp mã xác thực dễ đọc. Xác định báo cáo lỗi chi tiết với các đường dẫn và lý do cụ thể cho lỗi để dễ dàng khắc phục sự cố hơn.

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)
});

Tỷ lệ tương phản

Giữ logic miền, chẳng hạn như tính toán tỷ lệ tương phản, trong các hàm tiện ích riêng biệt.

/*
 * 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?)." };
  }
}

Hãy xem mã tiêu chí đánh giá của chúng tôi cho evalDataFormat()evalContrastRatio().

Kiểm thử các tiêu chí đánh giá dựa trên quy tắc

Các tiêu chí đánh giá dựa trên quy tắc là xác định, vì vậy, bạn có thể triển khai các kiểm thử đơn vị cổ điển để kiểm tra hành vi của chúng. Tạo các kiểm thử để chạy nhiều kết quả thông qua các tiêu chí đánh giá và xác nhận xem chúng có trả về nhãn PASS hoặc FAIL mà bạn mong đợi hay không.

Nếu một trường hợp kiểm thử mong đợi tiêu chí đánh giá trả về FAIL và tiêu chí đánh giá đó thực hiện như vậy, thì kiểm thử sẽ xuất ra PASS vì tiêu chí đánh giá hoạt động như dự định.

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;
 // ...
});

Dùng thử