# AI 에이전트

느낌표 하나 바꾸면 Claude Code 프롬프트 캐시가 깨질까?

@Hong2026-10-28

이 글에 담긴 코드와 결과는 직접 실행해 측정한 값을 바탕으로 작성했습니다. 실측은 Hong과 팀원들이 진행했고, 그 결과를 바탕으로 AI가 글을 쓰고 Hong이 검토합니다.

질문
지침 파일에 느낌표 하나만 붙여도 Claude Code의 프롬프트 캐시가 깨질까?
답
깨졌다. 15줄짜리 지침 파일에 느낌표 하나를 붙이고 새로 실행하자 캐시 쓰기가 303토큰에서 5,871토큰으로 뛰어 첫 실행(6,083토큰)과 비슷해졌고, 재검증에서도 같은 모양이었다.
조건
2026-09-04 1묶음과 재검증 1묶음, claude -p 새 실행 3번을 연달아, --safe-mode와 --append-system-prompt-file로 지침 파일만 바꿈

환경

측정일
지침 한 글자 실험 2026-09-04, MCP 구성 실험 2026-09-07
실행
claude -p --output-format json --max-turns 6, 실행마다 새로 시작
지침 실험
--safe-mode + --append-system-prompt-file(15줄 지침 파일), 3번 연속 실행 1묶음과 재검증 1묶음
MCP 실험
--mcp-config + --strict-mcp-config, 서버 1개 구성 3번 뒤 서버 2개 구성 2번, 1묶음
모델 교체
발행 글 인용(2026-10-12, Claude Code 2.1.295, Claude 구독, Opus 5.5 대화의 한 턴만 Sonnet 5.5, 조건마다 3회)
사실 확인
Claude Code와 Claude API 문서 기준(2026-10)
목차
  1. 캐시는 앞부분이 똑같을 때만 살아 있어요
  2. 한 글자로 캐시를 깨 볼게요
  3. 캐시는 세션이 아니라 앞부분 글자에 붙어요
  4. 앞부분은 시작할 때 정하고 작업 중에는 건드리지 않아요
  5. 지침만 앞부분인 게 아니에요
  6. 캐시가 깨지는 건 조용해요
  7. 정리

이번 시간에는 Claude Code의 프롬프트 캐시가 언제 쌓이고, 무엇이 깨뜨리고, 깨진 걸 어떻게 알아채는지를 claude -p 결과의 캐시 토큰 두 개로 배워가는 시간입니다.

캐시가 깨져도 작업은 멀쩡히 끝나요. 그래서 화면만 봐서는 모르고, 숫자를 봐야 알 수 있습니다.

캐시는 앞부분이 똑같을 때만 살아 있어요

먼저 원리부터 볼게요.

매 요청에는 도구 정의, 시스템 프롬프트, 대화 기록이 이 순서로 앞부분에 실립니다. 지침도 여기에 들어가요. 프롬프트 캐시는 이 앞부분이 직전 요청과 정확히 같을 때, 다시 처리하는 대신 저장해 둔 걸 읽는 장치예요.

처음에 캐시 쓰기가 한 번 일어나고, 그다음부터는 훨씬 싼 캐시 읽기로 처리되는 거죠.

지침이 어디에 실리는지는 넣는 방법에 따라 달라요.

  • CLAUDE.md: 시스템 프롬프트가 아니라 시스템 프롬프트 뒤의 사용자 메시지로 실려요. 작업 디렉터리와 상위 디렉터리의 CLAUDE.md, ~/.claude/CLAUDE.md가 세션을 시작할 때 자동으로 들어갑니다.
  • --append-system-prompt-file <파일>: 그 파일 내용을 시스템 프롬프트 뒤에 붙여요.

위치는 다르지만 둘 다 매 요청의 앞부분에 실린다는 점은 같아요. 그래서 아래 원리는 둘 다에 똑같이 적용됩니다.

여기서 핵심 조건이 "정확히 같을 때"예요.

앞부분 어딘가가 한 글자라도 달라지면, 달라진 지점부터 뒤로는 전부 다시 씁니다. 도구 정의가 바뀌면 시스템 프롬프트와 대화 기록까지, 시스템 프롬프트가 바뀌면 대화 기록까지 다시 쓰는 식이에요.

말로만 하면 안 와닿으니 직접 잰 값을 보죠.

한 글자로 캐시를 깨 볼게요

이 부분은 제가 실측한 결과를 기반으로 알려드릴게요.

예를 들어서 우리가 프로젝트 지침을 담은 15줄짜리 지침 파일 rules-lean.md를 쓰고 있다고 해볼게요. 코드 규칙, 커밋 메시지 규칙, 테스트 규칙, 보고 형식을 담은 파일이에요.

# 프로젝트 지침

## 코드
- 파이썬 표준 라이브러리만 사용한다. 외부 패키지 금지.
- 클래스는 PascalCase, 함수·변수는 snake_case. 들여쓰기 스페이스 4칸.

## 커밋
- 커밋 메시지는 반드시 "작업:"으로 시작하고 한국어로 쓴다.

## 테스트
- 파이썬 코드를 수정하면 반드시 .venv/bin/python -m pytest -q tests/baseline 로 확인한다.
- 테스트를 지우거나 테스트 쪽을 고쳐 통과시키지 않는다.

## 보고
- 작업이 끝나면 보고는 세 줄 이내. 바꾼 파일과 이유를 담는다.

app 디렉터리가 있는 작은 파이썬 프로젝트에서 같은 과제를 세 번 돌렸어요. 1회차와 2회차는 그대로 돌리고, 3회차 전에 이 파일의 "한국어로 쓴다" 뒤에 느낌표 하나만 붙였습니다.

1회차 명령은 이랬고, 2회차와 3회차는 결과 파일 이름만 c2.json, c3.json으로 바꿔 같은 명령을 다시 실행했어요.

Q="app 폴더에 파일이 몇 개인지 세어 줘."
claude --safe-mode --append-system-prompt-file rules-lean.md -p "$Q" --output-format json --max-turns 6 > c1.json 2>/dev/null

플래그는 이런 역할이에요.

  • --safe-mode: CLAUDE.md, 스킬, 플러그인, 훅, MCP 서버 같은 사용자 설정을 끄고 엽니다. 제 개인 설정이 섞이지 않게 하려고 넣었어요.
  • --append-system-prompt-file rules-lean.md: 지침 파일을 시스템 프롬프트 뒤에 붙입니다. safe-mode가 CLAUDE.md를 끄니까 지침은 이 플래그로 넣었어요. 실험에서 바뀌는 건 이 파일 하나뿐입니다.
  • -p "$Q": 대화 화면 없이 질문 하나를 보내고 결과를 받고 끝나요. 실행할 때마다 새 세션입니다.
  • --output-format json: 결과를 JSON으로 받아요. 캐시 토큰이 usage 안에 들어 있습니다.
  • --max-turns 6: 이 실행 안에서 모델과 주고받는 왕복을 최대 6번으로 제한해요.

결과 JSON에서는 usage 안의 두 값만 따라가시면 됩니다.

  • cache_creation_input_tokens: 캐시에 새로 쓴 양
  • cache_read_input_tokens: 캐시에서 읽은 양

두 값은 그 실행 안에서 모델에 보낸 요청들을 더한 값이에요. 요청 하나의 값이 아니라 실행 한 번의 값으로 읽어 주세요.

세 파일에서 두 값만 뽑아 보면 이렇게 나왔어요.

for i in 1 2 3; do
  echo "${i}회차:"
  python3 -m json.tool c$i.json | grep -E '^        "cache_(creation|read)_input_tokens"'
done
1회차:
        "cache_creation_input_tokens": 6083,
        "cache_read_input_tokens": 37820,
2회차:
        "cache_creation_input_tokens": 303,
        "cache_read_input_tokens": 43576,
3회차:
        "cache_creation_input_tokens": 5871,
        "cache_read_input_tokens": 37821,

1회차는 처음이니까 캐시에 쓰는 양이 6,083토큰으로 큽니다.

2회차는 앞부분이 똑같으니까 쓰기가 303토큰으로 떨어지고, 대부분이 싼 읽기로 처리됐어요. 1회차 쓰기의 약 5%(303 ÷ 6,083 ≈ 0.05)예요. 이렇게 앞부분을 캐시에서 읽는 상태를 warm이라고 부릅니다.

그리고 3회차를 보세요. 느낌표 하나 바꿨을 뿐인데 쓰기가 5,871토큰으로, 1회차의 약 97%(5,871 ÷ 6,083 ≈ 0.97)까지 돌아갔어요. 앞부분을 처음부터 다시 쓰는 상태, cold가 된 거예요.

느낌표 하나가 앞부분의 재작성을 만든 겁니다.

같은 순서를 한 번 더 돌린 재검증에서도 쓰기가 6,260 → 326 → 6,259토큰으로 같은 모양이었어요. 두 묶음뿐이라 숫자 자체보다 "어디서 올라가고 내려가는지"를 보시면 됩니다.

읽기도 하나 짚고 갈게요. 1회차도 읽기가 37,820토큰으로 0이 아니었고, 느낌표 때문에 다시 쓴 3회차도 37,821토큰을 읽었어요. 다시 쓴 실행에서도 읽기는 이만큼 잡힌다는 거예요. 그래서 "읽기가 0이 아니면 캐시가 유지됐다"고 판단하면 틀리고, 쓰기가 얼마나 큰지로 판단해야 합니다.

캐시는 세션이 아니라 앞부분 글자에 붙어요

여기서 하나 더 짚고 갈게요. 방금 우리는 claude -p를 세 번 따로 실행했어요. 셋 다 새로 시작한 실행이고, 다른 세션입니다. 그런데도 2회차에서 캐시가 먹었죠.

왜 그럴까요?

캐시가 세션에 붙는 게 아니라 요청 앞부분이라는 글자 자체에 붙기 때문이에요. 앞부분이 글자까지 같으면 세션이 달라도 캐시에서 읽습니다.

그러니까 새 세션이 곧 cold인 건 아니에요. 세션을 끊어서 비싸지는 게 아니라, 앞부분이 달라져서 비싸지는 겁니다.

그런데 cold가 된다는 게 단순히 혜택을 못 받는 수준이 아니에요. 평소보다 더 비싸게 내는 상태입니다.

문서 기준(2026-10)으로 캐시 단가는 기본 입력 단가에 대한 배수로 정해져 있어요.

  • 캐시 읽기: 0.1배. 일부 최신 모델은 더 싸서 0.05배, 0.025배예요.
  • 캐시 쓰기: 5분 캐시는 1.25배, 1시간 캐시는 2배예요.

warm으로 읽던 앞부분을 다시 쓰게 되면, 같은 분량에 읽기의 적어도 12.5배(1.25 ÷ 0.1)를 내는 거예요. 1시간 캐시라면 20배(2 ÷ 0.1)이고, 읽기가 0.05배인 모델이면 그 두 배가 됩니다. 조금 손해 보는 게 아니라 자릿수가 바뀌는 거죠.

앞부분은 시작할 때 정하고 작업 중에는 건드리지 않아요

자 이제 앞부분을 바꾸는 일들을 하나로 모아 볼게요.

지침 파일을 고치는 것도, 도구 구성을 바꾸는 것도, 모델을 교체하는 것도 전부 앞부분을 바꾸는 일이에요. 바뀐 내용이 앞부분에 실제로 실리면 하나같이 캐시를 cold로 되돌립니다. 사고 깊이(effort)를 바꾸는 것도 모델에 따라 캐시를 깨기도 해요. 문서 기준(2026-10)으로 Claude Code에서 Opus 5.5, Sonnet 5.5, Haiku 5.5, Fable 5.1은 effort를 바꿔도 캐시가 유지되고, 그 밖의 모델은 대부분 깨집니다.

지침 파일은 넣는 방법에 따라 깨지는 시점이 달라요. 세션 도중에 CLAUDE.md를 고치면 바로 반영되지 않고 캐시도 그대로예요. /clear, /compact, 재시작으로 바뀐 내용이 실릴 때 앞부분이 달라집니다. 방금 실험처럼 바뀐 파일로 새 실행을 시작하면 그 실행부터 다시 쓰고요.

그래서 규칙은 이겁니다. 앞부분에 실리는 것들은 작업을 시작하기 전에 정하고, 작업 중에는 건드리지 않는다. 지침을 고치고 싶으면 작업 사이에 몰아서 하시는 거죠.

그리고 크게 깨뜨리는 게 하나 더 있습니다. 압축이에요.

대화가 길어지면 쌓인 대화 기록을 요약으로 갈아 끼우는 압축을 쓰게 돼요. /compact로 직접 하거나, 컨텍스트 창이 차면 자동으로 일어납니다.

압축은 대화 부분을 통째로 바꾸니까, 압축 뒤에는 대화 부분을 다시 씁니다. 다만 그 앞의 시스템 프롬프트와, 세션 시작 뒤 바뀌지 않은 CLAUDE.md는 캐시에서 그대로 읽혀요.

압축이 공짜가 아닌 이유가 여기 있어요. 요약을 만드는 요청이 한 번 들고, 그 뒤 대화 부분을 다시 써요. 요약을 만드는 요청은 캐시가 살아 있으면 앞부분을 캐시에서 읽어 싸지만, 오래 쉬었다가 압축하면 전체를 새로 처리해서 가장 비쌉니다.

그리고 캐시에는 수명도 있어요. 문서 기준(2026-10)으로 기본 수명은 5분이고, 1시간을 고를 수 있습니다.

  • Claude Code 메인 대화(-p 포함): Claude 구독의 플랜 사용량 안이면 1시간, API 키나 사용량 크레딧, 클라우드 공급자로 쓰면 5분
  • 서브에이전트, 압축 같은 보조 요청: 5분

여기서 중요한 건 길이보다 갱신이에요. 캐시는 읽을 때마다 수명이 다시 채워지고, 이건 추가 비용이 없어요. 그래서 쉬지 않고 이어서 작업하면 한참을 가도 warm이 유지되고, 반대로 회의 한 번 다녀오면 아무것도 안 바꿨는데 cold가 됩니다.

점심 먹고 돌아온 첫 요청이 같은 세션인데도 비싼 이유가 이거예요. 작업을 몰아서 하는 게 실제로 돈을 아끼는 쪽입니다.

수명은 우리가 요청마다 제어할 수 있는 부분이 아니니까, 측정할 때 cold인지 warm인지를 구분해서 적는 걸로 대응하면 됩니다.

지침만 앞부분인 게 아니에요

앞부분을 흔들면 안 된다는 규칙에 걸리는 게 지침 파일만 있는 게 아니에요. 모델과 도구 구성도 같은 규칙에 걸립니다.

먼저 모델이에요. 캐시는 모델마다 따로 쌓입니다. 그러니까 세션 도중에 모델을 바꾸면, 새 모델 입장에서는 처음 보는 앞부분이에요. 내용이 같아도 처음부터 다시 씁니다.

이 값은 따로 잰 발행 글이 있어서 그 결과를 옮길게요. 2026년 10월 12일 Claude Code 2.1.295의 claude -p로, Opus 5.5로 시작한 4턴짜리 대화를 --resume으로 이어 가면서 3턴만 --model sonnet(Sonnet 5.5)으로 보낸 측정이에요. Claude 구독으로 돌려 캐시 수명이 1시간인 조건이었고, 대화 재료는 약 1만 토큰, 조건마다 3회였습니다.

  • 3턴(Sonnet 5.5): 세 번 모두 대화 약 1만 토큰(10,309~10,337토큰)을 캐시에 다시 썼어요. 그 턴 비용(API 단가로 환산한 추정치)은 아무것도 바꾸지 않은 대화의 3턴의 11배였습니다.
  • 4턴(다시 Opus 5.5): 2턴까지 쌓은 Opus 캐시가 수명(1시간) 안이라 남아 있어서, 새로 쓴 건 289토큰뿐이었어요.

질문도 지침도 그대로인데 모델만 바꿨는데요. 아끼려고 모델을 작은 쪽으로 내렸는데, 그 순간 지금까지 쌓아 둔 앞부분을 통째로 다시 쓰게 되는 거예요.

같은 글에서 긴 대화를 Haiku 5.5로 바꾼 턴도 쟀어요. 대화가 약 8만 4천 토큰일 때는 Haiku로 바꾼 턴이 Opus로 계속한 턴보다 쌌고, 약 11만 7천 토큰일 때는 약 3배 비쌌습니다. 세션 중간에 바꾸면 아낀 단가보다 다시 쓴 비용이 더 클 수 있다는 거죠.

이 부분이 더 궁금하면 세션 중간에 모델을 바꾸면 Claude 프롬프트 캐시는 얼마나 깨질까? 글을 참고하세요.

결론은 지침 때와 같아요. 모델도 작업을 시작하기 전에 정하고 작업 중에는 건드리지 않습니다.

도구 구성도 마찬가지예요. 도구 목록도 요청 앞부분에 실리니까, 다른 MCP 구성으로 새로 시작하면 앞부분이 달라집니다.

이것도 지침과 같은 방식으로 쟀어요. 서버 하나짜리 MCP 구성 파일(mcp-one.json)로 세 번 돌려 warm을 만들고, 거기에 서버를 하나 더한 구성 파일(mcp-two.json)로 두 번 더 돌렸습니다. 과제는 "protocol.md의 절 제목만 나열해 줘."였어요.

  • --mcp-config <파일>: 그 파일의 MCP 서버를 이번 실행에 붙여요.
  • --strict-mcp-config: --mcp-config로 준 서버만 쓰고, 다른 MCP 구성은 무시해요.

safe-mode는 MCP 서버를 끄기 때문에 이 실험은 safe-mode 없이 돌렸어요. 그래서 제 개인 설정도 함께 실렸고, 숫자는 같은 환경 안의 차이로만 봐 주세요.

다섯 번의 캐시 쓰기는 19,900 → 386 → 390 → 391 → 19,949토큰이었어요.

모양이 지침으로 본 것과 같아요. 첫 실행은 캐시 쓰기가 약 2만 토큰이고, 두세 번째는 수백으로 떨어집니다. 그런데 서버 하나를 더하자 그 2만이 다시 왔어요.

자세히 보시면 재작성이 구성을 바꾼 네 번째가 아니라 다섯 번째에 왔습니다. 네 번째는 391토큰으로 멀쩡했어요. 같은 실험을 다시 돌렸을 때는 구성을 바꾼 첫 실행에서 바로 뛴 적도 있었는데, 그 회차 숫자는 남기지 않았어요. 왜 한 박자 늦었는지는 이 한 묶음으로는 가릴 수 없었습니다.

이게 실무에서 뜻하는 건, 캐시가 튄 실행을 보고 방금 바꾼 게 범인이라고 단정하기 어렵다는 거예요.

세션 도중에 서버를 붙였다 떼는 경우는 조건에 따라 달라요. 문서 기준(2026-10)으로는 이렇습니다.

  • 기본 설정: Claude Code는 tool search(MCP 도구 정의를 처음부터 다 싣지 않고 필요할 때 찾아 불러오는 기능)로 MCP 도구를 불러와요. 이때는 첫 요청의 도구 목록을 대화 내내 유지해서, 세션 중에 서버를 연결하거나 해제해도 캐시가 깨지지 않아요.
  • tool search가 꺼졌거나 지원되지 않는 환경: 세션 중에 서버를 연결하거나, 도구를 추가하거나, 일부러 빼면 캐시가 깨져요.
  • 설정 파일만 고친 경우: 재시작할 때 반영돼요.

그래서 작업 유형별로 구성 파일을 미리 정해 두시고, 팀이 공유하는 구성은 저장소에 커밋하시면 됩니다. 실행할 때는 --strict-mcp-config로 그 구성만 쓰게 하시고요. 붙였다 뗐다 하고 싶어지는 순간이, 사실은 구성을 잘못 짰다는 신호예요.

캐시가 깨지는 건 조용해요

캐시가 안 먹어도, 컨텍스트가 평소보다 빨리 불어도, 작업 자체는 멀쩡히 진행됩니다. 화면만 봐서는 몰라요. 결국 청구서에서 알게 되는 거죠.

원인은 대개 뭔가가 앞부분을 계속 바꾸고 있는 겁니다.

  • 지침 파일을 자동으로 고쳐 쓰는 스크립트가 있는 경우
  • 날짜처럼 매번 달라지는 값이 지침에 박혀 있는 경우
  • 플러그인 업데이트가 도구 구성을 바꾸는 경우

탐지에 필요한 건 앞에서 본 cache_creation_input_tokens 하나예요.

기준선은 이겁니다. 반복하는 과제에서 warm 상태의 캐시 쓰기는 수백 토큰 수준이어야 해요. 이 글의 측정에서도 warm 실행은 303, 326, 386~391토큰이었어요.

주기적으로 점검하실 때는 같은 과제의 캐시 쓰기를 보세요. 이게 연속으로 수천 토큰씩 나오면 앞부분이 계속 흔들리고 있다는 신호입니다.

신호를 잡으셨으면 이 순서로 역추적하시면 돼요.

  1. 지침 파일 변경 이력
  2. 도구와 플러그인 구성
  3. 모델과 사고 깊이 설정
  4. 압축이 일어났는지

컨텍스트가 평소보다 빨리 찬다면, 대화형 세션에서 /context를 열어 보세요. 시스템 프롬프트, 시스템 도구, MCP 도구, 메모리 파일(CLAUDE.md), 스킬, 메시지 같은 항목별 사용량이 나와서 어느 항목이 불었는지 볼 수 있어요.

정리

범위: claude -p 새 실행을 연달아 돌려 잰 캐시 쓰기(2026-09-04 지침 한 글자 1묶음과 재검증 1묶음, 2026-09-07 MCP 구성 1묶음), 모델 교체는 발행 글(2026-10-12, 조건마다 3회) 인용, 단가·수명·압축·MCP 동작은 문서 기준(2026-10).

  • 15줄짜리 지침 파일에 느낌표 하나를 붙이자 캐시 쓰기가 303에서 5,871토큰으로 돌아가 첫 실행(6,083)과 비슷해졌고, 재검증(6,260 → 326 → 6,259)도 같은 모양이었어요. 앞부분은 한 글자만 달라도 그 지점부터 다시 쓴다고 보세요.
  • 따로 실행한 claude -p끼리도 앞부분이 같으면 캐시를 읽었어요. 비싸지는 이유는 세션을 끊어서가 아니라 앞부분이 달라져서입니다.
  • 다시 쓰기는 읽기의 적어도 12.5배(1.25 ÷ 0.1)예요. 지침, 모델, 도구 구성은 작업을 시작하기 전에 정하고, 고칠 일이 있으면 작업 사이에 몰아서 고치세요.
  • Opus 5.5 대화의 한 턴만 Sonnet 5.5로 바꾸자 세 번 모두 대화 약 1만 토큰을 다시 써서 그 턴이 바꾸지 않은 대화의 같은 턴보다 11배 비쌌어요. 작은 모델로 내리는 게 오히려 비쌀 수 있으니 세션 중간에는 모델을 바꾸지 마세요.
  • 서버를 하나 더한 MCP 구성으로 새로 시작하자 캐시 쓰기가 19,949토큰으로 다시 뛰었고, 이번에는 바꾼 다음 실행에서 왔어요. 캐시가 튄 실행 바로 앞의 변경만 의심하지 마세요.
  • 압축은 대화 부분을 다시 쓰게 하고, 오래 쉬었다가 압축하면 가장 비싸요. 캐시 수명은 읽을 때마다 다시 채워지니 작업은 쉬지 않고 몰아서 하세요.
  • warm의 캐시 쓰기는 수백 토큰이 정상이에요. 같은 과제에서 연속으로 수천이 나오면 지침, 도구·플러그인, 모델·사고 깊이, 압축 순서로 역추적하세요.
내 링크 만들기