{"product_id":"building-evals-xay-dựng-hệ-thống-danh-gia-cho-claude","title":"Building Evals — Xây dựng hệ thống đánh giá cho Claude","description":"\n\u003cp\u003eBạn đã viết một prompt cho Claude, nhưng làm sao biết nó thực sự \u003cem\u003etốt\u003c\/em\u003e? 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à \u003cstrong\u003eEvals\u003c\/strong\u003e.\u003c\/p\u003e\n\n\u003cp\u003eEvals (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ả.\u003c\/p\u003e\n\n\u003ch2\u003eBốn thành phần của một Eval\u003c\/h2\u003e\n\n\u003cp\u003eMỗi eval gồm 4 phần thiếu một không được:\u003c\/p\u003e\n\n\u003col\u003e\n  \u003cli\u003e\n\u003cstrong\u003eInput (đầu vào):\u003c\/strong\u003e Câu hỏi, văn bản, hoặc task bạn muốn evaluate\u003c\/li\u003e\n  \u003cli\u003e\n\u003cstrong\u003eOutput (đầu ra):\u003c\/strong\u003e Response thực tế từ Claude\u003c\/li\u003e\n  \u003cli\u003e\n\u003cstrong\u003eGolden answer (đáp án chuẩn):\u003c\/strong\u003e Câu trả lời \"đúng\" bạn mong muốn\u003c\/li\u003e\n  \u003cli\u003e\n\u003cstrong\u003eScore (điểm số):\u003c\/strong\u003e Kết quả so sánh output với golden answer\u003c\/li\u003e\n\u003c\/ol\u003e\n\n\u003cp\u003eVí dụ đơn giản nhất — eval phân loại sentiment:\u003c\/p\u003e\n\n\u003ctable\u003e\n  \u003cthead\u003e\n    \u003ctr\u003e\n\u003cth\u003eInput\u003c\/th\u003e\n\u003cth\u003eGolden Answer\u003c\/th\u003e\n\u003cth\u003eOutput Claude\u003c\/th\u003e\n\u003cth\u003eScore\u003c\/th\u003e\n\u003c\/tr\u003e\n  \u003c\/thead\u003e\n  \u003ctbody\u003e\n    \u003ctr\u003e\n\u003ctd\u003e\"Sản phẩm tuyệt vời!\"\u003c\/td\u003e\n\u003ctd\u003ePOSITIVE\u003c\/td\u003e\n\u003ctd\u003ePOSITIVE\u003c\/td\u003e\n\u003ctd\u003e1.0\u003c\/td\u003e\n\u003c\/tr\u003e\n    \u003ctr\u003e\n\u003ctd\u003e\"Giao hàng trễ quá.\"\u003c\/td\u003e\n\u003ctd\u003eNEGATIVE\u003c\/td\u003e\n\u003ctd\u003eNEGATIVE\u003c\/td\u003e\n\u003ctd\u003e1.0\u003c\/td\u003e\n\u003c\/tr\u003e\n    \u003ctr\u003e\n\u003ctd\u003e\"Tạm được, không quá tệ.\"\u003c\/td\u003e\n\u003ctd\u003eNEUTRAL\u003c\/td\u003e\n\u003ctd\u003ePOSITIVE\u003c\/td\u003e\n\u003ctd\u003e0.0\u003c\/td\u003e\n\u003c\/tr\u003e\n  \u003c\/tbody\u003e\n\u003c\/table\u003e\n\n\u003ch2\u003ePhương pháp 1: Code-based Grading\u003c\/h2\u003e\n\n\u003cp\u003eNhanh nhất và rẻ nhất — dùng code Python thuần để so sánh:\u003c\/p\u003e\n\n\u003ch3\u003eExact Match\u003c\/h3\u003e\n\n\u003cpre\u003e\u003ccode\u003edef exact_match_grader(output: str, golden: str) -\u0026gt; float:\n    \"\"\"1.0 nếu khớp chính xác, 0.0 nếu không.\"\"\"\n    return 1.0 if output.strip().lower() == golden.strip().lower() else 0.0\n\n# Test\nscore = exact_match_grader(\"POSITIVE\", \"POSITIVE\")  # 1.0\nscore = exact_match_grader(\"positive\", \"POSITIVE\")  # 1.0 (case-insensitive)\nscore = exact_match_grader(\"The sentiment is POSITIVE.\", \"POSITIVE\")  # 0.0\u003c\/code\u003e\u003c\/pre\u003e\n\n\u003ch3\u003eRegex Match\u003c\/h3\u003e\n\n\u003cpre\u003e\u003ccode\u003eimport re\n\ndef regex_grader(output: str, pattern: str) -\u0026gt; float:\n    \"\"\"1.0 nếu output chứa pattern, 0.0 nếu không.\"\"\"\n    return 1.0 if re.search(pattern, output, re.IGNORECASE) else 0.0\n\n# Linh hoạt hơn exact match\nscore = regex_grader(\"The answer is POSITIVE.\", r\"POSITIVE\")  # 1.0\nscore = regex_grader(\"sentiment: positive or neutral\", r\"positive\")  # 1.0\n\n# Kiểm tra số trong khoảng hợp lệ\ndef numeric_grader(output: str, min_val: float, max_val: float) -\u0026gt; float:\n    match = re.search(r\"[-+]?d*.?d+\", output)\n    if not match:\n        return 0.0\n    value = float(match.group())\n    return 1.0 if min_val \u0026lt;= value \u0026lt;= max_val else 0.0\u003c\/code\u003e\u003c\/pre\u003e\n\n\u003ch3\u003eHàm eval hoàn chỉnh\u003c\/h3\u003e\n\n\u003cpre\u003e\u003ccode\u003eimport anthropic\n\nclient = anthropic.Anthropic()\n\ndef run_eval(test_cases: list, grader_fn) -\u0026gt; dict:\n    \"\"\"Chạy eval trên danh sách test cases.\"\"\"\n    results = []\n\n    for case in test_cases:\n        # Gọi Claude\n        response = client.messages.create(\n            model=\"claude-haiku-4-5\",\n            max_tokens=100,\n            messages=[{\"role\": \"user\", \"content\": case[\"input\"]}]\n        )\n        output = response.content[0].text\n\n        # Chấm điểm\n        score = grader_fn(output, case[\"golden\"])\n        results.append({\n            \"input\": case[\"input\"],\n            \"output\": output,\n            \"golden\": case[\"golden\"],\n            \"score\": score,\n            \"passed\": score \u0026gt;= 0.5,\n        })\n\n    # Tổng kết\n    accuracy = sum(r[\"score\"] for r in results) \/ len(results)\n    return {\"accuracy\": accuracy, \"results\": results}\n\n# Test cases\ntest_cases = [\n    {\"input\": \"Classify: POSITIVE, NEGATIVE, or NEUTRAL?\n'Sản phẩm tuyệt vời!'\", \"golden\": \"POSITIVE\"},\n    {\"input\": \"Classify: POSITIVE, NEGATIVE, or NEUTRAL?\n'Giao hàng rất tệ.'\", \"golden\": \"NEGATIVE\"},\n    {\"input\": \"Classify: POSITIVE, NEGATIVE, or NEUTRAL?\n'Bình thường thôi.'\", \"golden\": \"NEUTRAL\"},\n]\n\nresults = run_eval(test_cases, lambda out, gold: exact_match_grader(out, gold))\nprint(f\"Accuracy: {results['accuracy']:.1%}\")\u003c\/code\u003e\u003c\/pre\u003e\n\n\u003ch2\u003ePhương pháp 2: Human Grading\u003c\/h2\u003e\n\n\u003cp\u003eVớ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à \u003cem\u003eground truth\u003c\/em\u003e thực sự.\u003c\/p\u003e\n\n\u003cpre\u003e\u003ccode\u003edef human_grading_interface(results: list):\n    \"\"\"Interface đơn giản cho human reviewer.\"\"\"\n    human_scores = []\n\n    for i, result in enumerate(results):\n        print(f\"\n--- Câu {i+1}\/{len(results)} ---\")\n        print(f\"INPUT: {result['input']}\")\n        print(f\"OUTPUT: {result['output']}\")\n        print(f\"GOLDEN: {result['golden']}\")\n        print()\n\n        while True:\n            try:\n                score = float(input(\"Điểm (0.0 - 1.0): \"))\n                if 0.0 \u0026lt;= score \u0026lt;= 1.0:\n                    break\n                print(\"Vui lòng nhập số từ 0.0 đến 1.0\")\n            except ValueError:\n                print(\"Nhập số hợp lệ\")\n\n        comment = input(\"Nhận xét (Enter để bỏ qua): \")\n        human_scores.append({\n            **result,\n            \"human_score\": score,\n            \"comment\": comment\n        })\n\n    return human_scores\u003c\/code\u003e\u003c\/pre\u003e\n\n\u003cp\u003e\u003cstrong\u003eTip:\u003c\/strong\u003e Dùng human grading để build dataset nhỏ (~100 cases) ban đầu, sau đó dùng dataset đó để train model-based grader.\u003c\/p\u003e\n\n\u003ch2\u003ePhương pháp 3: Model-based Grading (Claude chấm Claude)\u003c\/h2\u003e\n\n\u003cp\u003ePhươ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.\u003c\/p\u003e\n\n\u003cpre\u003e\u003ccode\u003eGRADER_PROMPT = \"\"\"Bạn là chuyên gia đánh giá chất lượng AI. Nhiệm vụ: đánh giá response của AI.\n\nINPUT từ user:\n{input}\n\nGOLDEN ANSWER (đáp án tham khảo):\n{golden}\n\nACTUAL OUTPUT (response cần đánh giá):\n{output}\n\nĐánh giá output theo các tiêu chí:\n1. Chính xác về thông tin (0-4 điểm)\n2. Đầy đủ, không bỏ sót ý quan trọng (0-3 điểm)\n3. Rõ ràng, dễ hiểu (0-3 điểm)\n\nTrả lời theo format:\n\u003cscore\u003eX\u003c\/score\u003e\n\u003creasoning\u003eGiải thích ngắn gọn\u003c\/reasoning\u003e\n\n(X là tổng điểm từ 0 đến 10)\"\"\"\n\ndef model_based_grader(input_text: str, output: str, golden: str) -\u0026gt; dict:\n    prompt = GRADER_PROMPT.format(\n        input=input_text,\n        golden=golden,\n        output=output\n    )\n\n    response = client.messages.create(\n        model=\"claude-sonnet-4-5\",  # Dùng model mạnh hơn để chấm\n        max_tokens=300,\n        messages=[{\"role\": \"user\", \"content\": prompt}]\n    )\n\n    text = response.content[0].text\n\n    # Extract score\n    score_match = re.search(r\"\u003cscore\u003e(d+(?:.d+)?)\u003c\/score\u003e\", text)\n    score = float(score_match.group(1)) \/ 10.0 if score_match else 0.0\n\n    # Extract reasoning\n    reasoning_match = re.search(r\"\u003creasoning\u003e(.*?)\u003c\/reasoning\u003e\", text, re.DOTALL)\n    reasoning = reasoning_match.group(1).strip() if reasoning_match else \"\"\n\n    return {\"score\": score, \"reasoning\": reasoning}\n\n# Ví dụ\nresult = model_based_grader(\n    input_text=\"Giải thích khái niệm machine learning cho người mới.\",\n    output=\"Machine learning là khi máy tính học từ dữ liệu.\",\n    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.\"\n)\nprint(f\"Score: {result['score']:.1f}\/1.0\")\nprint(f\"Reasoning: {result['reasoning']}\")\u003c\/code\u003e\u003c\/pre\u003e\n\n\u003ch2\u003eBest Practices khi xây dựng Evals\u003c\/h2\u003e\n\n\u003ch3\u003e1. Eval phải cụ thể và có thể đo lường\u003c\/h3\u003e\n\u003cp\u003eTránh eval chung chung như \"response phải tốt\". Thay vào đó:\u003c\/p\u003e\n\u003cul\u003e\n  \u003cli\u003e\"Response phải chứa ít nhất 3 ví dụ cụ thể\"\u003c\/li\u003e\n  \u003cli\u003e\"Độ dài response phải từ 100-300 từ\"\u003c\/li\u003e\n  \u003cli\u003e\"Score từ model grader phải trên 7\/10\"\u003c\/li\u003e\n\u003c\/ul\u003e\n\n\u003ch3\u003e2. Tự động hóa hoàn toàn\u003c\/h3\u003e\n\u003cpre\u003e\u003ccode\u003eimport json\nfrom datetime import datetime\n\ndef run_full_eval_suite(prompt_template: str, test_cases: list) -\u0026gt; dict:\n    \"\"\"Chạy eval đầy đủ và lưu kết quả.\"\"\"\n    timestamp = datetime.now().isoformat()\n    results = []\n\n    for case in test_cases:\n        # Inject input vào prompt template\n        full_prompt = prompt_template.replace(\"{input}\", case[\"input\"])\n\n        response = client.messages.create(\n            model=\"claude-haiku-4-5\",\n            max_tokens=200,\n            messages=[{\"role\": \"user\", \"content\": full_prompt}]\n        )\n        output = response.content[0].text\n\n        # Chạy nhiều graders\n        exact = exact_match_grader(output, case[\"golden\"])\n        model = model_based_grader(case[\"input\"], output, case[\"golden\"])\n\n        results.append({\n            \"case_id\": case.get(\"id\", f\"case_{len(results)+1}\"),\n            \"input\": case[\"input\"],\n            \"output\": output,\n            \"golden\": case[\"golden\"],\n            \"exact_match\": exact,\n            \"model_score\": model[\"score\"],\n            \"model_reasoning\": model[\"reasoning\"],\n        })\n\n    accuracy = sum(r[\"exact_match\"] for r in results) \/ len(results)\n    avg_model_score = sum(r[\"model_score\"] for r in results) \/ len(results)\n\n    report = {\n        \"timestamp\": timestamp,\n        \"prompt\": prompt_template,\n        \"n_cases\": len(test_cases),\n        \"accuracy\": accuracy,\n        \"avg_model_score\": avg_model_score,\n        \"results\": results,\n    }\n\n    # Lưu kết quả\n    with open(f\"eval_report_{timestamp[:10]}.json\", \"w\", encoding=\"utf-8\") as f:\n        json.dump(report, f, ensure_ascii=False, indent=2)\n\n    return report\u003c\/code\u003e\u003c\/pre\u003e\n\n\u003ch3\u003e3. Distribution phải đại diện\u003c\/h3\u003e\n\u003cp\u003eTest cases không chỉ nên là \"easy cases\" — phân bổ theo thực tế:\u003c\/p\u003e\n\u003cul\u003e\n  \u003cli\u003e\n\u003cstrong\u003e30% easy cases:\u003c\/strong\u003e Claude xử lý tốt ngay từ đầu\u003c\/li\u003e\n  \u003cli\u003e\n\u003cstrong\u003e50% normal cases:\u003c\/strong\u003e Đại diện cho traffic thực tế\u003c\/li\u003e\n  \u003cli\u003e\n\u003cstrong\u003e20% edge cases:\u003c\/strong\u003e Ambiguous, long inputs, unusual formats\u003c\/li\u003e\n\u003c\/ul\u003e\n\n\u003ch2\u003eỨng dụng thực tế: Theo dõi Prompt Regression\u003c\/h2\u003e\n\n\u003cpre\u003e\u003ccode\u003edef compare_prompts(prompt_v1: str, prompt_v2: str, test_cases: list):\n    \"\"\"So sánh hai phiên bản prompt.\"\"\"\n    results_v1 = run_full_eval_suite(prompt_v1, test_cases)\n    results_v2 = run_full_eval_suite(prompt_v2, test_cases)\n\n    print(\"=\" * 50)\n    print(f\"Prompt V1 accuracy: {results_v1['accuracy']:.1%}\")\n    print(f\"Prompt V2 accuracy: {results_v2['accuracy']:.1%}\")\n    delta = results_v2['accuracy'] - results_v1['accuracy']\n    print(f\"Delta: {'+' if delta \u0026gt; 0 else ''}{delta:.1%}\")\n\n    if delta \u0026gt; 0:\n        print(\"V2 tốt hơn — an toàn deploy!\")\n    elif delta \u0026lt; -0.05:\n        print(\"CẢNH BÁO: V2 kém hơn đáng kể — không deploy!\")\n    else:\n        print(\"Tương đương — xem xét các yếu tố khác (cost, latency)\")\u003c\/code\u003e\u003c\/pre\u003e\n\n\u003cp\u003eEvals 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.\u003c\/p\u003e\n\n\u003chr\u003e\n\u003ch3\u003eBài viết liên quan\u003c\/h3\u003e\n\u003cul\u003e\n\u003cli\u003e\u003ca href=\"\/en\/products\/content-moderation-xay-d%E1%BB%B1ng-b%E1%BB%99-l%E1%BB%8Dc-n%E1%BB%99i-dung-v%E1%BB%9Bi-claude\"\u003eContent Moderation — Xây dựng bộ lọc nội dung với Claude\u003c\/a\u003e\u003c\/li\u003e\n\u003cli\u003e\u003ca href=\"\/en\/products\/tool-evaluation-danh-gia-hi%E1%BB%87u-qu%E1%BA%A3-tools-trong-agent-systems\"\u003eTool Evaluation — Đánh giá hiệu quả tools trong agent systems\u003c\/a\u003e\u003c\/li\u003e\n\u003cli\u003e\u003ca href=\"\/en\/products\/fine-tuning-claude-tren-aws-bedrock-h%C6%B0%E1%BB%9Bng-d%E1%BA%ABn-t%E1%BB%ABng-b%C6%B0%E1%BB%9Bc\"\u003eFine-tuning Claude trên AWS Bedrock — Hướng dẫn từng bước\u003c\/a\u003e\u003c\/li\u003e\n\u003cli\u003e\u003ca href=\"\/en\/products\/fine-tuning-alternatives-khi-nao-c%E1%BA%A7n-tuy-ch%E1%BB%89nh-claude\"\u003eFine-tuning Alternatives — Khi nào cần tùy chỉnh Claude\u003c\/a\u003e\u003c\/li\u003e\n\u003cli\u003e\u003ca href=\"\/en\/products\/autonomous-coding-agent-ai-t%E1%BB%B1-vi%E1%BA%BFt-code-t%E1%BB%AB-spec\"\u003eAutonomous Coding Agent — AI tự viết code từ spec\u003c\/a\u003e\u003c\/li\u003e\n\u003c\/ul\u003e","brand":"Minh Tuấn","offers":[{"title":"Default Title","offer_id":47721829368020,"sku":null,"price":0.0,"currency_code":"VND","in_stock":true}],"thumbnail_url":"\/\/cdn.shopify.com\/s\/files\/1\/0821\/0264\/9044\/files\/building-evals-xay-d_ng-h_-th_ng-danh-gia-cho-claude.jpg?v=1774521022","url":"https:\/\/claude.vn\/en\/products\/building-evals-xay-d%e1%bb%b1ng-h%e1%bb%87-th%e1%bb%91ng-danh-gia-cho-claude","provider":"CLAUDE.VN","version":"1.0","type":"link"}