Hướng dẫn

Lập trình cặp với AI mà không phá kiến trúc repo

Đăng 2026-11-09 · Bản dịch: EN

Lập trình cặp với AI hữu ích khi bạn coi model như một junior nhanh cần biên giới rõ. Nó có hại khi bạn dán một mục tiêu mơ hồ, chấp nhận diff lớn, rồi một tuần sau phát hiện nửa logic domain nằm trong helper ngẫu nhiên. Bài này là vòng làm việc có thể tái dùng trên repo thật: ràng buộc nhiệm vụ, sinh code theo lát mỏng, review theo luật kiến trúc, rồi mới merge.

Minh họa nhanh

Bộ ràng buộc trước khi prompt: được phép, cấm, định nghĩa xong.

Bộ ràng buộc trước khi prompt: được phép, cấm, định nghĩa xong.

Vòng cắt nhỏ: prompt → diff → cổng review → merge.

Vòng cắt nhỏ: prompt → diff → cổng review → merge.

Chỉ đụng vùng được phép; giữ kiến trúc lõi ngoài phạm vi.

Chỉ đụng vùng được phép; giữ kiến trúc lõi ngoài phạm vi.

Bắt đầu bằng bộ ràng buộc viết sẵn

Trước prompt đầu tiên, ghi ba ghi chú ngắn trong chat hoặc trong file skill dự án:

  1. Bề mặt được phép — package, thư mục hoặc module nào agent được đụng.
  2. Động thái cấm — ví dụ “không thêm state library mới,” “không tự bịa HTTP client,” “không chuyển type dùng chung ra khỏi src/domain.”
  3. Định nghĩa xong việc — test cần chạy, file phải đổi, file tuyệt đối không được đụng.

Các ghi chú này quan trọng hơn prompt khéo. Model tối ưu để hoàn thành nhiệm vụ đã nêu. Nếu bạn không nêu kiến trúc, chúng sẽ tự bịa một kiến trúc vừa khít yêu cầu cục bộ.

Giữ bộ ràng buộc đủ ngắn để bạn thật sự tái dùng. Tuyên ngôn 40 dòng thường bị bỏ qua. Sáu gạch đầu dòng thì được tuân theo.

Cắt việc thành đơn vị review được

Mỗi lượt chỉ hỏi một lát dọc hoặc một mối quan tâm:

  • “Thêm validation cho field form này và nối với error component hiện có.”
  • “Tách format ngày trùng lặp sang util dùng chung mà repo đã có.”
  • “Viết test fail cho bug trong InvoiceService, rồi mới implement fix.”

Tránh mega-prompt kiểu “refactor auth rồi thêm OAuth rồi dọn API layer.” Những prompt đó tạo patch trông mạch lạc nhưng xuyên biên module và tốn kém khi rollback.

Heuristic kích thước hữu ích: nếu bạn không lướt diff trong hai phút mà vẫn biết kiến trúc có bị phá hay không, lát cắt còn quá lớn. Cắt nhỏ lại.

Đưa bản đồ cho model, không đưa cả thành phố

Dán hoặc @-mention:

  • interface và call site gần nhất
  • thư mục sở hữu concern đó
  • một hoặc hai ví dụ pattern local (đặt tên, xử lý lỗi, logging)

Đừng dump cả repository vào context theo mặc định. File thừa làm tăng khả năng model “hữu ích” rewrite code xa để khớp style mới. Ưu tiên con trỏ tường minh: “theo pattern trong payments/CheckoutForm.tsx; không đụng billing.”

Khi nhiệm vụ xuyên layer (UI → API → persistence), vẫn ràng buộc từng layer theo thứ tự. Ổn định thay đổi domain trước khi nhờ polish UI.

Cổng review bắt lỗi phá kiến trúc

Review của người phải trả lời câu hỏi cụ thể, không chỉ “có compile không?”

Kiểm biên. Code mới có import xuyên layer vốn đã tách không? File UI có bắt đầu nói chuyện với database client không? Package dùng chung có mọc dependency gắn feature cụ thể không?

Kiểm trùng. Model có viết lại thứ đã tồn tại dưới tên hơi khác không? Tìm helper anh em trước khi chấp nhận file “util mới.”

Kiểm bề mặt API. Type công khai, route hoặc hàm export có bị mở rộng tùy tiện không? Ưu tiên helper nội bộ cho đến khi shape đã chứng minh được.

Kiểm test. Test đang assert hành vi bạn quan tâm, hay chỉ assert mock được gọi? Một test đường đi thật đáng hơn năm spy tương tác dễ gãy.

Vệ sinh diff. Từ chối rename dư thừa, viết lại comment và churn format trộn vào feature. Bảo agent revert nhiễu rồi nêu lại patch.

Trình tự cổng thực dụng:

  1. Đọc danh sách file trước. Từ chối path bất ngờ ngay.
  2. Lướt import và export.
  3. Đọc logic lõi.
  4. Chạy test hẹp nhất cho khu vực đó.
  5. Chỉ sau đó mới nghĩ tới format rộng hoặc docs.

Pattern prompt giữ kiến trúc nguyên

Prompt ràng buộc trước

Chỉ trong src/billing. Tái dùng Money và InvoiceStatus. Không thêm thư viện. Thêm hàm đánh dấu invoice quá hạn sau dueDate và trả về error union hiện có. Viết plan năm gạch đầu dòng, rồi chờ.

Lập kế hoạch trước code giảm việc tạo file bất ngờ. Nếu plan đã phá luật, sửa trước khi sinh code.

Prompt giới hạn diff

Đổi tối đa ba file. Nếu cần nhiều hơn, dừng và giải thích vì sao.

Prompt khớp pattern

Xử lý lỗi giống createSubscription.ts. Cùng Result type, cùng logging helper.

Prompt sửa (sau patch xấu)

Revert utils/date2.ts mới. Dùng formatDate từ src/lib/date.ts. Giữ hành vi giống hệt.

Prompt sửa phải cụ thể như prompt feature. “Dọn giúp” mời lần swing kiến trúc thứ hai.

Dùng test làm hợp đồng, không phải phần phụ

Khi fix bug, hãy yêu cầu test fail trước. Với feature, yêu cầu test khóa hành vi công khai bạn muốn giữ. Điều này làm hai việc: ép interface rõ hơn, và làm lộ ra khi model giải bài khác với bài bạn nêu.

Nếu khu vực đích thiếu test, tự viết một characterization test mỏng trước khi mời AI sửa lớn. Module không cover là nơi agent bịa cấu trúc hung hãn nhất.

Khi nào đổi công cụ giữa chừng

Chat UI ổn cho thảo luận thiết kế, phác API và review snippet dán vào. IDE agent tốt hơn khi cần điều hướng nhiều file kèm project rule. Không cái nào thay người sở hữu bản đồ module.

Rời agent khi:

  • bước tiếp theo cần quyết định sản phẩm, không phải quyết định code
  • bạn sắp chấp nhận “fix nhỏ” lần thứ tư liên tiếp trên cùng file
  • model bắt đầu rename symbol để “làm rõ” dù bạn không yêu cầu

Lúc đó hãy dừng sinh code. Viết quyết định xuống. Tiếp tục bằng prompt hẹp hơn.

Vòng lặp hàng ngày có thể lặp lại

  1. Chọn một outcome vừa một PR ngắn.
  2. Dán ràng buộc và ví dụ liên quan.
  3. Bắt buộc plan ngắn; duyệt hoặc sửa.
  4. Sinh patch nhỏ nhất.
  5. Chạy cổng local: danh sách file, import, test.
  6. Commit với message nói ý định, không nói tên tool.
  7. Cập nhật ghi chú ràng buộc nếu học thêm một “không được.”

Sau vài tuần, ghi chú ràng buộc trở thành hướng dẫn kiến trúc nhẹ. Hướng dẫn đó giá trị hơn bất kỳ hàm sinh nào, vì nó dạy mọi session sau cách không phá repo.

“Tốt” trông như thế nào sau một tháng

Bạn sẽ thấy PR nhỏ hơn, ít module bất ngờ hơn, và ít thời gian tháo abstraction khéo. Model vẫn sẽ sai. Khác biệt là lỗi nằm cục bộ, đảo ngược được và review được — vì bạn không bao giờ giao cả kiến trúc như một prompt mở.

Nội dung mang tính giáo dục. Ranking phản ánh tiêu chí đã nêu tại thời điểm cập nhật — không phải lời khuyên đầu tư hay cam kết hiệu năng vĩnh viễn.