프롬프트 캐싱, 한 번 설정하면 API 비용이 눈에 띄게 달라진다
Claude 프롬프트 캐싱이 뭔지, 어떻게 설정하고, 어디서 실수하는지 실제 사용 경험 기반으로 정리했습니다. 긴 시스템 프롬프트 반복 호출하는 분들에게 특히 유용합니다.
API 요금 고지서를 보다가 뭔가 이상하다는 느낌이 온 적 있나요. 분명 기능은 그대로인데 토큰이 예상보다 훨씬 많이 나가고 있을 때. 저도 그랬어요. 시스템 프롬프트에 회사 내부 규정이랑 제품 설명을 잔뜩 써넣고 나서, 매 호출마다 그걸 통째로 보내고 있었거든요. 당연한 건데 당연하다고 생각해서 의심을 안 했던 거죠.
그때 알게 된 게 Claude의 프롬프트 캐싱이에요. 솔직히 처음엔 "그게 얼마나 차이 나겠어" 싶었는데, 설정하고 나서 토큰 소모가 확 줄었습니다. 지금은 길쭉한 컨텍스트를 다루는 거의 모든 프로젝트에 기본으로 넣고 있어요.
캐싱이 뭔지 먼저 감부터 잡자
캐싱이라는 단어가 낯설면 이렇게 생각하면 돼요. 수업 시간마다 교수님한테 "저는 3학년이고 경제학 전공이고 이번 학기에 이런 걸 배우고 있어요"를 매번 처음부터 말해야 한다고 상상해보세요. 교수님이 기억을 전혀 못 하면 그래야 하잖아요. 근데 그게 비효율적이니까, 한 번 소개하면 그다음엔 바로 본론으로 들어가는 게 캐싱의 개념이에요.
Claude API에서도 똑같아요. 시스템 프롬프트나 긴 문서 컨텍스트를 매 요청마다 다시 처리하면 그게 다 토큰 비용이에요. 프롬프트 캐싱은 Anthropic 서버에 그 내용을 임시로 저장해두고, 다음 요청에서는 "이거 저번에 처리한 거랑 같아" 하고 건너뛰게 해주는 거예요. 처리 비용이 뚝 떨어지죠.
실제로 얼마나 차이가 나는 거야
캐시가 적용된 토큰은 일반 입력 토큰보다 약 90% 저렴해요. Claude 3.5 Sonnet 기준으로 일반 입력이 1,000토큰당 $0.003인데, 캐시 읽기 비용은 $0.0003이에요. 숫자만 보면 작아 보이지만, 시스템 프롬프트가 2만 토큰짜리인데 하루에 500번 호출한다고 치면, 캐싱 없이는 1,000만 토큰 어치의 비용이 발생해요. 캐싱 켜면 그 90%가 사라지는 거고요.
저는 고객사 문서 분석 자동화 프로젝트를 돌릴 때 이 차이를 실감했어요. 제품 카탈로그 전체를 컨텍스트로 넣다 보니 시스템 프롬프트만 1만 5천 토큰 정도였는데, 캐싱 설정 전후로 일일 비용이 약 70% 줄었거든요. Claude API 쓰다가 요금 폭탄 맞기 전에 알아야 할 것들을 읽었을 때도 느꼈지만, 토큰 비용은 구조를 어떻게 짜느냐에 따라 같은 작업도 가격이 완전히 달라져요.
설정 방법, 생각보다 단순해요
코드로 보는 게 제일 빠르니까 바로 가요. Python 기준으로 핵심만 보면 이래요.
import anthropic
client = anthropic.Anthropic()
response = client.messages.create(
model="claude-3-5-sonnet-20241022",
max_tokens=1024,
system=[
{
"type": "text",
"text": "여기에 길고 반복 사용되는 시스템 프롬프트 내용...",
"cache_control": {"type": "ephemeral"}
}
],
messages=[
{"role": "user", "content": "실제 사용자 질문"}
]
)
핵심은 cache_control 필드예요. 캐싱하고 싶은 블록에 "cache_control": {"type": "ephemeral"}을 붙이면 끝이에요. ephemeral은 "임시"라는 뜻인데, 현재 Claude API에서 지원하는 캐시 타입이 이것 하나예요. 캐시 유효 시간은 5분이고, 해당 시간 내에 같은 프롬프트로 요청이 들어오면 캐시에서 읽어요.
시스템 프롬프트 외에도 user 메시지 안에 긴 문서를 넣을 때도 같은 방식으로 블록 단위로 캐싱 가능해요. 예를 들어 법률 문서나 기술 매뉴얼 전체를 컨텍스트로 주고 여러 질문을 던지는 패턴이라면, 그 문서 블록에 cache_control을 달아두면 돼요.
그러면 어디서 실수하냐고
여기서부터가 좀 중요한 부분이에요.
제일 흔한 실수는 캐시 경계를 이해 못 하고 쓰는 거예요. Claude는 프롬프트를 앞에서부터 순서대로 처리하는데, cache_control이 붙은 블록까지의 내용을 캐싱해요. 근데 그 블록 뒤에 뭔가를 추가하면? 캐시가 깨져요. 예를 들어 시스템 프롬프트를 두 블록으로 나눠서 첫 번째 블록에만 cache_control 달았는데, 매 요청마다 두 번째 블록 내용을 조금씩 바꾸면 의미 없어요. 캐시는 첫 번째 블록만 적용되거든요.
두 번째 실수는 너무 짧은 텍스트에 캐싱을 거는 거예요. Anthropic에서 정한 최소 캐싱 단위가 있어요. Claude 3 모델 기준으로 최소 1,024토큰 이상이어야 캐싱이 적용돼요. 그보다 짧으면 cache_control을 달아도 그냥 무시해버려요. 그러니까 한두 줄짜리 프롬프트에 캐싱 달아놓고 "왜 비용이 안 줄지?" 하면 답이 여기 있는 거예요.
세 번째는 캐시 쓰기 비용을 간과하는 거예요. 처음으로 캐시를 생성할 때는 일반 입력보다 오히려 25% 더 비싸요. 캐시를 만드는 비용인 거죠. 그래서 딱 한 번만 호출하는 경우엔 캐싱이 손해예요. 같은 컨텍스트로 여러 번 호출할 때 비로소 이득이 생겨요. 대충 3~4번 이상 호출할 거라면 캐싱이 유리하다고 보면 돼요.
이런 상황에 쓰면 딱 맞아요
제가 실제로 잘 쓰는 패턴 몇 가지만요.
첫째로, 챗봇에 고정된 페르소나나 회사 규정을 넣는 경우요. "너는 OO 브랜드의 고객상담 AI야, 말투는 이렇게 해야 하고, 아래 내용은 절대 언급하지 마" 같은 게 수백 줄이면 캐싱 안 하면 낭비예요.
두 번째로, 긴 문서를 기반으로 Q&A를 반복하는 경우요. 예를 들어 200페이지 분량의 제품 매뉴얼을 컨텍스트로 넣고 사용자가 계속 질문을 던지는 구조면, 그 문서 블록을 캐싱해두면 돼요. 5분 내에 대화가 이어진다는 가정 하에요.
세 번째로, 멀티턴 대화에서 이전 대화 이력이 쌓이는 경우요. 대화가 길어질수록 이전 메시지를 통째로 다시 보내야 하는데, 그 부분에 캐싱을 걸어두면 비용이 선형으로 늘어나는 게 아니라 훨씬 천천히 늘어나요. 토큰 관리 전략이랑 함께 쓰면 시너지가 꽤 나요.
캐싱 잘 됐는지 확인하는 법
API 응답 객체에 usage 정보가 있는데, 거기에 캐시 관련 필드가 따로 떠요.
print(response.usage)
# 출력 예시:
# Usage(cache_creation_input_tokens=15000, cache_read_input_tokens=0, input_tokens=200, output_tokens=350)
처음 호출이면 cache_creation_input_tokens에 숫자가 들어오고, 두 번째 호출부터 캐시가 히트되면 cache_read_input_tokens에 숫자가 떠요. 이 두 필드를 보면 캐싱이 제대로 작동하는지 금방 확인돼요. cache_read_input_tokens가 계속 0이면 뭔가 설정이 잘못된 거예요. 보통은 캐시 경계 문제거나 토큰 수 미달이에요.
참고로 Claude API를 처음 쓰는 분이라면, Claude API, 처음 연결하는 날 생기는 일들을 먼저 보고 오면 여기서 말하는 내용이 훨씬 빠르게 이해될 거예요.
📌 한 줄 정리: 프롬프트 캐싱은 반복되는 긴 컨텍스트를 Anthropic 서버에 임시 저장해 토큰 비용을 최대 90% 줄여주는 기능이에요. cache_control 필드 하나만 추가하면 되는데, 최소 1,024토큰 이상이어야 적용되고 5분 안에 재호출이 있어야 효과가 나요. 캐시 쓰기 비용이 먼저 발생하니까 같은 컨텍스트로 최소 3번 이상 호출하는 구조일 때 쓰는 게 맞아요.