Một AI reviewer tốt không thay thế human review — nó nâng chuẩn của human review lên, bằng cách dọn sạch những lỗi máy móc trước khi con người phải nhìn vào.
Vì Sao AI Code Review Thay Đổi Cuộc Chơi
Trước khi có AI coding agent, quy trình code review điển hình ở hầu hết các team là: mở PR, đọc diff, cố gắng hình dung context, rồi để lại vài comment — thường tập trung vào style, naming, hoặc những thứ dễ nhìn thấy bằng mắt. Những lỗi sâu hơn — một edge case bị bỏ sót, một N+1 query ẩn trong loop, một endpoint quên check quyền — thường trôi qua vì reviewer chỉ có 15-20 phút và hàng chục PR khác đang chờ. Đây không phải vì reviewer kém, mà vì review kỹ lưỡng theo cả 4 chiều (correctness, security, performance, architecture) trên mỗi PR là việc tốn thời gian không tương xứng với tốc độ mà team cần release.
AI coding agent thay đổi phương trình đó. Bạn có thể giao cho AI một pass review đầu tiên (first-pass review) trên toàn bộ diff, với instruction rõ ràng theo từng chiều, và nó sẽ đọc hết 100% code thay đổi — không mệt, không bỏ sót vì "gần cuối ngày rồi". Nó có thể trace qua nhiều file, kiểm tra một hàm mới có được gọi đúng cách ở tất cả các call site hay không, so sánh logic mới với test case hiện có, và liệt kê ra một danh sách cụ thể: dòng nào, vấn đề gì, tại sao là vấn đề. Điều này giải phóng human reviewer khỏi việc phải "quét lỗi cơ bản" và cho phép họ dồn năng lượng vào những thứ chỉ con người mới đánh giá được — trade-off sản phẩm, rủi ro chính trị trong tổ chức, liệu cách tiếp cận này có đúng hướng dài hạn của team hay không.
Nhưng đi kèm với lợi ích này là rủi ro mới. Rủi ro lớn nhất là over-trusting (tin tưởng quá mức) — khi một AI reviewer không tìm thấy gì bất thường, con người dễ có cảm giác an toàn giả (false sense of security) và lướt qua nhanh hơn, trong khi AI có thể đơn giản là chưa được hỏi đúng câu hỏi, hoặc thiếu context mà chỉ con người trong team mới biết (ví dụ: "tháng trước chúng ta đã cố dùng cache kiểu này và nó gây ra incident"). Rủi ro thứ hai là AI reviewer đưa ra nhận định rất tự tin (confident) về một đoạn logic phức tạp, nhưng thực chất đã hiểu sai ý đồ business. Vì vậy, cách dùng đúng là: coi AI review như một lớp lọc bắt buộc trước khi PR đến tay con người, không phải một sự thay thế cho human sign-off.
Mẹo: Bắt AI review chạy tự động (CI hoặc pre-review script) trên mọi PR trước khi gắn human reviewer — để reviewer con người luôn thấy comment của AI đã có sẵn, thay vì phải tự đi hỏi.
Review Correctness (Tính Đúng Đắn)
Correctness là chiều review cơ bản nhất nhưng cũng dễ bị AI review hời hợt nhất nếu bạn chỉ nói "review giúp tôi đoạn code này". Bạn cần prompt cụ thể để AI đào sâu vào logic, không chỉ đọc lướt xem code có "trông ổn" hay không. Những nhóm lỗi cần yêu cầu AI kiểm tra rõ ràng gồm: lỗi logic (sai điều kiện, sai thứ tự thao tác), off-by-one error (sai lệch chỉ số, vòng lặp chạy thừa/thiếu một lần), xử lý sai edge case (input rỗng, null, undefined, danh sách rỗng, số âm, giá trị biên), hành vi không khớp với spec hoặc acceptance criteria đã thống nhất, và cuối cùng là test coverage gaps — những nhánh logic quan trọng chưa có test nào phủ tới.
Điểm mấu chốt khi prompt AI review correctness là phải cho nó context về spec hoặc acceptance criteria, không chỉ đưa diff trần trụi. Nếu AI không biết yêu cầu nghiệp vụ ban đầu là gì, nó chỉ có thể đánh giá "code này có tự nhất quán với chính nó không", chứ không đánh giá được "code này có làm đúng cái task yêu cầu không". Cách làm hiệu quả là dán kèm ticket/spec gốc, hoặc ít nhất mô tả ngắn gọn hành vi mong đợi, rồi để AI đối chiếu.
Review this diff for correctness issues only. Here is the acceptance
criteria from the ticket:
"When a user applies a discount code that has expired, the checkout
should reject it with a clear error, and the order total must remain
unchanged. Expired codes must never be silently ignored and applied
as if valid."
Diff:
<paste diff or reference files: src/checkout/discount.ts, src/checkout/order.ts>
For each issue found, report:
1. File and line number
2. What the code currently does vs what it should do
3. A concrete input that triggers the wrong behavior
4. Whether an existing test would catch this (check test files in
src/checkout/__tests__/) — if not, propose the missing test case
Do not comment on style, naming, or performance in this pass.
Một chi tiết quan trọng: hãy tách riêng correctness review khỏi các chiều khác trong cùng một lần hỏi. Nếu bạn gộp chung "review giúp tôi cả correctness, security, performance" trong một prompt, AI thường sẽ lướt nhanh qua từng chiều và bỏ sót chi tiết, vì nó đang cố gắng bao quát quá nhiều thứ cùng lúc. Tách theo từng lượt hỏi (như cấu trúc bài này) giúp AI tập trung sâu hơn vào từng loại vấn đề, giống như cách một senior engineer chuyển "mindset" khi đọc code với câu hỏi khác nhau trong đầu.
Mẹo: Luôn dán kèm acceptance criteria hoặc mô tả hành vi mong đợi khi hỏi AI review correctness — không có nó, AI chỉ kiểm tra được tính nhất quán nội tại, không kiểm tra được đúng yêu cầu nghiệp vụ.
Review Security (Bảo Mật)
Security review là nơi AI thể hiện giá trị rõ rệt nhất, vì các lớp lỗ hổng phổ biến (vulnerability class) có pattern khá nhận diện được và AI đã được train trên rất nhiều ví dụ CVE thực tế. Những nhóm cần yêu cầu AI kiểm tra một cách tường minh: injection (SQL injection, command injection, template injection — bất cứ đâu input người dùng được nối trực tiếp vào query/command thay vì dùng parameterized query), lỗ hổng auth/authz bypass (thiếu kiểm tra quyền ở endpoint mới, broken object-level authorization — user A truy cập được resource của user B chỉ bằng cách đổi ID), secrets bị hardcode trong code (API key, token, connection string commit thẳng vào repo), unsafe deserialization (deserialize input không tin cậy thành object mà không validate, dẫn tới remote code execution), SSRF — server-side request forgery (server bị dụ gửi request tới địa chỉ nội bộ hoặc metadata endpoint do input không được kiểm soát), và insecure dependencies (thư viện mới thêm vào có CVE đã biết, hoặc version bị pin quá cũ).
Một sai lầm phổ biến là hỏi AI "có lỗ hổng bảo mật nào không?" một cách chung chung — câu hỏi mơ hồ này thường chỉ ra được những vấn đề hiển nhiên nhất. Prompt hiệu quả hơn nhiều là liệt kê rõ từng nhóm lỗ hổng cần kiểm tra, giống như một security checklist, và yêu cầu AI trả lời "có" hoặc "không" cho từng mục kèm bằng chứng cụ thể (dòng code, luồng dữ liệu).
Perform a security review of this diff. Check specifically for each
of these vulnerability classes, and report explicitly "found" or
"not found" for each one with evidence:
1. Injection: any user input concatenated into SQL, shell commands,
or templates instead of using parameterized queries/safe APIs
2. Authorization: does every new/modified endpoint verify the
requesting user actually owns or has permission over the resource
(not just that they are authenticated)?
3. Secrets: any API keys, tokens, passwords, or connection strings
hardcoded or logged in plaintext
4. Deserialization: any use of unsafe deserialization (e.g. pickle,
unchecked JSON->object mapping) on data from an untrusted source
5. SSRF: any server-side HTTP request where the target URL/host is
derived from user input without an allowlist
6. Dependencies: list any new packages added in this diff and flag
if their version has known CVEs
Files changed: <list files or paste diff>
For each finding, show the exact code snippet, explain the attack
scenario (what an attacker would send and what would happen), and
suggest the fix.
Với dependency check, nếu AI agent của bạn có quyền chạy tool, hãy để nó thực sự chạy audit command (npm audit, pip-audit, go list -m all kết hợp với vulnerability database) thay vì chỉ đoán dựa trên tên package — độ chính xác sẽ cao hơn hẳn so với việc AI "nhớ" CVE nào đó từ training data có thể đã lỗi thời.
Mẹo: Đừng hỏi security review chung chung — liệt kê rõ từng vulnerability class cần kiểm tra như một checklist, và bắt AI trả lời từng mục kèm bằng chứng, không chỉ tóm tắt cảm tính.
Review Performance (Hiệu Năng)
Performance là chiều dễ bị bỏ qua nhất trong review truyền thống, vì vấn đề hiệu năng thường không lộ ra khi đọc code tĩnh — nó chỉ lộ ra khi có tải thực tế hoặc dữ liệu lớn. Đây lại là điểm mạnh của AI review, vì AI có thể trace logic một cách kiên nhẫn để phát hiện pattern gây vấn đề mà không cần chạy thật. Những thứ cần yêu cầu kiểm tra: N+1 query (query bên trong vòng lặp thay vì batch/join một lần), re-render không cần thiết ở frontend (component re-render dù props/state không đổi thực chất, do thiếu memoization hoặc tạo object/function mới mỗi lần render), vòng lặp không giới hạn hoặc memory tăng dần không kiểm soát (unbounded loop, danh sách/cache phình to không có giới hạn hoặc TTL), thiếu index hoặc caching cho query/tính toán tốn kém lặp lại, và blocking I/O nằm trong hot path (đường xử lý được gọi thường xuyên, đọc file đồng bộ hoặc gọi network đồng bộ chặn event loop/thread).
Prompt cho performance review nên yêu cầu AI không chỉ chỉ ra vấn đề mà còn ước lượng độ nghiêm trọng dựa trên volume dữ liệu thực tế — một N+1 query trên bảng có 10 dòng không đáng lo, nhưng trên bảng có hàng triệu dòng thì là incident chờ xảy ra.
Review this diff for performance issues. Assume the `orders` table
has 5M+ rows and this endpoint is called on every checkout page load
(high traffic, latency-sensitive).
Diff: <paste diff or reference files: src/api/orders/list.ts>
Check specifically for:
1. N+1 queries — any loop that issues a DB call per iteration instead
of a single batched query or join
2. Missing indexes — any new WHERE/JOIN/ORDER BY clause on columns
that may not be indexed; list the columns and check against the
schema in db/schema.sql
3. Unbounded loops or growth — any array/cache/map that grows without
a size limit or eviction policy
4. Blocking I/O in a hot path — any synchronous file read, sync
network call, or CPU-heavy computation inside a request handler
5. For frontend diffs: any component re-rendering due to inline
object/function props, missing useMemo/useCallback, or state
updates that cascade unnecessarily
For each finding, estimate the impact given the scale above (e.g.
"this adds 1 query per order item, at ~20 items/order and 500
checkouts/min this is ~10K extra queries/min") and suggest the fix.
Một lưu ý quan trọng: AI review performance rất giỏi phát hiện pattern (N+1, thiếu index) nhưng không đo được độ trễ thực tế, vì nó không chạy code trong môi trường thật. Với những thay đổi ở đường xử lý quan trọng, đừng dừng lại ở AI review — hãy kết hợp với benchmark hoặc profiling thật trước khi merge.
Mẹo: Luôn cho AI biết scale dữ liệu và traffic thực tế của hệ thống khi hỏi performance review — nếu không, nó sẽ đánh giá mọi N+1 query như nhau, trong khi mức độ nghiêm trọng phụ thuộc hoàn toàn vào volume.
Review Architectural Fit (Phù Hợp Kiến Trúc)
Đây là chiều review khó nhất để làm tốt với AI, vì nó đòi hỏi hiểu biết về convention và pattern hiện có trong toàn bộ codebase — không chỉ đọc diff đơn lẻ. Review architectural fit cần trả lời bốn câu hỏi: code mới có tuân theo pattern/convention hiện có trong codebase hay không (ví dụ team dùng repository pattern cho data access, code mới có đi thẳng query DB bỏ qua layer đó không); code mới có tạo ra một abstraction cạnh tranh (competing abstraction) với cái đã có hay không (ví dụ đã có một ApiClient chung nhưng code mới tự viết một hàm gọi HTTP riêng); code mới có tôn trọng ranh giới module/layering hay không (ví dụ tầng UI import thẳng vào tầng data access, bỏ qua service layer ở giữa); và code mới có tạo ra tech debt đi ngược hướng team đang nhắm tới hay không (ví dụ team đang dần chuyển từ REST sang GraphQL, nhưng code mới lại thêm một REST endpoint mới).
Để AI review được chiều này một cách có ý nghĩa, bạn phải cho nó cách "nhìn" vào codebase hiện có, không chỉ diff. Nếu bạn dùng agent có quyền đọc filesystem (như Claude Code), hãy để nó tự đi tìm các file tương tự để so sánh pattern, thay vì mô tả convention bằng lời — mô tả bằng lời thường thiếu chi tiết và dễ lệch so với thực tế trong code.
Review this diff for architectural fit with the rest of the codebase.
New code: src/features/payments/discount-service.ts
Before judging, first explore the codebase to understand existing
conventions:
1. Find 2-3 existing "service" modules under src/features/*/
(e.g. src/features/orders/order-service.ts) and note their
common structure: how they access the DB, how they handle errors,
how they're tested, how they're exposed to controllers
2. Check src/lib/db/ to see the established data-access pattern
(repository, query builder, raw SQL?)
3. Check CLAUDE.md or ARCHITECTURE.md if present for stated
conventions
Then evaluate the new diff against what you found:
- Does it follow the same structural pattern as other services, or
does it introduce a new/different way of doing the same thing?
- Does it duplicate functionality that already exists elsewhere
(e.g. a new HTTP client, a new validation helper) instead of reusing it?
- Does it access the database directly instead of going through the
established data-access layer?
- Does it cross module boundaries it shouldn't (e.g. payments code
importing directly from the orders internals instead of orders'
public API)?
Report each mismatch with: what convention exists, what this diff
does differently, and why that matters (maintenance cost, confusion
for future readers, inconsistency risk).
Cần lưu ý là AI có thể tìm sai "convention chuẩn" nếu codebase của bạn vốn không nhất quán (nhiều pattern cũ mới lẫn lộn do lịch sử refactor dở dang) — trong trường hợp đó, review architectural fit cần có con người xác nhận đâu là hướng đi đúng mà team đang nhắm tới, AI không tự biết được "hướng tương lai" nếu không ai nói cho nó biết.
Mẹo: Trước khi hỏi AI review architectural fit, bắt nó tự explore 2-3 module tương tự đã có trong codebase để rút ra convention thực tế — đừng tự mô tả convention bằng lời, vì mô tả tay thường sai lệch so với code thật.
Những Gì AI Reviewer Bỏ Sót — Và Vì Sao Human Review Vẫn Quan Trọng
Dù AI review mạnh ở việc phát hiện pattern lỗi lặp lại, nó có những giới hạn nền tảng mà không prompt nào khắc phục hoàn toàn được. Giới hạn đầu tiên là AI không biết những convention bất thành văn (unwritten conventions) và bối cảnh chính trị nội bộ team (political context) — ví dụ "team đã quyết định không dùng thư viện X nữa sau một incident năm ngoái, dù nó vẫn còn trong codebase cũ", hoặc "feature này đang được xây tạm để demo cho khách hàng tuần sau, chất lượng code không cần hoàn hảo ở giai đoạn này". Những thông tin này chỉ tồn tại trong đầu con người, trong Slack thread cũ, trong cuộc họp không ghi chép — AI hoàn toàn không tiếp cận được trừ khi ai đó gõ nó ra trong prompt.
Giới hạn thứ hai là AI không đánh giá được product/business tradeoff. Một AI reviewer có thể chỉ ra "hàm này xử lý discount code theo cách phức tạp hơn cần thiết", nhưng nó không biết rằng độ phức tạp đó tồn tại vì sales team đã cam kết với một khách hàng lớn về một loại discount đặc biệt. Quyết định "độ phức tạp này có đáng đánh đổi hay không" là quyết định kinh doanh, không phải quyết định kỹ thuật thuần túy — và chỉ con người có đủ context để quyết định.
Giới hạn thứ ba, tinh vi hơn: AI có thể hallucinate confidence (tự tin một cách sai lầm) trên logic phức tạp. Nó có thể tuyên bố chắc chắn "hàm này xử lý đúng mọi trường hợp" trong khi thực chất bỏ sót một nhánh logic tinh vi — vì bản chất AI generate câu trả lời có vẻ hợp lý (plausible), không phải luôn luôn verify từng nhánh một cách máy móc như một model checker thực thụ. Điều này nguy hiểm hơn cả việc AI im lặng không nói gì, vì reviewer con người dễ bị thuyết phục bởi giọng điệu tự tin và bỏ qua việc tự kiểm tra lại.
Cuối cùng là accountability (trách nhiệm giải trình). Khi một bug lọt ra production, tổ chức cần biết ai đã duyệt, ai chịu trách nhiệm, và ai học được bài học gì để lần sau làm tốt hơn. AI không thể "chịu trách nhiệm" theo nghĩa đó — nó không có sự nghiệp, không học từ một sai lầm cụ thể theo cách một kỹ sư con người học. Vì vậy, dù AI review có thể là gatekeeper đầu tiên rất hiệu quả, sign-off cuối cùng — đặc biệt cho những thay đổi rủi ro cao, ảnh hưởng tới tiền bạc, dữ liệu người dùng, hoặc quyết định kiến trúc dài hạn — vẫn phải là một con người có tên, có trách nhiệm, đặt chữ ký (approve) của mình vào đó.
Mẹo: Với những PR chạm tới tiền, dữ liệu nhạy cảm, hoặc quyết định kiến trúc dài hạn, luôn yêu cầu ít nhất một human approval thực sự đọc hiểu — đừng bao giờ để AI approval thay thế hoàn toàn cho bước này.
Thực Hành: Code Review Đầy Đủ 4 Chiều
Hãy đi qua một ví dụ cụ thể: PR thêm tính năng "discount code" (mã giảm giá) vào flow checkout của một ứng dụng e-commerce. Diff bao gồm 3 file: src/checkout/discount.ts (logic validate và áp dụng mã giảm giá), src/api/checkout/apply-discount.ts (endpoint xử lý request), và src/checkout/order.ts (cập nhật lại tổng tiền đơn hàng). Đây là quy trình review thực tế theo 4 lượt hỏi tuần tự.
Bước 1 — Correctness. Dán acceptance criteria từ ticket ("mã hết hạn phải bị từ chối rõ ràng, tổng tiền không đổi; mã dùng quá số lần cho phép phải bị từ chối; giảm giá không được làm tổng tiền âm") kèm prompt review correctness đã mô tả ở phần trên. Kết quả review giả định thực tế mà một reviewer tốt sẽ tìm ra: hàm applyDiscount() kiểm tra expiresAt < now nhưng dùng < thay vì <=, khiến mã hết hạn đúng vào thời điểm hiện tại (edge case hiếm nhưng có thể xảy ra) vẫn được chấp nhận; đồng thời không có test nào cho trường hợp discount làm giá trị đơn hàng xuống dưới 0 khi mã giảm giá là fixed-amount trên đơn hàng giá trị nhỏ.
Bước 2 — Security. Chạy prompt security review với checklist injection/authz/secrets/deserialization/SSRF/dependencies đã nêu ở trên, trỏ vào cùng 3 file. Phát hiện thực tế: endpoint apply-discount.ts nhận orderId từ body request và query thẳng đơn hàng theo orderId mà không kiểm tra order.userId === currentUser.id — đây là lỗi Broken Object-Level Authorization (BOLA/IDOR) kinh điển, cho phép user A áp mã giảm giá lên đơn hàng của user B chỉ bằng cách đổi orderId trong request.
Bước 3 — Performance. Chạy prompt performance review, cho AI biết bảng discount_codes có thể lên tới hàng trăm nghìn mã và endpoint này được gọi mỗi lần user nhập mã ở trang checkout (tần suất cao). Phát hiện thực tế: hàm validateDiscountCode() load toàn bộ danh sách discount code đang active vào memory rồi lọc bằng JavaScript .find(), thay vì query trực tiếp theo mã code với index — đây là vấn đề sẽ chậm dần khi số lượng mã tăng lên, và không tận dụng được index có sẵn trên cột code.
Bước 4 — Architectural Fit. Chạy prompt architectural fit, cho AI tự explore các service khác trong src/checkout/ và src/features/. Phát hiện thực tế: các module khác trong codebase đều dùng repository pattern qua src/lib/db/repository.ts, nhưng discount.ts mới lại gọi thẳng db.query() — không nhất quán với convention, khiến việc mock trong test và thay đổi data layer sau này khó khăn hơn; ngoài ra logic tính tổng tiền sau giảm giá bị viết trùng lặp một phần trong order.ts thay vì tái sử dụng hàm calculateOrderTotal() đã có sẵn.
Sau 4 lượt review, bạn có một danh sách cụ thể: 1 correctness bug (off-by-one ở điều kiện hết hạn), 1 lỗ hổng bảo mật nghiêm trọng (IDOR), 1 vấn đề performance (thiếu index lookup), 2 vấn đề architectural fit (không dùng repository pattern, trùng lặp logic tính tổng tiền). Đây là lúc human reviewer vào cuộc — không phải để tìm lại từ đầu, mà để đánh giá độ ưu tiên (IDOR phải fix trước khi merge, vấn đề kiến trúc có thể để lại thành follow-up ticket nếu deadline gấp) và quyết định cuối cùng có approve hay không.
Mẹo: Luôn chạy đủ 4 lượt review theo thứ tự correctness → security → performance → architecture trên mọi PR quan trọng, và tổng hợp kết quả thành một checklist duy nhất trước khi đưa cho human reviewer — đừng để họ phải tự ghép các nhận xét rời rạc lại với nhau.
Những điểm chính
- AI code review là lớp lọc đầu tiên hiệu quả, giúp bắt lỗi máy móc trước khi con người phải nhìn vào diff, nhưng không thay thế human sign-off.
- Tách riêng từng lượt review theo 4 chiều (correctness, security, performance, architectural fit) thay vì gộp chung một prompt — mỗi chiều cần một "mindset" và checklist riêng để AI đào sâu thay vì lướt qua.
- Correctness review cần acceptance criteria đi kèm; không có nó, AI chỉ kiểm tra được tính nhất quán nội tại, không kiểm tra được đúng yêu cầu nghiệp vụ.
- Security review nên dùng checklist cụ thể theo từng vulnerability class (injection, authz, secrets, deserialization, SSRF, dependencies) thay vì câu hỏi mơ hồ.
- Performance review cần biết scale dữ liệu và traffic thực tế để đánh giá đúng mức độ nghiêm trọng của N+1 query hay thiếu index.
- Architectural fit review đòi hỏi AI tự explore codebase hiện có để rút ra convention thật, thay vì dựa vào mô tả bằng lời có thể lệch thực tế.
- AI reviewer không biết convention bất thành văn, bối cảnh chính trị nội bộ, không đánh giá được trade-off kinh doanh, có thể hallucinate confidence trên logic phức tạp, và không thể chịu trách nhiệm giải trình — vì vậy PR rủi ro cao luôn cần một human approval thực chất.
- Quy trình thực hành tốt nhất: chạy 4 lượt review AI theo thứ tự, tổng hợp thành một checklist, rồi để human reviewer tập trung vào việc ưu tiên và ra quyết định cuối cùng.