Đang tải...

Ếch Trendy

Cùng chú ếch nhỏ khám phá thế giới Web đầy biến động. Cập nhật trending nhanh như cách ếch đớp mồi! ⌨️🌿


0

AI Coding Workflow: Vibe Coding Với Prompt, Context Và Refactor Thông Minh

Ếch Trendy
Ếch Trendy

4 tháng trước · 8 phút đọc

Tại sao "vibe coding" không phải là gõ phím rồi copy-paste

Mình từng nghĩ dùng AI để code nghĩa là: hỏi → lấy code → paste vào editor → chạy. Kết quả? Sau 30 phút, file component dài 400 dòng, không có type nào đúng, logic rối như mớ bòng bong, và mình không hiểu gì trong đó.

Vấn đề không phải ở AI. Vấn đề là cách mình dùng nó.

"Vibe coding" - thuật ngữ do Andrej Karpathy đặt ra - mô tả trạng thái làm việc cùng AI theo flow tự nhiên: bạn có ý tưởng, bạn diễn đạt nó, AI hiểu và giúp hiện thực hóa. Nhưng để đạt được trạng thái đó, cần 3 thứ: prompt rõ ràng, context đầy đủ, và biết khi nào cần refactor.

Bài này mình sẽ đi vào workflow cụ thể, không lý thuyết suông.

344630 Flow lý tưởng: ý tưởng → prompt → code → refactor, lặp lại nhanh


Viết prompt tốt: từ "làm cái này" đến "làm cái này theo cách này"

Prompt tệ: Tạo component button cho React

Prompt tốt:

Tạo Button component trong React + TypeScript.
- Variants: primary, secondary, danger
- Sizes: sm, md, lg
- Props: onClick, disabled, loading (hiển thị spinner khi loading)
- Dùng Tailwind CSS
- Không dùng thư viện ngoài
- Export default, có interface Props

Khác biệt ở đâu? Prompt tốt trả lời 4 câu hỏi mà AI cần biết:

  1. Công nghệ - React + TypeScript + Tailwind (không phải Vue, không phải plain CSS)
  2. Behavior - có loading spinner, disabled state
  3. Constraints - không dùng thư viện ngoài
  4. Output format - export default, có interface

344631 Prompt rõ ràng = ít vòng lặp sửa = tiết kiệm thời gian thực sự

Một mẹo mình hay dùng: viết prompt theo dạng "Tôi cần X, với điều kiện Y, output là Z". Ví dụ:

Tôi cần một custom hook useFetch trong React.
Điều kiện: TypeScript, generic type T, handle loading/error/data state,
có cleanup khi unmount, không dùng axios (chỉ fetch API).
Output: file hook riêng, có JSDoc comment.

Kết quả sẽ khác hẳn so với chỉ gõ tạo useFetch hook.


Context là thứ quyết định AI hiểu bạn hay không

AI không biết codebase của bạn trông như thế nào. Nếu bạn hỏi "sửa bug này" mà không cho AI thấy đoạn code liên quan, file config, hay error message đầy đủ - bạn đang hỏi người mù tả con voi.

Context cần cung cấp theo thứ tự ưu tiên:

1. Code hiện tại - paste đoạn code đang bị lỗi hoặc cần sửa, kèm file structure nếu cần.

2. Error message đầy đủ - không phải "bị lỗi", mà paste nguyên stack trace.

3. Môi trường - Next.js 14 với App Router hay Pages Router? Node 18 hay 20? Quan trọng hơn bạn nghĩ.

4. Những gì bạn đã thử - giúp AI không đề xuất giải pháp bạn vừa thử xong.

344632 Context đầy đủ giúp AI tránh đề xuất giải pháp sai môi trường

Ví dụ thực tế: mình từng debug 1 giờ vì paste code mà không nói là đang dùng Next.js 14 App Router. AI cứ đề xuất cách dùng getServerSideProps - thứ không tồn tại trong App Router. 5 phút sau khi thêm context đó vào prompt, vấn đề được giải quyết.

Một pattern mình recommend cho Next.js projects:

Project: Next.js 14, App Router, TypeScript, Tailwind CSS
Vấn đề: [mô tả]
Code hiện tại:
[paste code]

Error:
[paste error]

Đã thử: [những gì đã thử]

Template đơn giản này tiết kiệm trung bình 3-4 vòng lặp hỏi đáp.


Chia nhỏ task: đừng bắt AI viết cả feature một lúc

Một trong những sai lầm phổ biến nhất: mô tả cả một feature phức tạp rồi mong AI ra code chạy ngay. Kết quả thường là code có vẻ đúng nhưng có lỗi ẩn, thiếu edge case, và bạn mất nửa buổi để debug.

Thay vào đó, chia nhỏ theo nguyên tắc "một prompt, một responsibility".

Ví dụ build trang product listing cho e-commerce với React:

Đừng làm vậy:

Tạo trang product listing với filter, sort, pagination, search,
add to cart, wishlist, và responsive layout.

Làm thế này:

Bước 1: Tạo ProductCard component (chỉ hiển thị data)
Bước 2: Tạo useProducts hook (fetch + state management)
Bước 3: Tạo FilterBar component (UI only, không logic)
Bước 4: Connect FilterBar với useProducts hook
Bước 5: Thêm pagination
...

344633 Chia nhỏ task = mỗi bước có thể test độc lập, lỗi dễ tìm hơn

Lợi ích thật ra rất thực tế: mỗi step bạn có thể review code ngắn hơn, test được ngay, và nếu AI sai thì chỉ sai ở một chỗ nhỏ thay vì sai toàn bộ feature.

Mình thường dùng pattern này với Cursor hoặc Claude: bắt đầu bằng data layer (hook, API call), sau đó UI layer (component không state), rồi mới connect hai thứ lại. Cách này cũng tự nhiên tạo ra code có separation of concerns tốt hơn.


Dùng AI để refactor, không chỉ để sinh code

Đây là phần mà 9.8 giờ/tuần viết code mới với AI (Digital Applied) dev bỏ qua - dùng AI như một người review code thay vì chỉ là máy sinh code.

Mình hay dùng AI theo 3 cách refactor:

1. Đơn giản hóa logic phức tạp

Paste đoạn code rồi hỏi: "Đoạn này làm gì? Có cách nào viết ngắn hơn mà vẫn rõ không?"

Thường AI sẽ chỉ ra được Array.reduce đang làm gì mà không cần 20 dòng vòng lặp, hoặc một chain của filter().map() có thể gộp lại.

2. Thêm TypeScript types cho code JavaScript cũ

Tôi có đoạn JS này (paste code). Hãy:
1. Thêm TypeScript types
2. Đặt interface/type riêng ra đầu file
3. Dùng generic nếu phù hợp
4. Không thay đổi logic

Constraint cuối cùng quan trọng: "không thay đổi logic" ngăn AI tự ý refactor những thứ bạn không muốn đụng đến.

3. Tìm potential bugs và edge cases

Review đoạn code này và liệt kê:
- Potential bugs (đặc biệt với undefined/null)
- Edge cases chưa handle
- Performance issues nếu có
KHÔNG sửa code, chỉ liệt kê vấn đề.

344634 AI như code reviewer 24/7 - nhưng bạn vẫn phải là người quyết định cuối

Vì sao thêm "KHÔNG sửa code"? Vì nếu không, AI sẽ tự động rewrite toàn bộ, và bạn lại rơi vào vòng lặp không kiểm soát được.

Workflow refactor mình thấy hiệu quả nhất: chạy AI review trước khi tạo PR. Chỉ mất 5 phút nhưng thường catch được 2-3 vấn đề mà bản thân không để ý khi đang code.


Workflow thực tế: build một feature Next.js từ đầu đến cuối

Mình lấy ví dụ cụ thể: build trang blog với Next.js 14 App Router, có filter theo category và infinite scroll.

Bước 1 - Prompt khởi động với đủ context:

Dự án: Next.js 14 App Router, TypeScript, Tailwind CSS
Mục tiêu: Trang blog listing tại /blog
Data source: API endpoint GET /api/posts?page=1&category=all
Response format: { posts: Post[], total: number, hasMore: boolean }

Tạo interface Post và custom hook usePostsWithFilter:
- State: posts, loading, error, hasMore
- Actions: fetchMore(), setCategory()
- Dùng useCallback cho fetchMore

Bước 2 - Sau khi có hook, build UI:

Tôi đã có usePostsWithFilter hook (paste hook vào đây).
Tạo PostList component:
- Nhận posts prop với type Post[]
- Hiển thị dạng grid 3 cột (responsive: 1 col mobile, 2 col tablet)
- Mỗi item dùng PostCard component (chưa tạo, chỉ cần placeholder)
- Dùng Tailwind CSS

Bước 3 - Review trước khi tiếp tục:

Review hook usePostsWithFilter này:
- Có memory leak không (cleanup effect)?
- Race condition khi category thay đổi nhanh?
- Loading state có đúng không khi fetchMore?
Không sửa, chỉ liệt kê vấn đề.

344635 3 bước lặp lại: build → review → fix, mỗi vòng ngắn và kiểm soát được

Sau bước review, mình mới sửa những vấn đề AI chỉ ra, rồi tiếp tục build PostCard. Pattern này mình dùng cho mọi feature phức tạp.

Muốn nắm vững React trước khi apply workflow này? Khóa Xây Dựng Website với ReactJS trên F8 cover từ hook cơ bản đến các pattern nâng cao - free hoàn toàn.

Tải template prompt workflow này để dùng ngay: Tải bộ template prompt AI coding

Trang web dùng cookie để hoạt động và đo hiệu quả quảng cáo. Xem chính sách bảo mật