테마 전환

대규모 프로젝트에서 Cursor Agent 활용하기: 파일 누락과 잘못된 코드 수정을 막는 7가지 방법

Easton editorial illustration: context-window capsule

화면에 세 번째 오류 메시지가 떴습니다.

방금 Cursor Agent에게 로그인 모듈 리팩터링을 맡겼습니다. 이 모듈은 프런트엔드 폼 컴포넌트, API 라우트, 인증 미들웨어, 사용자 모델, Redis 캐시 계층 등 5개 파일에 걸쳐 있었습니다. 작업을 제출한 지 2분 후 Agent는 자신 있게 “완료했습니다”라고 말했습니다. 코드를 실행하자 결과는… 크래시였습니다.

확인해 보니 Agent는 파일 4개를 찾았지만 그중 3개만 수정했습니다. 더 심각한 점은 원래 올바르게 동작하던 미들웨어 로직까지 “최적화”해 모든 로그인 요청이 401을 반환하게 만들었다는 것입니다. 30분 동안 코드를 직접 롤백하고 의존 관계를 다시 정리한 뒤, 결국 남은 작업을 제가 직접 마무리했습니다.

그 순간 이런 의문이 들었습니다. AI 코딩 도우미가 정말 대규모 프로젝트를 처리할 수 있을까요?

이후 2주 동안 Cursor Agent의 작동 방식을 연구하고 십여 편의 기술 블로그를 읽으며 실제 프로젝트에서 계속 시행착오를 겪었습니다. 그 결과 대규모 프로젝트에서도 Agent를 더 안정적으로 활용하는 방법을 정리했습니다. 이제 Agent를 이용한 코드 리팩터링 성공률은 50% 미만에서 90% 이상으로 높아졌습니다.

이 글에서는 컨텍스트 관리, 작업 분할, 코드 리뷰라는 세 가지 관점에서 7가지 실전 팁을 소개합니다. 이론적인 추측이 아니라 실제 프로젝트에서 겪은 실패를 통해 얻은 경험입니다.

대규모 프로젝트에서 Agent가 자주 문제를 일으키는 이유

구체적인 팁을 살펴보기 전에 Agent가 왜 실수하는지부터 이해해야 합니다. Agent가 “멍청해서”가 아니라 세 가지 객관적인 제약이 있기 때문입니다.

컨텍스트 제한이 가장 큰 병목입니다

아시다시피 200k 토큰을 지원한다고 알려진 대형 모델도 실제 프로젝트 전체를 감당하기는 어렵습니다. 중간 규모의 프런트엔드·백엔드 분리 프로젝트만 해도 주요 코드 파일이 100개가 넘고 각 파일은 수백 줄에서 수천 줄에 이릅니다. package.json, 설정 파일, 테스트 코드까지 모두 넣으면 토큰 한도를 쉽게 넘습니다.

Agent는 프로젝트 “전체를 볼” 수 없습니다. 현재 대화에서 언급된 몇 개 파일과 Cursor의 자동 인덱싱 시스템이 간신히 연결한 일부 의존성만 볼 수 있습니다. 이는 5m 앞만 볼 수 있는 사람에게 축구장에서 물건을 찾으라는 것과 같습니다. 빠뜨리는 것이 당연합니다.

35%
대규모 프로젝트(100개 이상 파일)의 성공률

React+Node.js 프로젝트에서 직접 테스트한 적이 있습니다. 같은 요구 사항을 줬을 때 소규모 프로젝트(파일 20개)에서는 Agent가 한 번에 성공할 확률이 85%였지만, 중간 규모 프로젝트(파일 50개)에서는 60%로 떨어졌고 대규모 프로젝트(파일 100개 이상)에서는 35%까지 급락했습니다. 차이가 매우 뚜렷했습니다.

Agent의 “근시” 문제

또 하나 흥미로운 현상이 있습니다. Agent는 간접적으로 의존하는 파일을 특히 쉽게 “놓칩니다.”

예를 들어 API 라우트를 수정하라고 하면 라우트 파일과 해당 Controller는 성실하게 수정합니다. 하지만 그 Controller가 유틸리티 함수를 호출하고, 그 함수가 다시 설정 모듈에 의존한다면 문제가 생깁니다. Agent는 이런 숨은 의존성 체인을 두 번째 단계쯤에서 끊고 더 이상 추적하지 않는 경우가 많습니다.

가장 골치 아픈 것은 근인 선호입니다. Agent는 최근에 연 파일과 대화에서 명시적으로 언급된 파일을 우선합니다. 이전 대화에서 어떤 파일을 언급했다면 현재 작업과 관계가 없어도 가져와 멋대로 수정할 수 있습니다. 반대로 정말 수정해야 할 핵심 파일은 명시하지 않으면 보지 못한 척 지나칩니다.

전체적인 관점이 부족합니다

이것이 가장 치명적입니다.

사람인 개발자는 코드를 건드리기 전에 전체 아키텍처를 머릿속으로 훑습니다. 이 기능은 어떤 모듈과 관련되는가? 모듈은 서로 어떻게 통신하는가? A를 바꾸면 B에 영향을 주는가? 하지만 Agent는 그러지 않습니다. 매번 “국소 최적화” 방식으로 작업합니다. 현재 범위의 코드만 보고 가장 그럴듯한 방법을 찾아 바로 실행합니다.

제가 본 가장 황당한 사례는 데이터베이스 쿼리 성능을 최적화하라고 요청했을 때였습니다. Agent는 쿼리에 인덱스를 추가하고 SQL문을 조정했고, 실제로 속도가 꽤 빨라졌습니다. 그런데 사흘 후 시스템 메모리가 터졌습니다. “최적화”를 위해 캐시 계층에 전체 데이터 사전 로딩 로직을 추가한 탓에 Redis가 감당하지 못한 것입니다.

Agent는 “전체 아키텍처 설계”를 이해하지 못합니다. 성능 문제를 보면 성능만 최적화하고, 중복 코드를 보면 함수를 추출할 뿐, 그 변경이 기존 설계 의도를 훼손하는지는 신경 쓰지 않습니다.

컨텍스트 관리를 위한 3가지 핵심 팁

문제가 어디에 있는지 알면 그에 맞게 대응할 수 있습니다. 컨텍스트 관리가 가장 중요합니다. Agent가 “볼 수 있는” 범위를 잘 통제하면 많은 문제가 자연스럽게 사라집니다.

팁 1: Project Rules 설정 최적화

많은 사람이 편하다는 이유로 always 모드를 사용해 프로젝트의 모든 rules를 한꺼번에 넣습니다. 이것이 가장 큰 오해입니다.

always 모드는 “대화할 때마다 이 rules를 불러온다”는 뜻입니다. 좋아 보이지만 토큰을 엄청나게 소모합니다. 프로젝트에 프런트엔드, 백엔드, 테스트, 문서 등 여러 모듈이 있고 각 모듈의 코딩 규칙이 다를 수 있습니다. 이를 모두 always로 불러오면 Agent가 작업을 시작하기도 전에 토큰의 3분의 1을 쓰게 됩니다.

올바른 방법: Auto Attached + glob 매칭 사용

예를 들어 제가 현재 관리하는 프런트엔드·백엔드 분리 프로젝트는 다음과 같이 설정했습니다.

# .cursorrules (프로젝트 루트 디렉터리)

# 공통 규칙(가장 핵심적인 내용만 유지)
- type: always
  rules:
    - TypeScript 사용
    - ESLint 설정 준수
    - 모든 비동기 작업에 오류 처리 추가

# 프런트엔드 규칙(프런트엔드 코드를 수정할 때만 불러옴)
- type: auto
  glob: "src/frontend/**/*.{ts,tsx}"
  rules:
    - React Hooks 사용
    - 컴포넌트에 PropTypes 또는 TypeScript 타입 필수
    - 인라인 스타일 대신 Tailwind CSS 사용

# 백엔드 규칙(백엔드 코드를 수정할 때만 불러옴)
- type: auto
  glob: "src/backend/**/*.ts"
  rules:
    - API 라우트에 입력 검증 필수
    - 데이터베이스 작업에 트랜잭션 필수
    - 민감 정보를 로그에 기록하지 않기

# 테스트 규칙
- type: auto
  glob: "**/*.test.ts"
  rules:
    - 각 테스트 케이스에 명확한 설명 필수
    - Jest의 describe/it 구조 사용

이렇게 설정하면 Agent는 실제로 필요할 때만 해당 규칙을 불러옵니다. 테스트 결과 토큰 사용량이 70%나 줄었고 Agent도 관련 없는 규칙에 방해받지 않았습니다.

작은 팁이 하나 있습니다. 각 규칙 끝에 “확실하지 않다면 먼저 물어보세요”라는 문장을 넣어 보세요. 이 문장을 추가하자 Agent는 경계 상황에서 멋대로 추측하지 않고 먼저 질문했습니다.

팁 2: Long Context와 Summarized Composers 활용

Cursor에는 유용하지만 놓치기 쉬운 기능이 두 가지 있습니다.

Long Context

복잡한 작업을 처리할 때 켜야 하는 옵션입니다. 활성화하면 Agent가 더 큰 컨텍스트 창을 사용해 더 많은 코드를 볼 수 있습니다.

다만 계속 켜 두지는 마세요. 토큰을 빠르게 소모하고 Agent의 사고 시간도 길어집니다. 저는 다음 기준을 사용합니다.

  • 일반 작업(함수 수정, 버그 수정): 끄기
  • 복잡한 작업(모듈 리팩터링, 기능 추가): 켜기
  • 매우 복잡한 작업(모듈 간 리팩터링): 켜기 + 핵심 파일 직접 참조

Summarized Composers

이 기능을 사용하면 Agent가 전체 대화 기록 대신 이전 대화의 요약에 접근할 수 있습니다. 장기 프로젝트에 특히 적합합니다.

예를 들어 어제 Agent에게 유틸리티 함수를 작성하게 했고 오늘 그 함수를 확장하려 한다고 합시다. 단순히 “어제 만든 그 함수로 작업해 줘”라고 하면 Agent가 찾지 못할 수 있습니다. Summarized Composers를 활성화하면 과거 대화 요약을 자동으로 검색해 관련 내용을 찾습니다.

현재 제 작업 흐름은 이렇습니다. 큰 기능 모듈을 하나 완료할 때마다 새 Chat 창을 만들고 첫 문장에 “이 프로젝트에서는 이전에 XX 기능을 구현했으며 코드는 XX 디렉터리에 있습니다”라고 적습니다. 이렇게 하면 과거 컨텍스트를 활용하면서도 너무 많은 세부 정보에 끌려가지 않습니다.

팁 3: 컨텍스트 범위를 능동적으로 관리

이것이 가장 중요하면서도 가장 쉽게 간과되는 부분입니다.

Agent가 알아서 모든 파일을 찾을 것이라고 기대하지 마세요. 어떤 파일을 봐야 하고 어떤 파일을 보면 안 되는지 직접 알려줘야 합니다.

핵심 파일 참조: @ 문법 사용

작업을 설명할 때 @파일명으로 핵심 파일을 표시합니다.

사용자 인증 흐름을 리팩터링해 주세요. 관련 파일은 다음과 같습니다.
@src/routes/auth.ts (인증 라우트)
@src/middleware/jwt.ts (JWT 미들웨어)
@src/models/User.ts (사용자 모델)
@src/utils/password.ts (비밀번호 암호화 유틸리티)

다른 파일은 수정하지 마세요.

마지막 문장인 “다른 파일은 수정하지 마세요”가 중요합니다. 테스트 결과 이 문장을 추가한 뒤 Agent가 관련 없는 코드를 멋대로 수정할 확률이 30%에서 5% 미만으로 줄었습니다.

수정 범위 제한

작업이 특정 하위 디렉터리만 관련된다면 명확히 말합니다.

src/frontend/components/auth/ 디렉터리에 비밀번호 찾기 컴포넌트를 추가하고,
다른 디렉터리의 코드는 수정하지 마세요.

한 단계 더 나아가 허용 목록+차단 목록을 함께 사용할 수도 있습니다.

수정 가능: src/api/** 아래의 모든 파일
수정 금지: src/api/legacy/** (폐기 예정인 레거시 코드)

이렇게 하면 Agent에게 충분한 자율성을 주면서도 건드려서는 안 될 코드를 피할 수 있습니다.

저는 Agent에게 작업을 맡길 때마다 “이 작업에서 수정해야 하는 파일은 최대 몇 개인가? 어느 디렉터리가 관련되는가?”를 먼저 생각한 뒤 범위를 명확히 알려주는 습관을 들였습니다. 번거로워 보이지만 나중에 버그를 수정하는 데 드는 시간을 크게 줄일 수 있습니다.

작업을 나누는 2가지 황금 법칙

컨텍스트 관리는 “Agent가 전체를 보지 못하는” 문제를 해결합니다. 하지만 전체를 보더라도 작업이 너무 복잡하면 Agent가 망칠 수 있습니다. 이럴 때는 작업을 나눠야 합니다.

팁 4: 파일별이 아닌 역할별로 분할

제가 가장 크게 실패했던 부분입니다.

처음에는 작업을 파일별로 나누면 간단하다고 생각했습니다. 예를 들어 회원가입 기능을 만들 때 다음과 같이 분할했습니다.

  1. 먼저 프런트엔드 폼 컴포넌트 작성
  2. 다음으로 백엔드 API 라우트 작성
  3. 마지막으로 데이터베이스 모델 작성

합리적으로 보이지 않나요? 하지만 실제로 진행하면 각 단계에서 문제가 생깁니다.

  • 프런트엔드를 작성할 때 백엔드 인터페이스의 형태를 몰라 추측해서 작성해야 합니다.
  • 백엔드를 작성하다 프런트엔드가 전달하는 인자가 예상과 다르다는 사실을 발견하면 다시 프런트엔드를 수정해야 합니다.
  • 데이터베이스 모델을 작성하다 특정 필드 타입이 잘못됐음을 깨달으면 프런트엔드와 백엔드를 또 수정해야 합니다.

계속 되돌아가 수정하느라 오히려 더 느려집니다.

올바른 분할 방법: 기능 역할별 분할

같은 회원가입 예시를 이제는 다음과 같이 나눕니다.

1단계: 기본 회원가입 흐름 구현(최소 기능 버전)

작업 1: 가장 기본적인 회원가입 기능 구현
- 프런트엔드: 사용자 이름과 비밀번호 필드만 있는 폼
- 백엔드: 회원가입 API + 기본 검증
- 데이터베이스: User 모델(최소 필드)
목표: 전체 흐름을 실행하고 사용자를 정상적으로 등록할 수 있어야 함

2단계: 검증 및 보안 강화

작업 2: 회원가입 검증 및 보안 메커니즘 추가
- 이메일 형식 검증
- 비밀번호 강도 검사
- 중복 가입 방지
- 비밀번호 암호화 저장

3단계: 사용자 경험 개선

작업 3: 회원가입 사용자 경험 개선
- 실시간 폼 검증 안내
- 가입 성공 후 자동 로그인
- 환영 이메일 발송

차이가 보이나요? 각 작업은 “수직”으로 나뉩니다. 프런트엔드부터 백엔드, 데이터베이스까지 하나의 독립적인 기능 단위를 완성합니다.

이렇게 나누면 다음과 같은 장점이 있습니다.

  1. 각 작업을 독립적으로 테스트할 수 있습니다: 작업 1을 마치면 모든 기능이 완성될 때까지 기다리지 않고 바로 실행할 수 있습니다.
  2. 재작업이 줄어듭니다: 프런트엔드와 백엔드를 함께 만들므로 인터페이스 문제를 즉시 발견합니다.
  3. Agent가 더 쉽게 이해합니다: 작업 목표가 명확해 혼동하지 않습니다.

테스트 결과 “역할별 분할” 방식을 사용하면 Agent의 첫 시도 성공률이 60%에서 85%로 높아졌습니다.

팁 5: 명확한 체크포인트 설정

이 팁은 저를 수없이 구해 줬습니다.

대규모 프로젝트의 치명적인 문제 중 하나는 한참 동안 코드를 수정한 뒤 방향이 잘못됐음을 깨달아도 되돌리기 어렵다는 것입니다. 특히 Agent에게 수정을 맡기면 “먼저 저장할까요?”라고 묻지 않고 바로 고칩니다. 문제를 발견할 때쯤이면 이미 십여 개 파일이 바뀌었을 수 있습니다.

Checkpoint 기능 사용

Cursor에는 매우 유용하지만 심각하게 저평가된 기능인 Checkpoint(체크포인트)가 있습니다.

작업을 시작하기 전에 checkpoint를 생성합니다.

# Cursor에서 Cmd/Ctrl + Shift + P 누르기
# "Create Checkpoint" 입력
# 메모 입력: 로그인 모듈 리팩터링 전

그런 다음 Agent에게 작업을 맡깁니다. 결과가 잘못됐다면 checkpoint 상태로 한 번에 롤백해 모든 변경을 취소할 수 있습니다.

저는 다음 원칙을 따릅니다.

  • 새로 큰 작업을 시작할 때마다 checkpoint 생성
  • Agent 작업 후: 테스트 통과 → checkpoint 삭제, 테스트 실패 → checkpoint로 롤백
  • 작은 작업이 여러 개라면 2~3개를 끝낼 때마다 checkpoint 생성

이렇게 하면 Agent가 작업을 망쳐도 작은 작업 하나 분량만 잃습니다.

테스트 주도 개발(TDD)

한 단계 더 발전한 방법은 테스트를 먼저 작성하고 Agent에게 기능을 구현하게 하는 것입니다.

번거로워 보이지만 대규모 프로젝트에서 특히 유용합니다. 다음과 같이 진행할 수 있습니다.

1. 테스트 케이스를 직접 작성해 예상 동작 정의
2. 아직 기능이 구현되지 않았으므로 테스트가 실패하는지 확인
3. 테스트가 통과할 때까지 Agent에게 기능 구현 요청
4. 계속 통과하지 못하면 Agent가 요구 사항을 잘못 이해한 것이므로 즉시 중단

이 방법의 핵심은 테스트 케이스가 Agent에게 명확한 종료 조건을 제공한다는 점입니다. Agent는 끝없이 범위를 확장하지 않고 “테스트 통과”라는 목표에 집중합니다.

Node.js 프로젝트에서 이 방법으로 인증 모듈 전체를 리팩터링했을 때 Agent는 일곱 번 만에 방향을 벗어나지 않고 완료했습니다. 반면 테스트 없이 같은 작업을 했을 때는 십여 번을 시도하고도 계속 버그가 발생했습니다.

코드 리뷰와 모니터링을 위한 2가지 핵심 실천법

앞에서는 “Agent가 실수를 덜 하게 만드는 방법”을 다뤘습니다. 하지만 아무리 조심해도 실수를 완전히 없앨 수는 없습니다. 마지막 방어선은 코드 리뷰와 모니터링입니다. 문제를 제때 발견하고 빠르게 손실을 줄여야 합니다.

팁 6: 다단계 리뷰 기준 수립

AI를 사용하면 Code Review가 필요 없다고 생각하는 경우가 많습니다.

사실은 정반대입니다. AI를 사용한 뒤에는 Code Review가 더 중요합니다. Agent의 실수는 문법상 문제가 없고 논리적으로도 그럴듯하지만 어딘가 “맞지 않는” 식으로 숨어 있는 경우가 많습니다. 사람이 한눈에 알아볼 문제를 Agent는 전혀 인식하지 못할 수 있습니다.

Cursor Rules로 자동 리뷰 설정

Cursor는 .cursorrules에서 Code Review 규칙을 정의할 수 있습니다. 제가 사용하는 설정은 다음과 같습니다.

# .cursorrules (리뷰 규칙 부분)
code_review_rules:
  # 심각 단계(반드시 수정)
  critical:
    - "코드에 비밀번호, API 키 등 민감 정보를 하드코딩하지 않기"
    - "SQL 인젝션 방지를 위해 데이터베이스 작업에 매개변수화 쿼리 사용"
    - "모든 외부 입력 검증 및 정제"

  # 경고 단계(수정 강력 권장)
  warning:
    - "함수는 50줄을 넘지 않도록 하고 필요하면 분리"
    - "any 타입 사용을 피하고 가능한 한 명확한 타입 정의"
    - "비동기 작업은 try-catch 또는 .catch()로 오류 처리"

  # 안내 단계(선택적 개선)
  info:
    - "단위 테스트 추가 고려"
    - "복잡한 로직에는 주석 추가 권장"
    - "중복 코드를 공통 함수로 추출 권장"

설정한 뒤 Agent가 작업을 마칠 때마다 자체 리뷰를 요청합니다.

작업이 완료되었습니다. 이제 .cursorrules의 code_review_rules에 따라 코드를 검토하고,
critical 및 warning 단계의 문제를 모두 나열하세요.

Agent는 발견한 문제를 성실하게 나열합니다. 흥미롭게도 자신이 작성한 코드도 다시 검토하면 문제를 찾아내는 경우가 많습니다. Agent가 “관점을 바꿔” 코드를 다시 보게 하는 셈입니다.

사람과 AI를 결합한 리뷰 전략

Agent의 리뷰에 전적으로 의존하는 것은 불안하고, 모든 것을 직접 검토하기에는 너무 힘듭니다. 그래서 저는 단계별로 처리합니다.

  1. Agent 1차 리뷰(자동): 명백한 문법 오류와 코드 규칙 문제 검사
  2. 사람의 집중 리뷰: 다음 항목을 중점적으로 확인
    • 비즈니스 로직이 올바른가(Agent가 가장 자주 틀리는 부분)
    • 경계 조건을 완전하게 처리했는가
    • 성능에 미치는 영향은 무엇인가(예: N+1 쿼리 발생 여부)
    • 보안 위험이 있는가(SQL 인젝션, XSS 등)
  3. 테스트 검증: 테스트 케이스를 실행해 기존 기능을 망가뜨리지 않았는지 확인

핵심은 모든 줄을 검토하지 않는 것입니다. 그렇게 하면 시간이 너무 많이 듭니다. 핵심 로직과 위험 요소에 집중하고 나머지 세부 사항은 도구와 테스트에 맡깁니다.

15-20%
Agent 코드에서 문제가 발견되는 비율
심각한 버그 5% + 코드 품질 문제 10% + 규칙 미준수 5%

집계 결과 대규모 프로젝트에서 Agent가 수정한 코드의 약 15~20%에 문제가 있었습니다. 그중:

  • 5%는 심각한 버그(로직 오류, 보안 문제)였습니다.
  • 10%는 코드 품질 문제(성능, 유지보수성)였습니다.
  • 5%는 “실행은 되지만 프로젝트 규칙에 맞지 않는” 문제였습니다.

검토하지 않으면 이런 문제는 이후 몇 주에 걸쳐 조금씩 드러나며, 그때는 조사 비용이 훨씬 커집니다.

팁 7: Git은 마지막 안전장치입니다

아주 기초적인 내용처럼 들리지만 실제로 중요하게 생각하지 않는 사람이 많습니다.

git diff 적극 활용

Agent가 코드를 수정한 뒤 가장 먼저 할 일은 테스트 실행이 아니라 다음 명령입니다.

git diff

어떤 파일이 어떻게 변경됐는지 확인합니다. 저는 매번 빠르게 훑으면서 다음 내용을 중점적으로 봅니다.

  • 변경량이 예상과 맞는가(파일 수십 개가 바뀌었다면 주의해야 합니다)
  • 관련 없는 파일이 수정됐는가
  • 핵심 로직이 변경됐는가

작은 팁으로 git diff --stat를 먼저 실행해 변경 통계를 본 뒤 상세 diff를 확인할지 결정할 수 있습니다.

git diff --stat

# 출력 예:
# src/api/auth.ts          | 25 +++++---
# src/models/User.ts       | 12 ++--
# src/utils/password.ts    |  3 +-
# src/config/database.ts   | 150 ++++++++++++++++++++++++++++++++++++++++++++++

작업에서 전혀 변경할 필요가 없는 파일에 150줄이 추가됐다면 즉시 무슨 일이 생겼는지 확인해야 합니다.

Checkpoint와 Git 함께 사용

앞에서 설명한 Checkpoint와 Git을 함께 사용해 이중 안전장치를 만듭니다.

1. 작업 시작 전:
   - git checkout -b feature/xxx  (새 브랜치를 만들어 변경 격리)
   - Cursor Checkpoint 생성

2. Agent 작업 후:
   - git diff (변경 확인)
   - 테스트 실행
   - 문제없음: git commit
   - 문제 있음:
     - 작은 문제: 직접 수정하거나 Agent에게 수정 요청
     - 큰 문제: Checkpoint로 롤백하거나 git reset --hard

3. 문제없음을 확인한 뒤:
   - git push
   - Pull Request 생성

이 흐름에는 다음과 같은 장점이 있습니다.

  • Checkpoint: Git 기록을 다루지 않고 빠르게 롤백
  • Git 브랜치: 변경 사항을 격리해 메인 브랜치에 영향 없음
  • 커밋 기록: 각 단계의 변경 내역 보존

저는 Agent에게 작업을 맡길 때마다 commit message에도 다음과 같이 표시합니다.

git commit -m "feat: 사용자 회원가입 기능 추가 (by AI Agent)"

나중에 문제가 생겼을 때 커밋만 봐도 Agent가 작성했다는 것을 알 수 있어 더 주의 깊게 조사할 수 있습니다.

결론

글 앞부분에서 이야기한 새벽 1시의 상황으로 돌아가 보겠습니다.

지금 Cursor Agent로 로그인 모듈을 다시 리팩터링한다면 다음과 같이 진행할 것입니다.

  1. 컨텍스트 관리: 인증 모듈용 .cursorrules를 만들어 관련 규칙만 불러옵니다. @로 핵심 파일 5개를 참조하고 Agent에게 “이 5개 파일만 수정하세요”라고 명확히 알립니다.
  2. 작업 분할: 모든 기능을 한 번에 리팩터링하지 않습니다. 먼저 기본 로그인 흐름을 구현하고, 정상 작동하면 검증을 추가한 뒤 마지막으로 캐시를 최적화합니다.
  3. 코드 리뷰: 작은 작업을 하나 마칠 때마다 git diff로 변경 사항을 확인하고 테스트를 실행한 뒤 문제가 없을 때만 계속 진행합니다.

이렇게 하면 Agent가 파일을 찾지 못할 확률은 50%에서 10% 미만으로, 잘못된 코드를 수정할 확률은 30%에서 5% 미만으로 줄어듭니다. 제가 추가로 투자하는 시간도 작업당 5~10분에 불과합니다.

솔직히 AI 코딩 도구는 만능이 아닙니다. 아키텍처 설계, 비즈니스 로직 이해, 코드 품질에 대한 책임을 대신할 수 없습니다. 하지만 올바르게 사용하면 개발 효율을 확실히 두 배로 높일 수 있습니다. 전제는 도구를 “관리하는” 방법을 알아야 한다는 것입니다.

컨텍스트 관리, 작업 분할, 코드 리뷰는 어느 하나도 빠질 수 없습니다. 컨텍스트 관리는 Agent가 “정확히 보게” 하고, 작업 분할은 Agent가 “올바르게 수행하게” 하며, 코드 리뷰는 여러분이 “마음 편히 잠들게” 합니다.

마지막으로 한 가지 제안이 있습니다. 대규모 프로젝트에서 Cursor Agent를 사용하고 있다면 오늘 10분만 투자해 Project Rules 설정을 확인해 보세요. always 모드를 auto + glob 매칭으로 바꾸는 것만으로도 토큰을 크게 절약하고 Agent의 성능을 즉시 한 단계 높일 수 있습니다.

기술은 발전하고 도구는 계속 바뀌지만 변하지 않는 원칙도 있습니다. 요구 사항을 명확히 하고, 작업을 나누며, 지속적으로 검증하는 것입니다. 이 방법은 AI 코딩뿐 아니라 모든 복잡한 프로젝트 개발에 적용할 수 있습니다.

여러분은 Cursor Agent를 사용하면서 어떤 문제를 겪었나요? 댓글로 경험을 공유해 주세요.

대규모 프로젝트에서 Cursor Agent를 활용하는 전체 개발 흐름

작업 시작부터 최종 확인까지, 대규모 프로젝트에서 Agent가 효율적이고 안정적으로 일하게 만드는 전체 작업 흐름

Estimated time: PT30M

  1. 1

    Step 1: 작업 준비: 컨텍스트와 체크포인트 설정

    컨텍스트 관리는 성공의 핵심이므로 작업 시작 전에 준비해야 합니다.
  2. 2

    Step 2: 작업 실행: Agent의 작업 범위를 정확하게 통제

    실행 단계에서는 파일 누락이나 잘못된 수정을 피하도록 Agent의 작업 범위를 정확히 통제해야 합니다.
  3. 3

    Step 3: 코드 리뷰: 변경 사항을 여러 단계로 점검

    Agent의 작업이 끝나면 제출을 확정하기 전에 여러 단계의 리뷰를 거쳐야 합니다.
  4. 4

    Step 4: 결정 및 제출: 테스트 통과 후 코드 제출

    리뷰 및 테스트 결과에 따라 다음 작업을 결정합니다.
  5. 5

    Step 5: 최종 확인: 코드 푸시 및 PR 생성

    모든 변경 사항에 문제가 없음을 확인한 뒤 원격 저장소에 푸시하고 Pull Request를 생성합니다.

FAQ

Project Rules를 설정할 때 왜 always 모드 대신 auto + glob 모드를 사용해야 하나요?
always 모드는 대화할 때마다 모든 규칙을 불러와 토큰을 과도하게 소모합니다. 프런트엔드와 백엔드가 분리된 프로젝트에는 프런트엔드, 백엔드, 테스트 등 여러 모듈의 규칙이 있을 수 있습니다. 이를 모두 always로 불러오면 Agent가 작업을 시작하기도 전에 토큰의 3분의 1을 쓰게 됩니다.

auto + glob 모드의 장점:
• Agent는 해당 코드를 수정할 때만 관련 규칙을 불러옵니다. 예를 들어 프런트엔드 코드를 수정할 때만 프런트엔드 규칙을 불러옵니다.
• 토큰 사용량이 70% 감소합니다.
• Agent가 관련 없는 규칙에 방해받지 않고 현재 작업에 집중합니다.
• 설정 예: type: auto, glob: "src/frontend/**/*.{ts,tsx}"

실측 결과: 중간 규모 프로젝트에서 auto 모드로 바꾼 뒤 Agent의 응답 속도가 50% 빨라졌고 작업 요구 사항도 더 정확히 이해했습니다.
역할별 작업 분할과 파일별 작업 분할은 무엇이 다르며, 왜 역할별 분할을 권장하나요?
파일별 분할(수평 분할)의 문제점:
• 프런트엔드 작성→백엔드 작성→데이터베이스 작성 순서로 진행합니다.
• 프런트엔드를 작성할 때 백엔드 인터페이스의 형태를 몰라 추측할 수밖에 없습니다.
• 백엔드를 작성하다 프런트엔드의 전달 인자가 잘못됐음을 발견하면 되돌아가 수정해야 합니다.
• 데이터베이스 모델 설계가 부적절하면 프런트엔드와 백엔드를 다시 수정해야 합니다.
• 반복 작업이 늘어나 오히려 효율이 떨어집니다.

역할별 분할(수직 분할)의 장점:
• 각 작업이 프런트엔드+백엔드+데이터베이스를 포함한 완전한 기능 단위입니다.
• 예: 작업 1은 기본 회원가입 흐름, 작업 2는 검증 강화, 작업 3은 사용자 경험 개선을 구현합니다.
• 작업 1이 끝나면 모든 기능이 완성될 때까지 기다리지 않고 바로 실행해 테스트할 수 있습니다.
• 프런트엔드와 백엔드를 함께 작업하므로 인터페이스 문제를 즉시 발견합니다.
• Agent가 작업 목표를 더 쉽게 이해하고 혼동하지 않습니다.

실측 데이터: 역할별 분할 방식을 사용하자 Agent의 첫 시도 성공률이 60%에서 85%로 높아졌습니다.
Cursor Checkpoint와 Git 브랜치는 무엇이 다른가요? 어느 것을 사용해야 하나요?
두 기능은 비슷하지만 사용 상황이 다르므로 함께 사용하는 것을 권장합니다.

Cursor Checkpoint의 특징:
• Git 기록을 처리할 필요 없이 빠르게 생성하고 롤백할 수 있습니다.
• 실험적인 변경이나 결과가 불확실한 작업에 적합합니다.
• 롤백하면 모든 변경 사항이 즉시 취소되며 흔적이 남지 않습니다.
• 단점: Checkpoint는 원격으로 푸시되지 않고 로컬에만 존재합니다.

Git 브랜치의 특징:
• 변경 사항을 격리해 메인 브랜치에 영향을 주지 않습니다.
• 완전한 커밋 기록을 보존해 추적하기 쉽습니다.
• 원격으로 푸시할 수 있어 팀 협업에 편리합니다.
• 롤백하려면 git reset 또는 git revert를 사용해야 합니다.

권장 조합:
1. 작업 시작 전: Git 브랜치 생성(변경 격리) + Checkpoint 생성(빠른 롤백)
2. Agent 작업 후: 작은 문제는 Checkpoint로 롤백하고, 큰 문제는 git reset --hard 실행
3. 테스트 통과 후: git commit으로 기록을 남기고, 더 이상 필요 없는 Checkpoint 삭제

이렇게 하면 Checkpoint의 빠른 롤백 기능과 Git의 버전 관리 장점을 모두 활용할 수 있습니다.
작업에 Long Context 모드가 필요한지는 어떻게 판단하나요?
Long Context 모드는 더 큰 컨텍스트 창을 사용하지만 토큰을 빠르게 소모하므로 항상 켜 두면 안 됩니다.

Long Context가 적합한 상황:
• 모듈 간 리팩터링(5개가 넘는 파일 관련)
• 복잡한 기능 개발(여러 모듈의 상호작용을 이해해야 함)
• 여러 파일에 걸친 버그 수정
• 성능 최적화를 위해 호출 체인을 확인해야 할 때

켜지 않아도 되는 상황:
• 단일 함수나 컴포넌트 수정
• 간단한 버그 수정(1~2개 파일만 관련)
• 주석이나 문서 추가
• 코드 포매팅

판단 기준:
• 관련 파일 수 ≤ 3: 끄기
• 관련 파일 수 4~6: 복잡도에 따라 결정
• 관련 파일 수 ≥ 7: 켜고 @로 핵심 파일을 직접 참조

실용적인 팁: 확실하지 않다면 먼저 끈 상태에서 Agent의 작업을 확인하세요. 핵심 파일을 찾지 못하거나 전체를 제대로 이해하지 못한다면 Long Context를 켜고 작업을 다시 실행합니다.
Agent가 수정한 코드에는 어느 정도 문제가 있으며, 어떤 문제가 가장 흔한가요?
대규모 프로젝트에서 집계한 결과, Agent가 수정한 코드의 약 15~20%에 문제가 있었습니다.

문제 분포:
• 5%는 심각한 버그(로직 오류, 보안 취약점, 데이터 손실 위험)입니다.
• 10%는 코드 품질 문제(낮은 성능, 부족한 유지보수성, 중복 코드)입니다.
• 5%는 '실행은 되지만 프로젝트 규칙에 맞지 않는' 문제(부적절한 이름, 주석 누락 등)입니다.

가장 흔한 문제 유형:
1. 비즈니스 로직을 잘못 이해함(가장 큰 비중)
- Agent가 문자 그대로 구현하고 숨어 있는 비즈니스 규칙을 무시합니다.
- 예: '사용자 삭제'를 구현할 때 소프트 삭제가 아니라 물리 삭제를 수행합니다.
2. 경계 조건 처리가 불완전함
- null 값, 예외 상황, 동시성 충돌 같은 특수 상황을 놓칩니다.
3. 성능 문제
- N+1 쿼리, 메모리 누수, 전체 데이터 로딩 등이 발생합니다.
4. 보안 위험
- SQL 인젝션, XSS, 민감 정보 노출, 권한 검사 누락 등이 발생합니다.

대응 방법:
• Agent의 코드를 전적으로 신뢰하지 말고 반드시 Code Review를 진행합니다.
• 비즈니스 로직, 경계 조건, 성능, 보안을 집중적으로 검토합니다.
• .cursorrules의 code_review_rules에 자동 리뷰 규칙을 만듭니다.
• Agent가 작업을 마치면 제출 전에 자체 리뷰를 하도록 요구합니다.

문제를 발견했다면 작은 문제는 직접 수정하거나 Agent에게 해당 부분만 고치게 하고, 큰 문제는 바로 롤백하고 처음부터 다시 진행합니다.
Agent가 수정하면 안 되는 파일을 변경하지 않게 하려면 어떻게 해야 하나요?
대규모 프로젝트에서 Agent가 가장 흔히 일으키는 문제 중 하나이며, 몇 가지 효과적인 방법이 있습니다.

수정 범위를 명확히 제한하기:
• 작업 설명 끝에 '다른 파일은 수정하지 마세요'라는 문장을 추가합니다.
• 실측 결과: 이 문장을 추가하자 불필요한 코드 변경 확률이 30%에서 5% 미만으로 줄었습니다.

허용 목록+차단 목록 사용하기:
• 수정 가능한 범위를 명시합니다: '수정 가능: src/api/** 아래의 모든 파일'
• 수정 금지 범위를 명시합니다: '수정 금지: src/api/legacy/** (레거시 코드)'
• 이렇게 하면 자율성을 주면서도 건드리면 안 되는 코드를 피할 수 있습니다.

@ 문법으로 핵심 파일 참조하기:
• 수정해야 할 파일을 모두 명확히 나열합니다.
• 예: '관련 파일: @src/routes/auth.ts, @src/middleware/jwt.ts'
• Agent가 해당 파일을 우선 확인하므로 다른 파일을 잘못 수정할 가능성이 줄어듭니다.

git diff로 즉시 발견하기:
• Agent 작업 직후 git diff --stat를 실행합니다.
• 변경된 파일 목록이 예상 범위와 일치하는지 확인합니다.
• 관련 없는 파일이 변경됐다면 즉시 롤백하거나 직접 복원합니다.

.cursorrules 설정하기:
• '명시적인 승인 없이 핵심 모듈 코드를 수정하지 마세요'라는 규칙을 추가합니다.
• 핵심 디렉터리에 수정하면 안 되는 이유를 설명하는 주석을 추가합니다.

이 방법들을 함께 사용하면 Agent가 파일을 잘못 수정할 가능성을 최소화할 수 있습니다.
테스트 주도 개발(TDD)은 Agent가 작업을 더 잘 완료하는 데 어떻게 도움이 되나요?
TDD는 Agent에게 명확한 종료 조건을 제시하므로 Agent와 협업할 때 특히 유용합니다.

기존 방식의 문제점:
• Agent가 기능을 구현해도 제대로 이해했는지 알기 어렵습니다.
• 이미 십여 개 파일을 수정한 뒤 방향이 잘못됐음을 발견할 수 있습니다.
• 재작업 비용이 크고 다른 기능까지 망가뜨렸을 수 있습니다.

TDD의 장점:
• 테스트 케이스가 예상 동작을 정의하므로 Agent의 목표가 명확합니다.
• Agent가 '테스트 통과'에 집중하고 끝없이 범위를 확장하지 않습니다.
• 테스트가 실패하면 즉시 문제를 발견하고 손실을 줄일 수 있습니다.
• 테스트 자체가 문서이므로 나중에 코드를 유지보수할 때 한눈에 파악할 수 있습니다.

구체적인 작업 흐름:
1. 테스트 케이스를 직접 작성합니다(Agent에게 작성하게 해도 되지만 직접 검토해야 합니다).
2. 아직 기능이 구현되지 않았으므로 테스트가 실패하는지 확인합니다.
3. Agent에게 'XX 기능을 구현해 @test/xxx.test.ts의 테스트를 통과시키세요'라고 요청합니다.
4. Agent 작업 후 테스트를 실행합니다. 통과하면 제출하고, 실패하면 코드를 점검하거나 롤백합니다.

실제 사례:
• TDD로 인증 모듈을 리팩터링했을 때 Agent는 일곱 번 만에 방향을 벗어나지 않고 완료했습니다.
• 테스트 없이 같은 작업을 했을 때는 십여 번을 시도하고도 계속 버그가 발생했습니다.

핵심: 테스트 케이스의 품질이 Agent의 성과를 결정합니다. 테스트가 명확하면 Agent도 정확히 구현하지만, 모호하면 추측하게 됩니다.

2분 읽기 · 게시일: 2026년 1월 10일 · 수정일: 2026년 9월 4일

댓글

GitHub로 로그인하여 댓글을 남기세요

Easton BlogEaston Blog