Cấp độ: Nền tảng · Thời lượng: 4 giờ · Đầu ra: thư mục evals/ dùng lại cho cả khoá

Mục tiêu

  • Viết prompt như một bản đặc tả: vai trò, nhiệm vụ, ràng buộc, định dạng đầu ra, ví dụ.
  • Xây một bộ eval có đáp án và chấm tự động, thay cho việc "đọc thấy ổn".
  • Dùng LLM làm giám khảo (LLM-as-judge) một cách có kiểm soát và đo độ lệch của giám khảo.
  • So sánh hai phiên bản prompt bằng số liệu, biết khi nào chênh lệch là nhiễu.

Prompt là đặc tả

Một prompt tốt trả lời năm câu hỏi mà một nhân viên mới cũng cần biết:

Thành phần Câu hỏi Ví dụ ngắn
Ngữ cảnh Ai dùng kết quả, để làm gì? "Câu trả lời hiện trong app ngân hàng cho khách lớn tuổi"
Nhiệm vụ Cụ thể phải làm gì? "Phân loại tin nhắn vào 1 trong 6 nhãn"
Ràng buộc Điều gì không được làm? "Không đoán số dư; thiếu dữ liệu thì trả nhãn can_nguoi"
Định dạng Máy đọc kết quả thế nào? JSON theo schema, không có chữ thừa
Ví dụ Ca khó trông ra sao? 3 đến 5 ví dụ, trong đó có ít nhất 1 ca biên

Các kỹ thuật đáng giá nhất theo thứ tự hiệu quả trên chi phí: chỉ dẫn rõ ràng, ví dụ chọn lọc (few-shot), tách dữ liệu bằng thẻ như <tai_lieu>, cho mô hình suy nghĩ trước khi trả lời ở nhiệm vụ nhiều bước, và ép định dạng bằng schema hoặc structured output. Đừng "dọa" mô hình bằng chữ in hoa; chỉ dẫn mâu thuẫn và mơ hồ mới là nguyên nhân chính của lỗi.

Eval: thứ phân biệt kỹ sư với người thử vận may

Một bộ eval gồm ba phần: ca kiểm thử (đầu vào và đáp án kỳ vọng), hàm chấm, và báo cáo. Thứ tự ưu tiên hàm chấm:

  1. So khớp chính xác hoặc theo quy tắc (nhãn, số, JSON hợp lệ): rẻ, tất định, nên dùng tối đa.
  2. Chấm bằng code có logic (có chứa từ khoá bắt buộc, không vượt độ dài, gọi đúng hàm).
  3. LLM làm giám khảo cho tiêu chí mềm (giọng văn, đầy đủ ý). Phải có rubric rõ, chấm theo thang nhỏ hoặc đạt/không đạt, và phải đo độ đồng thuận với người chấm trên 20 đến 30 mẫu trước khi tin.

Những bẫy kinh điển của giám khảo LLM: thiên vị câu dài, thiên vị vị trí (đáp án đứng trước), thiên vị văn phong của chính nó. Cách giảm: đổi thứ tự khi so sánh cặp, yêu cầu trích dẫn bằng chứng trước khi cho điểm, dùng model giám khảo khác họ với model được chấm khi có thể.

Thống kê tối thiểu. Với 50 ca và độ chính xác khoảng 80%, sai số chuẩn xấp xỉ căn(0,8 × 0,2 / 50) ≈ 5,7 điểm phần trăm. Một prompt "tốt hơn 3%" trên 50 ca rất có thể chỉ là nhiễu. Hoặc tăng số ca, hoặc chạy lặp và so sánh từng cặp ca (paired), hoặc chỉ kết luận khi chênh lệch đủ lớn.

Lab: bộ eval phân loại tin nhắn khách hàng

Bối cảnh tự dựng: tiệm bánh online "Bánh Mây" nhận tin nhắn qua chat. Nhãn: dat_hang, huy_don, hoi_gia, khieu_nai, giao_hang, khac.

  1. Tự viết 30 tin nhắn, mỗi nhãn ít nhất 4, có 6 ca khó: tin nhắn hai ý, tiếng lóng, viết không dấu, mỉa mai ("bánh ngon ghê, chờ 3 tiếng mới tới").
  2. Lưu vào evals/banh_may.jsonl, mỗi dòng {"id":..., "input":..., "label":...}.
  3. Viết run_eval.py: gọi model với prompt v1, parse JSON, so nhãn, in độ chính xác và ma trận nhầm lẫn.
import json, collections
from anthropic import Anthropic
client = Anthropic()
PROMPT = open("prompts/v1.txt").read()
cases = [json.loads(l) for l in open("evals/banh_may.jsonl")]
confusion, ok = collections.Counter(), 0
for c in cases:
    r = client.messages.create(model="claude-haiku-4-5", max_tokens=50, temperature=0,
        system=PROMPT, messages=[{"role": "user", "content": c["input"]}])
    pred = json.loads(r.content[0].text)["label"]
    ok += pred == c["label"]; confusion[(c["label"], pred)] += 1
print(f"accuracy {ok}/{len(cases)}"); print(confusion.most_common(10))

Tên model trong ví dụ chỉ là minh hoạ; lấy tên hiện hành trong trang Models của nhà cung cấp.

  1. Viết prompt v2 sửa đúng các lỗi ma trận nhầm lẫn chỉ ra. Chạy lại, ghi kết quả cả hai bản vào RESULTS.md.

Thử thách

Dễ (10 điểm). Prompt v2 đạt ít nhất 90% trên bộ 30 ca, đầu ra luôn là JSON hợp lệ (0 lỗi parse). Nghiệm thu: log chạy và file prompt.

Vừa (20 điểm): Giám khảo có kiểm chứng. Thêm trường reply (câu trả lời cho khách) và chấm bằng LLM theo rubric 3 tiêu chí đạt/không đạt. Tự chấm tay 25 mẫu. Nghiệm thu: tỉ lệ đồng thuận giữa bạn và giám khảo ≥ 80%, và một ví dụ cụ thể giám khảo chấm sai kèm cách bạn sửa rubric.

Boss (40 điểm): Đối kháng với chính bộ eval. Mở rộng lên 120 ca, trong đó 40 ca do một LLM khác sinh ra để cố tình phá prompt của bạn (bạn tự lọc và gán nhãn lại). Nghiệm thu: báo cáo độ chính xác có khoảng tin cậy 95% (bootstrap), danh sách 3 kiểu lỗi phổ biến nhất, và chứng minh prompt cuối cùng tốt hơn v1 bằng kiểm định cặp (ví dụ McNemar) với p < 0,05.

Quiz tự kiểm tra

  1. Vì sao nên dùng hàm chấm bằng quy tắc trước giám khảo LLM?
  2. Kể hai thiên vị thường gặp của LLM-as-judge và cách giảm.
  3. Prompt A đúng 41/50, prompt B đúng 43/50. Có nên kết luận B tốt hơn không?
  4. Ví dụ few-shot nên chọn thế nào?
  5. Vì sao bọc tài liệu đầu vào trong thẻ XML lại giúp ích?

Đáp án

  1. Rẻ, nhanh, tất định và không có thiên vị; giám khảo LLM tự nó cũng cần được kiểm chứng.
  2. Thiên vị độ dài và thiên vị vị trí; giảm bằng rubric bắt trích bằng chứng, đổi thứ tự trong so sánh cặp, và đối chiếu với người chấm.
  3. Chưa. Chênh 4 điểm phần trăm nằm trong biên sai số khoảng ±6 điểm của 50 ca; cần thêm ca hoặc kiểm định cặp.
  4. Đa dạng, đúng định dạng đầu ra, có ca biên, không lặp lại đúng dữ liệu kiểm thử để tránh "học thuộc" bộ eval.
  5. Nó tách rạch ròi chỉ dẫn với dữ liệu, giảm nhầm lẫn và là một lớp phòng thủ đầu tiên với prompt injection (Bài 7).

Đọc thêm