캐시가 깨지는 날
Claude Code 쓰다가 비용이 갑자기 뛴 이유. 프롬프트 캐싱 구조를 이해하고 나서 — 기억의 배치 순서가 내용보다 중요하다는 것을 알게 되었다.
Claude Code 쓰다가 비용이 갑자기 뛴 이유
Claude Code로 작업하다 보면 어떤 날은 유난히 느리고 비용이 높다. 같은 작업인데 — 어제는 빨랐고 오늘은 느리다. 처음에는 서버 문제인 줄 알았다.
아니었다. 내가 캐시를 깨고 있었다.
뭘 잘못했는가
Claude Code는 프롬프트 캐싱 위에서 돌아간다. 요청의 앞부분(시스템 프롬프트, 도구 정의, 프로젝트 컨텍스트)이 이전 요청과 같으면 — 그 부분을 다시 처리하지 않는다. 캐시 히트. 빠르고 싸다.
문제는 앞부분이 조금이라도 바뀌면 — 그 뒤 전체가 무효화된다는 것이다. 책장에 꽂힌 책을 앞쪽에서 하나 빼면 뒤의 모든 책 위치가 밀리는 것과 같다.
내가 한 실수들:
작업 중간에 MCP 도구를 추가했다. 도구 정의가 프리픽스에 포함되어 있어서 — 도구 하나 추가하는 순간 그 뒤 캐시 전체가 날아갔다. 체감상 갑자기 느려진 이유가 이거였다.
세션 도중에 모델을 바꿔봤다. 캐시가 모델별로 분리되어 있다는 걸 몰랐다. Sonnet에서 쌓아둔 캐시가 Opus로 바꾸는 순간 증발.
CLAUDE.md를 자주 고쳤다. 프로젝트 컨텍스트가 바뀌면 그 뒤가 전부 무효화된다. 오타 하나 고친 것뿐인데 — 캐시 입장에서는 전면 재구성.
구조를 이해하고 나서
요청이 쌓이는 순서가 있다:
1
시스템 프롬프트 → 도구 정의 → 프로젝트 컨텍스트 → 대화
앞에 있을수록 정적이고, 뒤에 있을수록 동적이다. 이 순서 자체가 캐싱을 위한 설계다. 변하지 않는 것이 앞, 변하는 것이 뒤. 앞을 안 건드리면 — 대화가 아무리 길어져도 앞부분은 캐시에서 바로 불러온다.
Claude Code가 Plan 모드에서 도구를 빼지 않고 EnterPlanMode라는 별도 도구를 만든 이유도 이거다. 도구 목록 자체를 건드리면 캐시가 깨지니까 — 목록은 그대로 두고 사용 규칙만 바꾸는 것이다.
MCP 도구가 많을 때도 마찬가지다. 전부 로드하면 토큰이 폭발하고, 빼면 캐시가 깨진다. 해법은 이름만 남긴 경량 스텁을 항상 같은 순서로 유지하고 — 필요할 때만 전체 스키마를 부르는 것이다.
Compaction: 잘 잊는 기술
대화가 길어지면 요약이 필요하다. 여기서도 같은 원칙이 적용된다. 요약을 새 요청으로 보내면 프리픽스가 달라져서 캐시가 깨진다. Claude Code는 원래 대화와 동일한 프리픽스를 유지한 채 — 요약 지시만 끝에 붙인다.
무엇을 남기고 무엇을 버릴지 결정하되 — 앞의 구조는 보호하는 것. 잊되, 뼈대는 건드리지 않는 것.
환자 차트와 같은 구조
이걸 이해하고 나니 — 익숙한 구조가 보였다.
환자 차트도 같다. 기본 정보(이름, 나이, 기저질환)는 맨 위에 고정이다. 매 방문마다 변하지 않는다. 그 아래에 방문 기록이 쌓이고, 가장 최근 기록이 맨 아래에 온다. 이 순서가 지켜지면 차트를 열었을 때 즉시 맥락이 잡힌다. 깨지면 매번 처음부터 읽어야 한다.
결국 캐싱이 가르쳐주는 건 이거다: 기억의 구조에서 가장 중요한 것은 내용이 아니라 배치 순서다. 무엇을 기억하느냐보다 — 변하지 않는 것을 앞에 두고, 변하는 것을 뒤에 두고, 앞을 절대 건드리지 않는 것.
