llm evaluation & observability
Tung Bui Thanh (TungDaDev)10 mins read

Dựng một bản demo LLM chạy trên máy local (Proof of Concept, PoC) thì dev nào cũng làm được trong một buổi chiều, vài dòng Python hay JavaScript là xong.
Nhưng đưa chính cái app đó lên production cho hàng triệu người dùng thật thì lại là một cơn ác mộng khác hẳn.
Phần mềm truyền thống lỗi thì có stack trace, có mã 500, có exception rõ ràng để lần theo. Còn LLM thì:
- Request trả về
200 OK, JSON đúng schema. - Nhưng nội dung bên trong lại là một câu bịa (hallucination) sai hoàn toàn, hoặc tệ hơn là vi phạm chính sách bảo mật của công ty.
Vậy đo chất lượng một hệ thống bất định (non-deterministic) kiểu gì? Đó là chuyện của LLM Evaluation & Observability (LLMOps).
# traditional monitoring khác llm observability ở đâu
Với backend truyền thống, mình theo dõi 4 tín hiệu vàng (Golden Signals): Latency, Traffic, Errors, Saturation.
Với app GenAI và Agentic Workflow thì chừng đó chưa đủ:
| Tiêu chí | Traditional Backend APM | LLM Observability |
|---|---|---|
| Output Type | Dữ liệu có cấu trúc, kết quả xác định (deterministic) | Văn bản tự do, kết quả mang tính xác suất (probabilistic) |
| Thế nào là "lỗi" | Exception, Status 4xx/5xx, Timeout | Trả lời sai sự thật, lạc đề (Drift), lộ dữ liệu mật, giọng điệu khó nghe |
| Metric chính | RPS, CPU/RAM, Error Rate, p99 Latency | Token Count, Cost per Request, Hallucination Rate, Faithfulness |
| Debugging | Stack trace theo từng hàm | Đồ thị thực thi từng bước qua chuỗi Agents, Tools, RAG context |
# bộ ba thước đo: rag triad of metrics
Bài toán LLM hay gặp nhất trong doanh nghiệp là RAG (Retrieval-Augmented Generation). Làm sao biết bot RAG trả lời tốt hay dở mà không phải ngồi đọc từng dòng log?
RAG Triad (khái niệm do nhóm làm TruLens đưa ra; Ragas có bộ metric tương tự như faithfulness, answer relevancy, context precision/recall) chia chất lượng RAG thành 3 thước đo:
1. Context Relevance (Độ liên quan của ngữ cảnh)
- Đo xem mấy mẩu dữ liệu (chunks) mà Vector Database trả về có thật sự liên quan tới câu hỏi không.
- Điểm này thấp: xem lại cách tìm kiếm, chunking strategy, embedding model, hoặc thêm bước reranking.
2. Faithfulness / Groundedness (Độ trung thực)
- Đo xem câu trả lời của LLM có chứng minh được hoàn toàn bằng dữ liệu trong context không.
- Faithfulness < 100%: có mệnh đề trong câu trả lời không tìm thấy căn cứ trong context. Thường là LLM bịa thêm (hallucination) hoặc lôi kiến thức đã học từ trước vào. Lưu ý là mệnh đề đó có thể vẫn đúng ngoài đời, nhưng với RAG thì "đúng mà không có trong tài liệu" vẫn là rủi ro, vì không ai kiểm chứng được nó.
- Các công cụ thường tính Faithfulness bằng cách tách câu trả lời thành từng mệnh đề rồi cho LLM kiểm tra từng cái với context, điểm là tỉ lệ mệnh đề có căn cứ. Nên điểm này cũng chỉ tin được tới mức judge tin được (xem phần dưới).
3. Answer Relevance (Câu trả lời có đúng trọng tâm không)
- Đo xem câu trả lời cuối có đi thẳng vào câu người dùng hỏi không. Đúng sự thật mà vòng vo, lạc đề thì điểm này vẫn thấp.
# llm-as-a-judge: dùng ai chấm điểm ai
Thuê người gắn nhãn bằng tay (Human-in-the-loop Evaluation) là chuẩn nhất, nhưng đắt và không scale nổi khi mỗi ngày có hàng trăm nghìn lượt hỏi đáp.
Cách hay dùng bây giờ là LLM-as-a-Judge: lấy một model mạnh (thường là model frontier của OpenAI, Anthropic hay Google) kèm một prompt chấm điểm thật chặt (rubric) để chấm câu trả lời của model đang chạy cho sản phẩm (thường là model nhỏ hơn, rẻ hơn hoặc model open-weight tự host):
[PROMPT TEMPLATE: EVALUATE FAITHFULNESS]
Bạn là một giám khảo khắt khe về tính trung thực của dữ liệu.
Nhiệm vụ: Hãy phân tích kỹ lưỡng từng mệnh đề trong "CÂU TRẢ LỜI" dưới đây.
Đối chiếu từng mệnh đề đó với thông tin có trong "NGỮ CẢNH CUNG CẤP".
NGỮ CẢNH:
{retrieved_context}
CÂU TRẢ LỜI:
{generated_response}
HÃY ĐÁNH GIÁ:
- Liệt kê các luận điểm trong câu trả lời.
- Với mỗi luận điểm, kiểm tra xem có căn cứ trong ngữ cảnh không.
- Trả về JSON theo định dạng:
{
"reasoning": "giải thích chi tiết logic chấm điểm",
"score": 1.0 (nếu hoàn toàn có căn cứ) hoặc 0.0 (nếu có mệnh đề bịa đặt)
}Mấy cái bẫy khi dùng LLM-as-a-Judge:
- Position Bias: khi so sánh từng cặp (pairwise comparison), model hay thiên vị câu trả lời đứng đầu hoặc đứng cuối. Cách giảm: chấm hai lần với thứ tự đảo ngược, chỉ tính khi hai lần đồng ý.
- Self-enhancement Bias: judge hay chấm điểm cao hơn cho câu trả lời do chính nó (hoặc model cùng họ) viết ra. Cách giảm: dùng judge khác họ với model đang chấm.
- Verbosity Bias: model thường cho rằng câu trả lời dài dòng, văn hoa là "tốt hơn" câu ngắn gọn, dù cả hai đều đúng. Cách giảm: ghi rõ trong rubric là độ dài không được cộng điểm.
Ba kiểu bias này được mô tả kỹ trong paper Judging LLM-as-a-Judge with MT-Bench and Chatbot Arena (Zheng và cộng sự, 2023). Dù dùng cách nào, trước khi tin judge thì nên lấy vài trăm mẫu cho người chấm tay, so độ đồng thuận giữa người và judge. Judge chưa khớp với người thì con số nó đưa ra chưa có ý nghĩa.
# full-stack tracing cho ai agent
Khi làm agent phức tạp (với LangGraph, AutoGen/Microsoft Agent Framework hay LlamaIndex), một request của người dùng có thể kéo theo cả một chuỗi việc:
- Agent lên kế hoạch (Planning)
- Gọi tool tìm kiếm trên web
- Đọc dữ liệu từ database SQL
- Thấy thiếu thông tin -> nghĩ tiếp và gọi thêm API phụ
- Tổng hợp câu trả lời cuối
Câu trả lời mất 12 giây mà còn sai, làm sao biết khâu nào bị nghẽn (bottleneck), khâu nào quyết định sai?
Lúc này cần distributed tracing riêng cho LLM. Công cụ mã nguồn mở tiêu biểu là Langfuse và Arize Phoenix. Bên dưới, cả hai đều nhận dữ liệu qua OpenTelemetry, còn OpenTelemetry GenAI Semantic Conventions là bộ quy ước đặt tên attribute (tên model, số token, prompt...) để trace từ framework này đọc được ở công cụ kia. Bộ quy ước này vẫn đang ở trạng thái phát triển, tên attribute có thể còn đổi, nên ghim phiên bản SDK cho cẩn thận:
Có Span & Trace như vậy, mình click vào request nào cũng xem được:
- Prompt gửi tới LLM chính xác là gì (kể cả system prompt).
- Temperature, top-p của model lúc gọi.
- Số Input/Output Tokens và chi phí tính bằng USD, chi tới từng phần trăm cent.
- Thời gian chạy của từng tool và tỉ lệ thành công của các bước lập luận.
# prompt drift & dataset curation: vòng lặp cải tiến liên tục
Làm observability không phải để có dashboard cho đẹp. Mục đích chính là tạo ra một vòng lặp phản hồi (Flywheel Feedback Loop):
- Bắt Prompt Drift: lâu dần, cách người dùng thật hỏi han sẽ khác xa so với dữ liệu team tưởng tượng hồi còn thử nghiệm. Theo dõi độ lệch ngữ nghĩa (semantic drift) giúp phát hiện sớm những lúc LLM bắt đầu không hiểu người dùng nữa.
- Gom "Golden Dataset" từ những lần hỏng: mỗi lần người dùng bấm Dislike (Thumbs Down) hoặc bot trả lời sai luật, trace đó phải được đánh dấu (flagged) ngay, rút cặp
{Query, Bad Response, Context}ra. Trước khi đưa vào bộ test chuẩn (Regression Test Suite), cần có người viết câu trả lời đúng hoặc tiêu chí chấm cho từng mẫu; chỉ có câu trả lời sai thì test không biết thế nào là đạt. - CI/CD cho prompt: mỗi lần ai đó sửa một chữ trong System Prompt hay nâng version model, CI/CD pipeline tự chạy bộ test trên toàn bộ Golden Dataset và tính xem điểm trung bình (F1, Accuracy, Faithfulness) tăng hay giảm, rồi mới cho merge vào nhánh
main. Vì cả model lẫn judge đều có độ ngẫu nhiên, điểm dao động vài phần trăm giữa hai lần chạy là bình thường; nên chạy lặp vài lần hoặc đặt ngưỡng chênh lệch tối thiểu, kẻo pipeline đỏ xanh thất thường.
# tổng kết
Cái gì không đo được thì không cải tiến được. (câu hay được gán cho Peter Drucker, dù chưa ai tìm ra chỗ ông thật sự nói vậy)
Câu này giờ còn đúng hơn với GenAI. Đưa sản phẩm AI ra thị trường mà không có Evaluation & Observability thì chẳng khác gì lái máy bay xuyên sương mù mà không có đồng hồ nào trên bảng điều khiển.
Kết hợp RAG Triad, LLM-as-a-Judge, tracing chi tiết tới từng span và vòng lặp test tự động, bạn sẽ biến một app AI khó đoán, nhiều rủi ro thành một hệ thống đáng tin, nhìn vào là biết chuyện gì đang xảy ra, và sẵn sàng scale.
Chỉ là những ghi chép cá nhân với hy vọng mang lại chút giá trị. Nếu thấy hữu ích, đừng ngại chia sẻ cho bạn bè & đồng nghiệp nhé!
Happy coding 😎 👍🏻 🚀 🔥.