PSA: Claude Code의 캐시 버그 2가지로 인한 API 비용 10~20배 폭증 문제 - 원인과 해결책
PSA: Claude Code has two cache bugs that can silently 10-20x your API costs — here's the root cause and workarounds
핵심 요약
Claude Code의 독립형 바이너리 내 캐시 버그로 인해 API 비용이 비정상적으로 급증하는 문제가 발견됨.
- 독립형 바이너리 버그 — 빌링 관련 문자열 치환 로직이 캐시 키를 오염시켜 매번 캐시를 재빌드함.
- Resume 캐시 미스 — v2.1.69부터 도입된 deferred_tools_delta로 인해 세션 재개 시 캐시가 무효화됨.
- 비용 영향 — 버그 발생 시 요청당 최대 0.20달러 이상의 추가 비용이 발생할 수 있음.
- 해결책 — 독립형 바이너리 대신 npx @anthropic-ai/claude-code를 사용하여 실행할 것.
지난 며칠 동안 Claude Code 독립형 바이너리(228MB ELF, Ghidra + MITM proxy + radare2)를 리버스 엔지니어링한 결과, 프롬프트 캐시를 깨뜨려 API 비용을 10~20배까지 조용히 부풀리는 두 가지 독립적인 버그를 발견했습니다. 다른 분들이 피해를 입지 않도록 공유합니다.
버그 1: 독립형 바이너리의 센티넬 치환으로 인해 대화 내용에 빌링 관련 내부 정보가 포함될 경우 캐시가 깨짐
문제: anthropics/claude-code#40524
독립형 Claude Code 바이너리(claude.ai/install.sh 또는 npm install -g로 설치하는 것)에는 Anthropic의 커스텀 Bun 포크에 내장된 네이티브 계층의 문자열 치환 기능이 포함되어 있습니다. 이 기능은 Zig HTTP 헤더 빌더 함수(Content-Length, User-Agent 등을 빌드하는 함수)에 주입되어 있습니다.
/v1/messages로 보내는 모든 API 요청에서 anthropic-version 헤더가 존재하면, JSON 요청 본문에서 cch=00000(빌링 속성 센티넬)을 찾아 00000을 본문 해시에서 파생된 5자리 16진수로 바꿉니다. 이는 JSON.stringify 이후, TLS 암호화 이전에 발생하므로 JavaScript에서는 전혀 보이지 않습니다.
언제 문제가 발생할까요? 이 치환은 본문에서 '첫 번째'로 나타나는 항목을 대상으로 합니다. messages[]가 직렬화된 JSON에서 system[]보다 앞에 오기 때문에, 대화 기록에 (CC 번들 소스를 읽거나, 빌링 헤더를 논의하거나, CLAUDE.md에 포함되어 있어) 센티넬이 문자 그대로 포함되어 있으면, system[0] 대신 메시지 내의 센티넬이 치환됩니다. 이로 인해 매 요청마다 메시지 내용이 바뀌어 캐시 접두사가 깨지고, 전체 캐시가 재빌드됩니다(컨텍스트 크기에 따라 요청당 약 $0.04~0.15).
일반적인 사용(CC 내부 구조를 논의하지 않는 경우)에서는 system[0]만 영향을 받으며, 여기에는 cache_control: null이 설정되어 있어 캐싱에 영향을 주지 않습니다.
해결책: 독립형 바이너리 대신 npx @anthropic-ai/claude-code*를 사용하여 Claude Code를 실행하세요. 치환 메커니즘은 독립형 바이너리에 컴파일된 커스텀 Bun 포크에만 존재하며, 표준 Bun/Node에서 실행되는 npm 패키지에는 치환 기능이 없습니다. 실험적으로 확인한 결과, 동일한 JS와 동일한 바이트코드에서 npx 실행 시 치환이 전혀 발생하지 않았습니다.
*- 이 명령어를 무작정 사용하지 말고, 무엇을 하는지 확인하세요(안전하지만 그래도 확인하는 것이 좋습니다).
버그 2: --resume는 항상 캐시를 깨뜨림(v2.1.69 이후)
문제: anthropics/claude-code#34629
모든 --resume은 전체 대화 기록에 대한 캐시 미스를 발생시킵니다. 시스템 프롬프트(~11-14k 토큰)만 캐시되고, 나머지는 처음부터 다시 cache_creation됩니다. 이는 재개 요청 시 비용이 약 10~20배 증가하는 결과입니다.
근본 원인: v2.1.69에서 Anthropic은 deferred_tools_delta를 도입했습니다. 이는 ToolSearch를 통해 사용 가능한 도구를 나열하는 새로운 시스템 알림 첨부 파일입니다. '새 세션'에서는 이 첨부 파일(지연 도구 + MCP 지침 + 기술 목록, ~13KB)이 AU$ 사용자 컨텍스트와 함께 에 주입됩니다. '재개' 시에는 이 파일들이 메시지 끝()에 추가되는 반면, 에는 AU$ 컨텍스트(~352B)만 포함됩니다.


