Dùng AI coding agent có trách nhiệm trong team Java
Tiếp đi: AI coding agent. Team mình bắt đầu dùng agent viết code cho shop-app. Tuần trước nó viết webhook handler chạy được nhưng thiếu idempotency, suýt lên production. Dùng sao cho an toàn?
Chuyện đó rất điển hình: code của AI trông đúng và chạy được, nhưng thiếu những thứ bạn không nói ra. Nguyên tắc cả bài: AI là đồng đội viết nhanh, bạn vẫn là người chịu trách nhiệm cho từng dòng merge.
1. Bài toán
Prompt: "viết webhook handler cho provider B"
AI trả: @PostMapping("/webhooks/b") ... cập nhật order = PAID
Thiếu:
- verify chữ ký webhook
- idempotency (B retry 5 lần)
- transaction + outbox như các handler khác trong repo
- test cho case event đến 2 lần
2. Vấn đề
- Prompt thiếu context: AI không biết convention của repo, ràng buộc business.
- Review lỏng vì "AI viết chắc ổn", diff dài nên đọc lướt.
- Rủi ro bảo mật: dán secret, dữ liệu khách vào prompt; AI hardcode key trong code.
- Rủi ro license: đoạn code giống hệt thư viện có license không tương thích.
- Dev junior dùng AI nhưng không hiểu code, không debug được khi lỗi.
3. Giải pháp: 4 vai trò của AI, 1 vai trò của bạn
| AI làm | Ví dụ trên shop-app | Bạn phải |
|---|---|---|
| Viết code (pair) | Adapter cho provider B theo interface có sẵn | Cho context, đọc diff, chạy test |
| Reviewer thứ hai | "Review PR này về idempotency và transaction" | Lọc ý đúng, không merge chỉ vì AI OK |
| Viết test | Sinh test case biên cho PriceCalculator | Kiểm tra test assert đúng hành vi, không chỉ cho xanh |
| Người phỏng vấn | Mock interview theo bài trong guide | Trả lời thật, nhờ chấm và đào sâu |
| Bạn: quyết định, chịu trách nhiệm, hiểu từng dòng được merge. | ||
4. Ví dụ và mẫu dùng ngay
Mẫu 1: Prompt có context
Yếu:
"viết webhook handler cho provider B"
Tốt:
Bối cảnh: shop-app, Spring Boot 3, Java 21, PostgreSQL, Flyway.
Xem PaymentWebhookController (provider A) và làm theo cùng pattern.
Yêu cầu:
- POST /webhooks/provider-b, verify HMAC header X-B-Signature
bằng secret từ ${PROVIDER_B_WEBHOOK_SECRET}
- Idempotent theo eventId (bảng processed_events, unique)
- Cập nhật order + ghi outbox trong 1 transaction
- Trả 2xx khi event đã xử lý trước đó
Ràng buộc: không thêm dependency mới, không đổi API public.
Viết test: chữ ký sai → 401, event trùng → không cập nhật lần 2.
Trước khi code, liệt kê kế hoạch và câu hỏi nếu có.
Câu cuối quan trọng: bắt AI nêu kế hoạch để bạn sửa hướng sớm, rẻ hơn sửa code.
Mẫu 2: Checklist verify output của AI
[ ] Đọc toàn bộ diff, từng file (git diff), không chỉ đọc tóm tắt của AI
[ ] Chạy ./mvnw verify ở máy mình, CI xanh
[ ] Test có assert hành vi thật? Thử làm hỏng code → test có đỏ không?
[ ] Có thêm dependency? Version, license, có thật tồn tại (không bị "bịa")?
[ ] Có secret, URL nội bộ, log dữ liệu cá nhân?
[ ] Có đổi file ngoài phạm vi yêu cầu?
[ ] Mình giải thích được từng dòng cho reviewer không?
Mục "làm hỏng code → test có đỏ không" bắt được kiểu test AI viết cho có, chỉ assert notNull.
Mẫu 3: AI làm reviewer
"Review diff dưới đây như senior Java engineer. Tập trung:
1. Race condition và transaction boundary
2. Idempotency khi provider retry
3. Lỗi bảo mật (input validation, secret, log PII)
Chỉ ra dòng cụ thể và mức độ (blocking/suggestion). Không sửa style."
AI review là lớp lọc thêm, không thay reviewer người. Quy trình review xem bài ADR & code review.
Mẫu 4: Security và secrets
| Không làm | Làm |
|---|---|
Dán application-prod.yml có key vào prompt | Dùng placeholder ${PROVIDER_B_API_KEY}; secret ở vault/env |
| Dán log có email, số điện thoại khách | Che dữ liệu trước khi dán |
| Cho agent quyền chạy lệnh tùy ý với credential production | Agent chạy trong môi trường dev, quyền tối thiểu, mình duyệt lệnh nguy hiểm |
| Dùng tool AI công ty chưa duyệt cho code nội bộ | Theo policy công ty về tool và dữ liệu |
Thêm secret scanning (ví dụ gitleaks) vào pre-commit và CI. Lưới an toàn này bắt cả lỗi của người lẫn AI.
Mẫu 5: Licensing
- Đoạn code dài trông như copy nguyên từ thư viện: hỏi nguồn, kiểm tra license (GPL trong sản phẩm đóng là vấn đề).
- Ưu tiên dùng thư viện chính thức qua dependency thay vì để AI chép lại logic.
- Theo policy công ty: một số nơi bật bộ lọc trùng code public.
Mẫu 6: Luyện phỏng vấn với guide này
"Bạn là interviewer cho vị trí Senior Java Backend.
Dựa vào nội dung bài sau [dán phần 'Phỏng vấn' và 'Tự kiểm tra' của 1 bài]:
1. Hỏi mình từng câu một, không đưa đáp án.
2. Sau mỗi câu trả lời, hỏi đào sâu 1-2 lớp như interviewer thật.
3. Cuối buổi chấm từng câu (1-5): đúng, đủ, rõ ràng, có ví dụ.
4. Với behavioral: kiểm tra mình có theo STARR, có số, có 'em' không."
Cách luyện hiệu quả:
- Trả lời bằng giọng nói (hoặc gõ) trước, rồi mới so với đáp án 🇻🇳/🇬🇧 trong guide.
- Nhờ AI sửa bản tiếng Anh cho tự nhiên, nhưng giữ ý của mình.
- Dán story bank (bài 20.5) và nhờ AI đóng vai interviewer khó tính hỏi "sao không làm cách khác?".
- Kiểm chứng kiến thức kỹ thuật AI đưa ra bằng docs chính thức hoặc chạy thử code. AI có thể sai tự tin.
5. Cách hoạt động: vòng làm việc với agent
Bạn: mục tiêu + context + ràng buộc
|
v
AI: kế hoạch ──> bạn duyệt / sửa hướng
|
v
AI: code + test (bước nhỏ, commit nhỏ)
|
v
Bạn: đọc diff ─> chạy test ─> thử làm hỏng ─> check secret/license
| |
| ổn | không ổn
v v
PR với mô tả rõ (có ghi dùng AI Feedback cụ thể cho AI, lặp lại
nếu team yêu cầu) ─> review người
6. So sánh
| Dùng AI tệ | Dùng AI tốt | |
|---|---|---|
| Prompt | Một dòng | Context, pattern trong repo, ràng buộc, test mong muốn |
| Kích thước | Cả feature một lần, diff 2.000 dòng | Bước nhỏ, mỗi bước review được |
| Verify | "Chạy được là được" | Đọc diff, test, thử làm hỏng |
| Trách nhiệm | "AI viết mà" | "Em merge thì em chịu trách nhiệm" |
7. Khi nào nên / không nên
- Nên: boilerplate, test case biên, migration script nháp, đọc hiểu code lạ, viết tài liệu, refactor có test bảo vệ.
- Cẩn thận: code đường tiền, bảo mật, concurrency. Dùng được, nhưng review gấp đôi.
- Không nên: dán dữ liệu khách hoặc secret; dùng khi bạn không đủ hiểu để review kết quả.
Junior trong team giờ cái gì cũng hỏi AI, code nhanh nhưng hỏi lại thì không giải thích được. Mình nên cấm không?
Không nên cấm, vì cấm thì họ vẫn dùng lén và bạn mất cơ hội dạy. Đặt chuẩn thay vì cấm:
- Luật "giải thích được": PR nào cũng phải giải thích được từng dòng khi review. Không giải thích được thì chưa merge.
- Dùng AI như gia sư: "giải thích vì sao
@Transactionaltrên method private không chạy", thay vì "sửa lỗi này hộ tôi". - Pair với AI có người: thỉnh thoảng bạn ngồi cùng junior xem cách họ prompt và verify. Đây là mentoring kiểu mới (xem bài 20.4).
Có cần ghi trong PR là code do AI viết không?
Tùy policy công ty, nhưng xu hướng chung là minh bạch. Nhiều team ghi trailer trong commit hoặc một dòng trong PR description. Lợi ích:
- Reviewer biết để chú ý các lỗi kiểu AI (API bịa, test hời hợt).
- Dễ truy vết nếu sau này có vấn đề license.
Dù ghi hay không, trách nhiệm không đổi: người mở PR chịu trách nhiệm.
Phỏng vấn hỏi "Bạn dùng AI trong công việc thế nào?" và "Làm sao đảm bảo code AI viết là đúng?" thì trả lời sao?
Q1. Bạn dùng AI trong công việc thế nào?
🇻🇳 Tiếng Việt:
Em dùng AI agent như một đồng đội viết nhanh: sinh boilerplate, test case biên, đọc code lạ, và làm reviewer thứ hai. Em luôn đưa context rõ: pattern trong repo, ràng buộc, test mong muốn, và bắt nó nêu kế hoạch trước khi code. Em làm từng bước nhỏ để diff đủ nhỏ để đọc kỹ. Với code đường tiền và bảo mật em review kỹ gấp đôi. Em không dán secret hay dữ liệu khách vào prompt.
🇬🇧 English:
I use AI agents like a fast pair programmer: boilerplate, edge-case tests, understanding unfamiliar code, and as a second reviewer. I always give clear context, such as existing patterns in the repo, constraints and expected tests, and I ask for a plan before any code. I work in small steps so each diff is small enough to read carefully. For payment and security code I review twice as hard. I never paste secrets or customer data into prompts.
Q2. Làm sao đảm bảo code AI viết là đúng?
🇻🇳 Tiếng Việt:
Em đối xử với nó như code của một đồng nghiệp mới: đọc toàn bộ diff, chạy test ở máy và CI, kiểm tra test có thật sự bắt lỗi bằng cách thử làm hỏng code, kiểm tra dependency mới có thật và license phù hợp, và quét secret. Nếu em không giải thích được một dòng, em không merge. Ví dụ ở shop-app, nhờ checklist này em bắt được webhook handler AI viết thiếu idempotency.
🇬🇧 English:
I treat it like code from a new teammate: read the full diff, run tests locally and in CI, check that tests actually catch bugs by deliberately breaking the code, verify new dependencies exist and have compatible licenses, and scan for secrets. If I can't explain a line, I don't merge it. In shop-app this checklist caught an AI-written webhook handler that was missing idempotency.
Q3. AI có làm bạn kém đi không? Bạn hướng dẫn junior dùng AI ra sao?
🇻🇳 Tiếng Việt:
Nếu dùng để né hiểu thì có. Em dùng AI để học nhanh hơn: hỏi vì sao, rồi tự kiểm chứng bằng docs hoặc chạy thử. Với junior, em đặt luật "giải thích được từng dòng thì mới merge" và thỉnh thoảng pair để xem cách họ prompt và verify.
🇬🇧 English:
It can, if you use it to avoid understanding. I use it to learn faster: I ask why, then verify against official docs or by running the code. For juniors, I set a rule that you must be able to explain every line before merging, and I occasionally pair with them to see how they prompt and verify.
Cách nhớ ngắn gọn
- Prompt = context + pattern repo + ràng buộc + test + "nêu kế hoạch trước".
- Verify = đọc diff + chạy test + thử làm hỏng + check dependency/license/secret.
- Không secret, không dữ liệu khách trong prompt.
- Người merge chịu trách nhiệm, không phải AI.
- Luyện phỏng vấn: AI hỏi, bạn trả lời trước, rồi mới so đáp án.
Tự kiểm tra
Một prompt tốt cho coding agent cần những gì?
Bối cảnh tech stack, pattern có sẵn trong repo, yêu cầu cụ thể, ràng buộc, test mong muốn, yêu cầu nêu kế hoạch trước.
Làm sao biết test do AI viết có giá trị?
Cố ý làm hỏng code; test phải đỏ. Kiểm tra assert hành vi thật, không chỉ notNull.
Ba rủi ro bảo mật khi dùng AI agent?
Lộ secret/dữ liệu khách qua prompt, AI hardcode secret, agent có quyền quá rộng trên môi trường thật.
Vì sao phải kiểm tra dependency AI thêm vào?
Có thể không tồn tại (bịa), sai version, hoặc license không tương thích.
Ai chịu trách nhiệm code AI viết?
Người mở và merge PR.