Chi phí ẩn của Git Diff khổng lồ trong AI Coding
AI coding có một sức hấp dẫn rất mạnh: tốc độ. Một yêu cầu nhỏ, một prompt tương đối rõ, và vài phút sau bạn đã có code, test, đôi khi cả phần refactor “tặng kèm”. Cảm giác này rất dễ khiến team nghĩ rằng mình đang tăng năng suất thần tốc. Nhưng trong thực tế, thứ đầu tiên tăng mạnh không phải lúc nào cũng là hiệu quả. Nhiều khi thứ phình to nhất lại là git diff.
Bạn định thêm một endpoint, AI sửa tám file. Bạn định vá một bug nhỏ, AI tranh thủ chỉnh luôn naming, formatting, helper và nửa đoạn validation cho “đồng bộ”. Nhìn thoáng qua thấy cũng xuôi mắt. Nhưng khi pull request dài vài trăm dòng, đội kỹ thuật bắt đầu phải trả một loại chi phí khá đau: chi phí ẩn của việc kiểm soát thay đổi.
Điều đáng nói là chi phí này không la hét ngay từ đầu. Nó không hiện thành một lỗi compile đỏ chói để ai cũng thấy. Nó xuất hiện âm thầm dưới dạng review chậm hơn, bug lọt dễ hơn, lịch sử repository khó đọc hơn và niềm tin vào codebase giảm dần. Tới lúc team nhận ra thì mọi người thường đã nói câu quen thuộc: “Dạo này sao release cái gì cũng mệt thế nhỉ?”
Bài viết này đi thẳng vào một thực tế quan trọng: git diff khổng lồ là một trong những chi phí ẩn lớn nhất khi dùng AI coding trong môi trường làm sản phẩm thật. Nó không chỉ là chuyện xấu mắt hay khó đọc. Nó ảnh hưởng trực tiếp đến tốc độ release, chất lượng review và sức khỏe tinh thần của đội kỹ thuật. Nghe hơi kịch tính, nhưng ai đã từng mở một PR 700 dòng chỉ để thêm một nút “Lưu” sẽ hiểu cảm giác đó chân thật đến đâu.
Git diff lớn không chỉ là chuyện nhiều dòng, mà là chuyện mất kiểm soát
Nhiều người nhìn git diff lớn và nghĩ đơn giản: “Ừ thì nhiều code hơn, đọc lâu hơn thôi mà.” Thực ra vấn đề sâu hơn nhiều. Trong engineering, một thay đổi tốt không chỉ cần đúng, mà còn cần rõ. Rõ mục tiêu. Rõ phạm vi. Rõ lý do. Git diff càng lớn, ba thứ đó càng bị pha loãng.
Một pull request đẹp thường trả lời rất nhanh câu hỏi: “Ticket này đang đổi cái gì?” Khi AI coding tham gia quá tự do, câu trả lời lại biến thành: “Thì… có vẻ là thêm feature này, nhưng cũng sửa style, đổi tên hàm, gom helper, chỉnh test, đụng config, tiện tay làm sạch vài chỗ luôn.” Đến đây reviewer bắt đầu thấy không phải mình đang review code nữa, mà đang điều tra hiện trường.
Git diff lớn nguy hiểm ở chỗ nó làm thay đổi trở nên mơ hồ. Khi thay đổi mơ hồ, năng lượng kỹ thuật bị đốt vào việc hiểu “rốt cuộc cái gì đang xảy ra” thay vì đánh giá xem giải pháp có tốt không. Năng suất đội ngũ giảm không phải vì mọi người dở đi, mà vì hệ thống làm việc bị buộc phải tiêu hao thêm nhận thức cho những thứ lẽ ra không cần phức tạp đến vậy.
Git diff nhỏ giúp team review quyết định. Git diff lớn buộc team dò manh mối.
Chi phí số 1: Code review chậm lại, và chậm theo cách rất đắt
Code review vốn đã là công việc tiêu hao tập trung. Người review phải đọc logic, suy nghĩ về edge case, hình dung luồng dữ liệu, kiểm tra tác động phụ, và đối chiếu với kiến trúc hiện tại. Khi pull request chỉ có vài chục dòng thay đổi, việc này vẫn nằm trong ngưỡng dễ kiểm soát. Nhưng khi diff dài 300, 500, 800 dòng, bộ não con người bắt đầu bật chế độ tiết kiệm pin.
Lúc đó reviewer thường rơi vào một trong ba trạng thái quen thuộc:
- Đọc lướt cho xong vì thời gian không cho phép
- Trì hoãn review vì nhìn diff đã thấy mệt
- Review quá lâu rồi xuống năng lượng, cuối cùng vẫn sót ý quan trọng
Cả ba đều tốn tiền theo nghĩa engineering. Đọc lướt thì bug dễ lọt. Trì hoãn review thì feature release chậm. Review quá lâu thì senior bị hút vào một PR quá mức cần thiết, trong khi đáng ra thời gian đó có thể dành cho thiết kế hệ thống, mentoring hoặc giải quyết vấn đề khó hơn. Đó là lý do tôi gọi đây là chi phí ẩn: nó không đứng riêng một mục trên hóa đơn, nhưng nó ăn dần vào vận tốc của cả đội.
Vì sao AI coding làm code review chậm hơn nhiều người tưởng?
Vì AI không chỉ thêm logic mới. Nó thường sửa cả các yếu tố xung quanh để “tối ưu” câu trả lời của nó. Thế là reviewer không được đọc một thay đổi, mà phải đọc một gói thay đổi trộn lẫn nhiều lớp mục đích. Việc này buộc người review liên tục chuyển ngữ cảnh: đây là logic mới, đây là refactor, đây là formatting, đây là rename, đây là side-effect hay chủ ý? Cứ mỗi lần chuyển ngữ cảnh như vậy, chi phí nhận thức tăng lên.
Nói vui một chút, review một diff gọn giống như kiểm tra hóa đơn điện. Review một diff do AI tung hơi mạnh lại giống kiểm toán công ty gia đình có ba người cô góp vốn và một người chú chuyên ghi sổ bằng trí nhớ. Không phải không làm được. Chỉ là ai cũng thấy hơi mệt.
Chi phí số 2: Thay đổi quan trọng bị chìm giữa một biển thay đổi phụ
Một trong những tác hại khó chịu nhất của git diff lớn là nó che giấu phần quan trọng nhất. Khi mọi thứ bị trộn chung vào một pull request, logic mới không còn nổi bật nữa. Reviewer phải đi lặn để tìm chỗ nào thực sự liên quan đến business, chỗ nào chỉ là AI đổi cách viết cho hợp “gu” của nó.
Đây là lý do nhiều pull request nhìn rất chăm chỉ nhưng lại làm người đọc mất phương hướng. Thứ đáng được chú ý nhất, ví dụ như điều kiện phân quyền mới, thay đổi quan hệ dữ liệu, logic tính tiền, hay cách xử lý lỗi ở production, lại bị kẹp giữa hàng chục thay đổi nhỏ như:
- Đổi tên biến cho “rõ hơn”
- Format lại đoạn code không liên quan
- Tách một hàm vì thấy dài
- Đổi thứ tự import hoặc cấu trúc file
- Viết lại test theo phong cách khác
Những thay đổi phụ này không hẳn sai. Vấn đề là chúng chen vào sai thời điểm và sai ngữ cảnh. Một PR production cần giúp người khác nhìn thấy trọng tâm ngay lập tức. Git diff khổng lồ lại làm điều ngược lại: nó khiến cái quan trọng bị loãng. Mà trong phần mềm, những bug đắt nhất thường không đến từ thứ to đùng ai cũng thấy. Chúng đến từ những dòng thay đổi nhỏ bị chìm giữa quá nhiều chuyển động.
Nguy hiểm nhất là sự mơ hồ
Khi reviewer không chắc đâu là thay đổi chính, chất lượng review giảm rất mạnh. Người review có thể bỏ qua phần đáng lẽ phải chất vấn sâu nhất, chỉ vì xung quanh nó có quá nhiều tiếng ồn. Đây là kiểu rủi ro không kịch tính nhưng rất nguy hiểm. Nó làm team tưởng mình đã review, trong khi thực chất mới chỉ đọc qua.
Chi phí số 3: Bug dễ lọt hơn vì con người không review vô hạn được
Rất nhiều người mặc định bug xuất hiện vì người viết code sai. Thực tế đầy đủ hơn là: bug thường xuất hiện vì cả hệ thống kiểm soát chất lượng đã không phát hiện kịp. Git diff lớn làm xác suất phát hiện bug giảm xuống đơn giản vì nó làm reviewer mệt và làm mục tiêu thay đổi kém rõ ràng.
AI coding có thể sinh ra code đúng cú pháp, nhìn hợp lý, thậm chí test pass. Nhưng production đâu chỉ sợ lỗi cú pháp. Production sợ lỗi hiểu sai nghiệp vụ, lỗi side-effect, lỗi case hiếm, lỗi race condition, lỗi dữ liệu cũ, lỗi tương thích ngược. Những lỗi này thường chỉ lộ ra khi một người hiểu hệ thống đọc thật kỹ và đặt câu hỏi đúng. Mà muốn đọc thật kỹ thì diff phải đủ gọn để não còn hoạt động tử tế.
Git diff càng lớn, reviewer càng dễ bỏ sót:
- Một điều kiện if đảo ngược logic
- Một chỗ thiếu kiểm tra null hoặc empty
- Một thay đổi nhỏ làm lệch behavior cũ
- Một dòng logging hoặc exception handling bị mất
- Một test không còn kiểm đúng mục tiêu ban đầu
Điều cay đắng là sau khi bug lên production, AI không phải người ngồi họp postmortem. Developer vẫn là người chịu trận, team lead vẫn là người giải thích, product vẫn là người cập nhật tình hình cho khách, còn người trực on-call vẫn là người thức đêm xem log. Nói vậy để thấy rằng diff lớn không chỉ là vấn đề “thẩm mỹ pull request”. Nó là vấn đề trách nhiệm vận hành.
Chi phí số 4: Lịch sử repository trở nên khó đọc và khó tin
Một repository khỏe mạnh giống như một cuốn nhật ký kỹ thuật rõ ràng. Mỗi commit, mỗi pull request nên kể được một câu chuyện tương đối mạch lạc: thêm feature gì, sửa bug gì, refactor phần nào, tại sao phải đổi. Khi lịch sử repo giữ được tính kể chuyện này, việc điều tra, rollback, onboarding và bảo trì đều dễ hơn nhiều.
Git diff lớn phá hỏng điều đó. Ba tháng sau, khi bạn dùng git blame hoặc đọc lại commit để truy nguyên một lỗi, bạn thấy một commit sửa 14 file, đổi 600 dòng, message thì đại loại “update feature” nghe rất hiền lành. Đến khi mở ra xem mới phát hiện trong đó có cả phần business logic, refactor, rename, formatting và test được tái cấu trúc nhẹ. Đọc xong chỉ muốn thở dài kiểu rất trưởng thành.
Vấn đề ở đây không chỉ là khó hiểu. Nó còn làm giảm khả năng điều tra sự cố. Khi một thay đổi quá rộng, rất khó tách xem chính xác dòng nào gây ra hồi quy. Rollback cũng khó hơn vì rollback cả commit có thể kéo theo việc gỡ luôn những phần không nên gỡ. Càng phụ thuộc vào các PR lớn, repository càng mất đi giá trị như một hệ thống ghi nhớ đáng tin cậy.
Lịch sử xấu tạo ra chi phí lãi kép
Chi phí này tích lũy theo thời gian. Mỗi PR khó đọc làm lần điều tra sau tốn thêm vài phút. Vài phút nhân lên qua hàng trăm lần trở thành rất nhiều giờ kỹ sư. Đó là chưa kể cảm giác bực bội kéo dài khi đội phát triển không còn tin vào lịch sử thay đổi của chính sản phẩm mình làm ra. Engineering không chỉ cần code chạy, engineering còn cần lịch sử đủ rõ để ngày mai không phải đoán mò.
Chi phí số 5: Niềm tin vào codebase giảm dần, và đây là một vấn đề thật sự
Đây là phần ít được nói nhất nhưng lại ảnh hưởng rất mạnh tới hiệu suất đội ngũ. Khi developer thường xuyên nhìn thấy pull request AI-generated quá lớn, họ bắt đầu nghi ngờ mọi thứ. Không phải vì họ ghét AI. Họ nghi ngờ vì kinh nghiệm dạy họ rằng những thay đổi rộng thường đi kèm rủi ro rộng.
Những câu hỏi kiểu này sẽ xuất hiện ngày càng nhiều:
- AI có sửa thêm gì ngoài yêu cầu mà mình chưa để ý không?
- Đoạn logic cũ có bị chạm vào theo cách tinh vi nào không?
- Test pass là vì test tốt, hay vì test cũng vừa bị AI sửa lại?
- Module này còn giữ đúng convention cũ không?
- Lần sau mình chạm vào đây có lại phải dọn một bãi bất ngờ nữa không?
Khi niềm tin giảm, team tự động tăng mức kiểm tra thủ công. Mọi người đọc kỹ hơn, test tay nhiều hơn, xác minh nhiều hơn, hỏi nhau nhiều hơn. Điều này nghe có vẻ cẩn thận, nhưng nếu nó xuất phát từ cảm giác thiếu tin tưởng liên tục thì về bản chất, năng suất đang bị bào mòn. Team không còn dùng năng lượng để tiến lên, mà dùng để tự phòng thủ.
Một codebase tốt giúp developer mạnh dạn thay đổi. Một codebase bị git diff lớn bào mòn khiến developer chạm đâu cũng dè chừng.
Vì sao AI coding lại hay sinh ra git diff khổng lồ?
Công bằng mà nói, git diff lớn không hoàn toàn là “lỗi của AI”. Phần lớn nó là hệ quả của cách chúng ta đưa AI vào quy trình. Khi AI được yêu cầu sửa trực tiếp trên repository với một context lớn, nó sẽ cố tạo ra một lời giải nhìn có vẻ đầy đủ và an toàn theo cách của nó. Mà “an toàn” với AI thường đồng nghĩa với việc chỉnh nhiều chỗ liên quan để tăng xác suất mọi thứ vẫn chạy.
Nói đơn giản, AI không có cảm giác tự nhiên về “đủ rồi, chỉ sửa tới đây thôi” trừ khi bạn buộc nó bằng quy trình, contract hoặc ranh giới rất rõ. Nếu không có lan can, nó sẽ có xu hướng:
- Sửa nhiều file để làm tròn ngữ cảnh
- Refactor thêm để câu trả lời nhìn gọn hơn
- Đồng bộ naming hoặc style ngoài phạm vi yêu cầu
- Chạm vào test, config, helper để tránh rủi ro cục bộ
- Mở rộng thay đổi vì nó thấy “hợp lý” chứ không vì ticket yêu cầu
Điều này hợp lý theo logic sinh mã. Nhưng nó lại không hợp lý với production repository, nơi thay đổi càng nhỏ và càng có chủ đích thì càng dễ kiểm soát. Nói cách khác, AI coding mặc định tối ưu cho việc hoàn thành bài toán trước mắt, còn engineering production tối ưu cho việc sống chung lâu dài với lời giải đó.
Git diff lớn đang làm chậm cả pipeline phát triển như thế nào?
Nếu nhìn ở mức hệ thống, git diff lớn tạo ra một chuỗi tác động liên hoàn:
- AI sinh thay đổi rộng hơn cần thiết.
- Reviewer cần nhiều thời gian hơn để hiểu và xác minh.
- Review bị trì hoãn hoặc chất lượng review giảm.
- Bug hoặc drift kiến trúc có cơ hội lọt cao hơn.
- Team tăng kiểm tra thủ công và trở nên dè chừng hơn ở các lần sửa sau.
Kết quả cuối cùng là gì? Người viết có thể thấy mình code nhanh hơn, nhưng cả pipeline từ viết, review, merge, release đến bảo trì lại chậm đi. Đây là kiểu tối ưu cục bộ rất dễ gây ảo giác năng suất. Dashboard cá nhân có thể trông đẹp hơn. Dashboard của cả hệ thống thì không chắc.
Team nên nhìn git diff lớn như một chỉ báo vận hành, không phải tiểu tiết
Nhiều đội coi chuyện diff lớn chỉ là sở thích cá nhân: người này thích PR nhỏ, người kia không ngại PR to. Thật ra với AI coding, kích thước và độ hỗn tạp của git diff nên được xem như một chỉ báo sức khỏe quy trình. Nếu pull request ngày càng rộng, ngày càng khó kể chuyện, đó là tín hiệu rằng team đang thiếu cơ chế bó phạm vi thay đổi.
Một vài dấu hiệu cảnh báo rất rõ:
- Ticket nhỏ nhưng PR thường xuyên sửa nhiều module
- Reviewer phải mất nhiều thời gian chỉ để hiểu mục tiêu thay đổi
- Commit history khó đọc lại sau vài tuần
- Refactor và feature thường xuyên bị trộn chung
- Team nói dùng AI để nhanh hơn nhưng chu kỳ release không cải thiện
Nếu những dấu hiệu này xuất hiện thường xuyên, vấn đề không nằm ở việc team thiếu chăm chỉ. Vấn đề là quy trình đang cho phép AI mở rộng thay đổi quá mức. Và production thường không thưởng cho kiểu tự do đó. Nó thường trả thưởng bằng bug khó chịu và những buổi chiều review kéo dài hơn mong muốn rất nhiều.
Kết luận
Git diff khổng lồ là một trong những chi phí ẩn đắt nhất của AI coding. Nó làm code review chậm, che giấu thay đổi quan trọng, tăng xác suất bug lọt vào production, phá vỡ lịch sử repository và bào mòn niềm tin của developer vào codebase. Đây không phải chuyện nhỏ. Đây là chuyện ảnh hưởng trực tiếp đến vận tốc kỹ thuật và chất lượng sản phẩm.
Điểm mấu chốt là: AI coding không tự nhiên sinh ra quy củ production. Nếu team không đặt ranh giới rõ ràng, AI sẽ rất nhiệt tình mở rộng phạm vi thay đổi. Mà trong engineering, sự nhiệt tình không kiểm soát thường là khởi đầu của một pull request rất dài và một buổi review rất buồn.
Vì vậy câu hỏi đúng không còn là “AI có viết code nhanh không?”. Câu hỏi đúng là:
Làm sao để AI viết code mà git diff vẫn nhỏ, thay đổi vẫn rõ và repository vẫn quản lý được?
Đó cũng là lý do những cách tiếp cận như contract coding bắt đầu được quan tâm nghiêm túc hơn. Nhưng trước khi đi vào giải pháp, chúng ta còn cần hiểu một kiểu sử dụng AI khác đang rất thịnh hành và cũng rất dễ gây ảo giác năng suất: vibe coding. Đó là câu chuyện của bài tiếp theo.