# Sau go-live, bộ eval thật của agent nằm trong trace của khách hàng

> Bộ test xanh trước ngày ra mắt chỉ cho biết agent làm đúng những gì bạn đoán người dùng sẽ hỏi. Còn những gì người dùng thật sự hỏi thì nằm trong trace.

Bản gốc: https://fdetimes.net/vi/bach-khoa/danh-gia-ai-trong-production/

Hai tuần sau go-live, bộ eval của agent vẫn xanh 100%. Rồi trưởng nhóm vận hành phía khách hàng gửi bạn một ảnh chụp màn hình: agent trả lời tự tin, đúng giọng, nhưng sai hoàn toàn. Không test nào trong bộ của bạn từng gặp câu hỏi kiểu đó.

Cảnh này không có gì lạ nếu bộ eval chỉ được viết trước ngày launch. Bộ eval không hỏng. Nó chỉ được viết cho một nhóm người dùng tưởng tượng, còn người dùng thật thì hỏi khác.

Kỹ năng cần có ở đây không phải viết thêm test thật nhanh. Bạn cần biến trace production của khách hàng thành bộ eval thật, và lặp lại việc đó đều đặn cho đến khi bàn giao.

## Vì sao bộ test trước launch luôn lệch?

Braintrust mô tả vấn đề khá thẳng: khi tự tay viết test case, bộ eval sẽ nghiêng về hành vi mà bạn kỳ vọng ở người dùng, chứ không phải hành vi thật của họ. Bạn viết những câu bạn nghĩ ra được.

Người dùng thật viết sai chính tả, dán nguyên email vào, hỏi hai việc trong một câu, hoặc dùng sản phẩm cho một việc không ai thiết kế.

Vì thế Anthropic tách hẳn một lớp giám sát production, bắt đầu chạy sau khi ra mắt. Lớp này dùng để phát hiện lệch phân phối và những lỗi ngoài đời thực mà không ai lường trước. Đã là lỗi không ai lường trước thì nó không thể nằm sẵn trong bộ test viết trước ngày launch.

Với phần mềm thường, đọc code là biết hệ thống sẽ làm gì. Với agent thì không: Harrison Chase của LangChain cho rằng nguồn sự thật đã chuyển từ code sang trace, tức bản ghi những gì agent thực sự làm, và trace production tự nó trở thành dataset đánh giá của bạn.

## Một vòng làm việc, đi từ đầu đến cuối

Thử hình dung một ví dụ: bạn triển khai một agent xử lý yêu cầu đổi trả cho một chuỗi bán lẻ. Agent đọc tin nhắn khách, tra đơn hàng qua tool, rồi quyết định duyệt, từ chối hoặc chuyển cho nhân viên. Tuần đầu sau go-live có vài nghìn trace.

**Bước 1: lấy mẫu có chủ đích, nhưng luôn giữ một phần ngẫu nhiên.** Hamel Husain và Shreya Shankar khuyên mỗi batch nên có một số trace chọn ngẫu nhiên. Nếu chỉ đọc trace bị gắn cờ (người dùng bấm "không hài lòng", tool trả lỗi), bạn chỉ thấy những lỗi đã ồn ào. Phần ngẫu nhiên là chỗ lộ ra những lỗi im lặng.

```python
import random

def sample_batch(all_traces, flagged, n=50, random_share=0.3):
# random_share là con số ví dụ, hãy tự điều chỉnh theo dự án
k_random = int(n * random_share)
picked = random.sample(all_traces, k_random)
picked_ids = {t["id"] for t in picked}
rest = [t for t in flagged if t["id"] not in picked_ids]
return picked + rest[: n - k_random]
```

**Bước 2: tự annotate trước, đừng nhờ máy vội.** Husain và Shankar đặt mức tối thiểu là 30 trace tự tay annotate, rồi mới xem gợi ý từ agent. Với mỗi trace, viết một dòng ngắn về chỗ đầu tiên agent đi sai, kiểu "gọi tool tra đơn bằng số điện thoại thay vì mã đơn". Chưa cần phân loại.

Đây là bước nhiều người muốn bỏ qua nhất. Nhưng hai tác giả này coi phân tích lỗi là hoạt động quan trọng nhất của eval. Mọi thứ phía sau đều dựa vào chất lượng của 30 dòng ghi chú này.

**Bước 3: gom thành pattern, rồi xếp hạng.** Braintrust gợi ý coi mỗi pattern đáng kể trong dữ liệu production là một eval slice ứng viên, và ưu tiên theo ba trục: volume, severity, rủi ro regression. Bảng dưới đây là ví dụ giả định cho agent đổi trả:

| Pattern (giả định) | Volume | Severity | Rủi ro regression |
|---|---|---|---|
| Khách gửi nhiều mã đơn trong một tin, agent chỉ xử lý mã đầu | Cao | Trung bình | Cao, dễ tái phát khi sửa prompt |
| Duyệt đổi trả cho đơn đã quá hạn chính sách | Thấp | Rất cao, mất tiền thật | Trung bình |
| Trả lời bằng giọng quá cứng với khách đang bực | Trung bình | Thấp | Thấp |

Pattern thứ hai ít gặp nhưng xếp trên cùng, vì một lần sai là thiệt hại tiền thật. Bảng này cũng là thứ bạn mang vào buổi họp với khách để cùng chốt thứ tự sửa.

**Bước 4: chuyển trace thành test case.** Anthropic khuyên biến lỗi do người dùng báo thành test case, để bộ eval phản ánh đúng cách sản phẩm được dùng. Giữ nguyên input gốc, kể cả lỗi chính tả, và ghi rõ hành vi đúng:

```python
case = {
"id": "return-expired-policy-017",
"source_trace": "trace_8f2c...",
"slice": "expired_policy",
"input": "TIN_NHAN_GOC_CUA_KHACH (giữ nguyên)",
"tool_state": {"order_date": "...", "policy_days": "..."},
"expected": "từ chối hoặc chuyển nhân viên, không tự duyệt",
}
```

**Bước 5: viết evaluator, rồi kiểm chính evaluator.** Nguyên tắc của Husain và Shankar là viết evaluator cho lỗi bạn đã phát hiện, không phải lỗi bạn tưởng tượng. Pattern "duyệt đơn quá hạn" có thể kiểm bằng code thuần, so ngày đơn với chính sách. Pattern "giọng quá cứng" có lẽ cần LLM làm grader.

Grader cũng sai được. Anthropic nói rõ bạn sẽ không biết grader có hoạt động tốt hay không nếu không đọc transcript và điểm chấm của nhiều lần chạy. Cách đơn giản nhất là đặt điểm của grader cạnh annotation của chính bạn ở bước 2:

```python
def check_grader(rows):
# rows: [{"trace_id": ..., "human": "pass"/"fail", "grader": "pass"/"fail"}]
disagree = [r for r in rows if r["human"] != r["grader"]]
agreement = 1 - len(disagree) / len(rows)
return agreement, disagree  # đọc lại transcript của từng trace bị lệch
```

Con số agreement chỉ cho bạn biết có vấn đề hay không. Danh sách `disagree` mới là thứ cần đọc: mở từng transcript, xem grader sai ở đâu, sửa grader trước khi tin vào bất kỳ con số nào nó trả về.

**Điểm mấu chốt:** Trace production không phải log để lưu trữ. Đó là đề bài thật mà người dùng đặt ra cho agent mỗi ngày.

## Những cái bẫy hay gặp

Bẫy đầu tiên là coi bộ test trước launch là xong việc và chỉ thêm case khi có người phàn nàn. Anthropic cảnh báo rằng dựa chủ yếu vào người dùng để bắt lỗi sẽ gây ảnh hưởng xấu cho chính họ. Với FDE, cái giá còn là niềm tin của nhà tài trợ dự án phía khách hàng.

Bẫy thứ hai là chỉ đọc trace bị gắn cờ. Nhìn qua thì có vẻ hiệu quả, nhưng như vậy bạn chỉ đo được loại lỗi khiến người dùng bấm nút, còn những lần agent sai một cách trơn tru thì bỏ lọt.

Bẫy thứ ba là để LLM phân loại lỗi ngay từ đầu. Nếu chưa tự đọc đủ trace, bạn không có chuẩn nào để biết gợi ý của máy đúng hay sai. Bẫy thứ tư đi cùng với nó: dựng cả chục evaluator cho những rủi ro nghe hợp lý trong buổi brainstorm, trong khi dữ liệu thật chưa từng cho thấy chúng.

## Biến kỹ năng này thành lợi thế khi đi xin việc

Khi đọc JD của các vị trí FDE hay AI engineer làm với khách hàng, hãy để ý những cụm như "production monitoring", "error analysis", "eval dataset from traces". Thấy chúng, bạn nên chuẩn bị sẵn câu chuyện về một vòng lặp như trên, lấy từ chính dự án của mình.

Trong CV, đừng chỉ ghi "xây dựng hệ thống eval". Hãy kể lại một vòng lặp: bạn đã annotate bao nhiêu trace, tìm ra pattern nào, xếp ưu tiên ra sao, thêm bao nhiêu test hồi quy. Khi phỏng vấn, kể chi tiết một pattern lỗi cụ thể sẽ thuyết phục hơn mọi định nghĩa về eval.

Ngày go-live không đánh dấu việc eval đã xong. Từ ngày đó trở đi, khách hàng mới bắt đầu cho bạn biết bộ eval của bạn còn thiếu những gì.

**Thử ngay tuần này:**

- Lấy 30 trace từ một agent hoặc chatbot bạn đang vận hành (hoặc từ một demo cá nhân có log), tự ghi một dòng nhận xét cho mỗi trace mà không dùng LLM gợi ý.
- Gom các nhận xét đó thành 3-5 pattern lỗi, chấm điểm sơ bộ theo volume, severity, rủi ro regression, rồi biến pattern ưu tiên cao nhất thành ít nhất một test case có input lấy từ trace thật.
- Viết lại một dòng trong CV theo mẫu: 'Dựng vòng eval từ trace production: annotate X trace, phát hiện Y pattern lỗi, thêm Z test case hồi quy'.

## Nguồn

- [Demystifying evals for AI agents](https://www.anthropic.com/engineering/demystifying-evals-for-ai-agents)

- [Agent observability powers agent evaluation](https://www.langchain.com/conceptual-guides/agent-observability-powers-agent-evaluation)

- [How to analyze AI agent usage patterns to build eval datasets (2026)](https://www.braintrust.dev/articles/analyze-ai-agent-usage-patterns-eval-datasets-2026)

- [AI Evals: Everything You Need to Know – Hamel's Blog](https://hamel.dev/blog/posts/evals-faq/)
