Claude Code 세션에서 '이 변수 이름을 변경해 줘'라는 문구를 8번째 메시지로 입력한 후, 다시 80번째로 같은 문구를 입력한다고 가정해 봅시다. 단어는 같고 답변도 같지만, 제 샘플 숫자로 계산했을 때 두 번째 요청은 약 세 배의 비용이 발생합니다. 프롬프트 캐싱(prompt caching)을 비활성화하면 그 비용은 여섯 배가 됩니다.
문제가 생긴 것은 아닙니다. 긴 세션은 이차 곡선(quadratic curve)에 두 번 걸립니다. 한 번은 모델 내부에서, 모든 토큰이 이전의 모든 토큰을 바라보는 과정이며, 다른 한 번은 청구서 상에서 발생합니다. 여기서 매 턴마다 전체 대화 내용을 다시 전송하기 때문입니다. 캐싱 기능은 반복 비용을 저렴하게 만들 뿐, 근본적인 형태 자체를 바꾸지는 못합니다.
모델에는 기억력이 없다
Claude Code의 문서는 이를 명확히 설명하고 있습니다: "모델은 요청 사이에 아무것도 기억하지 못하므로 Claude Code는 전체 컨텍스트(context)를 재전송합니다." 그리고 사용자가 보내는 하나의 메시지가 결코 단 한 번의 요청으로 끝나지 않습니다. 모든 도구 호출(tool call)은 그 결과를 새로운 요청으로 전송하며, 이 안에는 이전의 모든 내용이 담겨 있습니다.
모두가 서로를 확인하기 때문에 작업량이 n²이다
모델 내부에서 각 토큰은 쿼리(query) (무엇을 찾고 있는지), 키(key) (무엇을 제공하는지), 그리고 값(value) (무엇을 전달하는지)를 얻습니다. 하나의 토큰은 자신의 쿼리를 모든 키와 비교하고, softmax 함수가 이 점수들을 가중치로 변환하며, 최종 출력은 값들의 가중 평균이 됩니다:
Attention(Q, K, V) = softmax(Q·Kᵀ / √d_k) · V
여기서 Q·Kᵀ는 모든 쿼리가 모든 키와 비교되는 과정입니다. 이는 n개의 토큰에 대해 n × n 격자 형태를 만듭니다. 언어 모델은 과거만 바라보기 때문에 이 격자는 약 n²/2 셀을 가진 삼각형 형태로 줄어들지만, 여전히 이차적(quadratic)입니다. 토큰 수가 두 배가 되면 작업량은 네 배가 됩니다.
Ten words of a sentence, each compared with every earlier word, form a triangle of 55 cells. The row for the word
전체 버전에서는 사용자가 직접 입력하고 두 배로 늘릴 수 있는 라이브 격자(live grid)가 있습니다. 더 읽고 여기서 시도해 보세요.
FlashAttention은 전체 격자를 저장하지 않음으로써 메모리 측면의 문제를 해결했습니다. 하지만 여전히 모든 셀을 계산해야 하므로 시간 복잡도는 이차적(quadratic)으로 유지됩니다.
KV 캐시는 도움이 되지만, 생각하는 방식과는 다르다
응답은 한 토큰씩 나옵니다. KV 캐시(KV cache)는 이전 토큰들의 키(keys)와 값(values)을 GPU 메모리에 보관하여 재계산할 필요가 없게 합니다. 많은 설명자들이 이것이 생성을 선형적(linear)으로 만든다고 말합니다. 그렇지 않습니다. 새로운 토큰 하나하나가 여전히 이전 모든 토큰에 대해 하나의 내적(dot product)을 수행하기 때문에, 전체 응답은 여전히 n²/2 정도입니다. 캐시가 절약해 주는 것은 재실행(rerun)인데, 이것이 총합을 세제곱(cubic) 수준으로 끌어올릴 수 있는 것을 막아줍니다.
Two rows of three small triangles. With a KV cache each step adds one new white row and reuses the grey rest. Without it, the whole triangle is white and redone every step. For a 100,000-token prompt and a 1,000-token reply: about 5.1 billion dot products with the cache, about 5 trillion without.
이 모든 것이 청구서에 직접적으로 표시되지는 않습니다. Anthropic은 90만 토큰(900k-token) 요청이 "9천 토큰(9k-token) 요청과 동일한 토큰당 요율로 청구된다"고 말합니다. 그렇다면 무엇이 청구서를 이차식(quadratic)으로 만들까요?
당신의 청구서는 더 어리석은 이유로 이차식이 됩니다
세션이 S 토큰(시스템 프롬프트, 도구, CLAUDE.md)으로 시작하고 각 턴마다 약 a가 추가된다고 가정해 봅시다. k번째 턴은 대략 S + k·a를 전송하므로, K번의 턴은 총합적으로 S·K + a·K²/2 정도가 됩니다. 다시 삼각형을 생각해 보세요: 모든 턴이 한 행(row)이고, 각 행은 그 위에 있는 모든 것을 재전송합니다.
Six bars that grow longer with each request. In each bar the grey part was already sent and is read from cache, and a short white block at the end is new this turn and written to cache.
프롬프트 캐싱은 형태가 아닌 경사(slope)를 낮춥니다
요청의 시작 부분이 최근에 처리된 내용과 정확히 일치하면, API는 재계산을 건너뛰고 해당 부분을 훨씬 저렴하게 청구합니다. Anthropic은 무엇을 저장하는지 밝히지 않습니다. vLLM 같은 오픈 소스 서버들은 이전 요청들의 KV 블록(KV blocks)을 캐시하므로, 제 추측으로는 동일한 아이디어인 것 같습니다.
Claude Sonnet 5.5의 경우, 백만 토큰당 비용은 다음과 같습니다: 입력 $2, 5분 캐시 작성(write) $2.50, 읽기(read) $0.10, 출력 $10 (Anthropic 가격 페이지, 2026년 10월). 읽기 비용에 20배 할인이 적용되는 것은 모든 것을 해결하는 것처럼 들리지만, 캐시된 부분 자체가 증가하는 부분이 바로 그 지점입니다. 여전히 매 턴마다 전체 기록을 다시 읽어야 하며, 단지 더 저렴할 뿐이고, 이차식(quadratic)의 일부라도 여전히 이차적 성질을 가집니다.
제 샘플 세션: Sonnet 5.5를 사용하여 20k 토큰으로 시작하고 3k 토큰을 추가했으며 메시지당 4개의 API 요청이 발생했습니다. 메시지 8은 약 $0.05가 들고, 메시지 80은 약 $0.16이 듭니다. 전체 80개 메시지는 약 $8.10에 달하며, 캐싱을 사용하지 않을 경우 약 $112입니다. 캐시 읽기 비용은 총 캐시 청구서의 약 3분의 2 정도입니다. 이것이 할인된 재전송(re-sending) 비용입니다.
Four bars. With caching on, message 8 costs $0.05 and message 80 costs $0.16, about 3 times as much. With caching off, message 8 costs $0.41 and message 80 costs $2.60, about 6 times as much. Sample values, not a measurement.
타이머도 확인하세요. Claude Code 문서는 구독(subscription)의 경우 캐시가 1시간 지속된다고 하지만, API 키를 사용하거나 사용 크레딧(usage credits)을 사용하는 경우에는 5분만 유지됩니다. API 키로 커피 한 잔 마시고 다음 메시지를 보내면 전체 컨텍스트가 쓰기 가격으로 다시 작성됩니다.
전체 글에는 이 모든 것을 조절할 수 있는 슬라이더가 포함된 시뮬레이터가 있습니다. 여기에서 사용해 보기.
실제로 곡선을 움직이는 것(What actually moves the curve)
Six bars for the total cost of the same 80-message session on Sonnet 5.5. No caching: $112.10. 1-hour cache: $8.62. Default caching: $8.13. A 20-minute break before message 60: $8.72. /compact at message 41: $5.80. /clear at message 41: $5.70. Sample values.
- /clear는 세션을 초기화합니다. 시스템 프롬프트와 도구(tools)는 캐시(cached)에 유지됩니다. Anthropic의 문서에는 "/clear를 사용해도 비용이 들지 않는다"고 명시되어 있습니다.
- /compact 자체도 큰 요청입니다. 전체 대화를 읽어 요약본을 작성하기 때문에, /clear가 하는 것과 비슷한 효과를 얻지만 먼저 한 번의 대규모 읽기(read)에 대한 비용을 지불합니다.
- 세션 후반부에 긴 휴식 시간이 가장 치명적입니다. 5분 캐시 기준 메시지 60번 이전에 20분간 쉬면, 해당 메시지의 비용이 약 $0.13에서 약 $0.72로 올라갑니다.
- 모델을 전환하면 캐시가 모두 사라집니다. 또한 도구를 미리 로드하는 MCP 서버에 연결할 때도 마찬가지입니다.
- 서브 에이전트(Subagents)는 자체적인 컨텍스트를 가집니다. 따라서 그들의 노이즈가 섞인 출력물은 메인 대화 흐름에서 분리되어, 이후의 모든 메시지마다 재전송되지 않습니다.
이 글이 알려줄 수 없는 것들
- 이것은 실제 청구서가 아니라 샘플 값으로 구성된 모델입니다. 실제 비용을 확인하려면 Claude Code에서 /usage를 실행하세요.
- Pro 또는 Max 버전에서는 달러 금액보다는 사용량 제한(usage limits)에 도달하지만, 그 속도를 결정하는 곡선 자체는 동일합니다.
- 어텐션 수학(attention maths)은 교과서적인 내용이며 Claude의 고유한 것이 아닙니다. Anthropic은 아키텍처를 공개하지 않기 때문에, 그룹화된 KV 헤드(grouped KV heads)와 같은 트릭들은 상수를 변경할 수는 있지만, 표준 어텐션의 n² 형태 자체는 바꾸지 못합니다.
제가 실제로 할 것들
세션을 집이 아닌 가지처럼 취급하세요. 세션당 하나의 작업만 수행하고, 작업이 바뀔 때마다 /clear를 사용하세요. CLAUDE.md 파일은 모든 요청에 포함되므로 짧게 유지하는 것이 좋습니다. 모델은 처음에 하나 선택하고 계속 그대로 두세요. API 키를 사용하는 경우, 작업을 중간에 이탈하게 된다면 떠나기 전에 promptCacheTtl을 1h로 설정하거나 /compact를 사용하세요. 이러한 방법들은 비용 구조 자체를 바꾸지는 않습니다. 단지 저렴한 영역에 머물게 할 뿐입니다.
더 읽어보기
여러분은 /clear를 사용하기 전에 보통 얼마나 오래 세션을 유지하시나요? 댓글로 알려주세요.