04Quy trình ship với AIĐào sâu ③

Bug đắt nhất là bug để build xanh

Bắt agent đọc bán kính ảnh hưởng trước khi cho nó đụng đồ dùng chung

Đăng2026-05-30
Đọc3 phút đọc
LoạiGhi chép thực chiến
TL;DR

Bug đáng sợ nhất không phải bug làm build đỏ, mà bug để build xanh rồi nổ ở nơi khác. Trước khi agent đổi một thứ dùng chung, bắt nó liệt kê "ai đang phụ thuộc vào cái này".

Hai giờ sáng, điện thoại tôi réo. Production đỏ lừ. Tôi mò dậy, dò log, lần ngược… tới một thay đổi đã merge ba ngày trước — một thay đổi nhỏ xíu, lúc đó build xanh, test xanh, review lướt cũng xanh.

Đó là lúc tôi thấm: bug làm build đỏ chẳng đáng sợ. Nó nổ ngay trước mặt, khi bạn còn nhớ vừa đụng gì. Đáng sợ là loại để mọi thứ xanh — rồi nằm im chờ.

Và đây đúng là loại bug một agent giỏi tạo ra nhiều nhất.

01Vì sao agent mù chiều này

Agent nhìn thấy cái file trước mặt. Nó không thấy đồ thị lời gọi — cái mạng nhện những chỗ khác đang dựa vào đoạn nó sắp sửa. Tệ hơn: nó mất trí nhớ về phần còn lại của hệ thống. Bạn mở một hàm ra cho nó, nó sửa đúng cái hàm đó, gọn gàng — và hoàn toàn không biết có mười hai nơi đang trông cậy vào hành vi cũ.

12 nơi khác đang gọi
một hàm serialize
nổ lúc 2h sáng
một cột database
đổi 1 field

Một thay đổi tưởng nhỏ, sóng lan ra mọi nơi đang phụ thuộc. Agent chỉ thấy tâm sóng — không thấy vòng ngoài.

02Cái gì là "dùng chung"

Quy tắc: trước khi đổi bất cứ thứ gì nằm trên một ranh giới mà người hay đoạn-code khác dựa vào, hãy dừng. Danh sách hay là ranh giới: chữ ký hàm (đổi tham số, kiểu trả về), shape dữ liệu (thêm/bớt field), tên một field/key (nhất là thứ đi qua serialize, lưu DB, gửi qua API), hàm tiện ích dùng chung, config, một hợp đồng API công khai.

Sửa bên trong thân một hàm, không đụng ranh giới ngoài? An toàn, cứ để nó làm. Vượt một ranh giới người khác dựa vào? Vẽ bản đồ trước.

03Bắt nó vẽ bản đồ trước

Trước khi sửa, ép agent trả lời đúng một câu: "Cái gì đang phụ thuộc vào nó?" Và bắt nó liệt kê ra, không nói chung chung. Có công cụ phân tích phụ thuộc thì dùng — vài giây có danh sách. Không có thì câu lệnh tối thiểu: bắt nó grep cái tên đó toàn repo và bày từng nơi đọc/gọi ra cho bạn xem trước khi đụng dòng nào.

04Một ví dụ rất quen

Đổi tên một field từ userId thành accountId. Nghe như một thao tác rename.

Thực tế nó chạm: mười bốn chỗ đọc field, một hàm serialize ra JSON, một chỗ map sang cột database, và hai chuỗi nối tay mà rename tự động không bắt được. Agent không vẽ bản đồ sẽ đổi ba chỗ rõ nhất, báo "Done!", và để lại mười lăm quả mìn — mỗi quả chờ một code path khác kích nổ.

Chi phí bắt nó liệt kê phụ thuộc là ba mươi giây. Chi phí bỏ qua là một cú điện thoại lúc hai giờ sáng. Tôi biết rõ cái giá thứ hai — tôi trả nó rồi.

Hết bàiCụm 04 · 4/5
Người viết

craftagent là ghi chép của một người đang xây — kể bằng giọng cà phê, mỗi câu chuyện gói một bài học đã trả giá để học.