Product Management
Đăng nhập
ESC

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

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

Bài 3 — Xây engine sàng lọc & chấm điểm CV minh bạch, có trọng số

Đã đọc 0/10 mục · còn khoảng 4 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.

Có JSON ứng viên chuẩn hóa từ Bài 2, giờ ta xây phần "não" của agent: chấm điểm. Nguyên tắc cốt lõi: điểm số phải giải thích được và tái lập được, không phải một con số bí ẩn từ LLM.

Vì sao không để LLM tự cho điểm 0–100 tùy hứng

Nếu bạn hỏi "chấm CV này bao nhiêu điểm?", LLM sẽ cho số khác nhau mỗi lần, không nhất quán giữa các ứng viên, và không giải thích được với ứng viên/pháp lý. Giải pháp: tách tiêu chí → LLM đánh giá từng tiêu chí → công thức có trọng số cộng lại.

Bước 1: Định nghĩa rubric từ JD

Biến JD thành bảng tiêu chí có trọng số. Ví dụ vị trí Backend:

Tiêu chí (weight)          | Cách tính
---------------------------|---------------------------
Kỹ năng bắt buộc (40)      | % skill JD yêu cầu mà CV có
Số năm kinh nghiệm (25)    | min(năm_CV / năm_JD, 1) * 25
Cùng ngành (15)            | có/không
Học vấn (10)              | đạt/không đạt mức tối thiểu
Skill ưu tiên (10)         | % skill nice-to-have có

Tổng weight = 100. Trọng số này do con người quyết định, phản ánh ưu tiên tuyển dụng thật — đây là nơi bạn cài giá trị vào hệ thống.

Bước 2: Chấm từng tiêu chí (phần rule-based)

Những tiêu chí đo đếm được thì dùng code, không dùng LLM — rẻ, nhanh, chính xác:

def score_hard_skills(cv_skills, required):
    cv = {s.lower() for s in cv_skills}
    hit = sum(1 for r in required if r.lower() in cv)
    return hit / len(required) * 40   # weight 40

def score_experience(years_cv, years_jd):
    if not years_cv: return 0
    return min(years_cv / years_jd, 1) * 25

Bước 3: Dùng LLM cho phần "mềm"

Chỉ dùng LLM cho việc nó giỏi: đánh giá mức độ liên quan mà keyword không bắt được (ví dụ "đã build hệ thống thanh toán" ≈ kinh nghiệm fintech dù không ghi chữ "fintech"). Yêu cầu LLM trả điểm 0–1 kèm lý do, rồi bạn nhân với weight:

LLM_RELEVANCE = """Cho JD và CV, đánh giá độ liên quan ngành nghề 0.0–1.0.
Trả JSON: {"industry_match": float, "reason": str}. Chỉ dựa trên bằng chứng trong CV."""

Bước 4: Tổng hợp & giải thích

def final_score(cv, jd):
    parts = {
      "hard_skills": score_hard_skills(cv["skills"], jd["required"]),
      "experience": score_experience(cv["years_experience"], jd["years"]),
      "industry": llm_industry(cv, jd) * 15,
      # ... các phần khác
    }
    total = round(sum(parts.values()))
    reasons = build_reasons(parts, cv, jd)  # 3 dòng lý do rõ ràng
    return {"score": total, "breakdown": parts, "reasons": reasons}

Điểm mạnh: khi ai đó hỏi "vì sao ứng viên này 78 điểm?", bạn chỉ ra breakdown từng phần — hoàn toàn minh bạch.

Khung phân tầng để hành động

85–100  Tier A  → mời phỏng vấn ngay
70–84   Tier B  → recruiter xem nhanh rồi mời
50–69   Tier C  → giữ lại, xem nếu thiếu ứng viên
<50     Tier D  → không phù hợp vòng này
BẤT KỲ điểm nào có field null quan trọng → flag "xem tay"

Chống thiên vị (bias)

  • Loại trường gây bias khỏi input chấm điểm: tên, tuổi, giới tính, ảnh, trường học (nếu không thực sự cần).
  • Chấm trên năng lực và bằng chứng, không phải xuất thân.
  • Lưu log điểm để audit: nếu một nhóm bị điểm thấp bất thường, phải rà lại rubric.

Checklist engine chấm điểm

  • [ ] Rubric có trọng số, tổng = 100, do người duyệt
  • [ ] Tiêu chí đo đếm được dùng code, không dùng LLM
  • [ ] LLM chỉ chấm phần "mềm", trả điểm chuẩn hóa + lý do
  • [ ] Mỗi điểm có breakdown giải thích được
  • [ ] Đã loại trường gây bias khỏi input
  • [ ] Có log để audit

Sai lầm thường gặp

  • Để LLM cho điểm tổng trực tiếp. Không nhất quán, không giải thích được, không audit được.
  • Chấm bằng đếm keyword thuần. Ứng viên "biết chơi chữ" nhồi keyword sẽ điểm cao giả; ứng viên giỏi mô tả bằng ngôn ngữ khác bị thiệt. Kết hợp code + LLM ngữ nghĩa.
  • Không chuẩn hóa điểm LLM. Nếu LLM trả 0–100 tự do và bạn cộng vào, thang điểm loạn. Luôn ép về 0–1 rồi nhân weight.
  • Đưa tên/ảnh/tuổi vào chấm. Mở đường cho bias và rủi ro pháp lý.
  • Quên nhánh "thiếu dữ liệu". CV thiếu thông tin bị chấm thấp oan; phải flag cho người xem thay vì loại thẳng.
Bài sau: biến điểm số thành hành động — tự động đặt lịch phỏng vấn với interviewer.

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