
모든 Cursor 사용자가 같은 벽에 부딪힙니다. AI가 생성한 코드는 기술적으로는 작동하지만 프로젝트의 규칙을 무시하고, 잘못된 import 경로를 사용하고, 오래된 패턴을 따르며, 나머지 코드베이스와는 전혀 다른 구조의 컴포넌트를 만듭니다. Cursor rules는 AI에게 프로젝트가 어떻게 작동하는지에 대한 지속적인 맥락을 제공함으로써 이 문제를 해결합니다.
Cursor Rules란 무엇이고 왜 중요한가?
Cursor rules는 모든 AI 상호작용, 채팅, 자동완성, 코드 생성 등 모든 과정에 주입되는 영구적인 시스템 프롬프트 역할을 하는 마크다운 파일입니다. AI를 위한 온보딩 문서라고 생각하면 됩니다. 매 세션마다 같은 실수를 교정하는 대신, 한 번만 지시사항을 작성하면 그것이 계속 유지됩니다.
이전 방식은 프로젝트 루트의 단일 .cursorrules 파일이었습니다. 이것도 여전히 작동하지만 더 이상 권장되지 않습니다. 현재 시스템은 .cursor/rules/ 디렉토리를 사용하며 각각 특정 상황에 맞는 개별 .mdc (Markdown Cursor) 파일들을 포함합니다. 이것은 훨씬 더 좋은 설정입니다. 왜냐하면 모든 지시사항을 하나의 거대한 파일에 우겨넣지 않고 관심사별로 rules를 나누며, Cursor가 현재 하는 작업과 관련된 것들만 로드하기 때문입니다.
AI 도구를 위한 context engineering 작업을 해봤다면, 이 개념은 익숙할 것입니다: 더 나은 입력 맥락은 극적으로 더 나은 출력을 생산합니다. Rules는 전체 개발 워크플로우를 위한 context engineering입니다.
첫 번째 Rule 파일 설정하기
프로젝트 루트에 .cursor/rules/ 디렉토리를 만듭니다:
각 rule은 YAML frontmatter 다음에 마크다운 내용이 따라오는 .mdc 파일입니다. 기본 구조는 다음과 같습니다:
세 가지 frontmatter 필드가 모든 것을 제어합니다:
Cursor 자체를 통해 rules를 만들 수도 있습니다. 채팅에서 /create-rule을 입력하고 원하는 것을 설명하면 됩니다. 하지만 직접 작성하면 더 많은 제어가 가능합니다.
4가지 Rule 유형 설명
Rule이 활성화되는 방식은 frontmatter 구성에 따라 다릅니다. 4가지 모드가 있으며, 올바른 것을 선택하는 것이 context window 예산에 영향을 미칩니다.
Always Apply (항상 적용)
모든 AI 요청에 로드됩니다. 기술 스택 선언이나 모든 곳에 적용되는 중요한 규칙과 같은 프로젝트 전체의 기본 사항에만 사용하세요. 항상 활성화되는 모든 rule은 AI가 실제로 코드를 보기 전에도 모든 상호작용에서 토큰을 소비합니다.
Auto-Attached (자동 첨부, Glob 기반)
glob 패턴과 일치하는 파일을 편집할 때만 활성화됩니다. 이것은 핵심 rule 유형입니다. React 컴포넌트 규칙은 컴포넌트 파일에 있을 때 로드되고, API 패턴은 route handler에 있을 때 로드되고, 테스트 규칙은 테스트를 작성할 때 로드됩니다.
Agent-Requested (에이전트 요청, 지능형)
globs도 없고, always-apply도 없습니다. 단지 설명만 있습니다. Cursor의 에이전트가 설명을 읽고 현재 작업과 rule이 관련이 있는지 판단합니다. migration을 작성하라고 하면 이 rule을 가져오고, 버튼을 스타일링하고 있다면 건너뜁니다. 파일 경로로 명확하게 매핑되지 않는 rules에 대해 놀랍도록 잘 작동합니다.
Manual (수동)
frontmatter 필드가 설정되지 않은 것 (또는 비어있는 frontmatter). 이 rules는 채팅에서 @rule-name을 명시적으로 언급할 때만 활성화됩니다. 배포 체크리스트나 가끔만 필요한 리팩토링 가이드 같은 드물게 사용되지만 중요한 지시사항에 좋습니다.
실제로 작동하는 Glob 패턴
Globs는 어느 파일이 auto-attached rules를 트리거하는지 결정합니다. 잘못 설정하면 rules가 절대 실행되지 않거나 모든 곳에서 실행됩니다. 작동하는 것들:
실제 사용에서의 주의사항 몇 가지:
- src/는 한 수준의 디렉토리만 매칭합니다. 대부분 재귀 매칭을 위해 src//을 원합니다.
- *.js는 .jsx나 .ts 파일을 매칭하지 않습니다. 파일 확장자를 명시적으로 지정하세요.
- Globs는 YAML 리스트여야 합니다. {src,lib}/*/.ts 같은 중괄호 구문은 조용히 실패할 수 있으므로 별도의 리스트 항목으로 유지하세요.
- ! 접두사는 패턴을 제외하며, 생성된 파일이나 레거시 코드를 무시하는 데 유용합니다.
실용적인 Rule 예제
이제 이론이 현실과 만납니다. 이것들은 프로젝트에 바로 적용할 수 있는 rules이며 즉시 더 나은 AI 출력을 볼 수 있습니다.
프로젝트 전체 기본 Rule (Always Apply)
30줄 이하로 유지하세요. 모든 요청과 함께 로드되므로 모든 단어가 토큰을 소비합니다.
React 컴포넌트 Rule (Auto-Attached)
// useEffect 없이 컴포넌트에서 직접 Fetch
export async function UserProfile({ id }: { id: string }) {
const user = await db.query.users.findFirst({
where: eq(users.id, id),
});
return <div>{user.name}</div>;
}
Python API Rule (Auto-Attached)
from fastapi import APIRouter, Depends, HTTPException
from sqlalchemy.ext.asyncio import AsyncSession
router = APIRouter(prefix="/users", tags=["users"])
@router.get("/{user_id}", response_model=UserResponse)
async def get_user(
user_id: int,
db: AsyncSession = Depends(get_db)
) -> UserResponse:
user = await db.get(User, user_id)
if not user:
raise HTTPException(status_code=404, detail="User not found")
return UserResponse.model_validate(user)
Go 서비스 Rule (Auto-Attached)
func (s *UserService) GetByID(ctx context.Context, id string) (*User, error) {
user, err := s.repo.Find(ctx, id)
if err != nil {
if errors.Is(err, ErrNotFound) {
return nil, fmt.Errorf("user %s: %w", id, ErrNotFound)
}
return nil, fmt.Errorf("fetching user %s: %w", id, err)
}
return user, nil
}
토큰 세금 관리
여기 대부분의 Cursor 가이드가 건너뛰는 것이 있습니다: 작성하는 모든 rule은 토큰을 소비합니다. 20개의 항상-활성화된 rules가 있는 프로젝트는 AI가 실제로 코드를 보기 전에 요청마다 2,000개 이상의 토큰을 명령어에만 소비할 수 있습니다.
이것은 중요합니다. Cursor의 채팅 컨텍스트는 표준 모드에서 대략 20,000개의 토큰입니다. 만약 your rules이 그 중 25%를 소비한다면, 실제 질문에 대해 AI의 "생각 공간"의 1/4을 잃은 것입니다. rules가 쌓이면서 특히 더 긴 대화에서 더 나쁜 출력 품질을 알아챌 것입니다.
3가지 원칙이 토큰 예산을 건강하게 유지합니다:
-
auto-attached와 agent-requested rules를 공격적으로 사용하세요. 프로젝트 스택 선언만 항상-활성화되어야 합니다. 다른 모든 것은 조건부로 로드되어야 합니다. 그 React 컴포넌트 rule? SQL migrations을 작성할 때는 컨텍스트에 있을 필요가 없습니다.
-
많은 단어가 아닌 밀도 있게 작성하세요. "개발자가 공개 API 계약을 정의할 때 타입 별칭보다는 TypeScript 인터페이스를 사용하는 것을 강력하게 권장합니다"를 "공개 API에는 type보다 interface를 선호합니다"로 바꾸세요. AI는 설득이 필요 없고, 지시사항이 필요합니다.
-
3의 법칙을 적용하세요. AI가 패턴을 3번 틀렸을 때만 rule로 변환하세요. 만약 Cursor가 이미 rule 없이도 명명 규칙을 올바르게 처리한다면, rule을 건너뛰세요. 불필요한 모든 rule은 낭비된 컨텍스트입니다.
토큰 사용량을 Cursor 채팅 패널 하단의 상태 표시줄에서 모니터링할 수 있습니다. 100%에 가까워지는 것을 보면, 그것이 정리해야 할 신호입니다.
실제 프로젝트에서 Rules 조직하기
프로덕션 프로젝트는 일반적으로 5-8개의 rule 파일이 필요합니다. 잘 작동하는 구조는 다음과 같습니다:
personal.mdc를 제외한 모든 것을 version control에 커밋하세요. 그렇게 하면 전체 팀이 동일한 AI 동작을 얻으며, 이것이 핵심입니다. Cursor 포럼 사용자가 말한 바와 같이, 좋은 rules은 "더 많은 제안을 있는 그대로 수용할 수 있으며, 출력이 첫 번째 시도에서 규칙과 일치"한다는 뜻입니다.
Cursor 외에 다른 AI 코딩 도구로도 작업하고 있다면, 개념은 직접 전달됩니다. Claude Code는 CLAUDE.md를 사용하고, GitHub Copilot은 명령어 파일을 가지고 있으며, Windsurf는 자체 형식을 가지고 있지만, 기본 원칙은 동일합니다.
Rule 우선순위가 어떻게 작동하는가
여러 rules가 같은 파일에 적용될 때, Cursor는 명확한 계층을 따릅니다:
Team rules는 Team과 Enterprise 플랜에서 사용 가능합니다. Cursor 대시보드에서 관리자가 설정하며 조직 전체에 강제되고, 개별 개발자는 끌 수 없습니다.
프로젝트 rules 내에서, 같은 파일에 2개의 rules가 적용되고 충돌하면, 동작이 엄격하게 정의되지 않습니다. 실제로는 나중에 로드된 rules가 우선순위를 가지는 경향이 있습니다. 파일에 번호를 매기면 (001-base.mdc, 002-components.mdc) 예측 가능한 순서를 얻습니다.
흔한 실수와 해결 방법
...