Product Management
Đăng nhập
ESC

Nhập từ khóa để tìm kiếm

↑↓ Di chuyển
Enter Mở
ESC Đóng

Bài 5 — Braintrust & tư duy eval-first: dataset, task, scorer

Đã đọc 0/8 mục · còn khoảng 3 phút
Cách chúng tôi ghi nhận

Một mục được tính là đã đọc khi nó nằm giữa màn hình đủ lâu so với độ dài của nó (bảng và sơ đồ tính một nửa), bạn vẫn đang cuộn hoặc bấm phím, và bạn đã thấy tới cuối mục. Lướt nhanh hoặc để tab mở không được tính. Chúng tôi chỉ lưu thời gian đọc từng mục — không lưu gì khác.

Bài 5 — Braintrust & tư duy eval-first

Nếu LangSmith/Langfuse xuất phát từ observability rồi thêm eval, thì Braintrust đặt eval làm trung tâm: viết eval như viết test, chạy trong CI, so sánh phiên bản trực quan. Nó vẫn có logging/tracing cho production, nhưng thế mạnh là vòng lặp thử nghiệm nhanh.

Ba trụ cột của một eval

Mọi eval trên Braintrust (và về bản chất trên mọi nền tảng) gồm ba phần:

  • Data — bộ ca kiểm thử: mỗi ca có input và (tùy chọn) expected.
  • Task — hàm nhận input, trả output (chính là agent/prompt của bạn).
  • Scores — một hay nhiều scorer chấm output so với expected/tiêu chí.
from braintrust import Eval
from autoevals import Factuality, Levenshtein

Eval(
    "support-agent",                     # tên project
    data=lambda: [
        {"input": "Thời gian hoàn tiền?", "expected": "7 ngày làm việc"},
        {"input": "Có ship quốc tế không?", "expected": "Có, phí tính theo cân"},
    ],
    task=lambda question: run_agent(question),   # agent của bạn
    scores=[Factuality, Levenshtein],            # scorer
)

Chạy file này, Braintrust thực thi task trên từng ca, chấm điểm, và đẩy kết quả lên UI để bạn xem điểm trung bình từng scorer.

Bước 1 — Xây dataset từ trace thật

Dataset tốt không bịa ra — nó đến từ production. Quy trình:

  • Mở trace production, tìm các ca thất bại/gây tranh cãi.
  • "Bắt" chúng thành ca dataset: lưu input, và expected (câu trả lời đúng do bạn/chuyên gia xác định).
  • Gắn nhãn nhóm: refund, shipping, edge_case.
  • Giữ dataset nhỏ mà chất (20–100 ca chọn lọc) hơn là 10.000 ca rác.

Bước 2 — Chọn scorer phù hợp

  • Exact/Levenshtein: khi có đáp án chuẩn dạng chuỗi ngắn (mã, số, tên).
  • Factuality / LLM-judge: khi câu trả lời tự do, cần đánh giá đúng ý.
  • Custom scorer: bạn tự viết logic (ví dụ: có gọi đúng tool không, có chứa disclaimer không).
def calls_refund_tool(output, metadata):
    used = metadata.get("tools_used", [])
    return 1.0 if "get_refund_policy" in used else 0.0

Bước 3 — So sánh phiên bản (experiment)

Mỗi lần chạy Eval là một experiment. Bạn đổi prompt/model rồi chạy lại → Braintrust hiển thị bảng so sánh: ca nào cải thiện, ca nào hồi quy (regression). Đây là siêu năng lực: bạn thấy chính xác trade-off, không đoán.

Bước 4 — Đưa eval vào CI

# trong pipeline CI
- run: braintrust eval ./evals/support_agent.eval.py

Đặt ngưỡng: nếu điểm trung bình Factuality tụt dưới 0.8 hoặc có regression, fail build. Agent giờ được bảo vệ như code có unit test.

Khung tư duy eval-first

Mỗi khi sửa prompt/model/tool:
1. Có ca test nào cover thay đổi này chưa? (chưa -> thêm)
2. Chạy eval -> điểm tổng thể tăng hay giảm?
3. Có regression trên ca cũ không? (có -> cân nhắc lại)
4. Chỉ ship khi eval xanh.

Sai lầm thường gặp

  • Dataset chỉ toàn ca dễ: điểm đẹp nhưng production vẫn hỏng; phải nhồi edge case thật.
  • Chỉ nhìn điểm trung bình: che giấu regression cục bộ; luôn xem diff theo từng ca.
  • Dùng một scorer cho mọi thứ: câu trả lời tự do mà chấm bằng exact-match sẽ luôn 0 điểm oan.
  • Không cố định seed/model version: eval dao động, không tái lập được.
  • Tách eval khỏi CI: chạy tay thì sẽ quên; phải tự động hóa gate.
Bạn đã nắm ba nền tảng. Bài 6 đào sâu kỹ thuật khó nhất: LLM-as-judge.

Học xong bài này rồi? Tạo tài khoản miễn phí để lưu lại — lần sau vào là biết ngay đang dở ở đâu, và học hết khóa thì có chứng chỉ. Lưu tiến độ của tôi