Trung cấpHướng dẫnClaude APINguồn: Anthropic

Building Evals — Xây dựng hệ thống đánh giá cho Claude

Nghe bài viết
00:00

Điểm nổi bật

Nhấn để đến mục tương ứng

  1. 1 Tận dụng Claude hiệu quả: Mỗi eval gồm 4 phần thiếu một không được: Input đầu vào: Câu hỏi, văn bản, hoặc task bạn muốn evaluate Output đầu ra: — mẹo quan trọng là cung cấp đủ ngữ cảnh để AI trả về kết quả chính xác hơn 80% so với prompt chung chung.
  2. 2 Không có giải pháp hoàn hảo: Nhanh nhất và rẻ nhất — dùng code Python thuần để so sánh: Exact Match def exactmatchgraderoutput: str, golden: str. Bài viết phân tích rõ trade-off giúp bạn đưa ra quyết định phù hợp với tình huống thực tế.
  3. 3 Không thể bỏ qua: def humangradinginterfaceresults: list: """Interface đơn giản cho human reviewer.""" humanscores = for i, result in. Đây là kiến thức nền tảng mà mọi người làm việc với AI đều cần hiểu rõ.
  4. 4 Khai thác tối đa công cụ AI: INPUT từ user: {input} GOLDEN ANSWER đáp án tham khảo: {golden} ACTUAL OUTPUT response cần đánh giá: {output} Đánh giá. Bí quyết nằm ở cách bạn cấu trúc yêu cầu — prompt càng rõ ràng, output càng sát nhu cầu thực tế.
  5. 5 Thực tế không hoàn hảo: Thay vào đó: "Response phải chứa ít nhất 3 ví dụ cụ thể" "Độ dài response phải từ 100-300 từ" "Score từ model grader. Biết trước giới hạn sẽ giúp bạn thiết lập kỳ vọng đúng và tránh thất vọng không cần thiết.
gray and black metal machine

Bạn đã viết một prompt cho Claude, nhưng làm sao biết nó thực sự tốt? Cảm giác chủ quan không đủ — bạn cần một hệ thống đánh giá có thể đo lường được, tái lập được, và tự động hóa được. Đó là Evals.

Evals (evaluations) là nền tảng của mọi AI application nghiêm túc. Không có evals, bạn đang bay mù — không biết khi nào prompt regression xảy ra, không biết thay đổi nào thực sự cải thiện kết quả.

Bốn thành phần của một Eval

Mỗi eval gồm 4 phần thiếu một không được:

  1. Input (đầu vào): Câu hỏi, văn bản, hoặc task bạn muốn evaluate
  2. Output (đầu ra): Response thực tế từ Claude
  3. Golden answer (đáp án chuẩn): Câu trả lời "đúng" bạn mong muốn
  4. Score (điểm số): Kết quả so sánh output với golden answer

Ví dụ đơn giản nhất — eval phân loại sentiment:

Input Golden Answer Output Claude Score
"Sản phẩm tuyệt vời!" POSITIVE POSITIVE 1.0
"Giao hàng trễ quá." NEGATIVE NEGATIVE 1.0
"Tạm được, không quá tệ." NEUTRAL POSITIVE 0.0

Phương pháp 1: Code-based Grading

Nhanh nhất và rẻ nhất — dùng code Python thuần để so sánh:

Exact Match

def exact_match_grader(output: str, golden: str) -> float:
    """1.0 nếu khớp chính xác, 0.0 nếu không."""
    return 1.0 if output.strip().lower() == golden.strip().lower() else 0.0

# Test
score = exact_match_grader("POSITIVE", "POSITIVE")  # 1.0
score = exact_match_grader("positive", "POSITIVE")  # 1.0 (case-insensitive)
score = exact_match_grader("The sentiment is POSITIVE.", "POSITIVE")  # 0.0

Regex Match

import re

def regex_grader(output: str, pattern: str) -> float:
    """1.0 nếu output chứa pattern, 0.0 nếu không."""
    return 1.0 if re.search(pattern, output, re.IGNORECASE) else 0.0

# Linh hoạt hơn exact match
score = regex_grader("The answer is POSITIVE.", r"POSITIVE")  # 1.0
score = regex_grader("sentiment: positive or neutral", r"positive")  # 1.0

# Kiểm tra số trong khoảng hợp lệ
def numeric_grader(output: str, min_val: float, max_val: float) -> float:
    match = re.search(r"[-+]?d*.?d+", output)
    if not match:
        return 0.0
    value = float(match.group())
    return 1.0 if min_val <= value <= max_val else 0.0

Hàm eval hoàn chỉnh

import anthropic

client = anthropic.Anthropic()

def run_eval(test_cases: list, grader_fn) -> dict:
    """Chạy eval trên danh sách test cases."""
    results = []

    for case in test_cases:
        # Gọi Claude
        response = client.messages.create(
            model="claude-haiku-4-5",
            max_tokens=100,
            messages=[{"role": "user", "content": case["input"]}]
        )
        output = response.content[0].text

        # Chấm điểm
        score = grader_fn(output, case["golden"])
        results.append({
            "input": case["input"],
            "output": output,
            "golden": case["golden"],
            "score": score,
            "passed": score >= 0.5,
        })

    # Tổng kết
    accuracy = sum(r["score"] for r in results) / len(results)
    return {"accuracy": accuracy, "results": results}

# Test cases
test_cases = [
    {"input": "Classify: POSITIVE, NEGATIVE, or NEUTRAL?
'Sản phẩm tuyệt vời!'", "golden": "POSITIVE"},
    {"input": "Classify: POSITIVE, NEGATIVE, or NEUTRAL?
'Giao hàng rất tệ.'", "golden": "NEGATIVE"},
    {"input": "Classify: POSITIVE, NEGATIVE, or NEUTRAL?
'Bình thường thôi.'", "golden": "NEUTRAL"},
]

results = run_eval(test_cases, lambda out, gold: exact_match_grader(out, gold))
print(f"Accuracy: {results['accuracy']:.1%}")

Phương pháp 2: Human Grading

Với tasks phức tạp — dịch thuật, sáng tác, tư vấn — chỉ con người mới đánh giá được chính xác. Human grading tốn kém hơn nhưng là ground truth thực sự.

def human_grading_interface(results: list):
    """Interface đơn giản cho human reviewer."""
    human_scores = []

    for i, result in enumerate(results):
        print(f"
--- Câu {i+1}/{len(results)} ---")
        print(f"INPUT: {result['input']}")
        print(f"OUTPUT: {result['output']}")
        print(f"GOLDEN: {result['golden']}")
        print()

        while True:
            try:
                score = float(input("Điểm (0.0 - 1.0): "))
                if 0.0 <= score <= 1.0:
                    break
                print("Vui lòng nhập số từ 0.0 đến 1.0")
            except ValueError:
                print("Nhập số hợp lệ")

        comment = input("Nhận xét (Enter để bỏ qua): ")
        human_scores.append({
            **result,
            "human_score": score,
            "comment": comment
        })

    return human_scores

Tip: Dùng human grading để build dataset nhỏ (~100 cases) ban đầu, sau đó dùng dataset đó để train model-based grader.

Phương pháp 3: Model-based Grading (Claude chấm Claude)

Phương pháp mạnh nhất cho tasks phức tạp và tự động: dùng chính Claude (hoặc model mạnh hơn) để đánh giá output.

GRADER_PROMPT = """Bạn là chuyên gia đánh giá chất lượng AI. Nhiệm vụ: đánh giá response của AI.

INPUT từ user:
{input}

GOLDEN ANSWER (đáp án tham khảo):
{golden}

ACTUAL OUTPUT (response cần đánh giá):
{output}

Đánh giá output theo các tiêu chí:
1. Chính xác về thông tin (0-4 điểm)
2. Đầy đủ, không bỏ sót ý quan trọng (0-3 điểm)
3. Rõ ràng, dễ hiểu (0-3 điểm)

Trả lời theo format:
X
Giải thích ngắn gọn

(X là tổng điểm từ 0 đến 10)"""

def model_based_grader(input_text: str, output: str, golden: str) -> dict:
    prompt = GRADER_PROMPT.format(
        input=input_text,
        golden=golden,
        output=output
    )

    response = client.messages.create(
        model="claude-sonnet-4-5",  # Dùng model mạnh hơn để chấm
        max_tokens=300,
        messages=[{"role": "user", "content": prompt}]
    )

    text = response.content[0].text

    # Extract score
    score_match = re.search(r"(d+(?:.d+)?)", text)
    score = float(score_match.group(1)) / 10.0 if score_match else 0.0

    # Extract reasoning
    reasoning_match = re.search(r"(.*?)", text, re.DOTALL)
    reasoning = reasoning_match.group(1).strip() if reasoning_match else ""

    return {"score": score, "reasoning": reasoning}

# Ví dụ
result = model_based_grader(
    input_text="Giải thích khái niệm machine learning cho người mới.",
    output="Machine learning là khi máy tính học từ dữ liệu.",
    golden="Machine learning là nhánh AI giúp máy tính học từ dữ liệu mà không cần lập trình cụ thể từng bước, tìm ra patterns để dự đoán."
)
print(f"Score: {result['score']:.1f}/1.0")
print(f"Reasoning: {result['reasoning']}")

Best Practices khi xây dựng Evals

1. Eval phải cụ thể và có thể đo lường

Tránh eval chung chung như "response phải tốt". Thay vào đó:

  • "Response phải chứa ít nhất 3 ví dụ cụ thể"
  • "Độ dài response phải từ 100-300 từ"
  • "Score từ model grader phải trên 7/10"

2. Tự động hóa hoàn toàn

import json
from datetime import datetime

def run_full_eval_suite(prompt_template: str, test_cases: list) -> dict:
    """Chạy eval đầy đủ và lưu kết quả."""
    timestamp = datetime.now().isoformat()
    results = []

    for case in test_cases:
        # Inject input vào prompt template
        full_prompt = prompt_template.replace("{input}", case["input"])

        response = client.messages.create(
            model="claude-haiku-4-5",
            max_tokens=200,
            messages=[{"role": "user", "content": full_prompt}]
        )
        output = response.content[0].text

        # Chạy nhiều graders
        exact = exact_match_grader(output, case["golden"])
        model = model_based_grader(case["input"], output, case["golden"])

        results.append({
            "case_id": case.get("id", f"case_{len(results)+1}"),
            "input": case["input"],
            "output": output,
            "golden": case["golden"],
            "exact_match": exact,
            "model_score": model["score"],
            "model_reasoning": model["reasoning"],
        })

    accuracy = sum(r["exact_match"] for r in results) / len(results)
    avg_model_score = sum(r["model_score"] for r in results) / len(results)

    report = {
        "timestamp": timestamp,
        "prompt": prompt_template,
        "n_cases": len(test_cases),
        "accuracy": accuracy,
        "avg_model_score": avg_model_score,
        "results": results,
    }

    # Lưu kết quả
    with open(f"eval_report_{timestamp[:10]}.json", "w", encoding="utf-8") as f:
        json.dump(report, f, ensure_ascii=False, indent=2)

    return report

3. Distribution phải đại diện

Test cases không chỉ nên là "easy cases" — phân bổ theo thực tế:

  • 30% easy cases: Claude xử lý tốt ngay từ đầu
  • 50% normal cases: Đại diện cho traffic thực tế
  • 20% edge cases: Ambiguous, long inputs, unusual formats

Ứng dụng thực tế: Theo dõi Prompt Regression

def compare_prompts(prompt_v1: str, prompt_v2: str, test_cases: list):
    """So sánh hai phiên bản prompt."""
    results_v1 = run_full_eval_suite(prompt_v1, test_cases)
    results_v2 = run_full_eval_suite(prompt_v2, test_cases)

    print("=" * 50)
    print(f"Prompt V1 accuracy: {results_v1['accuracy']:.1%}")
    print(f"Prompt V2 accuracy: {results_v2['accuracy']:.1%}")
    delta = results_v2['accuracy'] - results_v1['accuracy']
    print(f"Delta: {'+' if delta > 0 else ''}{delta:.1%}")

    if delta > 0:
        print("V2 tốt hơn — an toàn deploy!")
    elif delta < -0.05:
        print("CẢNH BÁO: V2 kém hơn đáng kể — không deploy!")
    else:
        print("Tương đương — xem xét các yếu tố khác (cost, latency)")

Evals là investment quan trọng nhất bạn có thể làm cho một AI project. Bắt đầu với 20-30 test cases, chạy sau mỗi thay đổi prompt, và bạn sẽ tự tin hơn rất nhiều khi deploy lên production.


Bài viết liên quan

Tính năng liên quan:EvaluationTestingPrompt EngineeringModel Grading

Bai viet co huu ich khong?

Bản quyền thuộc về tác giả. Vui lòng dẫn nguồn khi chia sẻ.

Bình luận (0)
Ảnh đại diện
Đăng nhập để bình luận...
Đăng nhập để bình luận
  • Đang tải bình luận...

Đăng ký nhận bản tin

Nhận bài viết hay nhất về sản phẩm và vận hành, gửi thẳng vào hộp thư của bạn.

Bảo mật thông tin. Hủy đăng ký bất cứ lúc nào. Chính sách bảo mật.