Product Management
Đăng nhập
ESC

Nhập từ khóa để tìm kiếm

↑↓ Di chuyển
Enter Mở
ESC Đóng

Bài 5 — Verify từng bước: đừng tin agent, hãy để máy kiểm chứng

Đã đọc 0/7 mục · còn khoảng 3 phút
Cách chúng tôi ghi nhận

Một mục được tính là đã đọc khi nó nằm giữa màn hình đủ lâu so với độ dài của nó (bảng và sơ đồ tính một nửa), bạn vẫn đang cuộn hoặc bấm phím, và bạn đã thấy tới cuối mục. Lướt nhanh hoặc để tab mở không được tính. Chúng tôi chỉ lưu thời gian đọc từng mục — không lưu gì khác.

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/billing phả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, skip test).
  • 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ô.
Verify là cột sống của cả khóa học. Bài sau ta lắp mọi thứ lại thành một vòng lặp agent tự vận hành: plan → làm → verify → sửa → commit.

Học xong bài này rồi? Tạo tài khoản miễn phí để lưu lại — lần sau vào là biết ngay đang dở ở đâu, và học hết khóa thì có chứng chỉ. Lưu tiến độ của tôi