The golden rule of refactoring is that observable behavior must stay identical. AI cannot guarantee that without tests. Before asking AI to refactor anything meaningful, ensure coverage exists — or ask the AI to write characterization tests first.
Quy tắc vàng của refactoring là hành vi bên ngoài phải giữ nguyên. AI không thể đảm bảo điều đó nếu không có tests. Trước khi yêu cầu AI refactor bất kỳ thứ gì có ý nghĩa, hãy đảm bảo coverage đã tồn tại — hoặc yêu cầu AI viết characterization tests trước.
1# Step 1 — write characterization tests before touching the code2"Write characterization tests for the UserService class.3Cover every public method. The goal is to document current4behavior, not ideal behavior. Use the existing test patterns5in src/__tests__/."67# Step 2 — refactor in one small step at a time8"Extract the email validation logic from UserService.register()9into a private validateEmail() method. Do not change any other10behavior. Tests must stay green."1112# Step 3 — verify13npm test -- --testPathPattern=UserServiceRefactor theo từng bước nhỏ có thể verify được. Mỗi bước nên có thể commit độc lập.
Effective refactoring prompts specify the goal (what you want changed) and the constraints (what must not change). Missing constraints are the most common reason AI refactors drift out of scope.
Prompt refactor hiệu quả chỉ định rõ mục tiêu (điều bạn muốn thay đổi) và ràng buộc (điều không được thay đổi). Thiếu ràng buộc là nguyên nhân phổ biến nhất khiến AI refactor ngoài tầm kiểm soát.
1# Specify goal + constraints clearly2"Refactor the fetchUser function to use async/await instead of3Promise chains. Do not change the function signature, return type,4or error handling behavior. Existing tests must continue to pass."56# Extract a function7"Extract the discount calculation on lines 55-78 of CartService.ts8into a separate calculateDiscount(items, coupon) function in the9same file. The public API of CartService must not change."1011# Remove duplication12"The validation logic in createUser() and updateUser() is almost13identical. Extract it into a shared validateUserInput(data) helper.14Keep both callers working exactly as before."AI can find and rename a symbol consistently across the entire codebase — including imports, re-exports, and usages in tests. Still review the diff after completion.
AI có thể tìm và đổi tên một symbol nhất quán trên toàn bộ codebase — bao gồm imports, re-exports, và usages trong tests. Vẫn hãy review diff sau khi hoàn thành.
"Rename the UserDTO type to UserPayload across the entire codebase.
Update all imports, type annotations, and JSDoc references.
Do not rename the database column user_dto — only the TypeScript type."When a component or function grows too large, AI can identify natural boundaries and extract them into smaller, reusable units.
Khi một component hoặc function quá dài, AI có thể xác định các ranh giới tự nhiên và trích xuất chúng thành các đơn vị nhỏ hơn, có thể tái sử dụng.
AI is very good at converting nested if/else chains into early returns, replacing callback hell with async/await, or upgrading outdated patterns to idiomatic modern TypeScript.
AI rất giỏi chuyển đổi các chuỗi if/else lồng nhau thành early returns, thay thế callback hell bằng async/await, hoặc nâng cấp các pattern lỗi thời lên idiomatic TypeScript hiện đại.
1# Simplify conditionals2"Refactor the nested if/else in processOrder() to use early returns3and guard clauses. The function logic must not change."45# Modernize syntax6"Convert all .then()/.catch() chains in src/api/ to async/await.7Preserve all existing error handling. Do not touch test files."Ask AI to identify unused exports, parameters, or branches — but verify with your bundler or type checker, as AI may miss dynamic usages.
Yêu cầu AI xác định các export, tham số, hoặc nhánh không được sử dụng — nhưng hãy verify bằng bundler hoặc type checker, vì AI có thể bỏ sót dynamic usages.
After every refactor, the review process is non-negotiable. AI is fast but cannot replace human eyes for spotting subtle behavior changes.
Sau mỗi lần refactor, quy trình review là không thể bỏ qua. AI nhanh nhưng không thể thay thế đôi mắt của con người trong việc phát hiện những thay đổi hành vi tinh vi.
1# Review checklist after an AI refactor21. git diff — read every changed line, not just the summary32. npm test (or bun test) — all tests must pass43. bun run build — no type errors54. Check edge cases: null inputs, empty arrays, error paths65. Check that error messages and log output are unchanged76. If the change touched async code, verify error propagationHãy đặc biệt chú ý đến 'behavior drift' — khi AI tái cấu trúc logic và vô tình thay đổi kết quả ở một edge case. Thường không có error, chỉ có hành vi sai lặng lẽ.
AI refactors most safely within small, well-tested scopes. There are situations where you should slow down or decline entirely.
AI refactor an toàn nhất trong các phạm vi nhỏ, được test tốt. Có một số tình huống bạn nên làm chậm lại hoặc từ chối hoàn toàn.
- Large blast radius: changes affecting dozens of files or a public API with many callers.
Blast radius lớn: thay đổi ảnh hưởng đến hàng chục file hoặc public API được nhiều caller sử dụng.
- No tests: refactoring without tests is betting on AI confidence, not evidence.
Không có tests: refactor mà không có tests là đặt cược vào sự tự tin của AI, không phải bằng chứng.
- Performance-critical code: AI may replace a hand-tuned loop with a more convenient but slower abstraction.
Code critical về hiệu suất: AI có thể thay thế một vòng lặp thủ công bằng một abstraction tiện lợi hơn nhưng chậm hơn.
- Complex concurrent or async logic: race conditions and ordering guarantees are easy to break during restructuring.
Logic đồng thời hoặc async phức tạp: race conditions và ordering guarantees rất dễ bị phá vỡ khi cấu trúc lại.
- Security or cryptography code: any change needs review by someone with security expertise.
Code liên quan đến security hoặc cryptography: bất kỳ thay đổi nào cũng cần được review bởi người có chuyên môn về security.
- Always have tests — or AI-written characterization tests — before refactoring.
Luôn có tests (hoặc characterization tests do AI viết) trước khi refactor.
- Specify both the goal and the constraints in your refactoring prompt: what changes and what must not.
Chỉ định cả mục tiêu và ràng buộc trong prompt refactor của bạn: điều gì thay đổi và điều gì không được thay đổi.
- Refactor in small, committable steps — not one large hard-to-review change.
Refactor theo từng bước nhỏ, có thể commit được — không phải một lần lớn khó review.
- After every refactor: read the diff, run tests and build, check edge cases and error paths.
Sau mỗi lần refactor: đọc diff, chạy tests và build, kiểm tra edge cases và error paths.
- Watch for behavior drift — silent wrong behavior that causes no error but changes outcomes.
Chú ý behavior drift — hành vi sai lặng lẽ không gây ra error nhưng thay đổi kết quả.
- Decline unsupervised refactoring when: large blast radius, no tests, performance-critical paths, or security/concurrent logic.
Từ chối refactor không giám sát khi: blast radius lớn, không có tests, code critical về hiệu suất, hoặc logic security/concurrent.