Số liệu vừa được công bố tuần trước và không mấy tích cực: pull request tăng 20% YoY tại các công ty dùng AI coding tools, nhưng incidents-per-PR tăng 23.5% trong cùng kỳ. Nhiều code hơn, nhiều bug hơn, ít con mắt xem xét hơn trên mỗi dòng code.
Tôi đã là Tech Lead hơn 15 năm, và đây là lần đầu tiên tôi cảm thấy quy trình code review đang chống lại chúng ta. Không phải vì engineer lười biếng — họ không lười. Mà vì những giả định được xây dựng trong cách chúng ta review code được viết cho một thế giới mà con người viết mọi dòng code.
Thế giới đó không còn nữa.
Vấn đề thực sự không phải là Khối lượng, mà là Signal-to-Noise
Khi một con người viết 200 dòng code, bạn biết đại khái họ đang nghĩ gì. Code phản ánh mental model, thói quen, sự hiểu biết của họ về codebase. Bạn đang review lý luận của một con người.
Khi AI viết 200 dòng, bạn đang review output của một phân phối xác suất. Code có thể hoàn hảo về mặt phong cách và sai về mặt kiến trúc cùng một lúc. Nó pass linter, thỏa mãn tests, và đưa ra một race condition tinh vi chỉ xuất hiện trong các load pattern cụ thể.
AI không biết những gì nó không biết. Và bạn cũng không, nếu bạn review với tốc độ tương tự như review code của con người.
Những gì Tôi Quan sát được trong Team
Sau ba tháng áp dụng AI coding tools mạnh mẽ (chúng tôi dùng Claude Code và Cursor song song trên hai squad), đây là những gì tôi thực sự thấy:
Trước AI tools (Q1 2026):
PR size trung bình: 180 dòng
Review time mỗi PR: 45 phút
Incidents từ merged PRs: 2.1/tháng
Sau AI tools (Q2 2026):
PR size trung bình: 340 dòng ← +89%
Review time mỗi PR: 38 phút ← -16%
Incidents từ merged PRs: 3.8/tháng ← +81%
Các engineer đang review nhanh hơn vì code trông sạch hơn. Nhưng họ đang bỏ qua nhiều thứ. AI tạo ra code đọc tốt nhưng có thể nhúng các giả định không khớp với context hệ thống.
Năm Loại Lỗi của AI-Generated Code
Sau khi review 400+ PRs từ các session AI-assisted, tôi nhận thấy các pattern lỗi tập trung vào năm loại:
1. Context Blindness
AI tạo code đúng khi tách biệt nhưng bỏ qua các quy ước hệ thống hiện có. Ví dụ: thêm Redis caching vào một service mà chúng tôi không cache vì yêu cầu compliance. AI không đọc ARCHITECTURE.md. Nó tạo ra code caching hợp lệ nhưng vi phạm quy tắc kinh doanh.
// AI tạo ra — trông ổn, nhưng fail compliance
public async Task<UserData> GetUserAsync(string userId) {
var cached = await _cache.GetAsync($"user:{userId}");
if (cached != null) return cached;
// ...
}
// Đúng cho hệ thống của chúng tôi — không cache trên PII endpoints
public async Task<UserData> GetUserAsync(string userId) {
return await _repository.GetAsync(userId); // Luôn fresh cho audit trail
}
2. Test Coverage Illusion
AI viết tests pass nhưng không cover các edge case mà chính AI đã giới thiệu. Tỷ lệ coverage trông tốt. Actual risk coverage thì rỗng.
3. Dependency Sprawl
AI thường giới thiệu packages mới khi các utilities hiện có sẽ hoạt động. Tôi đã thấy ba PRs trong một tuần thêm ba thư viện JSON serialization khác nhau khi chúng tôi đã có một thư viện chuẩn.
4. Error Handling Gaps
AI xử lý happy path tốt. Error handling thường được pattern-match từ training data và không phù hợp với error taxonomy thực tế của hệ thống bạn.
5. Silent State Mutations
Khó phát hiện nhất: AI code thay đổi state như side effect, đặc biệt trong async contexts. Nó trông đúng, tests pass, và phá vỡ thứ gì đó ba lớp phía trên.
Protocol Review Mới: Bốn Câu hỏi Trước khi Merge
Tôi đã tái cấu trúc quy trình review của chúng tôi xung quanh bốn câu hỏi bắt buộc không tồn tại trước khi có AI coding tools:
C1: “Code này giả định gì về system state mà nó không verify?”
Với mỗi AI-generated PR, hỏi điều này một cách rõ ràng. AI giả định database schema khớp với training data của nó. Nó giả định API contract là những gì docstring nói. Nó giả định biến môi trường tồn tại.
Thực hiện bài tập tinh thần này: nếu mọi comment trong PR này bị xóa, một engineer mới có hiểu tại sao code này làm những gì nó làm không, không chỉ cái gì nó làm?
C2: “Code này sẽ hoạt động như thế nào ở mức tải 3x hiện tại?”
AI-generated code thường không tính đến concurrency, database connection pools, hay rate limits. Hãy ép bản thân trace các async paths.
C3: “Blast radius là gì nếu cái này fail silently?”
Silent failures là chuyên môn của AI. Hỏi: nếu cái này return một default value thay vì throw, điều gì sẽ bị ảnh hưởng downstream? Monitoring nào sẽ bắt được nó?
C4: “Cái này có khớp với cách team chúng ta xử lý [pattern X] không?”
Không phải cách internet xử lý nó. Không phải cách framework documentation trình bày. Mà cách team của bạn, trong codebase của bạn, đã quyết định xử lý nó.
Metrics Mới Bạn Cần Theo dõi Ngay
Ngừng đo PR count. Bắt đầu đo:
Incidents-per-PR theo Author-Type
Track riêng biệt: PRs từ AI-heavy sessions vs. human-only sessions. Của tôi cho thấy AI-heavy PRs có tỷ lệ incident cao hơn 2.1x trong tuần đầu tiên trên production.
Review Time Efficiency
(Bugs phát hiện trong review) / (Giờ spent reviewing) — điều này cho bạn biết quy trình review của bạn có thực sự tìm thấy vấn đề không.
Time-to-Failure cho Merged PRs
Bao lâu sau khi merge thì incidents xảy ra? AI-generated code có xu hướng pass initial QA rồi fail dưới các điều kiện production cụ thể (data shapes cụ thể, load patterns cụ thể, geographic-specific issues).
CLAUDE.md Coverage Score
Nếu bạn dùng Claude Code, track tỷ lệ phần trăm repos của team bạn có CLAUDE.md đầy đủ với các architectural constraints, naming conventions, và prohibited patterns. Đây là input ROI cao nhất cho AI code quality.
Phản hồi Tooling: AI-Assisted Review
Sự mỉa mai không khỏi nhận ra: giải pháp cho vấn đề AI-generated code có thể là AI-assisted review.
Chúng tôi đang thử nghiệm hai approach:
Approach 1: Pre-commit Harness Review
Trước khi một PR được mở, một Claude Code /review skill chạy trên diff và kiểm tra:
- Cái này có khớp với architectural patterns trong
ARCHITECTURE.mdkhông? - Có bất kỳ prohibited imports hay patterns nào không?
- Test coverage của các code paths mới là gì?
Điều này bắt được ~40% context-blindness issues trước khi chúng đến với human reviewer.
Approach 2: Intent-Before-Code Reviews
Lấy cảm hứng từ Upstream: engineer viết mô tả 3 câu về điều họ đang cố gắng hoàn thành trước khi AI tạo code. Reviewer review intent trước, code sau.
## Intent
Implement user preference caching để giảm DB calls trên dashboard.
CONSTRAINT: Không được cache PII fields (email, phone) theo compliance policy #SEC-42.
EXPECTED BEHAVIOR: Cache TTL 15 phút, bust khi profile update.
Chỉ điều này thôi đã cắt giảm 60% context-blindness incidents vì human constraint được baked vào prompt.
Điều gì Thực sự Hoạt động: Kế hoạch 30 ngày
Nếu bạn là Tech Lead đang đọc bài này với việc áp dụng AI tools đã đang diễn ra, đây là phản hồi viable tối thiểu:
Tuần 1 — Đo lường
Thêm label [AI-assisted] vào PRs. Bắt đầu track incidents riêng biệt. Lấy baseline.
Tuần 2 — Constrain
Viết hoặc cải thiện CLAUDE.md trong mỗi repo đang hoạt động. Tập trung vào: prohibited patterns, required conventions, compliance constraints, testing standards.
Tuần 3 — Process Triển khai intent-before-code template. Làm cho nó optional — bạn sẽ có 50% adoption ngay lập tức và 80% trong vòng hai tuần khi engineers thấy nó giúp ích.
Tuần 4 — Review Nhìn vào baseline Tuần 1 vs. hiện tại. Double down vào những gì đã giảm incidents-per-PR.
Sự Thật Khó chịu
AI coding tools đã ở đây để ở lại. Các engineers sử dụng chúng có năng suất cao hơn về khối lượng output thô. Câu hỏi là liệu quy trình review của bạn có tiến hóa để phù hợp không.
Sai lầm tôi thấy nhiều Tech Leads mắc phải nhất là coi AI code review như là fast human code review. Không phải vậy. Nó đòi hỏi các câu hỏi khác, metrics khác, và một mental model hoàn toàn khác về những gì bạn đang tìm kiếm.
Code đã được tạo ra. Công việc của bạn là verification, context-enforcement, và intent preservation. Đây là kỹ năng con người. Chúng cũng là, ngay lúc này, những kỹ năng đòn bẩy cao nhất trong engineering.
Bạn đã thay đổi quy trình code review cho AI-generated code chưa? Tôi muốn nghe những gì đang hiệu quả — tìm tôi trên LinkedIn hoặc GitHub.