Bối cảnh & Lý do
Vấn đề: Lệch chuẩn kiến trúc trong mã nguồn do AI tạo ra
Nếu yêu cầu năm lập trình viên cùng dựng khung cho một tính năng bằng trình biên tập tích hợp AI, rất có thể bạn sẽ nhận về năm kiến trúc xung đột nhau. Người thì import Axios trong khi dự án đã chuẩn hóa dùng fetch mặc định. Người khác lại viết React class component. Một người thứ ba lại đưa Redux vào một codebase đang vận hành trên Zustand. Hậu quả là các kỹ sư cấp cao phải tiêu tốn tới 30% thời gian review chỉ để bắt các lỗi lệch phong cách cơ bản và các package đã lỗi thời.
Nguyên nhân gốc rễ: Sự “mù mờ” về ngữ cảnh
Các mô hình ngôn ngữ dự đoán token dựa trên dữ liệu huấn luyện công khai. Khi mới cài đặt, mô hình AI hoàn toàn không biết gì về các quy chuẩn nội bộ, cấu trúc thư mục hay ranh giới kiến trúc trong repository của bạn. Việc nhắc lệnh (prompt) yêu cầu viết một database service mà không cung cấp ngữ cảnh dự án sẽ buộc AI phải “đoán mò”. Nó sẽ mặc định chọn pattern phổ biến nhất trên GitHub công khai—thứ hiếm khi khớp với tiêu chuẩn production của team bạn.
Giải pháp: Rào chắn cố định và giới hạn phạm vi ngữ cảnh
Cursor giải quyết hiện tượng lệch chuẩn này thông qua hai cơ chế: các file quy tắc ở cấp độ dự án và cú pháp nhắc tới symbol (symbol mentions) theo yêu cầu. Các file quy tắc đóng vai trò như system prompt giúp nạp sẵn các quy ước trước khi quá trình sinh code bắt đầu. Trong khi đó, context mentions theo phạm vi cho phép lập trình viên trực tiếp đưa chính xác các file mã nguồn liên quan vào prompt. Các nhóm áp dụng quy trình này thường giảm được số vòng review boilerplate từ ba lần xuống chỉ còn một lần.
Cài đặt & Thiết lập
Cài đặt Cursor
Cursor là một bản fork trực tiếp từ VS Code. Toàn bộ extension, theme và phím tắt hiện có của bạn sẽ được chuyển sang ngay trong lần khởi chạy đầu tiên. Tải bộ cài đặt phù hợp với nền tảng của bạn:
# macOS (Homebrew)
brew install --cask cursor
# Linux (AppImage chính thức)
curl -LO https://downloader.cursor.sh/linux/appImage/x64
chmod +x x64 && ./x64
Khởi tạo thư mục chứa quy tắc
Cursor tải các quy tắc từ hai vị trí: file gốc kế thừa (.cursorrules) và các file quy tắc dạng module bên trong .cursor/rules/. Hãy tạo thư mục module tại thư mục gốc của dự án:
cd /path/to/your/project
mkdir -p .cursor/rules
Nên sử dụng các quy tắc dạng module cho dự án mới. Chúng sẽ được nạp có chọn lọc dựa trên các file bạn đang chỉnh sửa, giúp tiết kiệm lượng token sử dụng và tăng tốc độ phản hồi.
Cấu hình
1. File quy tắc chung (.cursorrules)
Nếu bạn muốn có một file duy nhất để thiết lập các rào chắn cơ bản cho toàn bộ repo, hãy đặt .cursorrules tại thư mục gốc của dự án. Hãy giữ file này ngắn gọn—dưới 100 dòng—để tránh làm chiếm dụng cửa sổ ngữ cảnh (context window) của prompt.
# Tiêu chuẩn cơ sở của team
## Stack
- Runtime: Next.js 14 (App Router), TypeScript (strict: true)
- Styling: Tailwind CSS v3.4
- State: Zustand cho client store, TanStack Query cho server state
- ORM: Prisma 5 với PostgreSQL
## Quy ước
- Chỉ sử dụng named export. Không dùng default export.
- Khai báo kiểu trả về tường minh cho tất cả các function được export.
- Custom error bắt buộc phải kế thừa từ `AppError` trong `@/lib/errors`.
- Tuyệt đối không import các tiện ích server (ví dụ: `fs`, database client) vào Client Component (`"use client"`).
## Kiểm thử
- Unit test sử dụng Vitest và React Testing Library.
- Mock toàn bộ các HTTP request ra bên ngoài bằng Mock Service Worker (MSW).
- Đặt file test cùng thư mục với mã nguồn theo quy ước đặt tên `[name].test.ts`.
2. Quy tắc dạng module (.cursor/rules/*.mdc)
Định dạng .mdc của Cursor sử dụng frontmatter để chỉ gắn hướng dẫn vào những file có liên quan. Ví dụ: các quy tắc về cơ sở dữ liệu không nên tiêu tốn token khi bạn đang tinh chỉnh CSS. Bạn có thể tiết kiệm từ 3.000 đến 5.000 token cho mỗi prompt bằng cách giới hạn phạm vi quy tắc theo file glob.
Tạo file .cursor/rules/api-routes.mdc dành riêng cho các backend endpoint:
---
description: Quy ước cho API Route Handler
globs: app/api/**/*.ts
alwaysApply: false
---
# Tiêu chuẩn API Route
- Xác thực toàn bộ request JSON gửi đến bằng Zod schema định nghĩa trong `@/lib/validations`.
- Trả về response theo cấu trúc chuẩn: `{ success: boolean, data?: T, error?: string }`.
- Bọc mọi handler trong helper `withSession()` để bắt buộc xác thực người dùng.
- Ghi log các ngoại lệ vận hành bằng `logger.error({ err, route: req.url })`.
- Luôn chỉ định rõ ràng mã HTTP status code (200, 201, 400, 401, 500).
3. Context Mentions chính xác theo ngữ cảnh
Các quy tắc đóng vai trò đặt ra ranh giới thụ động. Đối với các tác vụ cụ thể, context mentions sẽ chỉ định chính xác cho mô hình biết đoạn code nào cần noi theo. Gõ @ trong cửa sổ chat hoặc Composer của Cursor để duyệt qua các tài nguyên tham chiếu:
- @Files: Trỏ mô hình tới một file cụ thể (ví dụ:
@src/lib/auth.ts). Điều này ngăn AI tự chế ra các hàm tiện ích vốn đã sẵn có trong codebase của bạn. - @Folders: Cung cấp toàn bộ một thư mục (ví dụ:
@components/ui/) để các component mới được sinh ra sẽ tự động tuân theo design token và cấu trúc prop sẵn có. - @Docs: Kéo tài liệu framework đã được lập chỉ mục vào ngữ cảnh (ví dụ: Tailwind v4 hoặc Next.js 14). Giúp tránh hiện tượng hallucination với các API đã lỗi thời.
- @Git: Đưa diff của commit hoặc nhánh PR vào prompt. Tính năng này cực kỳ hữu ích khi cần tạo tóm tắt pull request chuẩn xác hoặc review xung đột merge.
- @Codebase: Kích hoạt tìm kiếm ngữ nghĩa (semantic search) đã được lập chỉ mục trên toàn bộ repository. Dùng tính năng này cho các câu hỏi khám phá mã nguồn như "Đoạn code nào đang xử lý payment webhook?"
Kết hợp quy tắc và mentions để tạo ra các prompt có độ chuẩn xác cao:
Tạo một checkout route cho hóa đơn tại app/api/checkout/route.ts.
Áp dụng cấu trúc xử lý lỗi tương tự như trong @app/api/subscriptions/route.ts.
Validate payload dựa theo schema trong @types/billing.ts.
Kiểm tra & Giám sát
Kiểm tra mức độ tuân thủ quy tắc
Hãy kiểm thử các quy tắc bằng một prompt cố tình kích thích vi phạm nếu không có chỉ dẫn. Mở cửa sổ Composer bằng Cmd+I (macOS) hoặc Ctrl+I (Linux/Windows) và nhập prompt sau:
Build a simple toggle button component with an export default.
Nếu quy tắc bắt buộc dùng named export của bạn hoạt động chính xác, Cursor sẽ bỏ qua yêu cầu dùng default export trong prompt và xuất ra kết quả như sau:
import { useState } from 'react';
interface ToggleButtonProps {
initialState?: boolean;
onToggle?: (active: boolean) => void;
}
// Đã xác thực: Sử dụng named export và kiểu trả về tường minh theo .cursorrules
export const ToggleButton = ({
initialState = false,
onToggle
}: ToggleButtonProps): JSX.Element => {
const [isActive, setIsActive] = useState<boolean>(initialState);
const handleToggle = (): void => {
const next = !isActive;
setIsActive(next);
onToggle?.(next);
};
return (
<button
type="button"
onClick={handleToggle}
className={`px-3 py-1.5 rounded-md font-medium transition-colors ${
isActive ? 'bg-emerald-600 text-white' : 'bg-slate-200 text-slate-800'
}`}
>
{isActive ? 'Bật' : 'Tắt'}
</button>
);
};
Áp dụng tiêu chuẩn vào quy trình CI/CD
Các quy tắc AI giúp cải thiện chất lượng code được tạo ra ở máy local, nhưng không thể thay thế cho hệ thống tích hợp liên tục (CI). Hãy commit cả .cursorrules lẫn thư mục .cursor/ lên Git để mọi thành viên cùng chia sẻ một cấu hình chuẩn. Đồng thời, củng cố quy chuẩn bằng các bước kiểm tra tự động nghiêm ngặt trong GitHub Actions:
name: Kiểm tra chất lượng code
on: [pull_request]
jobs:
lint-and-validate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
cache: 'npm'
- run: npm ci
- run: npm run lint
- run: npm run typecheck
- run: npm run test:unit
Hãy xem các file quy tắc như mã nguồn sống. Thường xuyên rà soát và cập nhật chúng trong các buổi retrospective của sprint mỗi khi dự án thay đổi dependency hoặc nâng cấp kiến trúc.

