
로컬 프록시를 통해 Claude Code 비용을 67% 절감한 방법
요약
Claude Code 사용 시 발생하는 높은 비용을 줄이기 위해 로컬 프록시를 활용하여 불필요한 데이터를 제거하는 방법을 소개합니다. 프롬프트 캐싱 혜택을 유지하면서도 캐시되지 않은 입력 토큰을 67% 절감할 수 있는 기술적 접근법을 다룹니다.
핵심 포인트
- 프롬프트 캐싱은 고정된 접두사에만 적용되어 새로운 데이터는 정가로 청구됨
- 캐시된 접두사를 수정하면 캐시 할인 혜택을 잃게 되므로 주의 필요
- 로컬 프록시를 통해 캐시 영역을 건드리지 않고 불필요한 데이터만 제거 가능
- llmtrim 도구를 사용하여 Claude Code, Cursor 등 다양한 도구에 적용 가능
Claude Code 청구서를 확인했는데, 금액이 마음에 들지 않아 그 이유를 찾아보게 되었습니다.
캐싱 (Caching)은 생각보다 절약 효과가 적습니다
프롬프트 캐싱 (Prompt caching)은 사용자가 표시한 고정된 접두사 (stable prefix)에 대해서만 할인을 제공합니다. 매 턴 발생하는 새로운 콘텐츠, 즉 최신 메시지와 새로운 도구 출력값 (tool output)은 정가를 모두 지불해야 합니다. 그리고 이 새로운 콘텐츠 영역이 청구서의 대부분을 차지합니다.
에이전트가 명령을 실행하고 400줄짜리 git log나 테스트 덤프를 읽으면, 그 방대한 텍스트 전체가 다음 턴에 정가로 다시 전송됩니다. 모델 자체의 응답 (replies) 또한 비용이 발생합니다.
처음에는 프롬프트 축소 (prompt-shrinking) 도구들을 몇 가지 시도해 보았습니다. 문제는 캐싱된 접두사를 다시 작성하는 모든 행위는 캐시 할인 혜ట을 포기하게 만든다는 점입니다. 즉, 텍스트를 줄이더라도 남은 부분에 대해 캐싱되지 않은 요율 (uncached rate)을 지불하게 됩니다. 결과적으로 손해를 볼 수도 있습니다.
따라서 저에게 필요했던 규칙은 명확했습니다. 이미 정가로 지불되는 부분만 줄이고, 캐싱된 접두사는 절대 건드리지 않는 것이었습니다.
내가 만든 것
Claude Code와 API 사이에서 실행되는 작은 바이너리 (binary)입니다. 요청이 나갈 때 이를 통과하며 불필요한 데이터 (junk)가 제거되고, 응답은 수정되지 않은 채 돌아옵니다.
저는 Claude Code에서 실행하고 있지만, Claude 전용은 아닙니다. HTTPS_PROXY를 통해 라우팅되는 것이라면 무엇이든 동일한 처리를 받을 수 있습니다: Codex, Cursor, Aider 등 무엇이든 가능합니다.
npm install -g @llmtrim/cli && llmtrim setup
# 그 다음 Claude Code를 위해 새로운 터미널을 엽니다
llmtrim status --watch
다음은 벤치마크가 아닌 실제 Claude Code 사용 환경에서 가져온 저의 대시보드입니다:
$198.05는 캐싱을 제외한 후 실제로 청구서에서 차감된 금액입니다. 저는 입력값 수치(-67%, 캐시 제외)를 정직한 수치로 읽었습니다. 출력 절감액은 추정치이며, 프록시는 사용자의 실시간 트래픽에 대해 A/B 테스트를 수행할 수 없기 때문입니다.
두 가지 요소 덕분에 이를 계속 실행해 두어도 안전합니다.
cache_control 마커 아래에 있는 내용은 절대 다시 쓰지 않으므로, 캐시 할인 (cache discount) 혜택이 유지됩니다. 캐시 이점은 반복되는 접두사 (repeated-prefix) 워크로드에서만 나타나지만, 다양한 원샷 (one-shot) 트래픽에서는 어차피 캐싱할 내용이 거의 없습니다.
비용을 더 늘릴 수도 없습니다. 요청이 나가기 전에 매 단계마다 다시 측정하며, 비용 절감 효과가 없는 것은 모두 되돌립니다. 제공업체가 압축된 요청을 거부하나요? 그러면 원본이 그대로 나갑니다. 최악의 경우 아무것도 하지 않는 것입니다. OpenAI의 토크나이저 (tokenizer)는 정확합니다. Anthropic과 Gemini에는 공개된 정확한 토크나이저가 없으므로, BPE 프록시 (BPE proxy)로 동작하며 status를 통해 이를 알 수 있습니다.
루프 안에 두 번째 모델이 들어가지 않습니다. 이는 결정론적인 (deterministic) 텍스트 정리이며, 사용자의 프롬프트 (prompt)는 절대 기기를 떠나지 않습니다.
비용이 발생하는 지점은 도구 출력 (Tool output)입니다
낭비되는 대부분은 명령 출력 (command output)입니다. 에이전트가 빌드를 실행하여 200줄의 결과를 받으면, 그중 중요한 오류는 2줄뿐입니다. 나머지 198줄은 비용을 전액 지불하며 다시 전송해야 하는 노이즈입니다.
실제 예시로, bash 도구가 반환한 빌드 로그를 보겠습니다.
이전, 58줄:
[2026-06-13T10:02:00Z] INFO compiling module core::worker::task_0 (incremental)
[2026-06-13T10:02:01Z] INFO compiling module core::worker::task_1 (incremental)
... 28개의 거의 동일한 INFO 라인 추가 ...
...
이후, 5줄:
[{}] INFO compiling module core::worker::task_{} (incremental) [×30: 0..29]
[2026-06-13T10:02:31Z] ERROR src/worker/pool.rs:214: mismatched types: expected `usize`, found `i64`
[{}] INFO compiling module core::net::conn_{} (incremental) [×25: 0..24]
...
오류와 요약 내용은 글자 하나 틀리지 않고 그대로 유지됩니다. 반복되는 INFO 라인은 범위가 규칙적이기 때문에, 손실 없이 템플릿과 해당 값으로 접힙니다. 모델은 발생한 일을 확인하면서도 비용은 5분의 1로 줄어듭니다.
가장 밀접한 도구(Headroom)가 타겟팅하는 도구 출력 계층에서, llmtrim은 동일한 o200k_base 토크나이저를 사용하여 Headroom의 36%와 비교했을 때 입력 토큰을 약 84% 제거했습니다. Headroom은 입력에만 관여하므로, 이는 전체 트래픽이 아닌 도구 출력 부분에 대한 결과입니다.
Log-folding (로그 폴딩)은 10가지 압축 방식 중 하나입니다. 또 다른 방식은 JSON 배열을 압축된 테이블로 재인코딩합니다. 행(row)은 동일하지만 토큰은 3분의 1로 줄어듭니다:
전: [{"id":1,"city":"Paris","ok":true},{"id":2,"city":"Lyon","ok":false}, … 200 rows]
후: [200]{id,city,ok}: 1,Paris,true; 2,Lyon,false; … (무손실)
수치와 솔직한 주의사항
모든 케이스는 원본과 압축본 두 가지로 각각 한 번씩 전송되며, 두 답변 모두 실제 요율로 점수가 매겨지고 비용이 청구됩니다. 비용과 품질은 추정치가 아닌 함께 측정되었습니다. 11개 코퍼스(각 5~12개)에 걸친 112개의 쌍을 이룬 A/B 케이스가 모두 리포지토리(repo)에 포함되어 있습니다.
| 지표 | 결과 |
|---|---|
| 입력 토큰 (Input tokens) | -31% |
| ... |
그 66%라는 수치를 인용하기 전에 다음 주의사항을 읽어보세요:
토큰 절감량(입력 -31%, 출력 -74%)은 모델에 독립적입니다. 달러 수치는 각 모델의 출력 대비 입력 가격 비율을 따르므로, qwen3-next-80b (비-추론형)에서는 -66%이며, Opus 및 Sonnet 요율에서는 약 -59%에 도달합니다. 귀하의 모델에서 직접 실행해 보세요.
품질은 총합 기준으로는 유지되었으나(+3.3pp), 작업 부하(workload)별로는 초등 수학에서 -8pp부터 멀티홉 RAG (multi-hop RAG)에서 +21pp까지 다양하며, 코퍼스별 델타(delta) 중 일부는 신뢰 구간(confidence interval) 내에 있습니다. 손실이 발생하는(lossy) 코드 단계 하나는 -21.6pp를 기록하여 기본 설정에서 제외되었습니다. 따라서 총합 수치가 핵심이며, 코퍼스별 수치는 방향성을 나타내는 지표로만 취급하십시오.
리포지토리에서 재현할 수 있습니다:
python3 crates/llmtrim-cli/bench/scripts/download.py 40
cargo run -q --features live -- bench suite # OPENROUTER_API_KEY 필요
프록시 없이 사용하기
트래픽을 프록시를 통해 라우팅하고 싶지 않다면, 동일한 엔진을 MCP 서버, CLI, 임베디드 가능한 Rust 크레이트(crate), 또는 Python, Ruby, Swift, Kotlin용 바인딩(bindings)으로 실행할 수 있습니다.
import llmtrim
out = llmtrim.compress(request_json, llmtrim.Provider.OPEN_AI, "aggressive")
print(out.input_tokens_before, "->", out.input_tokens_after)
아직 초기 단계이며, 여러분의 수치를 원합니다
이 기술은 일부 미흡한 부분이 있으며 모든 작업 부하에 도움이 되지는 않을 것입니다. 짧은 프롬프트를 사용하는 채팅은 압축할 내용이 없습니다.
제가 여러분에게 가장 바라는 실행 방식은 승리(win)의 반대 상황, 즉 llmtrim이 거의 아무것도 절감하지 못하는 워크로드(workload)를 찾는 것입니다. 바로 그런 상황들이 버그를 찾아내기 때문입니다. 세션(session)을 대상으로 테스트해 보고 무엇이 보이는지 저에게 알려주세요.
Repo, AGPL-3.0: https://github.com/fkiene/llmtrim
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기