AILapTrinh.comAI Lập Trình
Gỡ lỗi cùng AI

Khoanh vùng lỗi bằng chia đôi và git bisect: tìm commit gây hỏng, để AI đọc đúng chỗ

Khi không có thông báo lỗi rõ, chia đôi mã và lịch sử commit để khoanh vùng. Lệnh git bisect từng bước, kịch bản kiểm tự động, câu lệnh cho AI.

Developer working late at a home desk in Hai Phong, laptop and second monitor both blank, desk lamp glow, sticky notes without writing, hands on keyboard, seen from behind

Khi lỗi không để lại thông báo rõ ràng, hoặc thông báo trỏ vào chỗ chẳng liên quan, việc đầu tiên là khoanh vùng: thu hẹp dần nơi lỗi có thể nằm cho tới khi chỉ còn vài dòng. Cách khoanh vùng chắc tay nhất là chia đôi, áp dụng cho mã, cho dữ liệu và cho cả lịch sử commit qua lệnh git bisect.

AI rất giỏi đọc một đoạn mã ngắn và nói nó sai ở đâu, nhưng kém hơn hẳn khi phải đoán lỗi nằm ở đâu trong một dự án vài trăm tệp. Bài này hướng dẫn bạn làm phần khoanh vùng một cách có hệ thống, rồi mới đưa cho AI đúng mảnh mã cần đọc. Kết quả là ít vòng hỏi đáp hơn và ít cách sửa trật hơn.

Vì sao chia đôi nhanh hơn đoán

Nếu lỗi có thể nằm ở một trong một nghìn chỗ, đoán từng chỗ là việc may rủi. Chia đôi thì khác: mỗi lần kiểm loại được một nửa số chỗ còn lại. Một nghìn chỗ chỉ cần khoảng mười lần kiểm là còn một, vì hai mũ mười là một nghìn không trăm hai mươi bốn. Đây là lý do người trong nghề tin vào chia đôi hơn vào linh cảm, kể cả linh cảm của AI.

Chia đôi áp dụng được ở ba trục. Trục mã: tắt một nửa các bước xử lý, xem lỗi còn không. Trục dữ liệu: chạy với một nửa tệp đầu vào, xem lỗi nằm ở nửa nào. Trục thời gian: lỗi chưa có ở bản tuần trước, đã có ở bản hôm nay, vậy nó được đưa vào bởi commit nào ở giữa. Mỗi trục hợp với một loại lỗi khác nhau, và nhiều khi bạn dùng kết hợp.

AI giúp được ở việc đề xuất cách chia. Ví dụ giả định: bạn mô tả một luồng xử lý có tám bước, từ đọc tệp tới ghi báo cáo, và lỗi là tổng tiền cuối cùng lệch. Một câu lệnh như “Đề xuất cách chia đôi luồng tám bước này để tìm bước làm lệch số, mỗi lần kiểm cần in gì” sẽ cho bạn kế hoạch kiểm gọn gàng hơn tự nghĩ. Nhưng việc chạy và đọc kết quả vẫn là của bạn.

Dùng git bisect từng bước

Lỗi hồi quy là lỗi xuất hiện sau một thay đổi: tính năng vốn chạy tốt, bỗng một ngày hỏng. Với dự án dùng git, lệnh bisect làm việc chia đôi lịch sử thay bạn. Các lệnh dưới đây là lệnh git chuẩn, chạy trong thư mục dự án.

  1. Đảm bảo không có thay đổi chưa commit: chạy git status, nếu còn thì commit hoặc cất tạm bằng git stash.
  2. Bắt đầu phiên chia đôi bằng lệnh git bisect start.
  3. Đánh dấu bản hiện tại là hỏng bằng lệnh git bisect bad.
  4. Đánh dấu một bản cũ chắc chắn còn chạy tốt bằng git bisect good, kèm mã commit hoặc thẻ phiên bản, ví dụ git bisect good v1.4.0.
  5. Git tự chuyển sang một commit ở giữa. Chạy kiểm tra, rồi gõ git bisect good nếu còn tốt, git bisect bad nếu đã hỏng. Commit nào không dựng được vì lý do khác thì gõ git bisect skip.
  6. Lặp lại tới khi git in ra commit đầu tiên bị hỏng. Ghi mã commit đó lại.
  7. Kết thúc bằng git bisect reset để quay về nhánh ban đầu.

Với vài trăm commit, thường chỉ mất tám đến chín lần kiểm. Điều kiện quan trọng là bạn có một cách kiểm rõ ràng, cho ra tốt hoặc hỏng không mơ hồ. Nếu cách kiểm phải nhìn bằng mắt và cảm nhận, kết quả bisect dễ sai ở một bước giữa chừng và dẫn bạn tới commit vô can.

Cho bisect tự chạy bằng một kịch bản kiểm

Lệnh git bisect run. Thay vì gõ good, bad bằng tay, bạn đưa cho git một lệnh kiểm. Git chạy lệnh đó ở mỗi bước, mã thoát 0 nghĩa là tốt, mã thoát từ 1 tới 127 trừ 125 nghĩa là hỏng, riêng 125 nghĩa là bỏ qua commit này. Ví dụ: git bisect run python -m pytest tests/test_bao_cao.py -q.

Viết ca kiểm thử tái hiện lỗi trước. Kịch bản kiểm tốt nhất là một ca kiểm thử nhỏ hỏng đúng vì lỗi đang tìm. Nhờ AI viết ca này từ mô tả lỗi là việc hợp lý, miễn là bạn chạy thử trên bản hiện tại thấy nó hỏng và chạy trên bản cũ thấy nó qua.

Giữ ca kiểm thử ngoài lịch sử. Nếu ca kiểm thử mới chỉ có ở bản hiện tại, khi git lùi về commit cũ, tệp đó sẽ không còn. Đặt kịch bản kiểm ở một thư mục ngoài dự án, hoặc ở tệp chưa được git theo dõi, để mọi bước bisect đều thấy nó.

Phân biệt hỏng vì lỗi và hỏng vì chuyện khác. Ở commit cũ, dự án có thể không cài được thư viện, thiếu tệp cấu hình mới. Kịch bản nên trả mã 125 trong những trường hợp đó để git bỏ qua thay vì kết luận sai.

Dọn sạch giữa các bước. Tệp đệm, thư viện đã cài, cơ sở dữ liệu thử từ bước trước có thể ảnh hưởng bước sau. Thêm lệnh dọn và cài lại phụ thuộc vào đầu kịch bản nếu dự án thay đổi phụ thuộc thường xuyên.

Khi đã tìm ra commit thủ phạm, đưa gì cho AI

Có mã commit rồi, chạy git show kèm mã đó để xem toàn bộ thay đổi. Một commit gọn thường chỉ vài chục dòng, đúng kích cỡ mà AI đọc tốt nhất. Lúc này bạn đưa cho AI ba thứ: mô tả lỗi, phần thay đổi của commit, và ca kiểm thử tái hiện. Câu lệnh mẫu: “Commit dưới đây làm ca kiểm thử này từ qua chuyển sang hỏng. Chỉ ra thay đổi nào trong commit gây ra điều đó, giải thích cơ chế, chưa đề xuất sửa.”

Nếu commit thủ phạm quá lớn, chẳng hạn một lần gộp cả tuần làm việc với hàng chục tệp, bisect đã làm hết phần của nó và bạn lại cần chia đôi ở trục mã. Tạo một nhánh tạm từ commit tốt cuối cùng, áp từng phần thay đổi của commit lớn vào, mỗi phần chạy lại kiểm thử. Đây cũng là bài học cho cả nhóm: commit nhỏ, mỗi commit một ý, giúp những lần gỡ lỗi sau nhẹ đi rất nhiều.

Một điểm cần nhớ khi dán phần thay đổi cho AI: commit có thể chứa tệp cấu hình với khoá hoặc mật khẩu, hoặc dữ liệu mẫu lấy từ khách thật. Lọc chỉ những tệp mã liên quan bằng cách thêm đường dẫn tệp sau lệnh git show, và đọc lại trước khi dán.

Chia đôi ở trục dữ liệu và trục mã

Không phải lỗi nào cũng là lỗi hồi quy. Có lỗi đã nằm sẵn từ đầu, chỉ lộ ra khi gặp dữ liệu lạ. Bảng dưới gợi ý cách chia đôi cho từng tình huống, kèm việc nên nhờ AI.

Tình huốngCách chia đôiNhờ AI làm gì
Nhập tệp 10.000 dòng thì lỗi, tệp mẫu 10 dòng thì khôngCắt tệp làm hai nửa, chạy từng nửa, lặp với nửa còn lỗi tới khi còn một dòngViết lệnh hoặc đoạn mã nhỏ để cắt tệp; giải thích vì sao dòng tìm được gây lỗi
Báo cáo cuối luồng sai số, không có thông báo lỗiIn kết quả trung gian ở bước giữa luồng, xem sai từ nửa trước hay nửa sauĐề xuất điểm in và giá trị cần so ở mỗi điểm
Trang web hỏng sau khi bật nhiều tiện ích hay mô-đunTắt một nửa số mô-đun, xem trang còn hỏng khôngLiệt kê thứ tự tắt hợp lý dựa trên phụ thuộc giữa các mô-đun
Cấu hình dài, đổi xong thì ứng dụng không khởi độngQuay về cấu hình cũ, áp lại từng nửa thay đổiSo hai bản cấu hình và chỉ ra khác biệt đáng ngờ

Điểm chung của cả bốn: AI không thay bạn chạy kiểm từng nửa, trừ khi bạn dùng tác tử có quyền chạy lệnh và đã giới hạn nó trong một thư mục thử. Ngay cả khi đó, bạn vẫn cần xem lại từng kết luận của nó trước khi tin.

Những bẫy hay gặp khi khoanh vùng

Khoanh vùng có hệ thống nhưng vẫn có chỗ dễ trượt. Danh sách dưới tập hợp những trường hợp khiến cả người lẫn AI đi lạc.

  • Lỗi không ổn định: lúc hỏng lúc không ở cùng một commit. Bisect sẽ cho kết quả sai. Phải làm cho lỗi tái hiện ổn định trước, hoặc chạy kiểm nhiều lần ở mỗi bước.
  • Hai lỗi chồng lên nhau: mỗi nửa đều có một lỗi, nên nửa nào cũng hỏng. Khi kết quả chia đôi mâu thuẫn, nghi ngay có nhiều hơn một nguyên nhân.
  • Môi trường thay đổi chứ không phải mã: thư viện tự nâng phiên bản, dữ liệu trên máy chủ đổi. Bisect trên mã sẽ không tìm thấy gì vì mã không có lỗi.
  • Cách kiểm sai: ca kiểm thử dùng để bisect lại phụ thuộc vào thứ mới thêm sau này, nên ở commit cũ luôn hỏng vì lý do khác.
  • Tin kết luận của AI mà không chạy lại: AI có thể chỉ một dòng trong commit nghe rất hợp lý, nhưng chỉ có chạy lại mới xác nhận.

Mỗi bẫy đều có lối ra giống nhau: dừng lại, viết rõ điều đang biết chắc và điều mới chỉ đoán, rồi mới tiếp tục. Đưa bản ghi đó cho AI cũng giúp nó gợi ý đúng hướng hơn so với chỉ dán thêm lỗi mới.

Ghi lại kết quả để lần sau không phải tìm lại

Tìm ra commit thủ phạm và sửa xong, nhiều người đóng máy luôn. Năm phút ghi chép lúc này đáng giá hơn nhiều so với công sức bỏ ra. Trong mô tả của commit sửa lỗi, ghi mã commit đã gây lỗi, triệu chứng khách gặp, nguyên nhân bằng một câu, và tên ca kiểm thử đã thêm. Khi ai đó trong nhóm, kể cả chính bạn sáu tháng sau, tìm lịch sử theo triệu chứng, họ sẽ thấy ngay toàn bộ câu chuyện.

Ca kiểm thử dùng để bisect nên được giữ lại trong bộ kiểm thử của dự án sau khi sửa. Nó là hàng rào chặn lỗi cũ quay lại, điều rất hay xảy ra khi một người khác sửa đúng vùng mã đó mà không biết lịch sử. Nhờ AI chỉnh lại tên và chú thích của ca kiểm thử cho dễ hiểu là việc vặt hợp với nó, miễn là bạn chạy lại để chắc ca đó vẫn hỏng trên bản cũ và qua trên bản đã sửa.

Nếu nhóm có thói quen họp rút kinh nghiệm, commit thủ phạm là chất liệu tốt để bàn về quy trình chứ không phải để trách người viết: vì sao thay đổi đó lọt qua rà soát, kiểm thử nào lẽ ra đã bắt được, và lần sau cần thêm bước gì.

Câu hỏi thường gặp

Git bisect có làm mất mã đang viết dở không?

Không làm mất nếu bạn commit hoặc cất tạm thay đổi trước khi bắt đầu. Bisect chỉ chuyển qua lại giữa các commit đã có. Khi xong, lệnh git bisect reset đưa bạn về đúng nhánh và commit ban đầu.

Không có bản nào chắc chắn còn chạy tốt thì dùng bisect được không?

Cần ít nhất một điểm tốt. Thử lùi về các thẻ phiên bản cũ hoặc commit của vài tuần trước để tìm một bản không có lỗi. Nếu lỗi có từ đầu dự án thì đó không phải lỗi hồi quy, nên chuyển sang chia đôi ở trục mã hoặc trục dữ liệu.

AI có tự chạy git bisect được không?

Tác tử AI có quyền chạy lệnh trên máy làm được, nhất là với git bisect run và một ca kiểm thử rõ ràng. Nên cho nó làm trên một bản sao dự án hoặc nhánh riêng, và tự xem lại commit nó tìm được trước khi kết luận.

Vì sao bisect chỉ ra một commit có vẻ vô can?

Thường do cách kiểm không ổn định, do lỗi phụ thuộc dữ liệu hay môi trường thay đổi theo thời gian, hoặc do commit đó làm lộ một lỗi đã nằm sẵn từ trước. Kiểm lại ca kiểm thử ở hai commit hai bên vài lần để chắc kết quả.

Có cần chia đôi khi đã có thông báo lỗi rõ ràng không?

Thường không cần. Khi ngăn xếp lời gọi trỏ thẳng vào mã dự án và lỗi tái hiện được, đọc tại chỗ nhanh hơn. Chia đôi phát huy khi lỗi im lặng, khi thông báo trỏ vào chỗ không liên quan, hoặc khi chỉ biết là trước đây chạy được.

Commit lớn có làm bisect kém hiệu quả không?

Có. Bisect chỉ khoanh tới mức một commit, nên commit càng lớn thì vùng còn lại càng rộng. Thói quen commit nhỏ, mỗi commit một thay đổi có ý nghĩa, giúp bisect chỉ thẳng vào vài dòng mã và giúp AI đọc phần thay đổi chính xác hơn.

Cần tư vấn cụ thể cho trường hợp của bạn?

Chúng tôi sẽ liên hệ trong vòng 24 giờ.

Đăng ký tư vấn ngay

Bài viết liên quan

Bạn cần hỗ trợ thêm?

Để lại thông tin, chúng tôi sẽ liên hệ trong 24 giờ.

hoặc
Gọi ngay 0926 138 138