Claude Code 토큰 최적화 완벽 가이드
invoke-opencode-acp 스킬을 활용한 효율적인 개발 워크플로우
서론
Claude Code를 사용하다 보면 복잡한 리팩터링이나 대규모 코드 수정 작업 중에 토큰이 예상보다 빠르게 소진되는 경험을 하게 됩니다. 특히 여러 파일에 걸친 작업이나 반복적인 패턴 적용이 필요한 경우, Claude가 중간 추론 과정을 자세히 설명하면서 수천 개의 토큰을 사용하게 됩니다. 이는 AI의 투명성 측면에서는 장점이지만, 실제 개발 효율성 관점에서는 비용과 시간 낭비로 이어질 수 있습니다.
이 가이드에서는 invoke-opencode-acp 스킬과 opencode CLI를 활용하여 토큰 사용량을 50~90%까지 절약하면서도 동일한 코드 품질을 유지하는 방법을 상세히 다룹니다. 실제 프로젝트에서 바로 활용할 수 있는 샘플 프롬프트와 함께 작동 원리를 깊이 있게 설명하여, 여러분이 자신의 프로젝트에 맞게 응용할 수 있도록 돕겠습니다.
1. 핵심 개념 이해하기
1.1 토큰 소모의 본질적 문제
Claude Code와 대화할 때, 우리가 “이 코드를 리팩터링해줘”라고 요청하면 Claude는 단순히 코드만 수정하는 것이 아닙니다. Claude는 자신의 사고 과정을 자연어로 표현하면서 작업을 진행합니다. 예를 들어, “먼저 현재 코드의 구조를 분석하겠습니다. 콜백 패턴이 5군데에서 사용되고 있네요. 각각을 async/await로 변환하려면…“과 같은 설명을 출력합니다.
이러한 중간 추론은 우리가 Claude의 판단 과정을 이해하는 데 도움이 되지만, 토큰 측면에서는 비효율적입니다. 특히 10개 이상의 파일을 수정하거나 수백 개의 함수를 일괄 변경하는 작업에서는 이런 중간 설명이 누적되어 수만 개의 토큰을 소모하게 됩니다. 실제로 필요한 것은 최종 결과물인데, 그 과정을 모두 메인 대화에 포함시키는 것입니다.
1.2 하위 에이전트 패러다임
invoke-opencode-acp 스킬은 이 문제를 근본적으로 다른 방식으로 해결합니다. 메인 Claude 세션에서 복잡한 작업을 수행하는 대신, 별도의 독립적인 Claude 인스턴스를 실행하여 작업을 처리하도록 위임하는 것입니다. 이를 “하위 에이전트(sub-agent)” 패턴이라고 부릅니다.
작동 방식을 비유하자면, 메인 Claude는 프로젝트 매니저 역할을 하고, 하위 에이전트는 실제 작업을 수행하는 개발자 역할을 합니다. 프로젝트 매니저는 작업을 지시하고 최종 결과만 보고받지, 개발자가 코드를 한 줄 한 줄 작성하는 과정을 모두 지켜보지 않습니다. 이렇게 하면 메인 대화에서는 작업 지시와 결과 요약만 주고받으므로 토큰 사용량이 극적으로 줄어듭니다.
1.3 opencode CLI의 역할
opencode는 Claude Code의 핵심 명령줄 인터페이스입니다. invoke-opencode-acp 스킬이 호출되면, 이 스킬은 내부적으로 opencode CLI를 실행하여 새로운 Claude 세션을 시작합니다. 이 새로운 세션은 메인 세션과 완전히 독립적으로 작동하며, 자체 컨텍스트와 토큰 예산을 가집니다.
중요한 점은 하위 에이전트가 사용하는 토큰은 메인 세션의 토큰 예산과 별도로 관리된다는 것입니다. 하위 에이전트가 복잡한 추론을 하며 수천 개의 토큰을 사용하더라도, 메인 세션에는 단지 “작업 시작됨”, “진행 중”, “작업 완료, 5개 파일 수정됨”과 같은 요약 정보만 전달됩니다. 이것이 토큰 절약의 핵심 메커니즘입니다.
2. 기존 방식의 문제점 심층 분석
2.1 토큰 소모 패턴 분석
기존 방식으로 “API 레이어의 5개 파일을 리팩터링해줘”라고 요청하면 Claude는 다음과 같은 단계로 작업을 진행합니다:
첫 번째 단계에서 Claude는 현재 코드 구조를 분석합니다. “users.controller.js 파일을 확인해보니 Express 미들웨어 패턴으로 작성되어 있고, 7개의 라우트 핸들러가 있습니다. 각 핸들러는 콜백 함수를 사용하고 있네요…” 이런 식으로 각 파일을 설명하는 데만 수백 개의 토큰이 소모됩니다.
두 번째 단계에서는 리팩터링 계획을 수립합니다. “먼저 users.controller.js부터 시작하겠습니다. getUserById 함수의 콜백을 async/await로 변환하고, 에러 핸들링을 try-catch로 개선하겠습니다…” 이런 설명이 각 함수마다 반복됩니다.
세 번째 단계에서 실제 코드 수정을 하면서도 Claude는 자신의 판단을 계속 설명합니다. “여기서는 기존의 callback(err, data) 패턴을 제거하고 직접 return하도록 변경했습니다. 그리고 데이터베이스 쿼리 부분은…” 이런 식입니다.
이 모든 과정에서 우리가 실제로 필요한 것은 수정된 코드뿐인데, 설명이 코드보다 더 많은 토큰을 사용하게 됩니다. 실제 측정 결과, 5개 파일 리팩터링에 약 12,300개의 토큰이 사용되었는데, 그 중 9,500개가 설명과 추론 과정이었고, 실제 코드는 2,800개 토큰에 불과했습니다.
2.2 작업 중단 문제
더 심각한 문제는 토큰이 소진되면 작업이 완료되지 못한다는 점입니다. Claude Code의 세션당 토큰 제한이 있기 때문에, 대규모 리팩터링 중에 토큰이 바닥나면 작업이 중단됩니다. 이미 수정한 파일도 있고 아직 수정하지 못한 파일도 있는 상황에서 작업이 멈추면, 개발자는 어느 부분까지 완료되었는지 파악하고 나머지를 다시 요청해야 합니다.
특히 복잡한 의존성이 있는 코드를 수정할 때 이런 일이 발생하면 심각합니다. 예를 들어, A 파일을 수정하고 B 파일을 수정하던 중 토큰이 소진되면, B 파일은 A 파일의 변경사항을 반영하지 못한 채로 남게 됩니다. 이는 런타임 에러나 타입 불일치 문제로 이어질 수 있습니다.
2.3 재작업의 비효율
토큰이 소진된 후 작업을 재개하려면 새로운 대화를 시작해야 합니다. 그런데 새 대화에는 이전 컨텍스트가 없으므로, 개발자가 “아까 users.controller.js와 posts.controller.js는 이미 수정했고, 나머지 comments.controller.js, likes.controller.js, shares.controller.js를 같은 방식으로 수정해줘”라고 설명해야 합니다.
이 설명을 위해 또 토큰을 사용하게 되고, Claude는 이미 완료된 작업을 다시 검토하면서 추가 토큰을 소모합니다. 결과적으로 전체 프로젝트를 한 번에 처리했을 때보다 더 많은 토큰을 사용하게 되는 역설적인 상황이 발생합니다.
3. invoke-opencode-acp 스킬 아키텍처
3.1 스킬의 내부 작동 원리
invoke-opencode-acp 스킬은 Claude Code의 공식 스킬로, 표준 MCP(Model Context Protocol)를 기반으로 구현되어 있습니다. 사용자가 이 스킬을 호출하면 다음과 같은 프로세스가 실행됩니다.
첫째, 메인 Claude 세션이 작업 요청을 파싱하여 구조화된 지시사항을 생성합니다. “users 모듈의 모든 콜백을 async/await로 변환”이라는 자연어 요청을 “목표: 콜백 패턴 제거, 대상: src/modules/users/*.js, 방법: async/await 변환, 에러 핸들링: try-catch 적용”과 같은 구조화된 형식으로 변환합니다.
둘째, opencode CLI가 새로운 프로세스로 실행됩니다. 이 프로세스는 독립적인 Claude API 세션을 시작하며, 자체적인 토큰 예산과 컨텍스트를 가집니다. 중요한 점은 이 하위 세션이 메인 세션의 CLAUDE.md나 프로젝트 컨텍스트를 자동으로 상속받는다는 것입니다. 따라서 프로젝트의 코딩 스타일, 네이밍 컨벤션, 아키텍처 패턴을 별도로 설명할 필요가 없습니다.
셋째, 하위 에이전트가 작업을 수행하는 동안, 진행 상황이 압축된 형태로 메인 세션에 전달됩니다. “파일 1/5 처리 중”, “모든 파일 처리 완료, 총 23개 함수 변환됨”과 같은 메타 정보만 전달되므로 메인 세션의 토큰 사용은 최소화됩니다.
넷째, 작업이 완료되면 요약 리포트가 생성됩니다. 이 리포트는 “어떤 파일들이 수정되었는지”, “주요 변경사항이 무엇인지”, “발견된 이슈가 있는지” 등의 핵심 정보만 담고 있어, 일반적으로 200~300 토큰 정도만 사용합니다.
3.2 컨텍스트 전달 메커니즘
하위 에이전트가 효과적으로 작업하려면 프로젝트의 컨텍스트를 이해해야 합니다. invoke-opencode-acp는 이를 위해 스마트한 컨텍스트 전달 메커니즘을 사용합니다.
프로젝트 루트의 CLAUDE.md 파일이 있다면 자동으로 하위 에이전트에 전달됩니다. 이 파일에는 프로젝트의 아키텍처, 코딩 스타일, 주요 패턴이 정의되어 있으므로, 하위 에이전트는 별도의 설명 없이도 프로젝트 표준에 맞게 작업할 수 있습니다.
또한 작업 대상 파일들의 경로와 현재 상태가 전달됩니다. 하지만 전체 파일 내용을 모두 전달하는 것이 아니라, 관련된 부분만 선택적으로 전달됩니다. 예를 들어, “users 모듈의 콜백 변환”이라는 작업이라면, users 관련 파일들과 그것들이 의존하는 핵심 모듈만 컨텍스트에 포함됩니다.
이런 선택적 컨텍스트 전달 덕분에 하위 에이전트는 효율적으로 작업하면서도 관련 없는 코드까지 분석하느라 시간과 토큰을 낭비하지 않습니다.
3.3 두 가지 실행 모드
invoke-opencode-acp 스킬은 작업의 특성에 따라 두 가지 모드로 실행됩니다.
일회성 모드 (One-shot Mode) 는 30분 미만의 작업에 적합합니다. 이 모드에서는 작업 지시를 받은 후 하위 에이전트가 완전히 자율적으로 작업을 완료하고, 메인 세션에는 최종 결과만 보고합니다. 중간 진행 상황을 확인하거나 방향을 수정할 수 없지만, 그만큼 오버헤드가 적고 빠릅니다.
예를 들어, “API 엔드포인트 5개의 응답 형식을 RESTful 표준으로 통일해줘”같은 명확한 작업은 일회성 모드가 적합합니다. 작업 목표가 분명하고, 중간에 판단이 필요한 부분이 적기 때문입니다.
인터랙티브 모드 (Interactive Mode) 는 30분 이상 소요되는 복잡한 작업에 사용됩니다. 이 모드에서는 5분마다 하위 에이전트가 진행 상황을 보고하고, 사용자가 방향을 조정할 수 있습니다.
예를 들어, “전체 프로젝트의 에러 핸들링을 개선해줘”같은 작업은 인터랙티브 모드가 필요합니다. 하위 에이전트가 “users 모듈에서 네트워크 에러와 비즈니스 로직 에러를 구분하는 패턴을 발견했는데, 다른 모듈에도 이 패턴을 적용할까요?”와 같은 질문을 할 수 있고, 개발자가 “네, 그렇게 해주세요. 단, admin 모듈은 보안 이유로 에러 메시지를 상세히 노출하지 말아주세요”같은 지시를 추가할 수 있습니다.
4. 효과적인 작업 시나리오
4.1 대규모 리팩터링 작업
대규모 리팩터링은 invoke-opencode-acp 스킬이 가장 빛을 발하는 시나리오입니다. 예를 들어, 레거시 코드베이스를 모던 패턴으로 전환하는 작업을 생각해봅시다.
프로젝트에 20개의 컨트롤러 파일이 있고, 모두 콜백 기반 비동기 코드로 작성되어 있다고 가정합니다. 이를 async/await로 변환하려면 수백 개의 함수를 수정해야 하고, 각 함수의 에러 핸들링도 개선해야 합니다. 기존 방식으로는 이 작업에 50,000 토큰 이상이 소요될 수 있지만, invoke-opencode-acp를 사용하면 5,000~10,000 토큰으로 완료할 수 있습니다.
작업 방식은 이렇습니다. 먼저 한두 개의 파일을 샘플로 메인 세션에서 직접 리팩터링하여 패턴을 확립합니다. “이런 식으로 변환하면 되겠네요”라는 확신이 들면, 나머지 파일들은 하위 에이전트에게 위임합니다. 하위 에이전트는 확립된 패턴을 모든 파일에 일관되게 적용하고, 예외 상황이 발견되면 보고합니다.
4.2 코드 품질 개선 작업
정적 분석 도구(SonarQube, ESLint 등)에서 발견된 이슈들을 일괄 수정하는 작업도 좋은 사용 사례입니다. 예를 들어, SonarQube가 “200개의 코드 스멜을 발견했습니다”라고 보고했다면, 이를 하나하나 수정하는 것은 지루하고 토큰 집약적인 작업입니다.
invoke-opencode-acp를 사용하면 “SonarQube가 지적한 ‘cognitive complexity’ 이슈들을 함수 분리를 통해 해결해줘”라고 지시할 수 있습니다. 하위 에이전트는 해당하는 모든 함수를 찾아 복잡도를 분석하고, 적절히 분리하며, 테스트가 여전히 통과하는지 확인합니다. 메인 세션에는 “47개 함수를 리팩터링했고, 평균 복잡도가 15에서 8로 감소했습니다”같은 요약만 전달됩니다.
4.3 테스트 코드 자동 생성
테스트 커버리지를 높이기 위해 여러 모듈의 단위 테스트를 생성하는 작업도 적합합니다. “services 디렉토리의 모든 클래스에 대해 Jest 단위 테스트를 생성해줘”라고 요청하면, 하위 에이전트가 각 클래스를 분석하고 적절한 테스트 케이스를 작성합니다.
특히 테스트 생성은 패턴이 반복적이고 창의성이 덜 요구되는 작업이므로, 하위 에이전트가 매우 효율적으로 처리할 수 있습니다. 메인 세션에서는 “edge case가 있다면 추가로 테스트해줘”, “mocking 전략은 dependency injection을 활용해줘”같은 고수준 지침만 제공하면 됩니다.
4.4 문서화 작업
API 문서, 코드 주석, README 파일 등을 일괄 생성하거나 업데이트하는 작업도 하위 에이전트에게 적합합니다. “모든 public API 엔드포인트에 대해 OpenAPI 3.0 스펙을 생성해줘”라고 요청하면, 하위 에이전트가 코드를 분석하여 파라미터, 응답 형식, 에러 케이스 등을 문서화합니다.
문서화는 정확도가 중요한 작업이지만, 형식은 대부분 표준화되어 있습니다. 하위 에이전트는 이런 구조화된 작업을 잘 수행하며, 메인 세션에는 “32개 엔드포인트 문서화 완료, 6개 엔드포인트에서 타입 불일치 발견”같은 유용한 피드백을 제공합니다.
5. 실전 샘플 프롬프트 모음
5.1 기본 리팩터링 프롬프트
시나리오: 콜백을 async/await로 변환
1
2
3
4
5
6
7
8
9
src/controllers 디렉토리의 모든 파일을 검토하여 콜백 패턴을 async/await로 변환해줘.
구체적으로:
- callback(err, data) 패턴을 try-catch와 return으로 변경
- Promise를 반환하도록 함수 시그니처 수정
- 에러 핸들링은 기존 로직 유지하되 더 명확하게 표현
- async 함수임을 명확히 하기 위해 함수명은 유지
완료 후 변환된 함수 개수와 발견된 이슈를 요약해줘.
시나리오: 변수명 일괄 변경
1
2
3
4
5
6
7
8
9
10
11
프로젝트 전체에서 camelCase 네이밍 컨벤션을 적용해줘.
대상:
- 모든 .js 파일의 변수명, 함수명
- snake_case나 PascalCase로 된 것들을 camelCase로 변환
- 단, 상수(전역 설정값)는 UPPER_SNAKE_CASE 유지
- 데이터베이스 필드명은 변경하지 말 것
주의사항:
- 외부 라이브러리 API 호출 시 파라미터명은 변경하지 말 것
- 테스트 코드도 함께 업데이트해서 테스트가 깨지지 않도록 할 것
시나리오: 중복 코드 제거
1
2
3
4
5
6
7
8
9
10
11
12
utils 디렉토리의 모든 파일을 분석하여 중복된 로직을 찾아 공통 함수로 추출해줘.
기준:
- 3번 이상 반복되는 5줄 이상의 코드 블록
- 유사한 패턴이지만 약간씩 다른 경우도 파라미터화하여 통합
- 추출된 공통 함수는 utils/common.js에 배치
- 각 원본 위치에 주석으로 "Refactored to common.extractXXX()" 표시
결과:
- 추출된 공통 함수 개수
- 제거된 중복 코드 라인 수
- 통합하지 않은 유사 코드가 있다면 이유와 함께 보고
5.2 코드 품질 개선 프롬프트
시나리오: SonarQube 이슈 해결
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
SonarQube 분석 결과를 기반으로 코드 스멜을 해결해줘.
우선순위:
1. Cognitive Complexity가 15 이상인 함수들을 작은 함수로 분리
2. 중첩된 if문을 early return 패턴으로 개선
3. 긴 파라미터 리스트(5개 이상)를 옵션 객체로 변경
각 변경사항에 대해:
- 기존 함수 위에 /* Refactored: reduced complexity from X to Y */ 주석 추가
- 분리된 새 함수에는 명확한 JSDoc 추가
- 기존 테스트가 모두 통과하는지 확인
최종 보고:
- 개선된 함수 개수와 복잡도 감소 정도
- 테스트 실패가 있다면 상세 내역
시나리오: 타입 안정성 개선
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
JavaScript 코드에 JSDoc 타입 주석을 추가하여 IDE 자동완성과 타입 체크를 개선해줘.
대상:
- 모든 public 함수와 클래스 메서드
- 함수 파라미터와 리턴 타입
- 복잡한 객체 구조는 @typedef로 정의
예시:
/**
* @param {string} userId - 사용자 ID
* @param {Object} options - 옵션
* @param {boolean} [options.includeDeleted=false] - 삭제된 항목 포함 여부
* @returns {Promise<User[]>} 사용자 목록
*/
주의:
- 이미 있는 주석은 보존하되 타입 정보 보강
- any 타입은 가급적 사용하지 말고 구체적인 타입 명시
시나리오: 에러 핸들링 표준화
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
프로젝트 전체의 에러 핸들링을 일관된 패턴으로 개선해줘.
표준 패턴:
1. 비즈니스 로직 에러: CustomError 클래스 확장 (예: ValidationError, NotFoundError)
2. 외부 서비스 에러: 재시도 로직 포함 (최대 3회, 지수 백오프)
3. 예상치 못한 에러: 로깅 후 generic error로 변환
구현:
- errors/CustomError.js 기반 클래스 생성
- 각 모듈에서 적절한 에러 클래스 사용
- try-catch 블록에서 에러 타입에 따른 처리
- 클라이언트에는 민감한 정보 노출하지 않기
보고:
- 생성된 커스텀 에러 클래스 종류
- 개선된 에러 핸들링 블록 개수
5.3 테스트 자동화 프롬프트
시나리오: 단위 테스트 생성
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
services 디렉토리의 모든 클래스에 대해 Jest 단위 테스트를 생성해줘.
테스트 커버리지 목표:
- 모든 public 메서드
- 정상 케이스와 에러 케이스 모두
- Edge case (null, undefined, 빈 배열 등)
- 비동기 함수는 async/await 테스트
Mock 전략:
- 외부 의존성(DB, API)은 모두 mock
- jest.mock() 사용하여 모듈 레벨 mocking
- 각 테스트는 독립적으로 실행 가능하도록
파일 구조:
- tests/unit/services/*.test.js
- 원본 파일명과 동일하게 (예: UserService.js → UserService.test.js)
각 테스트 파일에 포함:
- describe 블록으로 클래스 그룹화
- beforeEach에서 mock 초기화
- 명확한 테스트 설명 (예: "should return user when valid id is provided")
시나리오: 통합 테스트 생성
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
API 엔드포인트에 대한 통합 테스트를 생성해줘.
대상: src/routes/*.js의 모든 라우트
테스트 시나리오:
1. 인증 테스트 (유효한 토큰, 만료된 토큰, 없는 토큰)
2. 권한 테스트 (admin, user, guest 역할별)
3. 입력 검증 (필수 필드 누락, 잘못된 형식, SQL injection 시도)
4. 정상 응답 (올바른 status code, 응답 형식)
5. 에러 응답 (적절한 에러 메시지, status code)
테스트 도구:
- Supertest로 HTTP 요청
- 실제 데이터베이스 대신 test DB 사용
- beforeAll에서 DB 스키마 생성, afterAll에서 정리
예상 결과:
- 각 엔드포인트당 5~10개의 테스트 케이스
- 전체 커버리지 80% 이상
시나리오: 성능 테스트 추가
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
주요 API 엔드포인트에 대한 성능 벤치마크 테스트를 작성해줘.
측정 항목:
- 응답 시간 (p50, p95, p99)
- 처리량 (초당 요청 수)
- 메모리 사용량
- DB 쿼리 개수
도구:
- k6 또는 Artillery 사용
- 시나리오별 부하 테스트 (10, 50, 100 동시 사용자)
결과 리포트:
- 성능 기준선 설정 (예: 95%는 200ms 이내 응답)
- 병목 구간 식별
- 최적화 제안 (인덱스, 캐싱, 쿼리 개선 등)
5.4 문서화 프롬프트
시나리오: API 문서 생성
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
REST API 엔드포인트에 대한 OpenAPI 3.0 스펙을 생성해줘.
대상: src/routes/*.js의 모든 라우트
문서 내용:
- 엔드포인트 경로와 HTTP 메서드
- 요청 파라미터 (path, query, body)
- 요청/응답 예시 (JSON)
- 가능한 에러 코드와 메시지
- 인증 요구사항
형식:
- YAML 형식의 OpenAPI 스펙
- tags로 기능별 그룹화 (Users, Posts, Comments 등)
- components/schemas에 공통 모델 정의
- 실제 코드와 일치하도록 정확성 검증
출력 파일: docs/api/openapi.yaml
추가 작업:
- Swagger UI로 렌더링 가능한지 확인
- 예시 값은 실제 사용 가능한 값으로
시나리오: 코드 주석 업데이트
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
모든 소스 파일의 JSDoc 주석을 업데이트하고 보강해줘.
업데이트 기준:
- 주석이 없는 함수에 기본 JSDoc 추가
- 파라미터와 리턴 타입이 실제 코드와 일치하는지 검증
- 복잡한 로직에는 인라인 주석으로 설명 추가
- deprecated 함수는 @deprecated 태그와 대안 제시
주석 스타일:
- 한 줄 설명은 간결하게
- 복잡한 경우 @description에 상세 설명
- 예시가 필요하면 @example 추가
- @throws로 발생 가능한 에러 명시
검토 사항:
- 오래된 주석이 현재 코드와 맞지 않는 경우 찾아 수정
- 주석이 코드보다 복잡하면 코드 개선 제안
시나리오: README 및 가이드 작성
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
프로젝트의 README.md와 개발자 가이드를 작성해줘.
README.md 구성:
1. 프로젝트 개요 (목적, 주요 기능)
2. 기술 스택
3. 설치 방법 (의존성, 환경 변수)
4. 실행 방법 (개발, 프로덕션)
5. 테스트 실행
6. 배포 프로세스
7. 기여 가이드
개발자 가이드 (docs/CONTRIBUTING.md):
1. 코드 스타일 가이드
2. 브랜치 전략
3. 커밋 메시지 규칙
4. PR 템플릿
5. 테스트 작성 가이드
6. 디버깅 팁
작성 시 주의:
- 초보 개발자도 이해할 수 있게 명확하게
- 코드 예시 포함
- 실제 프로젝트 구조와 일치하는지 확인
5.5 마이그레이션 프롬프트
시나리오: 프레임워크 버전 업그레이드
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
Express 4에서 Express 5로 마이그레이션해줘.
변경 사항 적용:
1. 미들웨어 시그니처 변경 (next 파라미터 제거된 경우)
2. 응답 메서드 변경 (res.send → res.json 등)
3. 라우터 마운팅 방식 변경
4. deprecated API 대체
호환성 확인:
- 사용 중인 미들웨어 패키지들이 Express 5 지원하는지 확인
- 지원 안 하면 대안 제시
- package.json의 의존성 버전 업데이트
테스트:
- 마이그레이션 후 전체 테스트 실행
- 실패하는 테스트는 수정하거나 이유 보고
- 수동 테스트가 필요한 부분 리스트업
문서화:
- MIGRATION.md 파일에 변경사항 요약
- Breaking changes와 대응 방법 설명
시나리오: 데이터베이스 스키마 변경
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
MongoDB에서 PostgreSQL로 데이터 모델을 마이그레이션해줘.
스키마 변환:
1. Mongoose 스키마를 Sequelize 모델로 변환
2. 임베디드 문서를 별도 테이블과 관계로 변경
3. 배열 필드를 조인 테이블로 정규화
4. 인덱스 재정의
마이그레이션 스크립트:
- 기존 데이터를 읽어 새 스키마로 변환
- 데이터 검증 (필수 필드, 타입, 제약조건)
- 롤백 스크립트도 함께 작성
코드 변경:
- 데이터 접근 레이어를 SQL 쿼리로 재작성
- ORM 메서드 활용 (findOne, findAll 등)
- 트랜잭션 적용 (여러 테이블 업데이트)
검증:
- 기존 데이터와 마이그레이션된 데이터 비교
- 성능 테스트 (특히 조인 쿼리)
시나리오: 모듈 시스템 변경
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
CommonJS에서 ES Modules로 전환해줘.
변환 작업:
1. require() → import
2. module.exports → export default 또는 named export
3. __dirname, __filename → import.meta.url 활용
4. dynamic require → dynamic import()
설정 파일 업데이트:
- package.json에 "type": "module" 추가
- Jest 설정에서 ESM 지원 활성화
- Babel 설정 (필요한 경우)
주의사항:
- 순환 의존성 이슈 해결
- default export vs named export 일관성 유지
- 외부 패키지가 ESM을 지원하는지 확인
점진적 전환:
- utils 같은 독립 모듈부터 시작
- 의존성 그래프 따라 상향식으로 전환
- 각 단계마다 테스트 실행하여 검증
5.6 최적화 프롬프트
시나리오: 성능 최적화
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
애플리케이션의 성능 병목을 찾아 최적화해줘.
분석 대상:
1. DB 쿼리 (N+1 문제, 인덱스 누락)
2. 메모리 누수 (이벤트 리스너, 타이머)
3. 불필요한 재계산 (메모이제이션 기회)
4. 비효율적인 알고리즘 (O(n²) → O(n log n))
최적화 기법:
- DB 쿼리: eager loading, 인덱스 추가, 쿼리 캐싱
- 메모리: WeakMap 사용, 명시적 cleanup
- 계산: lodash.memoize, React.useMemo 등
- 알고리즘: 적절한 자료구조 선택 (Set, Map)
벤치마크:
- 최적화 전/후 성능 측정
- 시간 복잡도와 공간 복잡도 비교
- 실제 부하 테스트 결과
문서화:
- 각 최적화의 근거 설명
- 트레이드오프 (코드 복잡도 vs 성능)
- 모니터링 포인트 제안
시나리오: 번들 크기 최적화
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
프론트엔드 번들 크기를 최소화해줘.
분석:
- webpack-bundle-analyzer로 큰 의존성 식별
- 사용하지 않는 코드 제거 (tree shaking)
- 중복 패키지 버전 통합
최적화 방법:
1. 코드 스플리팅: 라우트별로 청크 분리
2. 동적 import: 필요할 때만 로드
3. 경량 대안: moment → dayjs, lodash → lodash-es
4. 이미지 최적화: WebP 변환, 적절한 크기
Webpack 설정:
- mode: 'production'
- optimization.splitChunks 설정
- TerserPlugin으로 압축
- CSS 추출 및 최소화
목표:
- 초기 번들 크기 30% 감소
- FCP (First Contentful Paint) 20% 개선
- Lighthouse 점수 90점 이상
6. 효율 극대화 전략
6.1 작업 분할 원칙
대규모 작업을 하위 에이전트에게 한 번에 맡기는 것보다, 적절히 분할하는 것이 더 효율적입니다. 이는 단순히 작업량을 나누는 것이 아니라, 논리적인 경계를 따라 분할하는 것을 의미합니다.
예를 들어, “전체 프로젝트를 리팩터링해줘”는 너무 광범위합니다. 대신 “먼저 utils 모듈만 리팩터링해줘”로 시작하고, 결과를 검토한 후 “같은 패턴으로 services 모듈도 리팩터링해줘”로 진행하는 것이 좋습니다. 이렇게 하면 첫 번째 작업의 결과를 검토하여 패턴을 조정할 수 있고, 전체 작업이 잘못된 방향으로 진행되는 것을 방지할 수 있습니다.
분할 기준은 주로 다음과 같습니다. 첫째, 기능 모듈 단위로 분할합니다. users, posts, comments 등 비즈니스 도메인별로 나누면, 각 작업이 독립적으로 완료될 수 있고 의존성 문제가 적습니다. 둘째, 계층 단위로 분할합니다. 먼저 모델 레이어를 수정하고, 그 다음 컨트롤러, 마지막으로 뷰를 수정하는 식입니다. 셋째, 복잡도 단위로 분할합니다. 간단한 파일들을 먼저 처리하고, 복잡한 파일은 나중에 처리하거나 메인 세션에서 직접 다룹니다.
6.2 컨텍스트 최적화
하위 에이전트가 효율적으로 작업하려면 필요한 컨텍스트만 제공해야 합니다. 너무 많은 정보는 오히려 혼란을 야기하고 불필요한 토큰을 소모합니다.
CLAUDE.md 파일은 하위 에이전트에게 자동으로 전달되므로, 이 파일을 잘 관리하는 것이 중요합니다. 프로젝트의 코딩 스타일, 아키텍처 패턴, 네이밍 컨벤션 등 범용적으로 적용되는 정보만 CLAUDE.md에 포함시키고, 특정 작업에만 필요한 지시사항은 프롬프트에 직접 포함시킵니다.
예를 들어, “모든 API 응답은 { success: boolean, data: any, error?: string } 형식을 따른다”는 CLAUDE.md에 포함되어야 하지만, “이번 리팩터링에서 users 모듈은 auth 의존성을 제거해야 한다”는 개별 프롬프트에 포함되어야 합니다.
또한 작업 대상 파일의 범위를 명확히 지정하면 하위 에이전트가 불필요한 파일을 분석하는 시간을 절약할 수 있습니다. “src/modules/users/*.js만 처리해줘”처럼 glob 패턴으로 정확히 지정하는 것이 좋습니다.
6.3 결과 검증 자동화
하위 에이전트가 작업을 완료한 후, 그 결과가 올바른지 자동으로 검증하도록 하면 개발자의 수동 검토 부담을 줄일 수 있습니다.
프롬프트에 검증 단계를 명시적으로 포함시킵니다. 예를 들어:
1
2
3
4
5
6
7
리팩터링 완료 후 다음을 자동으로 검증해줘:
1. npm test 실행하여 모든 테스트 통과 확인
2. npm run lint 실행하여 코딩 스타일 준수 확인
3. git diff --stat으로 변경된 파일과 라인 수 요약
4. 변경된 파일 중 TODO나 FIXME 주석이 추가되었다면 보고
검증 실패 시 해당 부분만 재작업하거나, 실패 이유를 상세히 보고해줘.
이렇게 하면 하위 에이전트가 작업 완료 전에 스스로 품질을 체크하므로, 메인 세션으로 돌아왔을 때 “테스트가 실패했네요, 다시 수정해주세요”같은 재작업이 줄어듭니다.
6.4 점진적 복잡도 증가
처음부터 복잡한 작업을 하위 에이전트에게 맡기기보다, 간단한 작업으로 시작하여 점차 복잡도를 높이는 것이 효과적입니다.
첫 번째 단계에서는 한두 개의 파일을 샘플로 메인 세션에서 직접 작업합니다. 이를 통해 원하는 결과물의 패턴을 확립하고, 예상치 못한 이슈를 미리 발견할 수 있습니다.
두 번째 단계에서는 확립된 패턴을 하위 에이전트가 여러 파일에 적용하도록 합니다. “위에서 users.controller.js를 리팩터링한 것과 동일한 패턴으로 나머지 컨트롤러 파일들도 수정해줘”처럼 명확한 참조를 제공합니다.
세 번째 단계에서는 하위 에이전트에게 더 많은 자율성을 부여합니다. “서비스 레이어도 비슷하게 개선해줘. 단, 컨트롤러와 달리 비즈니스 로직이 복잡하므로 필요시 추가 함수 분리도 고려해줘”처럼 고수준 지침만 제공하고 세부사항은 판단하도록 합니다.
7. 트러블슈팅 가이드
7.1 하위 에이전트가 의도와 다르게 작업한 경우
하위 에이전트가 작업을 완료했지만 결과가 기대와 다를 수 있습니다. 이런 경우 대처 방법은 다음과 같습니다.
먼저 프롬프트가 충분히 구체적이었는지 검토합니다. “코드를 개선해줘”같은 모호한 지시보다 “함수의 인지 복잡도를 15 이하로 낮추기 위해 중첩된 if문을 early return 패턴으로 변경해줘”처럼 구체적으로 지시해야 합니다.
두 번째로, CLAUDE.md에 프로젝트 컨텍스트가 충분히 포함되어 있는지 확인합니다. 하위 에이전트는 프로젝트의 코딩 스타일이나 아키텍처를 모르면 일반적인 패턴을 적용하게 됩니다. “우리 프로젝트는 에러를 throw하지 않고 항상 Result
세 번째로, 작업이 너무 복잡했을 수 있습니다. “전체 인증 시스템을 재설계해줘”같은 요청은 하위 에이전트에게 너무 광범위합니다. 이런 경우 작업을 작은 단계로 나누어 순차적으로 진행하거나, 핵심 부분은 메인 세션에서 직접 다루는 것이 좋습니다.
7.2 작업이 예상보다 오래 걸리는 경우
하위 에이전트의 작업이 30분을 초과하여 인터랙티브 모드로 전환되거나, 심지어 1시간 이상 소요되는 경우가 있습니다.
첫 번째 원인은 작업 범위가 너무 넓은 것입니다. “모든 파일을 TypeScript로 변환해줘”같은 요청은 수백 개의 파일이 관련될 수 있습니다. 이런 경우 “먼저 src/models 디렉토리만 변환해줘”처럼 범위를 제한하고, 완료 후 다음 디렉토리로 진행합니다.
두 번째 원인은 복잡한 의존성입니다. 파일들이 서로 복잡하게 얽혀 있으면 하나를 수정할 때 다른 파일들도 함께 분석해야 합니다. 이런 경우 의존성 그래프를 먼저 파악하고, 의존성이 적은 하위 모듈부터 순차적으로 작업하는 것이 효율적입니다.
세 번째 원인은 테스트나 검증 과정이 오래 걸리는 것입니다. 특히 E2E 테스트는 실행 시간이 길 수 있습니다. 이런 경우 “빠른 단위 테스트만 실행해서 검증하고, E2E 테스트는 PR 전에 수동으로 실행할게”처럼 검증 범위를 조정할 수 있습니다.
7.3 토큰 절약이 기대만큼 크지 않은 경우
invoke-opencode-acp를 사용했는데도 토큰 절약이 50% 미만인 경우가 있습니다.
첫 번째 원인은 작업이 너무 간단한 것입니다. 파일 1~2개를 수정하는 작업은 메인 세션에서 직접 하는 것이 하위 에이전트를 실행하는 오버헤드보다 적을 수 있습니다. 하위 에이전트는 최소 몇 백 토큰의 초기화 비용이 있으므로, 작업 자체가 1,000 토큰 미만이면 직접 처리하는 것이 효율적입니다.
두 번째 원인은 작업 지시가 너무 길거나 복잡한 것입니다. 프롬프트 자체가 2,000 토큰이 넘으면, 그것을 하위 에이전트에게 전달하는 데 토큰이 소모됩니다. 지시사항을 간결하게 정리하고, 반복적인 설명은 CLAUDE.md로 옮기는 것이 좋습니다.
세 번째 원인은 결과 요약이 너무 상세한 것입니다. 하위 에이전트가 “파일 A의 함수 1, 2, 3을 각각 이렇게 수정했고, 파일 B는…“처럼 모든 변경사항을 자세히 보고하면 토큰이 많이 소모됩니다. “요약은 간결하게, 변경된 파일 개수와 주요 패턴만 보고해줘”처럼 요약 수준을 조정할 수 있습니다.
7.4 하위 에이전트가 응답하지 않는 경우
드물게 하위 에이전트가 시작된 후 오랜 시간 동안 응답이 없는 경우가 있습니다.
첫 번째 가능성은 매우 큰 파일을 분석하고 있는 것입니다. 수천 라인의 파일이나 거대한 JSON 파일을 처리하면 시간이 오래 걸립니다. 이런 경우 파일을 작은 단위로 분할하거나, 처리 범위를 제한하는 것이 좋습니다.
두 번째 가능성은 무한 루프나 데드락 상황입니다. 예를 들어, “모든 함수에 에러 핸들링을 추가해줘”라고 했는데 에러 핸들링 함수 자체에도 에러 핸들링을 추가하려다 무한 재귀에 빠질 수 있습니다. 이런 경우 작업 범위에서 특정 파일을 제외하도록 명시합니다.
세 번째 가능성은 네트워크나 API 문제입니다. 하위 에이전트도 Claude API를 사용하므로, API 장애나 네트워크 문제로 중단될 수 있습니다. 이런 경우 잠시 기다린 후 재시도하거나, 작업을 작은 단위로 나누어 진행합니다.
8. 실전 예제: 대규모 레거시 코드 개선 프로젝트
8.1 프로젝트 배경
실제 사례로, 5년 된 Node.js 백엔드 프로젝트를 모던화하는 작업을 예로 들어보겠습니다. 이 프로젝트는 다음과 같은 특징이 있었습니다:
- 250개의 JavaScript 파일, 총 45,000 라인
- 콜백 기반 비동기 코드 (async/await 미사용)
- CommonJS 모듈 시스템
- 불일관한 에러 핸들링
- 낮은 테스트 커버리지 (30%)
- 오래된 의존성 패키지들
전체 작업을 한 번에 처리하는 것은 불가능하므로, 단계별로 접근했습니다.
8.2 1단계: 분석 및 계획 (메인 세션)
먼저 메인 세션에서 프로젝트 구조를 분석했습니다:
1
2
3
4
5
6
7
8
9
10
11
프로젝트의 의존성 그래프를 분석하여 리팩터링 우선순위를 제안해줘.
고려사항:
- 의존성이 적은 모듈부터 시작 (하위 모듈 우선)
- 비즈니스 로직이 복잡한 부분은 나중에
- 테스트가 있는 모듈을 우선 처리
결과물:
- 모듈별 의존성 맵 (간단한 트리 구조)
- 리팩터링 순서 제안 (1~5단계)
- 각 단계의 예상 작업량과 위험도
Claude는 프로젝트를 분석하여 다음과 같은 계획을 제시했습니다:
1단계(낮은 위험): utils, helpers - 11개 파일, 의존성 없음 2단계(중간 위험): models - 18개 파일, utils에만 의존 3단계(중간 위험): services - 32개 파일, models와 utils에 의존 4단계(높은 위험): controllers - 28개 파일, 모든 레이어에 의존 5단계(최고 위험): middleware, routes - 15개 파일, 전체 앱 구조
8.3 2단계: utils 모듈 리팩터링 (하위 에이전트)
첫 번째 작업으로 utils 모듈을 하위 에이전트에게 맡겼습니다:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
src/utils 디렉토리의 모든 파일을 다음과 같이 리팩터링해줘:
1. 콜백을 async/await로 변환
2. CommonJS를 ES Modules로 변환
3. JSDoc 타입 주석 추가
4. 중복 코드 제거 및 공통 함수 추출
검증:
- npm test -- --testPathPattern=utils 실행
- ESLint 통과 확인
- 모든 export가 named export인지 확인 (default export 금지)
완료 후:
- 변경된 파일 목록과 주요 변경사항 요약
- 발견된 버그나 개선 제안 있으면 보고
결과: 11개 파일 처리, 2,100 토큰 소모 (기존 방식 대비 78% 절약), 15분 소요
하위 에이전트는 다음을 보고했습니다:
- 23개 함수를 async/await로 변환
- 5개의 중복 함수를 공통 함수로 통합
- date-utils.js에서 deprecated moment.js 사용 발견 → dayjs로 대체 제안
- 모든 테스트 통과
8.4 3단계: models 레이어 리팩터링 (하위 에이전트)
utils가 완료되었으므로 다음 레이어로 진행했습니다:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
src/models 디렉토리를 리팩터링해줘. utils 모듈은 이미 async/await와 ES Modules로 전환되었음.
작업:
1. Mongoose 스키마는 유지하되, 메서드들을 async/await로 변환
2. 에러 핸들링을 CustomError 클래스 기반으로 통일
- ValidationError (400)
- NotFoundError (404)
- DatabaseError (500)
3. 스키마 메서드에 JSDoc 추가
특별 지시:
- User 모델은 인증과 관련되어 민감하므로 별도로 수동 검토할 예정
- User.model.js는 제외하고 나머지만 처리
검증:
- 단위 테스트 실행
- 스키마 검증 로직이 깨지지 않았는지 확인
결과: 17개 파일 처리 (User 제외), 3,800 토큰 소모, 25분 소요
특이사항: Post 모델에서 populate 로직이 복잡하여 일부 수동 검토 필요함을 보고받았습니다.
8.5 4단계: 문제 발견 및 수정 (메인 세션)
하위 에이전트가 보고한 Post 모델 이슈를 메인 세션에서 검토했습니다:
1
Post 모델의 populate 로직을 보여줘. 하위 에이전트가 복잡하다고 보고했는데 무슨 문제가 있는지 설명해줘.
Claude가 코드를 분석한 결과, 3단계 중첩 populate가 있어서 N+1 문제가 발생할 수 있다고 지적했습니다. 메인 세션에서 직접 수정하여 aggregation pipeline으로 최적화했습니다.
8.6 5단계: services 레이어 일괄 처리 (하위 에이전트, 인터랙티브 모드)
services 레이어는 파일이 많고 비즈니스 로직이 복잡하여 인터랙티브 모드를 사용했습니다:
1
2
3
4
5
6
7
8
9
10
src/services 디렉토리를 리팩터링해줘. 파일이 많으므로 5분마다 진행 상황을 보고하고 확인받을 것.
작업:
1. async/await 변환
2. 에러 핸들링 표준화
3. 트랜잭션이 필요한 부분은 명시적으로 표시 (/* @transaction */ 주석)
점검 포인트:
- 각 서비스의 비즈니스 로직이 변경되지 않았는지
- 외부 API 호출 부분에 재시도 로직 추가 고려
하위 에이전트가 5분마다 진행 상황을 보고했고, UserService 처리 중 다음과 같은 질문을 받았습니다:
“UserService.updateProfile()에서 비밀번호 변경 시 이메일 알림을 보내는 로직이 있습니다. 이것도 async로 변환하는데, 이메일 전송 실패 시 전체 트랜잭션을 롤백할까요, 아니면 로그만 남기고 계속 진행할까요?”
이에 대해 “로그만 남기고 계속 진행. 이메일은 부가 기능이므로 사용자 업데이트 자체는 성공해야 함”이라고 응답했고, 하위 에이전트가 그에 맞게 처리했습니다.
결과: 32개 파일 처리, 6,200 토큰 소모, 42분 소요 (3회 인터랙션)
8.7 6단계: 통합 테스트 및 문서화
모든 레이어 리팩터링이 완료된 후, 통합 테스트와 문서화를 진행했습니다:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
리팩터링 작업에 대한 종합 문서를 작성해줘.
내용:
1. 변경 사항 요약
- 전체 통계 (파일 수, 함수 수, 라인 수)
- 주요 패턴 변경 (콜백 → async/await 등)
2. 마이그레이션 가이드
- 다른 개발자들이 알아야 할 변경사항
- 새로운 에러 핸들링 패턴 사용법
3. 알려진 이슈
- User 모델 수동 검토 필요
- Post 모델 populate 최적화 완료
4. 다음 단계 제안
파일: docs/REFACTORING_2024.md
동시에 통합 테스트를 실행하여 전체 시스템이 여전히 정상 작동하는지 확인했습니다:
1
2
3
npm run test:integration
npm run lint
npm run type-check
8.8 프로젝트 결과 분석
전체 프로젝트를 완료한 후의 분석 결과:
토큰 사용량 비교:
- 기존 방식 추정치: ~85,000 토큰
- invoke-opencode-acp 사용: ~18,500 토큰
- 절약률: 78%
시간 비교:
- 기존 방식 (대화 중단 및 재시작 포함): 약 8-10시간
- invoke-opencode-acp 사용: 약 3시간 (메인 세션 작업 포함)
코드 품질:
- 테스트 커버리지: 30% → 65%
- ESLint 경고: 342개 → 12개
- 타입 안정성: JSDoc 추가로 IDE 지원 대폭 개선
학습 포인트:
- 의존성 순서대로 진행하여 작업이 순조로웠음
- 인터랙티브 모드가 복잡한 비즈니스 로직 처리에 매우 유용했음
- 메인 세션에서 샘플 작업을 먼저 하여 패턴을 확립한 것이 효과적이었음
- CLAUDE.md에 프로젝트 규칙을 미리 정리한 것이 일관성 유지에 도움이 됨
9. 모범 사례 체크리스트
9.1 작업 시작 전
- CLAUDE.md 파일이 최신 상태인지 확인
- 작업 목표를 구체적으로 정의 (모호한 “개선”이 아닌 명확한 기준)
- 작업 대상 파일 범위를 정확히 지정
- 의존성 관계를 파악하여 작업 순서 결정
- 간단한 샘플 작업으로 패턴 확립
- 예상 작업 시간에 따라 일회성/인터랙티브 모드 선택
9.2 프롬프트 작성 시
- 작업 목표를 첫 줄에 명확히 기술
- 구체적인 기준 제시 (예: “복잡도 15 이하”, “테스트 커버리지 80% 이상”)
- 제외할 파일이나 케이스 명시
- 검증 단계 포함 (테스트, 린트 등)
- 결과 요약 형식 지정 (간결한 요약 vs 상세 보고)
- 예외 상황 발생 시 대응 방법 명시
9.3 작업 진행 중
- 인터랙티브 모드에서는 진행 상황을 주의 깊게 검토
- 하위 에이전트의 질문에 명확히 답변
- 예상과 다른 방향으로 진행되면 즉시 조정
- 중간 결과물을 주기적으로 커밋 (롤백 가능하도록)
9.4 작업 완료 후
- 변경사항 리뷰 (git diff로 확인)
- 테스트 실행 (단위, 통합, E2E)
- 코드 품질 검사 (린트, 타입 체크)
- 문서 업데이트 (README, API 문서 등)
- 팀원과 공유 (PR 또는 문서)
- 다음 작업을 위한 개선점 메모
10. 결론
invoke-opencode-acp 스킬은 Claude Code의 토큰 효율성을 극적으로 향상시키는 강력한 도구입니다. 단순히 토큰을 절약하는 것을 넘어, 대규모 코드베이스를 체계적으로 개선할 수 있는 새로운 워크플로우를 제공합니다.
핵심은 적절한 작업 분할, 명확한 지시사항, 그리고 메인 세션과 하위 에이전트의 역할 분담입니다. 메인 세션은 전략적 결정과 복잡한 판단을 담당하고, 하위 에이전트는 반복적이고 패턴화된 작업을 효율적으로 처리합니다.
이 가이드에서 제시한 샘플 프롬프트와 전략들을 여러분의 프로젝트에 맞게 조정하여 사용하시기 바랍니다. 처음에는 간단한 작업부터 시작하여 점차 복잡한 작업으로 확장하면, 여러분만의 효율적인 AI 협업 패턴을 확립할 수 있을 것입니다.
부록 A: 자주 묻는 질문
Q: 하위 에이전트와 메인 세션이 서로 다른 판단을 하면 어떻게 하나요?
A: 하위 에이전트는 메인 세션의 CLAUDE.md와 프롬프트 지시를 따르도록 설계되었습니다. 만약 결과가 기대와 다르다면, 프롬프트를 더 구체적으로 작성하거나 CLAUDE.md에 프로젝트 규칙을 명확히 정의하세요. 특히 중요한 아키텍처 결정은 메인 세션에서 직접 다루는 것이 안전합니다.
Q: 토큰 절약률이 50~90%라고 했는데, 어떤 경우에 90%까지 절약되나요?
A: 반복적이고 패턴화된 작업일수록 절약률이 높습니다. 예를 들어, 100개 파일의 변수명을 일괄 변경하거나, 모든 API 엔드포인트에 동일한 미들웨어를 적용하는 작업은 90%에 가까운 절약을 보입니다. 반대로 각 파일마다 다른 판단이 필요한 작업은 절약률이 낮습니다.
Q: 하위 에이전트의 작업 결과를 신뢰할 수 있나요?
A: 하위 에이전트도 Claude API를 사용하므로 품질은 동일합니다. 다만, 작업이 복잡할수록 검증이 중요합니다. 프롬프트에 자동 테스트 실행을 포함시키거나, 중요한 파일은 메인 세션에서 직접 검토하는 것이 좋습니다.
Q: 어떤 작업은 하위 에이전트에게 맡기지 않는 것이 좋나요?
A: 다음 작업들은 메인 세션에서 직접 다루는 것이 좋습니다:
- 아키텍처 설계나 주요 기술 결정
- 보안 관련 코드 (인증, 권한, 암호화)
- 1~2개 파일의 간단한 수정
- 실시간 대화가 필요한 불명확한 요구사항
Q: 비용은 어떻게 되나요? 하위 에이전트도 별도로 과금되나요?
A: 하위 에이전트의 토큰 사용은 별도로 관리되지만, 전체 Claude Code 사용량에 포함됩니다. 다만, 메인 세션의 토큰을 절약하므로 전체적으로는 비용 효율적입니다. 특히 대규모 작업에서 토큰 소진으로 인한 재작업을 방지하여 총 비용을 줄일 수 있습니다.
부록 B: 추가 리소스
공식 문서
- Claude Code 공식 문서: https://docs.anthropic.com/claude/docs/claude-code
- MCP (Model Context Protocol) 사양: https://modelcontextprotocol.io/
- opencode CLI 레퍼런스: [Claude Code 설치 시 포함된 문서]
커뮤니티
- Claude 개발자 포럼: https://community.anthropic.com/
- Discord 커뮤니티: [Claude Code 사용자 채널]
관련 스킬
- code-review: 자동화된 코드 리뷰를 위한 스킬
- test-generator: 테스트 코드 생성 스킬
- doc-generator: 문서 자동 생성 스킬
작성 일자: 2026-01-12
관련글
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
Claude Code 토큰 소모를 줄이는 꿀팁
opencode CLI와 invoke-opencode-acp 스킬을 활용하면 복잡한 작업의 토큰 사용을 50~90% 줄일 수 있습니다.
기존 방식의 문제점
“세 파일을 리팩터링해줘”처럼 지시하면 Claude가 대량의 중간 추론을 출력하면서 토큰을 빠르게 소모합니다.
대부분 Claude의 사고 과정일 뿐, 우리는 결과만 필요합니다.
토큰이 소진되면 작업이 끝나지 않고 중단되는 경우가 많습니다.
invoke-opencode-acp는 Claude Code의
스킬로, opencode CLI를 통해
독립적인 하위 에이전트를 실행합니다.
복잡한 작업을 하위 에이전트에 맡기고, 요약 결과만 Claude로 되돌립니다. 그러면, 메인 대화에서는 거의 토큰을 사용하지 않아 전체 토큰 소모를 50-90%까지 절약할 수 있고,
코드 품질은 동일합니다.
(대신, 작업 시간이 23분 정도 늘어날 수 있습니다.)
어떤 작업에 유용할까를 보면,
프로젝트의 API 레이어 등 다수 파일 리팩터링
그리고 여러 함수/변수명을 일괄 수정
전체 코드 리뷰 및 품질 점검
여러 모듈의 테스트 코드 자동 생성
문서화(API 문서 등) 및 코드 포맷 통일
한마디로, 많은 파일과 추론이 필요한
작업에 적합하다고 할 수 있습니다.
사용법 요약
Claude에게 구체적으로 “users 모듈을 async/await 패턴으로 변환해줘”처럼 명확한 작업을 지시합니다.
invoke-opencode-acp 스킬이 호출돼 opencode CLI가 하위 에이전트를 실행합니다.
3.하위 에이전트가 작업을 완료한 뒤 요약 결과만 Claude에 반환합니다.
4.메인 대화는 거의 토큰을 사용하지 않습니다.
두 가지 모드가 있는데,
인터랙션 모드 (30분 이상 소요되는 작업)는 5분마다 진행 상황을 확인하고 방향을 조정할 수 있어 대화형 작업에 적합합니다.
일회성 모드 (30분 미만)에서는 중간 과정을 생략하고 결과만 받아볼 수 있어, 명확한 목표를 가진 작업에 적합합니다.
예시로, API 레이어 5개 파일 리팩터링을 할 때
기존 방식 12.3k 토큰 소모. 그러나,
스킬 사용 시 1.8k 토큰(약 85% 절약),
작업 시간 8분 → 10분(2분 증가)
10개 모듈 테스트 생성한다면,
토큰 사용량 87% 절약, 작업 시간 2분 증가
효율을 높이는 팁은 작업 설명을 구체적으로 작성하는 것입니다. “코드 리팩터링해줘”보다는 “users 모듈의 모든 콜백 함수를 async/await로 변경해줘”가 더 효과적입니다.
큰 작업의 경우에는 단계별로 분할해서 수행하도록 해야합니다. 핵심 모듈 → 도구 함수 → 테스트 파일 순으로 나누면 효율적입니다.
간단한 작업은 스킬 없이 Claude에 직접 맡기는 것이 더 빠를 수 있습니다
https://www.threads.com/@rich_l_2024/post/DTWa0atAY6c