CLI 코딩 에이전트는 청구서가 오기 전까지는 자유롭게 느껴집니다. Claude Code 또는 Codex를 리포지토리에 연결하고 “이 모듈을 리팩터링해줘”라고 요청하면, 10분 뒤 에이전트는 40개 파일을 읽고 테스트를 세 번 실행하며 필요 없는 컨텍스트에 수십만 토큰을 소비할 수 있습니다. 8명의 엔지니어가 하루 종일 에이전트를 실행한다면 이 비용은 더 이상 무시할 수 없습니다. 다행히 대부분의 낭비는 모델을 바꾸거나 품질을 낮추지 않고도 CLI 사용 방식만 바꿔 줄일 수 있습니다.
요약
CLI 에이전트 비용을 줄이는 핵심은 모델에 도달하기 전에 컨텍스트를 줄이는 것입니다.
실행 가능한 체크리스트는 다음과 같습니다.
- 작업 파일을 명시해 탐색 범위를 줄입니다.
-
CLAUDE.md같은 메모리 파일을 짧고 안정적으로 유지합니다. - 긴 세션은
/compact또는/clear로 압축하거나 초기화합니다. - 안정적인 프롬프트 접두사에는 프롬프트 캐싱을 적용합니다.
- 단순 작업은 더 저렴한 모델로 라우팅합니다.
- 테스트 로그, 설치 로그, diff 출력은 필터링합니다.
- 실행당 토큰과 비용을 기록해 실제 절감 효과를 측정합니다.
서론
문제는 보통 두 가지 방식으로 나타납니다.
첫째, 주간 또는 세션 한도를 초과해 작업 도중 갑자기 멈춥니다. 둘째, 월별 API 청구서가 도착한 뒤 “AI 비서가 왜 주니어 계약자보다 비싼가?”라는 질문을 받습니다.
근본 원인은 동일합니다. CLI 에이전트는 기본적으로 토큰을 많이 씁니다.
- 10줄만 필요해도 전체 파일을 읽습니다.
- 매 턴마다 전체 대화 기록을 다시 보냅니다.
- 원시 명령 출력을 그대로 컨텍스트에 넣습니다.
- 동일한 시스템 프롬프트와 리포지토리 규칙을 반복 전송합니다.
하지만 리팩터링 대상 코드가 2,000토큰이라면 180,000토큰의 컨텍스트가 항상 필요한 것은 아닙니다. 이 차이가 절감 가능한 비용입니다.
이 글에서는 CLI 에이전트 실행에서 토큰이 어디로 가는지 설명하고, 다음 영역별로 줄이는 방법을 다룹니다.
- 컨텍스트 관리
- 메모리 파일 정리
- 프롬프트 캐싱
- 모델 라우팅
- 도구 출력 트리밍
- 실행당 비용 측정
예시는 Claude Code와 Codex를 기준으로 설명하지만, 토큰 단위로 과금되는 API 기반 에이전트라면 동일하게 적용할 수 있습니다.
에이전트 비용에서 자주 놓치는 부분은 API 디버깅입니다. 에이전트가 불안정한 내부 API를 호출하면 실패하고, 오류 본문을 읽고, 문서를 다시 읽고, 재시도합니다. 이 반복마다 토큰 비용이 발생합니다.
💡에이전트가 API를 사용하는 경우, 연결 전에 Apidog에서 API를 설계, 모의, 테스트하면 값비싼 시행착오를 줄일 수 있습니다. 에이전트는 예측 불가능한 라이브 엔드포인트가 아니라 검증된 계약을 기준으로 작업하게 됩니다.
CLI 에이전트 실행 시 토큰이 어디로 가는지
최적화하려면 먼저 한 번의 에이전트 턴에서 무엇에 비용을 지불하는지 이해해야 합니다.
일반적으로 한 턴은 다음으로 구성됩니다.
- 모델로 보내는 입력 페이로드
- 모델이 반환하는 출력 페이로드
대부분의 공급자에서 출력 토큰은 입력 토큰보다 더 비쌉니다. 예를 들어 특정 최신 모델 제품군에서는 입력이 100만 토큰당 약 3달러, 출력이 약 15달러 수준일 수 있습니다. 더 작은 모델은 입력 약 1달러, 출력 약 5달러 수준일 수 있습니다.
정확한 가격은 공급자별로 바뀌므로 실제 가격 페이지를 확인해야 합니다. 중요한 점은 구조입니다.
출력은 비싸고, 입력은 쉽게 커집니다.
일반적인 입력 페이로드에는 다음이 포함됩니다.
시스템 프롬프트 및 도구 정의
에이전트 지침과 도구 JSON 스키마입니다. 매 턴 반복 전송되며 5,000~15,000토큰이 될 수 있습니다.메모리 및 프로젝트 파일
CLAUDE.md, 리포지토리 규칙, 영구 지침 등입니다. 관련 여부와 관계없이 매 턴 로드될 수 있습니다.대화 기록
이전 사용자 메시지, 모델 응답, 도구 호출, 도구 결과가 매 턴 다시 전송됩니다. 긴 세션에서 가장 큰 비용원이 됩니다.검색된 파일 내용
에이전트가 읽은 파일입니다. 1,200줄 파일 하나를 읽으면 대략 12,000~18,000토큰이 될 수 있습니다.도구 출력
테스트 로그,npm install출력,git diff, 스택 트레이스 등입니다. 기본적으로 매우 장황합니다.
출력 페이로드는 모델의 설명, 계획, 코드 편집입니다. 입력보다 작을 수 있지만 토큰당 가격이 높으므로 장황한 응답도 비용에 영향을 줍니다.
가장 중요한 사실은 이것입니다.
대화 기록은 매 턴 다시 재생됩니다.
30턴 세션은 1턴 비용의 단순 30배가 아닙니다. 점점 커지는 접두사를 계속 다시 보내므로 후반 턴일수록 이전 모든 컨텍스트 비용을 함께 부담합니다.
세션 및 한도 계산 방식은 Claude Code 토큰 창이 재설정되는 방식에서 더 자세히 볼 수 있습니다.
컨텍스트 관리 및 메모리 파일
가장 저렴한 토큰은 보내지 않는 토큰입니다. 컨텍스트 관리는 이후 모든 턴의 입력 페이로드를 줄이기 때문에 가장 먼저 적용해야 합니다.
1. 시작 전에 작업 범위를 지정하세요
리포지토리 루트에서 다음처럼 요청하지 마세요.
claude "결제 로직을 리팩터링하세요"
이 프롬프트는 에이전트가 관련 파일을 찾기 위해 광범위하게 탐색하게 만듭니다.
대신 파일과 범위를 명시합니다.
claude "src/payments/retry.ts 및 해당 테스트 파일에서만 재시도 로직이 지수 백오프를 사용하도록 리팩터링하세요"
더 좋은 프롬프트는 다음 속성을 가집니다.
- 수정할 파일을 지정합니다.
- 읽어도 되는 디렉터리를 제한합니다.
- 변경하지 말아야 할 영역을 명시합니다.
- 원하는 결과를 구체적으로 설명합니다.
예시:
claude "
src/payments/retry.ts와 src/payments/retry.test.ts만 수정하세요.
목표는 재시도 지연을 고정 간격에서 지수 백오프로 변경하는 것입니다.
공개 함수 시그니처는 변경하지 마세요.
전체 리포지토리를 탐색하지 말고, 필요한 경우 이 두 파일 안에서만 확인하세요.
"
파일 이름을 알려주는 것만으로도 에이전트가 후보 파일 20개를 읽는 상황을 막을 수 있습니다.
2. 메모리 파일을 짧게 유지하세요
CLAUDE.md 같은 프로젝트 메모리 파일은 매 턴 컨텍스트에 포함될 수 있습니다. 팀이 이 파일을 위키처럼 사용하면 매 요청마다 불필요한 온보딩 문서를 다시 전송하게 됩니다.
먼저 크기를 확인하세요.
# 문자 수 / 4는 대략적인 토큰 추정치입니다.
wc -c CLAUDE.md | awk '{print "≈", int($1/4), "tokens per turn"}'
좋은 CLAUDE.md에는 다음만 둡니다.
# Project Rules
## Commands
- Test: `npm test --silent -- --reporter=dot`
- Lint: `npm run lint`
- Typecheck: `npm run typecheck`
## Rules
- Public API signatures must not change without explicit request.
- Do not edit generated files in `dist/`.
- Prefer small targeted diffs.
## Docs
- API contract details: `docs/api-contract.md`
- Payment domain notes: `docs/payments.md`
피해야 할 내용은 다음과 같습니다.
- 긴 아키텍처 설명 전체
- 오래된 온보딩 문서
- 드물게 쓰는 운영 절차
- 대형 API 스펙 전문
- 매번 필요하지 않은 예시 코드
자주 필요하지 않은 내용은 문서 파일로 분리하고, 메모리 파일에는 위치만 남기세요.
3. 긴 세션은 압축하거나 초기화하세요
하나의 작업이 끝났는데 같은 세션에서 다른 작업을 계속하면 이전 기록 전체가 새 작업 비용에 포함됩니다.
Claude Code에서는 다음을 사용합니다.
/compact
기록을 짧은 요약으로 압축하고 원시 기록을 줄입니다.
새 작업을 완전히 분리하려면 다음을 사용합니다.
/clear
권장 규칙은 간단합니다.
세션 하나에는 논리적 작업 하나만 넣고, 작업 사이에는
/compact또는/clear를 실행하세요.
예시 워크플로우:
# 1. 결제 재시도 로직 수정
claude "src/payments/retry.ts와 테스트만 수정하세요..."
# 2. 테스트 후 작업 완료
/compact
# 3. 별도 작업 시작
claude "이제 src/users/profile.ts의 null 처리만 수정하세요..."
Claude Code 워크플로우에서도 이처럼 작업 단위를 좁히는 패턴이 중요하게 사용됩니다.
4. 무시 파일을 설정하세요
에이전트가 생성물, 빌드 출력, 벤더링된 의존성을 읽지 않도록 제한하세요.
예시:
node_modules/
dist/
build/
coverage/
.next/
.cache/
*.lock
에이전트별 무시 파일을 지원한다면 다음도 추가합니다.
node_modules/
dist/
coverage/
package-lock.json
pnpm-lock.yaml
yarn.lock
에이전트가 보지 못하면 읽거나 diff하지 않습니다. 한 번 설정하면 모든 실행에서 비용을 줄입니다.
프롬프트 캐싱: 동일한 접두사에 전체 비용을 내지 마세요
프롬프트 캐싱은 반복 실행에서 큰 효과를 냅니다.
아이디어는 간단합니다.
- 시스템 프롬프트
- 도구 정의
- 리포지토리 규칙
- 안정적인 컨텍스트
같은 요청 접두사를 공급자가 캐시합니다. 이후 동일한 접두사를 공유하는 요청은 전체 입력 비용이 아니라 할인된 캐시 읽기 비용으로 처리됩니다.
Anthropic의 프롬프트 캐싱 문서 기준으로, 캐시 쓰기는 일반 입력보다 비쌀 수 있지만 캐시 읽기는 일반 입력의 약 10% 수준입니다. 즉 캐시된 부분에 대해 약 90% 할인 효과가 있습니다.
적용 원칙은 다음입니다.
안정적인 내용은 앞에, 자주 바뀌는 내용은 뒤에 둡니다.
일반적인 순서는 다음과 같습니다.
tools → system → messages
캐시 중단점 앞에 타임스탬프, 랜덤 ID, 사용자별 동적 문자열을 넣으면 캐시가 깨질 수 있습니다.
직접 CLI 래퍼를 구현한다면 다음처럼 설정할 수 있습니다.
response = client.messages.create(
model="claude-sonnet-4-6",
max_tokens=2048,
system=[
{
"type": "text",
"text": SYSTEM_PROMPT + REPO_CONVENTIONS,
"cache_control": {"type": "ephemeral"},
}
],
messages=[
{
"role": "user",
"content": user_task,
}
],
)
u = response.usage
print("cache write:", u.cache_creation_input_tokens)
print("cache read :", u.cache_read_input_tokens)
print("fresh input:", u.input_tokens)
예를 들어 매일 동일한 시스템 프롬프트와 8,000토큰의 리포지토리 규칙을 60번 사용한다면, 캐싱이 없을 때는 8,000토큰 블록에 대해 60번 전체 비용을 지불합니다.
캐싱을 사용하면 다음 구조가 됩니다.
- 첫 요청 또는 캐시 만료 시: 캐시 쓰기 비용
- 이후 요청: 캐시 읽기 비용
운영 시 주의할 점은 두 가지입니다.
접두사를 바이트 단위로 안정적으로 유지하세요.
캐시 중단점 앞에서 한 글자라도 바뀌면 캐시가 무효화될 수 있습니다.관련 실행을 가까운 시간에 묶으세요.
단명 캐시를 사용하는 경우 실행을 흩어 놓으면 캐시 적중률이 낮아집니다.
OpenAI API도 지원 모델에서 캐시된 입력에 유사한 할인을 자동 적용할 수 있습니다. 세부 동작은 다르지만 원리는 동일합니다.
캐싱만으로 충분하지 않다면 Codex를 통해 GPT-5.5를 무료로 실행하는 방법 같은 라우팅 및 무료 티어 전략도 함께 검토할 수 있습니다.
모델 라우팅: 저렴한 작업에는 저렴한 모델
모든 작업에 가장 비싼 모델이 필요한 것은 아닙니다.
다음 작업은 보통 작은 모델로도 충분합니다.
- 커밋 메시지 작성
- diff 요약
- 변경 로그 초안
- 단순 변수명 변경
- 테스트 이름 정리
- 실패 로그 요약
반대로 다음 작업은 더 강한 모델이 필요할 수 있습니다.
- 아키텍처 재설계
- 복잡한 버그 추적
- 보안 영향 분석
- 여러 모듈에 걸친 리팩터링
- 모호한 요구사항 해석
CLI에서는 작업별로 모델을 명시하세요.
# 단순 작업
claude --model haiku "스테이지된 diff에 대한 컨벤션 커밋 메시지를 작성하세요"
# 복잡한 작업
claude --model sonnet "결제 서비스의 캐싱 계층을 재설계하세요"
좋은 기본 정책은 다음입니다.
기본값은 저렴한 모델로 두고, 필요한 경우에만 강한 모델로 올립니다.
많은 팀은 반대로 운영합니다. 모든 작업에 플래그십 모델을 사용하고, 커밋 메시지에도 3~5배 비용을 지불합니다.
서브 에이전트에도 라우팅을 적용하세요
에이전트 프레임워크가 하위 작업 위임을 지원한다면, 서브 에이전트에는 작은 모델과 작은 컨텍스트를 주는 것이 좋습니다.
예시 구조:
상위 에이전트: sonnet
- 전체 문제 해결
- 최종 의사결정
- 코드 변경 승인
하위 에이전트: haiku
- 관련 파일 검색
- 테스트 실패 요약
- diff 요약
- 문서 초안
이렇게 하면 비싼 모델이 전체 원시 로그와 파일을 직접 읽지 않고, 정제된 결과만 보게 됩니다.
Codex 및 Claude Code 전반의 목표 명령에서는 이런 자율 루프와 위임 패턴을 더 자세히 다룹니다.
사용량 제한 요금제를 쓰는 경우에도 라우팅은 중요합니다. 프리미엄 모델 허용량을 커밋 메시지에 쓰면 팀은 빠르게 한도에 도달합니다. Claude Code 주간 한도 증가가 도움이 될 수 있지만, 허용량을 오래 쓰려면 라우팅이 필요합니다.
도구 출력 및 검색 트리밍
도구 출력은 조용한 비용 폭탄입니다.
에이전트가 실행하는 명령은 텍스트를 반환하고, 그 텍스트는 컨텍스트에 들어갑니다. 이후 턴에서도 다시 재생될 수 있습니다.
대표적인 낭비는 다음입니다.
-
npm install의 긴 설치 로그 - verbose 테스트 출력
- 전체
git diff - 생성된 lockfile diff
- 긴 스택 트레이스
- 불필요한 경고 목록
에이전트에는 보통 전체 로그가 필요하지 않습니다. 필요한 것은 실패 여부와 관련 오류입니다.
1. 명령 자체를 조용하게 만드세요
나쁜 예:
npm test
더 나은 예:
npm test --silent -- --reporter=dot
나쁜 예:
npm install
더 나은 예:
npm install --silent --no-audit --no-fund
Python 테스트도 마찬가지입니다.
# 장황함
pytest
# 간결함
pytest -q
2. 에이전트가 보기 전에 필터링하세요
전체 로그 대신 마지막 부분만 전달합니다.
pytest -q 2>&1 | tail -n 30
전체 diff 대신 통계만 먼저 봅니다.
git diff --stat
실패 라인만 추립니다.
npm test 2>&1 | grep -E "(FAIL|✗|Error)" | head -n 20
TypeScript 오류도 요약할 수 있습니다.
npm run typecheck 2>&1 | grep -E "error TS[0-9]+" | head -n 40
3. 전체 파일 대신 필요한 함수 주변만 읽게 하세요
프롬프트에서 명시적으로 지시합니다.
전체 파일을 읽지 말고, retry 로직을 담당하는 함수와 그 주변 80줄만 확인하세요.
또는 CLI에서 직접 컨텍스트를 잘라 전달합니다.
grep -n "function retry" src/payments/retry.ts
sed -n '120,220p' src/payments/retry.ts
대형 파일에서는 전체 18,000토큰을 읽는 대신 800토큰만 읽게 만들 수 있습니다.
4. 검색 결과 개수와 크기를 제한하세요
RAG나 코드 검색을 사용하는 경우 다음을 제한하세요.
- 검색할 디렉터리
- 반환할 청크 수
- 청크당 토큰 수
- 포함할 파일 확장자
나쁜 예:
전체 리포지토리에서 결제 관련 코드를 찾아 분석하세요.
좋은 예:
src/payments 디렉터리에서 retry, backoff, timeout 키워드만 검색하세요.
상위 5개 결과만 보고, 각 결과는 함수 주변 40줄로 제한하세요.
검색된 토큰은 모델이 실제로 사용하지 않아도 비용이 듭니다. 적게 가져오는 것이 중요합니다.
실행당 비용 측정 및 귀속
측정하지 않으면 줄일 수 없습니다. “이번 달 청구서가 줄었다”는 충분한 측정이 아닙니다. 작업 단위로 비용을 봐야 어떤 전술이 효과가 있었는지 알 수 있습니다.
API 응답의 사용량 객체를 기록하세요.
u = response.usage
# 예시 요금입니다. 실제 모델 가격으로 교체하세요.
INPUT_RATE = 3.00 / 1_000_000
OUTPUT_RATE = 15.00 / 1_000_000
CACHE_READ = 0.30 / 1_000_000
CACHE_WRITE = 3.75 / 1_000_000
cost = (
u.input_tokens * INPUT_RATE +
u.output_tokens * OUTPUT_RATE +
u.cache_read_input_tokens * CACHE_READ +
u.cache_creation_input_tokens * CACHE_WRITE
)
print(
f"run cost ≈ ${cost:.4f} "
f"(in={u.input_tokens} "
f"out={u.output_tokens} "
f"cache_read={u.cache_read_input_tokens})"
)
CLI를 직접 사용하는 경우에는 세 가지 방법이 있습니다.
# 1. CLI가 제공하는 비용 명령 확인
claude /cost
# 2. 프로젝트별 API 키 사용
# 공급자 콘솔에서 API 키별 지출을 분리해 확인합니다.
# 3. 실행 래퍼 작성
# 타임스탬프, 작업명, 모델, 보고된 토큰 수를 CSV로 기록합니다.
간단한 래퍼 예시:
#!/usr/bin/env bash
TASK="$1"
MODEL="${MODEL:-sonnet}"
START=$(date -Iseconds)
claude --model "$MODEL" "$TASK"
END=$(date -Iseconds)
echo "$START,$END,$MODEL,\"$TASK\"" >> agent-runs.csv
가능하다면 비용 또는 토큰 수까지 함께 기록합니다.
start,end,model,task,input_tokens,output_tokens,cost
2026-05-20T10:00:00Z,2026-05-20T10:04:00Z,sonnet,retry refactor,42000,3500,0.18
대표 작업별로 하나의 지표를 추적하세요.
- 일일 리팩터링 실행당 비용
- PR 리뷰 실행당 비용
- 테스트 실패 디버깅당 비용
- 문서 생성당 비용
캐싱을 켰거나 모델 라우팅을 적용했다면 이 숫자가 움직여야 합니다. 움직이지 않는다면 전술이 예상대로 적용되지 않은 것입니다.
전술 비교
| 전술 | 일반적인 토큰 절감 | 노력 |
|---|---|---|
| 작업 세트 범위 지정 | 실행당 입력 30–60% | 낮음 |
| 짧고 안정적인 메모리 파일 | 매 턴 5–15% | 낮음 |
작업 간 /compact 또는 /clear
|
긴 세션에서 40–80% | 낮음 |
| 안정적인 접두사에 프롬프트 캐싱 | 캐시된 접두사에서 약 90% | 중간 |
| 모델 라우팅 | 라우팅된 하위 작업에서 50–80% | 중간 |
| 조용하거나 필터링된 도구 출력 | 도구 사용량이 많은 실행에서 20–50% | 낮음 |
| 전체 파일 대신 대상 지정 읽기 | 대용량 파일 편집에서 70–95% | 낮음 |
| 제한된 검색 범위 | RAG 사용량이 많은 에이전트에서 30–60% | 중간 |
| 실행당 비용 측정 | 직접 절감은 없지만 모든 최적화를 검증 | 낮음 |
절감 범위는 예시입니다. 실제 효과는 현재 낭비가 어디에서 발생하는지에 따라 달라집니다.
바로 적용할 수 있는 운영 규칙
팀에 바로 도입하려면 다음 규칙부터 시작하세요.
1. 에이전트에게 작업 파일을 먼저 지정한다.
2. 한 세션에는 하나의 논리적 작업만 넣는다.
3. 작업이 끝나면 /compact 또는 /clear를 실행한다.
4. 테스트와 설치 명령은 silent 모드로 실행한다.
5. 전체 diff보다 git diff --stat을 먼저 사용한다.
6. 커밋 메시지, 요약, 초안 작성은 저렴한 모델로 보낸다.
7. CLAUDE.md는 1,000토큰 이하를 목표로 한다.
8. 주 1회 작업별 에이전트 비용을 리뷰한다.
결론
CLI 에이전트 토큰 비용의 상당 부분은 작업 자체가 아니라 운영 방식에서 발생합니다.
비용을 키우는 주요 원인은 다음입니다.
- 불필요하게 큰 컨텍스트
- 매 턴 반복 전송되는 대화 기록
- 장황한 도구 출력
- 전체 파일 읽기
- 단순 작업에 비싼 모델 사용
- 측정되지 않는 실행 비용
먼저 낮은 노력의 항목부터 적용하세요.
- 작업 범위를 파일 단위로 지정합니다.
- 메모리 파일을 줄입니다.
- 테스트와 설치 로그를 조용하게 만듭니다.
- 긴 세션을 압축하거나 초기화합니다.
그다음 프롬프트 캐싱과 모델 라우팅을 추가하세요. 이 조합만으로도 품질을 낮추지 않고 에이전트 비용을 의미 있게 줄일 수 있습니다.
Top comments (0)