Tái hiện được lỗi mới chỉ thấy triệu chứng. Root cause analysis (RCA) tìm nguyên nhân gốc — thứ mà sửa nó thì lỗi biến mất và không tái phát. Agent hỗ trợ RCA bằng cách thu thập bằng chứng (log, stack trace, diff), lập giả thuyết và loại trừ có hệ thống.
Khung tư duy: 5 Whys + Giả thuyết
5 Whys: hỏi "tại sao" liên tiếp cho tới khi chạm nguyên nhân có thể sửa được.
Triệu chứng: Export CSV trả 504
1. Tại sao? -> Request quá 30s bị gateway cắt
2. Tại sao lâu? -> Query gom 12 tháng quét toàn bảng
3. Tại sao quét toàn bảng? -> Thiếu index trên cột created_at
4. Tại sao thiếu index? -> Migration thêm cột nhưng quên index
=> Nguyên nhân gốc: thiếu index created_at (sửa được)
Quan trọng: agent phải làm việc theo giả thuyết có thể bác bỏ, không đoán bừa. Mỗi giả thuyết đi kèm cách kiểm chứng.
Các bước RCA cùng agent
- Thu thập bằng chứng: stack trace, log quanh thời điểm lỗi, request/response, và
git log/diff gần nhất chạm vùng code. - Định vị vùng nghi ngờ từ stack trace (file:line trên cùng của mã ta sở hữu, bỏ qua thư viện).
- Sinh 2–3 giả thuyết kèm cách kiểm chứng cho mỗi cái.
- Loại trừ bằng bằng chứng: cái nào mâu thuẫn với log thì bỏ.
- Xác nhận nguyên nhân gốc bằng một phép thử tối thiểu (tắt/bật, đổi input).
hypotheses = [
{"h": "Thiếu index created_at", "test": "EXPLAIN query -> Seq Scan?"},
{"h": "N+1 query trong vòng lặp", "test": "đếm số query/response"},
{"h": "Timeout gateway quá thấp", "test": "đo thời gian query thô"},
]
Đọc stack trace đúng cách
- Đọc từ trên xuống: dòng đầu là nơi ném lỗi; tìm frame đầu tiên thuộc code của bạn.
- Phân biệt nơi lỗi phát ra với nơi lỗi gây ra: NullPointer bắn ở A nhưng giá trị null được set ở B.
- Dùng git bisect khi biết "trước đây chạy tốt": nhị phân qua các commit để tìm commit gây hồi quy.
Correlation vs Causation
Agent hay mắc bẫy: thấy hai thứ xảy ra cùng lúc rồi kết luận cái này gây cái kia. Luôn ép agent kiểm chứng bằng phép thử can thiệp (đổi X, xem lỗi có đổi không) trước khi chốt.
Checklist RCA
[ ] Có stack trace / log đúng thời điểm lỗi
[ ] Đã định vị frame code của mình (không phải thư viện)
[ ] Có >= 2 giả thuyết, mỗi cái có cách kiểm chứng
[ ] Đã loại trừ giả thuyết mâu thuẫn bằng chứng cứ
[ ] Nguyên nhân gốc SỬA ĐƯỢC (không phải "do người dùng sai")
[ ] Đã xác nhận bằng phép thử can thiệp
Sai lầm thường gặp
- Dừng ở triệu chứng ("thêm try/catch cho hết crash") thay vì nguyên nhân gốc → lỗi âm thầm quay lại.
- Nhầm tương quan thành nhân quả → sửa nhầm chỗ.
- Đọc stack trace từ dưới lên hoặc dừng ở frame thư viện → định vị sai file.
- Chốt một giả thuyết mà không loại trừ cái khác → bỏ sót nguyên nhân thật.
- Không dùng git bisect với lỗi hồi quy → dò tay tốn hàng giờ.
<!--les-append-->
Ba bẫy RCA mà agent mắc thường xuyên nhất
| Bẫy | Biểu hiện cụ thể | Câu lệnh chặn |
|---|---|---|
| Dừng ở nguyên nhân gần nhất | "Query chậm" — đúng nhưng chưa sửa được | "Tiếp tục hỏi tại sao cho tới khi chạm một thay đổi code hoặc cấu hình cụ thể" |
| Chọn giả thuyết đầu tiên khớp | Thấy thiếu index là kết luận ngay | "Nêu 3 giả thuyết và bằng chứng bác bỏ cho từng cái" |
| Nguyên nhân gốc là con người | "Do dev quên thêm index" | "Nguyên nhân gốc phải là thứ sửa được bằng code, test, hoặc quy trình" |
Câu hỏi thứ năm mà 5 Whys thường bỏ
Sau khi tìm ra nguyên nhân gốc, thêm một câu:
> "Vì sao chúng ta không phát hiện điều này sớm hơn?"
Ví dụ với bug index: nguyên nhân gốc là thiếu index. Nhưng câu hỏi thứ năm cho một phát hiện khác — không có test nào chạy trên dữ liệu đủ lớn để lộ ra vấn đề hiệu năng. Sửa cái thứ hai ngăn được cả một họ lỗi, không chỉ lỗi này.
Đây là phần biến RCA từ việc sửa một bug thành việc cải thiện hệ thống. Nó gần như luôn cho một việc đáng làm, và nó gần như luôn bị bỏ vì lúc đó ai cũng muốn đóng ticket.
Khi nào dừng đào
5 Whys không có nghĩa là đúng năm lần. Dừng khi cả ba điều kiện đạt:
- Nguyên nhân sửa được bằng một thay đổi cụ thể.
- Sửa nó thì lỗi biến mất — đã xác nhận bằng phép thử can thiệp.
- Đào thêm một bước nữa chỉ ra những nguyên nhân về tổ chức, không về hệ thống ("vì chúng ta thiếu người").
Git bisect: nêu rõ vì sao nó mạnh
Với lỗi hồi quy, git bisect cho bạn commit gây lỗi trong khoảng log(n) bước — 10 bước cho 1.000 commit. Điều quan trọng với agent: nó cần một lệnh kiểm tự động trả về pass/fail để bisect chạy được. Nếu bạn đã có MCPE từ bài 3, bạn đã có lệnh đó. Đây là lý do thực dụng vì sao bước tái hiện phải làm trước và làm tử tế.
<!--/les-append-->