Cursor rules: Bốn chế độ, bẫy .cursorrules và template
.cursorrules không có tác dụng trong Agent mode — 0/9 kiểm thử tuân thủ. Bốn chế độ rule, năm anti-pattern im lặng và sáu template thực tế có chú thích.
Bởi Ethan
2.766 từ · 14 phút đọc
Nếu bạn đang dùng .cursorrules, hãy dừng lại — nó không làm gì cả trong Agent mode. Hãy chuyển sang các file .cursor/rules/*.mdc với YAML frontmatter đúng chuẩn, giữ các rule always-on dưới 2.000 token, và giới hạn phạm vi của mọi thứ còn lại bằng glob hoặc description. Đó là tóm tắt. Phần còn lại của bài viết này giải thích tại sao, cho bạn thấy rule engine thực sự hoạt động như thế nào, và cung cấp sáu template dùng được ngay.
Bài viết này dành cho ai
Dành cho các developer đang dùng Cursor, viết rule theo bản năng và không chắc tại sao đôi khi chúng hoạt động còn đôi khi lại không có tác dụng gì. Nếu bạn chưa bao giờ mở .cursor/rules/, hãy bắt đầu từ đây. Nếu bạn đang cân nhắc giữa Cursor và các công cụ AI coding khác, hãy xem Cursor vs GitHub Copilot hoặc Cursor vs Claude Code.
Engine đánh giá rule như thế nào
Hệ thống rule của Cursor được tài liệu hóa tại cursor.com/docs/rules. Ba trường frontmatter trong mỗi file .mdc điều khiển mọi quyết định kích hoạt: alwaysApply, description, và globs.
Engine chạy theo thứ tự này mỗi khi Agent Chat mở một prompt mới:
- Always Apply rules được nối vào vô điều kiện — chúng xuất hiện trong mọi session, không ngoại lệ.
- Auto Attached rules được thêm vào khi một file khớp với pattern
globscủa chúng xuất hiện trong context hội thoại. - Agent Requested rules: các trường
descriptioncủa chúng xuất hiện trong block<available_instructions>. Model gọi một tool nội bộfetch_rulesđể tải bất kỳ rule nào mà nó đánh giá là liên quan đến task hiện tại. - Manual rules cũng xuất hiện trong
<available_instructions>nhưng không bao giờ được tải tự động trừ khi bạn gõ@rule-nametrong chat. - Tất cả các rule được khớp sẽ được gộp lại và chèn vào đầu model context theo thứ tự: Team Rules → Project Rules → User Settings Rules. Rule xuất hiện trước sẽ thắng khi có xung đột.
Cơ chế này đã được phân tích và ghi chép lại bởi roman.pt, người đã truy vết cấu trúc prompt thực tế mà Cursor gửi đi.
Một điều khiến hầu hết mọi người bị nhầm: rule chỉ áp dụng cho Agent Chat. Chúng không có tác dụng gì với Tab autocomplete hay inline Edit (Cmd+K). Nếu bạn đang thắc mắc tại sao các rule không ảnh hưởng đến gợi ý, đó là lý do.
Bốn chế độ hoạt động
Chế độ kích hoạt của mỗi file rule được xác định bởi các trường frontmatter mà bạn thiết lập.
Always Apply
---
alwaysApply: true
---
Được tải vô điều kiện. Dùng tiết kiệm — xem anti-pattern 1 bên dưới.
Auto Attached
---
globs: ["src/components/**/*.tsx"]
alwaysApply: false
---
Được chèn vào khi một file khớp với glob xuất hiện trong context. Đây là chế độ hữu ích nhất để giới hạn rule cho các phần cụ thể của codebase.
Agent Requested
---
description: "Use when writing git commit messages or summarizing changes for a PR"
alwaysApply: false
---
Agent đọc description và quyết định có nên tải toàn bộ rule cho task hiện tại hay không. Một description tốt chính là cả cơ chế — hãy viết nó như một lệnh gửi đến model, không phải một tiêu đề.
Manual
---
alwaysApply: false
---
Không có description, không có globs. Cursor liệt kê nó trong <available_instructions> nhưng không bao giờ tải tự động. Bạn gọi nó bằng @rule-name trong chat. Phù hợp cho các template scaffold từng bước mà bạn muốn dùng khi cần.
Cạm bẫy của .cursorrules
Nếu bạn có file .cursorrules trong thư mục gốc của project và đang dùng Agent mode, các rule của bạn không có tác dụng gì.
The Prompt Shelf đã ghi chép điều này qua kiểm thử tuân thủ: cùng nội dung rule nhưng dưới dạng file .cursorrules chỉ đạt 0/9 tuân thủ trong Agent mode. Khi chuyển sang file .mdc với alwaysApply: true, cùng nội dung đó đạt 9/9.
Agent mode sử dụng một execution path khác không đọc .cursorrules. Cursor không báo lỗi, không cảnh báo — file bị âm thầm bỏ qua. Bạn có thể dành hàng tuần tinh chỉnh một file rule cẩn thận và hoàn toàn không có tác dụng gì với output của Agent.
So sánh:
.cursorrules | .cursor/rules/*.mdc | |
|---|---|---|
| Agent mode | ✗ bị bỏ qua âm thầm | ✓ |
| Tab autocomplete | ✓ | ✗ |
| Giới hạn theo từng mục đích | ✗ (một file, không có frontmatter) | ✓ (một file cho mỗi mục đích) |
| Team Rules (Enterprise) | ✗ | ✓ bắt buộc |
| Version control | ✓ | ✓ |
Khi nào nên giữ .cursorrules: project cá nhân, không bao giờ dùng Agent mode, hoặc khi publish rule để cộng đồng dễ tìm (hầu hết các repo tại PatrickJS/awesome-cursorrules dùng format này vì đây là định dạng quen thuộc). Với bất kỳ workflow có agent nào, hãy chuyển đổi.
Chuyển đổi: di chuyển nội dung của .cursorrules vào .cursor/rules/base.mdc, thêm frontmatter alwaysApply: true, và xóa file cũ. Một lệnh nếu bạn đã cài yq:
echo "---\nalwaysApply: true\n---\n" | cat - .cursorrules > .cursor/rules/base.mdc
rm .cursorrules
Chỉ các file có phần mở rộng .mdc mới được đọc — các file .md trong .cursor/rules/ bị âm thầm bỏ qua. Phần mở rộng quan trọng.
Thư viện template
Sáu file này bao quát một project TypeScript full-stack điển hình. Copy chúng vào .cursor/rules/, điều chỉnh theo tech stack của bạn.
1. Base rule toàn project — Always Apply
Dành cho project Next.js 15 / TypeScript / Drizzle. Giữ ngắn gọn; token của always-apply rule khá tốn kém. Nguồn: techsy.io.
---
alwaysApply: true
---
# Project: Acme Dashboard
## Tech Stack
- Next.js 15 (App Router only — no Pages Router)
- TypeScript strict mode
- Tailwind CSS v4
- Drizzle ORM with PostgreSQL
- pnpm for package management
## Critical Conventions
- All components are React Server Components by default
- Use "use client" only when the component needs interactivity
- Import paths use @/ alias mapped to src/
- Error handling: wrap async operations in try/catch, never use .catch()
- No default exports except for pages and layouts
Khoảng ~120 token. Đủ nhỏ để dùng always-on mà không làm phình context.
2. Rule React component — Auto Attached theo glob
Giới hạn cho các file component. Chỉ tiêu tốn token khi một component xuất hiện trong context. Nguồn: techsy.io, morphllm.com.
---
description: "React component authoring rules"
globs: ["src/components/**/*.tsx", "src/app/**/*.tsx"]
alwaysApply: false
---
# React Component Rules
## Structure (in order)
1. Imports
2. Props interface (above the function)
3. Component function (named export)
4. Sub-components if any
## Patterns
- YES: `export function Button({ label }: ButtonProps)`
- NO: `export default function Button()`
- No barrel exports (index.ts re-exports)
- No prop drilling beyond 2 levels
- Extract sub-components when component exceeds 150 lines
- forwardRef for any component wrapping a DOM element
## Anti-patterns
- No useEffect for data fetching — use Server Components
- No CSS modules — Tailwind only
3. Rule kiểm thử — Auto Attached
Kích hoạt trên các file test. Nguồn: danh mục PatrickJS/awesome-cursorrules và các pattern cộng đồng.
---
description: "Unit and integration testing conventions"
globs: ["**/*.test.ts", "**/*.spec.ts", "**/__tests__/**/*.ts"]
alwaysApply: false
---
# Testing Standards
- Describe blocks group related tests, not implementation details
- One assertion per test where feasible; max three
- Test file mirrors module path: src/utils/format.ts → src/utils/format.test.ts
- Use `it('should ...')` phrasing for behavior
- Mock at the boundary (external HTTP, DB), never internal module functions
- Each test is independent — no shared mutable state
- Prefer `userEvent` over `fireEvent` in React Testing Library
## What to test
- Happy path + two most likely failure modes per function
- Edge: empty arrays, null/undefined, empty strings
- NOT implementation details (private methods, internal state)
4. Rule commit message — Agent Requested
Description được viết như một điều kiện, không phải tiêu đề — đó là thứ agent đọc để quyết định có nên tải rule hay không. Lấy cảm hứng từ danh mục “Git Conventional Commit Messages” trên PatrickJS/awesome-cursorrules.
---
description: "Use when writing git commit messages or summarizing changes for a PR"
alwaysApply: false
---
# Commit Message: Conventional Commits
Format: `<type>(<scope>): <subject>`
Types: feat | fix | refactor | test | docs | chore
- Subject max 72 characters, imperative mood ("add" not "adds")
- No period at end of subject line
- Reference issue in footer: `Closes #123`
Examples:
feat(auth): add Google OAuth sign-in flow
fix(api): handle null response from payment provider
Agent sẽ tải rule này khi bạn yêu cầu nó viết commit message, mà không cần bạn phải nhắc đến.
5. Rule TypeScript strict-mode — Auto Attached
Loại trừ các file test qua ký hiệu phủ định ! trong glob để hướng dẫn strict-mode không xung đột với các pattern dành riêng cho test. Nguồn: stevekinney.com, morphllm.com.
---
description: "TypeScript type safety and strict-mode conventions"
globs: ["**/*.ts", "**/*.tsx", "!**/*.test.ts"]
alwaysApply: false
---
# TypeScript Conventions
- No `any` — use `unknown` and narrow it
- Explicit return types on public functions
- `satisfies` operator over `as` for literal validation
- No non-null assertions (`!`) — handle null explicitly
- Discriminated unions over boolean flags for state
- `type` for unions/intersections; `interface` for object shapes
- Avoid enums — use `as const` object + `typeof` extraction
- Zod for runtime validation at system boundaries
## Version: TypeScript 5.4+
- `NoInfer<T>` utility type is available
6. Template API scaffold — Manual
Không có description, không có globs. Được gọi bằng @api-scaffold khi bạn muốn agent tạo scaffold một route mới theo quy ước của bạn. Pattern từ sitepoint.com.
---
alwaysApply: false
---
# New API Route Template
Invoke with `@api-scaffold` before asking Cursor to create a new route.
1. Create route.ts at the correct src/app/api/ path segment
2. Import shared response helpers from @/lib/api-response
3. Validate request body with Zod schemas from src/schemas/
4. Use the db singleton from @/lib/db — never instantiate Drizzle directly
5. Return `{ data: T }` on success, `{ error: string, code: string }` on failure
6. Add a corresponding .test.ts file at the same path
Từ kinh nghiệm cộng đồng tại techsy.io và morphllm.com: năm đến tám rule là điểm cân bằng thực tế. Một base rule always-apply, ba đến bốn rule auto-attached theo loại file, một hoặc hai template thủ công. Nhiều hơn thế là bạn tự chiến đấu với giới hạn context. Để tích hợp Cursor với MCP servers và tool bên ngoài, xem cách xây dựng MCP tools tùy chỉnh cho Cursor.
Một số team đặt tiền tố số cho tên file (001-base.mdc, 020-react.mdc) để kiểm soát thứ tự gộp. Không chính thức — Cursor sắp xếp tên file theo chuỗi ký tự — nhưng nó hoạt động.
Năm anti-pattern âm thầm phá vỡ rule
1. Lạm dụng alwaysApply
Mọi always-apply rule đều xuất hiện trong mọi prompt, vô điều kiện. morphllm.com đo được 8–12% context bị tiêu thụ bởi các rule trước khi bất kỳ code nào được đọc, khi nhiều rule lớn mang alwaysApply: true.
Với quá nhiều always-on rule, model cố thỏa mãn tất cả cùng lúc và vi phạm một phần hầu hết chúng, ưu tiên các rule xuất hiện trước trong tập hợp đã gộp.
Giới hạn: giữ tổng nội dung always-apply dưới ~2.000 token. Một hoặc hai rule ngắn mang tính toàn cục. Mọi thứ còn lại được giới hạn bằng glob hoặc description.
2. .cursorrules trong Agent mode
Đã đề cập ở trên. Tóm tắt: 0/9 so với 9/9 tuân thủ trong kiểm thử có tài liệu. Không có cảnh báo. Hãy chuyển đổi.
3. Suy giảm theo độ dài session
Các rule được tuân thủ lúc đầu session sẽ dần trôi dạt sau 10–15 lượt hội thoại. Context đầu session bị giảm ưu tiên khi session kéo dài hơn. dev.to/vibestackdev và nhiều thread forum ghi chép điều này.
Cách khắc phục: bắt đầu session mới cho các task mới. Dùng các Auto Attached rule giới hạn bằng glob thay vì always-apply khi có thể — chúng được tái chèn theo từng request và không bị suy giảm theo cách tương tự.
4. Team Rules đã tắt vẫn tải (bug đã xác nhận, tháng 5/2026)
Cursor Enterprise cho phép team publish các rule chung mà từng thành viên có thể bật hoặc tắt. Nhưng tắt đi không có tác dụng. Các rule đã bị tắt vẫn xuất hiện trong context của agent và được báo cáo là “always applied workspace rules.”
Kỹ sư Cursor đã xác nhận bug này vào ngày 18 tháng 5 năm 2026: “the fix that shipped in 3.4.12 was incomplete. Your disabled rules are still being injected into the agent context through a separate server-side path.” Trạng thái: chưa được giải quyết tính đến tháng 6 năm 2026 (xác nhận trên 3.4.20).
Cách xử lý tạm thời: xóa hoàn toàn các team rule tùy chọn thay vì chỉ tắt chúng.
5. Lỗi cú pháp YAML frontmatter âm thầm bỏ qua file
Bất kỳ lỗi YAML nào cũng khiến Cursor bỏ qua toàn bộ file .mdc — không ghi lỗi, không cảnh báo. Rule đơn giản là không tồn tại. dev.to/vibestackdev ghi lại ba dạng lỗi phổ biến nhất:
# SAI — glob không được bọc trong array
globs: "src/components/**/*.tsx"
# SAI — boolean viết hoa (YAML phân biệt chữ hoa/thường)
alwaysApply: True
# SAI — có dấu --- mở nhưng không có dấu --- đóng
---
description: "My rule"
alwaysApply: false
(file tiếp tục mà không có dấu phân cách đóng)
Dạng đúng:
---
description: "My rule"
globs: ["src/components/**/*.tsx"]
alwaysApply: false
---
Thêm một pre-commit hook chạy YAML linter trên các file .cursor/rules/*.mdc. Chi phí của một CI check là nhỏ; chi phí của một rule bị hỏng âm thầm là một ngày debug hành vi model.
Rule so với system prompt một lần
Nếu bạn sẽ gõ lại cùng lệnh đó vào tuần tới cho cùng task, hãy biến nó thành rule. Nếu nó chỉ đặc thù cho một session — “treat all async functions as fire-and-forget for this refactor” — đặt nó trong chat và quên đi.
Cách kiểm tra: một thành viên mới trong team có cần biết điều này cho mọi Cursor session, hay chỉ cho task hôm nay?
Bạn nên làm gì ngay bây giờ
- Kiểm tra xem bạn có file
.cursorruleskhông. Nếu có và bạn dùng Agent mode, hãy chuyển đổi ngay hôm nay. - Kiểm tra các rule hiện tại của bạn để tìm
alwaysApply: true. Nếu có nhiều hơn hai rule mang cờ đó, hãy chuyển các rule còn lại sang dạng giới hạn bằng glob hoặc description. - Validate frontmatter
.mdccủa bạn bằng YAML linter. Thêm nó như một pre-commit hook. - Nếu bạn dùng Cursor Enterprise và đã tắt team rules: hãy xóa chúng thay vì chỉ toggle.
Cursor tiếp tục phát triển nhanh. Hệ thống rule đã thay đổi đáng kể qua các phiên bản nhỏ, và bug im lặng của .cursorrules chỉ trở nên phổ biến khi kiểm thử cộng đồng làm rõ vấn đề này. Hãy xem rule của bạn như code — version chúng, review chúng, và validate chúng.
Tham khảo
- cursor.com/docs/rules — tài liệu chính thức, bảng bốn chế độ, cú pháp glob
- roman.pt — Cursor under the hood — cấu trúc prompt được phân tích ngược
- thepromptshelf.dev — .cursorrules vs .cursor/rules (2026) — kiểm thử tuân thủ 0/9 so với 9/9
- Cursor forum — disabled team rules bug — bug đã xác nhận và phản hồi kỹ thuật, tháng 5/2026
- dev.to/vibestackdev — rules silently ignored — lỗi YAML, suy giảm session
- techsy.io — cursor rules guide — template thực tế
- morphllm.com — cursor rules best practices — phân loại anti-pattern, đo lường overhead token
- PatrickJS/awesome-cursorrules — bộ sưu tập rule cộng đồng lớn nhất
- stevekinney.com — cursor rules TypeScript — các pattern TypeScript strict-mode
- sitepoint.com — cursor rules advanced guide — các pattern template thủ công