Phần IV · Production & Improve Chương 11

Phân tích dữ liệu trace: từ pattern đến giả thuyết đã kiểm chứng

Chapter 11 — Data Analysis for Traces

TL;DR

  • Error analysis đọc từng trace; data analysis nhìn cả tập trace để quyết định nên đọc kỹ trace nào.
  • Cluster, biểu đồ, tương quan, outlier chỉ sinh giả thuyết — không phải failure mode. Luôn quay lại đọc trace thật.
  • Xác nhận giả thuyết: đọc ~20 trace → viết tiêu chí kiểm được → tiêu chí đúng cho 70–80% cụm.
  • Semantic search mở rộng một ví dụ lỗi thành cả quần thể lỗi; coi chừng "cùng chủ đề" ≠ "cùng lỗi".
  • AI coding assistant: để nó tìm, tóm tắt, search, vẽ — không để nó kết luận nguyên nhân.

11.1Từ đọc từng trace đến nhìn cả tập

EDA (Exploratory Data Analysis) là việc "chọc ngoáy" dữ liệu để nảy ra giả thuyết — thuật ngữ John Tukey (cha đẻ box plot) đưa ra như đối trọng với confirmatory analysis (fit model, chạy kiểm định). Muốn xác nhận gì thì trước hết phải biết xác nhận cái gì; EDA trả lời câu đó. Error analysis ở Chương 3 thực chất cũng là EDA trên văn bản.

🫧
Clustering
hypothesis generation

Gom trace giống nhau, đọc vài đại diện mỗi cụm, hỏi "khác biệt giữa các cụm gợi ý agent sai ở đâu?".

📊
Metric theo trace
per-trace metrics

Turns, latency, tool call, token, sentiment… — phân phối, bảng chéo, tương quan, outlier.

🔎
Semantic search
expand a failure mode

Từ 1–2 ví dụ lỗi, tìm thêm trace tương tự để biết lỗi phổ biến cỡ nào.

🤖
AI coding assistant
Claude Code · Codex

Tăng tốc phần cơ học (nạp, vẽ, tìm) — không thay bạn suy luận.

Sai lầm số 1

Coi một cụm là một failure mode. Cụm, biểu đồ cột, hệ số tương quan… đều chỉ là lời nhắc đi đọc trace bên dưới. Vòng lặp đúng: giả thuyết thô → chọn một lát dữ liệu → đọc → làm sắc hoặc bỏ. Phần lớn giả thuyết đầu tiên sẽ bị bỏ — đó là chuyện bình thường.

11.2Clustering để sinh giả thuyết

Đôi khi cluster xong chẳng thấy gì mới: các cụm khó phân biệt, hoặc chỉ ra những nhóm ai cũng biết (hỏi về căn hộ / hỏi về nhà phố). Đó vẫn là thông tin: hoặc embedding không bắt được biến thiên bạn quan tâm, hoặc biến thiên đó không phải trục chính của dữ liệu.

Trợ lý bất động sản Cluster theo embedding của câu hỏi người dùng → ra các nhóm hiển nhiên: đặt lịch xem nhà, tìm nhà, soạn email.

Hữu ích để hiểu phân bố tác vụ, nhưng không nói gì về chỗ agent sai.

Đổi sang cluster theo embedding của email agent viết ra → xuất hiện một nhóm nhỏ email đều mở đầu bằng lời xin lỗi dài dòng trước khi đưa ra bất kỳ căn nhà nào.

Đây là lỗi giọng văn mà vòng error analysis trước đã bỏ sót. Bài học: nếu cụm vô vị, đổi thứ đem đi embed.

11.3Metric theo từng trace

Ngoài clustering, tính cho mỗi trace: số lượt, latency, số tool call, token vào/ra, sentiment, phân khúc người dùng, giờ trong ngày. Rồi xem chúng phân bố, tương quan và tách theo metadata ra sao.

Hình dạng phân phối nói gì?

Một đỉnh unimodal Hai đỉnh bimodal Đuôi dài long-tailed nhóm A nhóm B đuôi Đọc outlier hai đầu 2 nhóm / 2 lỗi trộn lẫn → tách ra, đọc từng nhóm Vài trace cực lớn → đọc riêng phần đuôi
Histogram minh hoạ (số liệu bịa) của một metric như turns/phiên hoặc latency. Hình dạng quyết định bước đọc tiếp theo.
Kỹ thuậtLàm gìTín hiệu đáng đào tiếp
Phân phối
histogram · box plot
Xem hình dạng một metricHai đỉnh, đuôi dài bất thường
Bảng chéo
cross-tab
Tỷ lệ thumbs-down theo persona, phiên bản agent, giờ, độ dài phiênMột nhóm có tỷ lệ lỗi vượt trội (vd phiên dài lỗi nhiều hơn)
Tương quanTool call vs latency; tool call vs thumbs-downCó liên hệ rõ → đào sâu (xem confounder ở 11.7)
Lọc lát rồi đọcLấy một lát (thumbs-down, >5 lượt, có tool X) và đọc ~20 trace liền một mạchPattern chỉ lộ ra khi đọc dồn, không lộ khi đọc lẻ tẻ
Săn outlierGắn cờ trace có metric lệch hẳnHai quy tắc: IQR hoặc cắt percentile

Quy tắc outlier IQR

0s 5s 10s 15s 20s latency Q1 Q3 IQR = Q3 − Q1 rào trên = Q3 + 1.5·IQR outlier → đọc kỹ Phương án thay thế: cắt 1% trên + 1% dưới
Minh hoạ (số liệu bịa). Dùng quartile thay vì mean nên bền với dữ liệu lệch — vài phiên cực chậm kéo mean chứ không kéo Q1/Q3.

Một đoạn minh hoạ ngắn (tự viết) để gắn cờ outlier bằng IQR trên file trace:

import pandas as pd

df = pd.read_json("traces.jsonl", lines=True)
q1, q3 = df["latency_s"].quantile([0.25, 0.75])
iqr = q3 - q1
mask = (df["latency_s"] < q1 - 1.5 * iqr) | (df["latency_s"] > q3 + 1.5 * iqr)
to_read = df[mask].sample(min(20, mask.sum()))   # đọc tối đa 20 cái

11.4Từ cụm đến giả thuyết đã xác nhận

Một cụm trông như "mơ hồ về địa điểm" có thể gồm nhiều lỗi khác nhau chỉ trông giống nhau ở output. Trước khi hành động, chạy một giao thức xác nhận nhẹ.

Toàn bộ trace log production EDA cluster · phân phối outlier · search Giả thuyết pattern ≠ kết luận ① Đọc ~20 trace trong cụm, liền mạch ② Tiêu chí kiểm được, cụ thể ③ Đúng cho ≥70–80%? Failure mode → vào taxonomy rồi search đo quy mô không Tách cụm / bỏ cụm quá lẫn lộn tách / làm sắc lại giả thuyết Phần lớn giả thuyết đầu sẽ bị bỏ — bình thường.
Clustering → giả thuyết → xác nhận. Chỉ pattern qua được bước ③ mới được gọi là failure mode.
  1. Đọc kỹ khoảng 20 trace trong cụm ứng viênKhông lướt nhãn cụm — đọc nội dung thật.
  2. Viết một tiêu chí kiểm đượcVí dụ: "agent hiểu tên khu phố thành tên thành phố". Phải trả lời được có/không cho từng trace.
  3. Đếm: tiêu chí đúng cho 70–80% trace trong cụm?Có → pattern thật, thêm vào taxonomy. Không → cụm không đồng nhất, tách nhỏ hoặc xem lại.

Khi LLM trích feature để cluster

Nếu bạn nhờ LLM trích feature (vd "loại lỗi của trace này là gì") rồi cluster trên đó, hãy kiểm độ chính xác trích xuất trên một tập nhỏ gán nhãn tay trước. Dưới ~90% thì các cụm xây trên đó không đáng tin → dùng rule-based hoặc gán tay cho những feature quan trọng nhất.

11.5Semantic search: tìm thêm trace giống lỗi đã thấy

Error analysis thường chỉ lộ ra 1–2 ví dụ xấu. Câu hỏi thật là: lỗi này phổ biến cỡ nào, và có dồn vào phân khúc người dùng nào không? Semantic search (embedding) giúp mở rộng ví dụ thành quần thể.

Lấy một trace có lỗi (vd email mở đầu bằng lời xin lỗi) → tìm các láng giềng gần nhất theo embedding → đọc danh sách xếp hạng.

Dùng khi đã có một ví dụ điển hình.

Viết mô tả pattern cần tìm (vd "email xin lỗi trước khi đưa ra căn nhà nào") → embed chính câu mô tả → tìm.

Dùng khi biết pattern trông thế nào nhưng chưa có ví dụ chuẩn.

Cho LLM trích feature riêng của ứng dụng từ mỗi trace — có đặt lịch xem nhà không? có nhắc giờ trùng không? có trả lời vòng vo không? — hoặc một tóm tắt ngắn, rồi embed cái đó thay vì trace thô.

LLM có thể tự đề xuất danh sách feature nếu bạn đưa vài ví dụ lỗi. Kết quả: khái niệm "giống nhau" gần với ý bạn hơn.

Độ giống embedding ≠ độ giống bạn cần

Hai trace có thể nằm gần nhau chỉ vì cùng chủ đề ("đặt lịch xem nhà") trong khi lỗi bạn săn hẹp hơn nhiều ("đặt trùng hai lịch xem"). Nếu có vài nhãn, đo precision (bao nhiêu kết quả thật sự là lỗi đó) và recall (bắt được bao nhiêu % lỗi có nhãn); chỉnh ngưỡng similarity hoặc đổi model embedding.

11.6Dùng AI coding assistant mà không để nó "bịa" phân tích

Setup điển hình: một thư mục chứa file trace (JSON/JSONL), mô tả ngắn về ứng dụng và ý nghĩa từng field, và (nếu cần) code của app → mở phiên Claude Code / Codex tại đó và dùng làm scratchpad.

✓ Giao cho assistant
find · summarize · search · plot

• Vẽ phân phối (vd histogram turns/phiên, trục y log, tách theo phân khúc)
• Xin nhiều biểu đồ một lúc, chỉ đọc cái bất thường
• Phác regex / rubric từ vài ví dụ lỗi
• Tóm tắt một cụm trace
• Tìm trực tiếp pattern trong trace

✗ Đừng giao cho assistant
"why are these failing?"

Hỏi "vì sao các trace này hỏng" → nhận một lời giải thích nghe rất hợp lý, rất tự tin, dựng từ vài ví dụ nó thấy — nhưng có thể sai, và rất khó nhận ra là sai.

Mọi khẳng định nhân quả = giả thuyết.

"Stick to asking the AI agent to find, summarize, search, or plot."— Shankar & Husain, Ch.11

Tìm trực tiếp hay dựng index embedding?

Quy mô traceCách tìm pattern
Vừa context window (vài nghìn trace ngắn)Cho agent tìm thẳng trong file — bỏ qua bước dựng embedding index
Vượt context window (hàng chục nghìn, hoặc trace dài)Quay về semantic search / index chuẩn

Kiểm một giải thích nhân quả

  1. Viết giải thích thành giả thuyết cụ thểVd "lỗi do mô tả tool thiếu định dạng ngày".
  2. Đổi đúng một biếnSửa prompt, thay tool, hoặc chỉnh một tham số — không đổi nhiều thứ cùng lúc.
  3. Chạy golden set trước và sauGiả thuyết đúng → tỷ lệ của đúng failure mode đó phải giảm. Không giảm → giải thích sai, dù nghe thuyết phục đến đâu.

11.7Pitfalls thường gặp

Confounder: đừng vội tin tương quan

Nhìn gộp tỷ lệ lỗi theo số tool call 10% 30% ≤5 tool call >5 tool call "Tool call gây lỗi!"? Phân tầng theo độ khó stratify by query complexity 8% 9% Câu hỏi dễ 34% 36% Câu hỏi khó Trong từng tầng: gần như không khác → do độ khó ≤5 tool call >5 tool call
Số liệu minh hoạ (bịa). Câu hỏi khó vừa cần nhiều tool call vừa khó trả lời — tương quan gộp là do độ khó, không phải do tool call.

Ghép lại

Error analysis cho bạn taxonomy từ việc đọc kỹ. Data analysis thêm kỹ thuật tổng hợp: EDA/clustering để nảy giả thuyết, metric theo trace để thấy pattern không lộ khi đọc lẻ, semantic search để đo quy mô một lỗi. AI assistant tăng tốc phần cơ học — output của nó luôn là giả thuyết cần đối chiếu với trace thật.

Áp dụng cho dự án model-routing của bạn

  • Mỗi quyết định route là một trace có metric: model được chọn, domain, độ dài prompt, latency, cost, điểm judge/chất lượng. Vẽ chất lượng và cost theo model × loại request; latency hai đỉnh thường là hai nhánh route trộn lẫn → tách ra đọc.
  • Confounder độ khó là bẫy lớn nhất: request được đưa lên model lớn vốn đã khó hơn, nên "model lớn có tỷ lệ lỗi cao" không chứng minh router sai. Stratify theo độ khó (hoặc theo điểm của một judge độc lập) trước khi so.
  • Cluster theo feature trích xuất (loại tác vụ, cần reasoning nhiều bước, có code, có tool) thay vì prompt thô → tìm nhóm request bị route xuống model quá yếu. Kiểm feature extractor ≥ ~90% trên tập gán tay trước.
  • Dùng semantic search từ một ca route sai để ước lượng có bao nhiêu request tương tự — đó là con số cho biết lỗi này đáng sửa đến đâu.
  • Mỗi vòng review: kèm mẫu ngẫu nhiên request, không chỉ những ca bị escalate hay bị người dùng chê.

Tự kiểm tra

Bạn cluster trace và thấy một cụm lớn tên "sai giọng văn". Có thể thêm ngay vào taxonomy lỗi không?
Chưa. Nhãn cụm là giả thuyết. Đọc ~20 trace trong cụm, viết tiêu chí kiểm được, và chỉ thêm vào taxonomy nếu tiêu chí đúng cho khoảng 70–80% cụm.
Cluster trên embedding của câu hỏi người dùng chỉ ra các nhóm ai cũng biết. Nên làm gì?
Đó là tín hiệu embedding không bắt được trục biến thiên bạn cần. Đổi thứ đem embed — vd output của agent, hoặc feature do LLM trích ra — rồi cluster lại.
Vì sao quy tắc IQR hợp với metric trace hơn quy tắc dựa trên mean ± độ lệch chuẩn?
Metric trace (latency, token, số lượt) thường lệch: vài phiên cực lớn kéo mean và độ lệch chuẩn, nhưng không kéo quartile. IQR vì thế bền hơn.
Trace có >5 tool call lỗi gấp 3 lần. Kết luận "giảm tool call sẽ giảm lỗi" được chưa?
Chưa. Có thể có confounder — câu hỏi khó vừa cần nhiều tool call vừa khó trả lời. Stratify theo độ khó; nếu trong từng tầng không còn khác biệt thì tool call không phải nguyên nhân.
Claude Code đưa ra lời giải thích rất thuyết phục cho một nhóm lỗi. Bước tiếp theo?
Coi đó là giả thuyết. Đổi đúng một biến theo giả thuyết (prompt, tool, tham số), chạy golden set trước/sau: tỷ lệ của failure mode đó phải giảm. Không giảm → giải thích sai.
Semantic search trả về nhiều trace cùng chủ đề nhưng không có lỗi bạn đang tìm. Xử lý thế nào?
Đó là precision thấp. Đo precision/recall trên vài nhãn, chỉnh ngưỡng hoặc đổi embedding model; tốt hơn là embed feature riêng của ứng dụng hoặc tóm tắt ngắn thay vì trace thô.