규칙 파일을 코드처럼 설계하라—AI 코딩 도구를 길들이는 진짜 방법

규칙 파일을 코드처럼 설계하라—AI 코딩 도구를 길들이는 진짜 방법

CLAUDE.md와 .cursorrules는 프롬프트가 아니라 아키텍처다—컨텍스트 드리프트를 구조로 막고, AI를 팀 컨벤션의 실행자로 만드는 설계 원칙

Cursor Rules CLAUDE.md 컨텍스트 드리프트 AI 코딩 도구 규칙 파일 설계 DX 향상 프롬프트 엔지니어링 개발자 경험
광고

밤 11시 47분, AI가 아침에 생성해준 코드를 고치다 한 시간을 날린 경험이 있다면—에러 핸들링도 없고, 타입도 없고, console.log('here')가 덩그러니 남아 있는 그 코드—당신은 이미 AI 코딩 도구의 핵심 문제를 몸으로 겪은 것이다. 문제는 AI가 멍청한 게 아니다. AI에게 '기억'을 기대했다는 게 문제다.

프롬프트로는 부족하다, 구조가 필요하다

Claude나 Cursor에게 "TypeScript strict 모드 써줘"라고 말하면 처음엔 잘 따른다. 그런데 대화가 길어질수록 슬그머니 any가 등장하고, 요청하지 않은 리팩토링이 붙고, 네 가지 변경이 한꺼번에 들어온다. 이걸 흔히 '컨텍스트 드리프트(context drift)'라고 부른다. LLM은 대화를 '기억'하는 게 아니라 컨텍스트 윈도우를 읽는다. 대화가 쌓일수록 초반에 넣은 지시사항은 주의(attention) 경쟁에서 밀려난다. 더 길고 자세한 프롬프트로 대응하는 건 증상 치료다. 원인은 '지시가 대화 안에 있다'는 구조 자체에 있다.

dev.to에 올라온 두 편의 실전 가이드—Cursor Rules 자동화 사례와 CLAUDE.md 컨텍스트 제어 아티클—는 이 문제를 같은 방향으로 해결한다. AI에게 말로 부탁하는 대신, 규칙을 파일로 선언하고, 그 파일이 매 세션마다 자동으로 로드되게 만든다. .cursorrulesCLAUDE.md는 프롬프트 템플릿이 아니라 프로젝트 헌법이다.

규칙 파일의 작동 원리: 'passive rule'과 'enforcement hook'의 차이

핵심 개념을 하나만 가져온다면 이것이다. 채팅창에 쓴 지시사항은 패시브 룰(passive rule)—대화 흐름 속에서 희석된다. 반면 CLAUDE.md.cursorrules에 담긴 규칙은 인포스먼트 훅(enforcement hook)—매번 재로드되기 때문에 희석되지 않는다.

비유하자면, 팀원에게 "코드 리뷰할 때 타입 꼭 써줘"라고 구두로 부탁하는 것과, 그 규칙을 PR 체크리스트에 박아넣는 것의 차이다. 전자는 잊혀지고, 후자는 강제된다. AI 도구도 마찬가지다. 규칙이 '대화'가 아닌 '환경'에 존재할 때 비로소 일관성이 생긴다.

실제로 동작하는 규칙은 어떻게 생겼나

규칙 파일을 처음 만들면 대부분 "클린 코드를 써라", "베스트 프랙티스를 따르라" 같은 문장으로 채운다. 이런 규칙은 아무 효과가 없다. AI는 이미 그렇게 하려고 훈련됐기 때문이다. 실제로 행동을 바꾸는 규칙에는 세 가지 특성이 있다.

첫째, 금지가 허용보다 강하다. "TypeScript를 써라"보다 "any 타입을 절대 쓰지 마라. unknown으로 받고 narrowing 하라"가 훨씬 명확하다. LLM은 "이 규칙을 위반했는가?"라는 이진 판단을 "이게 충분히 concise한가?"라는 모호한 평가보다 훨씬 잘 처리한다. Cursor Rules 자동화 사례에서도 8개 규칙 대부분이 금지 형태로 시작한다—console.log 금지, process.env 직접 접근 금지, 200줄 초과 금지.

둘째, 추상적 지시 대신 구체적 예시. "커밋 메시지를 잘 써라"가 아니라 fix(auth): resolve expired token handling / NOT fixed stuff처럼 정답과 오답을 나란히 보여준다. LLM은 패턴 매칭으로 작동한다. 네거티브 예시를 함께 주면 경계가 훨씬 선명해진다.

셋째, 스코프 앵커링. "변경을 최소화하라"보다 "현재 요청과 직접 관련된 파일만 수정하라. 스코프 밖에서 버그를 발견하면 수정하지 말고 언급만 하라"가 구체적이다. 이 마지막 문장이 중요하다—AI의 '도움이 되고 싶다'는 학습 성향에 압력 해소 밸브를 달아주는 것이다. 무언가를 완전히 막으면 AI는 다른 방식으로 그 욕구를 표현하려 한다. 발견은 허용하되 실행은 막는 방식이 실무에서 훨씬 안정적으로 작동한다.

프론트엔드 워크플로우에 직접 적용하면

Next.js + TypeScript 프로젝트를 기준으로 규칙 파일이 실질적으로 해결하는 문제들을 구체적으로 짚어보면:

  • 패키지 매니저 혼선: pnpm을 쓰는 프로젝트에서 AI가 npm install을 실행해 lockfile을 망가뜨리는 일은 생각보다 자주 일어난다. CLAUDE.mdpnpm (NOT npm)을 명시하면 끝난다.
  • 환경 변수 누출: process.env.STRIPE_KEY를 코드 곳곳에 직접 참조하는 대신, src/config/env.ts에서 zod로 검증한 env 객체를 import하도록 규칙화하면 타입 안전성과 시작 시점 검증을 동시에 얻는다.
  • 테스트 없는 구현: 구현 전에 실패하는 테스트를 먼저 작성하게 강제하면 AI가 함수 시그니처를 먼저 확정하고 최소 구현을 작성하는 흐름이 자연스럽게 만들어진다.
  • 완료 정의의 모호함: "done"을 "타입체크 통과 + 린트 통과 + 테스트 통과 + 신규 any 없음"으로 체크리스트화하면 AI가 스스로 완료를 선언하기 전에 이 단계를 거친다.

규칙 파일을 유지보수하는 법

규칙 파일의 진짜 가치는 초기 설정이 아니라 팀의 실수를 코드화하는 과정에 있다. CLAUDE.md Quick Start 가이드가 제안하는 원칙이 이것이다: 규칙 하나당 사고 하나. AI가 예상치 못한 행동을 했을 때마다 "규칙이 있었다면 이걸 막을 수 있었을까?"를 묻고, 막을 수 있었다면 규칙을 추가한다.

이 관점에서 규칙 파일은 팀의 포스트모템 아카이브이기도 하다. migrations/ 폴더를 건드리지 마라는 규칙이 있다면, 그 뒤에는 누군가 AI가 마이그레이션 파일을 수정하는 바람에 스테이징이 망가진 경험이 있다는 뜻이다. 규칙 파일을 git으로 관리하고 PR 리뷰 대상에 포함시키면, 팀이 AI와 어떻게 일하기로 합의했는지가 코드 히스토리에 남는다.

시사점: AI 도구 실력은 '프롬프트 기술'이 아니라 '규칙 설계 능력'

지금 많은 팀이 AI 코딩 도구를 도입했지만 실질적인 생산성 향상을 못 느끼는 이유 중 하나는, 도구를 '매번 새로 지시해야 하는 조수'로 사용하고 있기 때문이다. 매 세션마다 스택을 설명하고, 컨벤션을 상기시키고, 같은 실수를 다시 고치는 루프는 AI가 없을 때보다 오히려 인지 비용을 높인다.

.cursorrulesCLAUDE.md가 보여주는 방향은 다르다. 규칙을 한 번 잘 설계해두면, AI는 그 규칙의 실행자가 된다. 개발자는 '무엇을 하지 말라고 다시 말할까'를 고민하는 대신, '어떤 규칙을 추가하면 이 클래스의 실수 전체를 막을 수 있을까'를 고민한다. 이것이 프롬프트 엔지니어링과 규칙 설계의 근본적인 차이다—전자는 매번 소비되고, 후자는 누적된다.

전망: 규칙 파일은 팀 컨벤션의 새 레이어가 된다

ESLint 설정과 .prettierrc가 코드 스타일의 팀 합의를 코드화했듯, CLAUDE.md.cursorrules는 AI와의 협업 방식에 대한 팀 합의를 코드화하는 레이어로 자리잡을 것이다. 이미 일부 팀에서는 신규 입사자 온보딩 문서에 이 파일들을 포함시키기 시작했다—"우리 팀은 AI와 이렇게 일한다"는 약속의 형태로.

앞으로 AI 코딩 도구가 더 강력해질수록, 도구를 얼마나 잘 쓰느냐보다 도구를 어떤 규칙 안에서 작동하게 하느냐가 팀 역량의 기준이 될 가능성이 높다. 규칙 파일은 그 설계의 시작점이다. 오늘 당장 빈 CLAUDE.md를 열고, 지난주에 AI가 저질렀던 실수 하나를 규칙으로 바꾸는 것—그게 가장 현실적인 첫 걸음이다.

출처

더 많은 AI 트렌드를 Seedora 앱에서 확인하세요