Bài 1 — Vì sao Agent cần Observability & Evals
Bạn dựng xong một agent trợ lý hỗ trợ khách hàng. Demo chạy ngon. Nhưng tuần sau khách phàn nàn: agent trả lời sai chính sách hoàn tiền, đôi khi gọi nhầm tool, thỉnh thoảng lặp vòng và tốn 40.000 token cho một câu hỏi đơn giản. Bạn mở log ra và chỉ thấy... print() rải rác. Không biết agent "nghĩ" gì, gọi tool nào, vì sao lạc hướng.
Đó chính là lý do của khóa học này. Với phần mềm truyền thống, đầu vào cố định thì đầu ra cố định. Với agent LLM, cùng một câu hỏi có thể ra kết quả khác nhau, đi qua số bước khác nhau, gọi tool khác nhau. Bạn không thể "đọc code" để biết nó đúng hay sai — bạn phải quan sát hành vi thực tế (observability) và đo lường chất lượng có hệ thống (evals).
Ba khái niệm cốt lõi
- Trace: bản ghi đầy đủ một lần agent chạy — gồm nhiều span lồng nhau (LLM call, tool call, retriever, bước reasoning). Trace giống "hộp đen" của máy bay: khi rớt, bạn mở ra xem chuyện gì đã xảy ra.
- Observability: khả năng nhìn xuyên vào hệ thống đang chạy — độ trễ, token, chi phí, lỗi, đường đi của từng request — mà không cần đoán.
- Evals: đo chất lượng đầu ra một cách có hệ thống, lặp lại được, thay vì "cảm thấy có vẻ ổn". Có eval offline (chạy trên bộ dataset trước khi ship) và eval online (chấm điểm traffic thật đang chạy production).
Khung tư duy: vòng đời tin cậy của Agent
Instrument (gắn trace)
-> Observe (xem trace, tìm lỗi thực tế)
-> Build dataset (biến lỗi thành test case)
-> Eval (chấm điểm, so sánh phiên bản)
-> Ship (release phiên bản tốt hơn)
-> Monitor (giám sát production, bắt lỗi mới)
-> quay lại Observe
Không có vòng lặp này, bạn cải tiến agent bằng cảm tính. Có nó, mỗi lần sửa prompt hay đổi model bạn đều có bằng chứng số liệu.
Ví dụ cụ thể: đọc một trace
Giả sử agent đặt lịch. Một trace điển hình:
Trace: "Đặt lịch họp thứ 3" (latency 6.2s, 3.100 tokens, $0.011)
├─ LLM: plan (chọn tool check_calendar)
├─ Tool: check_calendar (trả về 3 slot trống)
├─ LLM: plan (chọn tool create_event)
├─ Tool: create_event (ERROR: thiếu tham số 'duration')
├─ LLM: plan (thử lại create_event)
└─ Tool: create_event (OK)
Chỉ nhìn output cuối "Đã đặt lịch xong" bạn tưởng mọi thứ hoàn hảo. Nhưng trace cho thấy có 1 lần gọi tool thất bại và 1 vòng lặp thừa — tốn tiền và thời gian. Đây là thứ observability phơi bày.
Các bước bắt đầu
- Xác định đơn vị bạn muốn quan sát: một request người dùng = một trace.
- Chọn 3 chỉ số vàng ban đầu: latency, token/chi phí, tỉ lệ lỗi tool.
- Chọn 1 nền tảng để bắt đầu (khóa học dùng LangSmith, Langfuse, Braintrust).
- Gắn tracing tự động thay vì log tay.
- Sau 1 tuần chạy thật, mở 20 trace ngẫu nhiên ra đọc — bạn sẽ tìm ra lỗi mình không ngờ tới.
Checklist "agent đã sẵn sàng quan sát chưa?"
- [ ] Mỗi request tạo đúng 1 trace, có ID truy được.
- [ ] Mỗi LLM call ghi lại input, output, token, latency.
- [ ] Mỗi tool call ghi lại tham số vào và kết quả ra (kể cả lỗi).
- [ ] Có gắn metadata: user_id, session_id, phiên bản prompt.
- [ ] Có ít nhất 1 bộ dataset eval nhỏ (10–20 ca) để đo trước khi ship.
Sai lầm thường gặp
- Dựa vào eyeballing (nhìn bằng mắt) mãi mãi: xem trace tay tốt lúc đầu, nhưng không scale. Phải chuyển thành eval tự động.
- Chỉ log output cuối: mất toàn bộ chuỗi reasoning và tool call — nơi 90% lỗi ẩn nấp.
- Đợi "khi nào rảnh" mới gắn observability: bạn sẽ không bao giờ rảnh, và sự cố production sẽ ập tới trước.
- Nhầm eval với test đơn vị: eval đo chất lượng "mềm" (đúng ý, hữu ích) chứ không chỉ đúng/sai tuyệt đối.
- Không gắn metadata phiên bản: khi so sánh không biết trace nào thuộc prompt cũ, prompt mới.