Bài này bạn dựng bộ khung kỹ thuật để agent chạy được. Mục tiêu cuối bài: có một script biến file CV PDF thành JSON có cấu trúc — nền tảng cho mọi bước sau.
Chọn stack: no-code hay code?
| Nhu cầu | Lựa chọn | Khi nào dùng |
|---|---|---|
| Không biết code, ít CV/tháng | n8n / Make + node OpenAI | Team HR nhỏ, cần nhanh |
| Cần kiểm soát & mở rộng | Python + LLM API | Volume lớn, logic phức tạp |
| Đã có ATS | Webhook + serverless | Tích hợp vào hệ thống sẵn có |
Các bước thiết lập
- Tạo môi trường Python cô lập và cài thư viện đọc PDF + gọi LLM.
- Lấy API key của nhà cung cấp LLM, lưu vào biến môi trường (không hardcode).
- Chuẩn bị thư mục
cv_inbox/chứa CV thô vàcv_json/chứa kết quả. - Viết hàm trích xuất text từ PDF (nhiều CV là scan → cần OCR dự phòng).
- Viết prompt trích xuất có JSON schema cố định.
python -m venv venv && source venv/bin/activate
pip install pdfplumber openai python-dotenv
# .env (KHÔNG commit lên git)
# LLM_API_KEY=sk-xxxx
Trích xuất text từ CV
import pdfplumber, os
def extract_text(path):
text = ""
with pdfplumber.open(path) as pdf:
for page in pdf.pages:
text += (page.extract_text() or "") + "\n"
if len(text.strip()) < 50:
# PDF scan ảnh → cần OCR (ví dụ Tesseract) hoặc đánh dấu lỗi
return None
return text
Lưu ý: khoảng 15–30% CV thực tế là scan ảnh hoặc layout 2 cột rối. Luôn có nhánh xử lý CV "đọc không được" thay vì để agent im lặng bỏ qua.
Chuẩn hóa thành JSON có cấu trúc
Đây là bước quyết định chất lượng cả hệ thống. Prompt phải ép LLM trả đúng schema:
SCHEMA_PROMPT = """Trích xuất thông tin từ CV sau thành JSON đúng schema.
Nếu không có thông tin, để null, TUYỆT ĐỐI không bịa.
Schema:
{
"full_name": str|null,
"years_experience": number|null,
"skills": [str],
"education": str|null,
"current_title": str|null,
"industries": [str],
"contact_email": str|null
}
Chỉ trả JSON, không giải thích.
CV:
---
{cv_text}
"""
Mẹo quan trọng: yêu cầu "không bịa, thiếu thì null" giảm mạnh hiện tượng LLM tự sáng tác kinh nghiệm không có trong CV — một lỗi cực nguy hiểm khi chấm điểm.
Khung "3 lớp bảo vệ dữ liệu"
Lớp 1 — Validate: JSON parse được không? đủ field không?
Lớp 2 — Sanity check: years_experience có âm/quá lớn không?
Lớp 3 — Human flag: field quan trọng null → đánh dấu "cần xem tay"
Mỗi CV chạy qua 3 lớp; chỉ CV "sạch" mới vào bước chấm điểm tự động, phần còn lại xếp hàng cho người.
Checklist môi trường sẵn sàng
- [ ] API key nằm trong biến môi trường,
.envđã vào.gitignore - [ ] Trích xuất được text từ CV mẫu (test 5 CV thật, đủ định dạng)
- [ ] Có nhánh xử lý CV scan/đọc lỗi
- [ ] JSON output validate được bằng schema
- [ ] Đã thử prompt với CV "thiếu thông tin" xem có bịa không
Sai lầm thường gặp
- Hardcode API key trong code. Rò rỉ khi push git, có thể bị lạm dụng tốn tiền. Luôn dùng env var.
- Giả định mọi CV đều là PDF text. CV scan sẽ ra chuỗi rỗng và làm hỏng bước chấm điểm mà bạn không hay biết.
- Cho LLM trả text tự do rồi tự parse bằng regex. Rất giòn. Ép JSON schema ngay từ đầu.
- Không test case "thiếu thông tin". LLM có xu hướng lấp chỗ trống bằng phỏng đoán; phải kiểm tra và chặn bịa đặt.
- Bỏ qua quyền riêng tư. CV chứa dữ liệu cá nhân; đừng gửi lên dịch vụ không kiểm soát, và xóa dữ liệu theo chính sách lưu trữ.
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