Agent rất giỏi tạo ra code trông đúng. "Trông đúng" và "đúng" là hai chuyện khác nhau. Trong refactor quy mô lớn, một sai lệch ngữ nghĩa nhỏ nhân lên 500 lần thành thảm họa. Nguyên tắc cốt lõi: không tin mắt, không tin lời agent — chỉ tin máy kiểm chứng khách quan.
Thang bậc verify (từ rẻ đến đắt)
Sắp xếp kiểm tra theo tốc độ, chạy cái rẻ trước để fail nhanh:
1. Lint / format (giây) -> bắt lỗi cú pháp, style
2. Typecheck (giây-phút) -> bắt sai kiểu, sai signature
3. Build / compile (phút) -> bắt lỗi liên kết
4. Unit test (phút) -> bắt sai hành vi cục bộ
5. Integration/e2e (nhiều phút) -> bắt sai tích hợp
6. So sánh hành vi (tùy) -> bằng chứng mạnh nhất (dưới đây)
Trong vòng lặp từng file, chạy tầng 1–4. Cuối mỗi lô, chạy đủ tới tầng 5.
Vũ khí mạnh nhất: so sánh hành vi (characterization / golden test)
Refactor đúng nghĩa là đổi cấu trúc mà giữ nguyên hành vi. Vậy cách chứng minh mạnh nhất là so sánh output trước/sau:
# Trước khi refactor: ghi lại hành vi hiện tại làm "vàng"
git switch main
node run-scenarios.js > golden.txt
# Sau khi agent refactor:
git switch migrate/reports
node run-scenarios.js > after.txt
diff golden.txt after.txt # RỖNG = hành vi không đổi = an toàn
Với migration có đổi hành vi có chủ đích, hãy tách phần "đáng lẽ giữ nguyên" và phần "cố ý đổi", chỉ diff phần đầu.
Vì sao "build xanh" chưa đủ
Ví dụ agent đổi fetchUser sang trả Result:
// Agent viết — biên dịch xanh, test cũ vẫn qua vì test không kiểm nhánh lỗi
const r = await getUser({ userId });
return r.value; // BUG: khi r.error, r.value là undefined, im lặng nuốt lỗi
Build xanh, thậm chí một số test xanh, nhưng nhánh lỗi bị nuốt. Chỉ characterization test hoặc test bao phủ nhánh lỗi mới bắt được. Do đó độ phủ test là điều kiện tiên quyết của migration an toàn — thiếu thì phải bổ sung test trước khi refactor.
Quy trình verify mỗi lô
- Agent làm xong lô, tự chạy
verify.sh(lint→typecheck→build→test). - Chạy characterization diff so với golden của lô đó.
- Kiểm điều kiện hoàn thành theo goal: ví dụ
grep -rc "moment" src/billingphải = 0. - Đọc lướt diff của agent tìm dấu hiệu "làm xanh gian lận" (xóa assertion,
@ts-ignore,skiptest). - Chỉ khi cả 4 pass mới đổi manifest lô đó thành
done.
Checklist chống "xanh giả"
[ ] Có test bao phủ nhánh lỗi, không chỉ happy path?
[ ] Diff có xuất hiện @ts-ignore / eslint-disable / .skip mới không?
[ ] Có assertion nào bị xóa/nới lỏng không?
[ ] Số test passed KHÔNG tụt so với baseline?
[ ] Characterization diff rỗng (hoặc chỉ chứa thay đổi có chủ đích)?
[ ] Điều kiện goal (grep = 0) đã đạt?
Sai lầm thường gặp
- Coi build/typecheck xanh là đã đúng: bỏ lọt lỗi ngữ nghĩa và nhánh lỗi.
- Tin bản tự đánh giá của agent ("tôi đã kiểm tra kỹ, mọi thứ ổn"): đó là văn bản, không phải bằng chứng.
- Không có golden/characterization khi codebase thiếu test: refactor mù, không có gì bảo chứng hành vi.
- Cho phép agent nới test để làm xanh: che giấu regression thật.
- Verify quá nặng nên bỏ giữa chừng: hãy phân tầng, chạy nhanh trong vòng lặp, đầy đủ ở cuối lô.