목차
Claude 가이드 - 이 글은 시리즈의 일부입니다.
이 글은 Claude API 공식 문서의 Prompt Caching 페이지를 정리한 글입니다. 원문: https://platform.claude.com/docs/en/build-with-claude/prompt-caching 마지막 확인: 2026-05-08
한 줄 요약 #
Claude에게 보낸 자료를 5분~1시간 동안 캐시(임시 저장)해두면, 그 다음 호출부터는 같은 자료를 10% 가격에 읽어옵니다.
무엇이고 왜 필요한가 #
Claude API는 호출할 때마다 입력 전체에 대해 토큰 단위로 요금을 매깁니다. 같은 매뉴얼·코드·시스템 프롬프트를 매 호출마다 다시 보내고 있다면, 변하지 않는 부분에 대해서도 매번 100% 가격을 지불하고 있는 셈입니다.
Prompt Caching은 단골 식당이 메뉴를 미리 외워두는 것과 같습니다. 첫 호출 때 Claude가 자료를 “외우고”, 그 다음 호출들은 외운 부분을 다시 읽기만 합니다.
가격 구조 (입력 토큰 1개 가격을 1배라고 할 때) #
| 동작 | 가격 |
|---|---|
| 캐시 만들기 (첫 호출) | 1.25배 |
| 캐시 읽기 (5분 안의 두 번째 호출부터) | 0.1배 ← 90% 절감 |
| 1시간 유지 옵션 | 만들기 2배 / 읽기 동일 0.1배 |
즉, 같은 자료를 5분 안에 두 번만 써도 이미 절감입니다. 자주 호출할수록 효과가 커집니다.
실제 사용 사례 3가지 #
비용·코드를 함께 보면 어느 상황에서 효과적인지 직관적으로 파악할 수 있습니다.
시나리오 1: 회사 정책 챗봇 (HR 봇) #
상황: 사내 직원이 “환불 정책”, “휴가 신청”, “출장비 규정” 등 회사 매뉴얼 관련 질문을 챗봇에게 합니다. 매뉴얼은 약 50,000토큰(A4 약 100장).
코드:
import anthropic
client = anthropic.Anthropic()
COMPANY_MANUAL = open("company_manual.txt").read() # 50,000토큰 분량
def ask_hr_bot(user_question: str):
response = client.messages.create(
model="claude-opus-4-7",
max_tokens=1024,
# system을 블록 배열로 두고, 매뉴얼 블록에 캐시 표시
system=[
{"type": "text", "text": "당신은 회사 HR 비서입니다. 매뉴얼을 근거로 답하세요."},
{
"type": "text",
"text": COMPANY_MANUAL,
"cache_control": {"type": "ephemeral"} # ← 매뉴얼만 캐시
}
],
messages=[{"role": "user", "content": user_question}]
)
print(f"쓰기:{response.usage.cache_creation_input_tokens} 읽기:{response.usage.cache_read_input_tokens}")
return response.content[0].text
# 첫 호출 — 캐시 만듦 (1.25배 가격)
ask_hr_bot("환불 정책 알려줘")
# → 쓰기:50000 읽기:0
# 5분 안의 두 번째 호출 — 캐시 읽음 (0.1배 가격)
ask_hr_bot("휴가 신청은 어떻게 해?")
# → 쓰기:0 읽기:50000
# 1시간 안의 백 번째 호출 — 여전히 캐시 읽음
ask_hr_bot("출장비 규정?")
# → 쓰기:0 읽기:50000월 비용 비교 (질문 1만 회 / 매뉴얼 50,000토큰 / Opus 4.7 입력 $5/MTok 가정):
| 방식 | 계산 | 월 비용 |
|---|---|---|
| 캐싱 없음 | 10,000회 × 50,000토큰 × $5/MTok | $2,500 |
| 5분 캐싱 | 첫 호출 1.25배 + 나머지 0.1배 | 약 $250 (90% 절감) |
시나리오 2: 코드 리뷰 어시스턴트 #
상황: GitHub 저장소 코드 전체(약 100,000토큰)를 컨텍스트에 올려두고, 같은 코드에 대해 여러 질문(이 함수 뭐 해?, 버그 찾아줘, 리팩토링 제안)을 합니다.
코드:
import os
def load_codebase(repo_path: str) -> str:
"""저장소의 모든 .py 파일을 하나의 문자열로 합치기"""
chunks = []
for root, _, files in os.walk(repo_path):
for f in files:
if f.endswith(".py"):
path = os.path.join(root, f)
chunks.append(f"--- {path} ---\n{open(path).read()}\n")
return "\n".join(chunks)
CODEBASE = load_codebase("./my_project") # 약 100,000토큰
def review_code(question: str):
return client.messages.create(
model="claude-opus-4-7",
max_tokens=2048,
system=[
{"type": "text", "text": "당신은 시니어 코드 리뷰어입니다."},
{
"type": "text",
"text": f"분석 대상 코드베이스:\n\n{CODEBASE}",
"cache_control": {"type": "ephemeral", "ttl": "1h"} # ← 1시간 캐싱
}
],
messages=[{"role": "user", "content": question}]
)
# 한 시간 안에 자유롭게 여러 질문 — 첫 호출만 비싸고 나머지는 0.1배
review_code("auth.py의 login_user 함수에 보안 취약점이 있나?")
review_code("이 코드베이스의 핵심 모듈 3개와 의존성을 그려줘")
review_code("models.py를 리팩토링한다면 어떤 순서로 할까?")왜 1시간 옵션을 썼나요? 코드 리뷰는 일반적으로 한 세션에 5분 이상 걸리고, 질문 사이 텀이 있을 수 있어 5분 캐시가 자주 만료됩니다. 1시간 캐시는 만들 때 2배지만, 한 세션 안에 여러 질문을 하면 훨씬 경제적입니다.
시나리오 3: 멀티턴 RAG 챗봇 (대화 누적) #
상황: RAG(Retrieval-Augmented Generation, 검색 증강 생성) 챗봇. 사용자와 여러 턴 대화하면서 대화 기록이 누적됩니다. 시스템 프롬프트(고정) + 검색된 문서(고정) + 대화 기록(점점 길어짐).
코드:
SYSTEM_PROMPT = "(긴 안내 프롬프트 5,000토큰)"
RETRIEVED_DOCS = "(검색된 관련 문서 30,000토큰)"
conversation = [] # 점점 늘어남
def chat(user_message: str):
conversation.append({"role": "user", "content": user_message})
response = client.messages.create(
model="claude-opus-4-7",
max_tokens=1024,
system=[
{"type": "text", "text": SYSTEM_PROMPT},
{
"type": "text",
"text": RETRIEVED_DOCS,
"cache_control": {"type": "ephemeral"} # ← 검색 문서까지 캐시
}
],
messages=conversation
)
assistant_reply = response.content[0].text
conversation.append({"role": "assistant", "content": assistant_reply})
return assistant_reply
# 첫 호출: 시스템 + 문서 35,000토큰 캐시 만듦 (1.25배)
chat("환불 신청은 어떻게 해?")
# 두 번째 호출: 시스템 + 문서는 캐시 읽음 (0.1배), 대화 기록만 새로 입력
chat("환불 처리 기간은?")
# 열 번째 호출: 여전히 시스템 + 문서는 0.1배. 대화 기록만 누적
chat("결제 수단별로 차이 있어?")효과: 대화가 길어질수록 캐시 절감 효과가 누적됩니다. 시스템+문서 35,000토큰이 매번 0.1배로 처리되니까요.
가격을 직접 계산해보기 #
월 청구액이 얼마나 줄어드는지 시뮬레이션 (Opus 4.7 입력 $5/MTok 기준):
| 시나리오 | 자료 크기 | 월 호출 | 캐싱 없음 | 캐싱 적용 | 절감액 |
|---|---|---|---|---|---|
| HR 챗봇 | 50K 토큰 | 10,000회 | $2,500 | $250 | $2,250 |
| 코드 리뷰 | 100K 토큰 | 1,000회 | $500 | $51 | $449 |
| RAG 챗봇 | 35K 토큰 | 50,000회 | $8,750 | $876 | $7,874 |
💡 절감액이 가장 큰 건 자주 호출되는 챗봇. 호출 빈도가 높을수록 캐시 효과가 누적됩니다.
함정 / 주의사항 #
⚠️ 함정 1: 짧은 자료는 캐시 안 됨 #
각 모델마다 최소 캐시 가능 토큰 수가 있습니다.
| 모델 | 최소 토큰 |
|---|---|
| Opus 4.7 / 4.6 / 4.5, Sonnet 4.6, Haiku 4.5 | 4096 |
| Sonnet 4.5, Opus 4.1 이하 | 1024 |
| Haiku 3.5 | 2048 |
미만이면 에러 없이 캐싱이 그냥 스킵됩니다. “캐시 켰는데 비용이 안 줄어드네?” 싶다면 가장 흔한 원인.
확인 방법: response.usage.cache_creation_input_tokens 와 cache_read_input_tokens 둘 다 0이면 캐싱 미적용. 자료 크기를 늘리세요.
💡 약 4000자 = 2000
3000토큰. 즉 **A4 23장 분량 이상**이어야 안전합니다.
⚠️ 함정 2: 자료를 조금만 바꿔도 캐시 무효 #
캐시는 글자 단위로 같아야 유효합니다. 한 글자만 바뀌어도 새 캐시를 만듭니다.
가장 흔한 실수: 캐시할 블록 안에 타임스탬프나 사용자 이름처럼 매번 바뀌는 값을 섞기.
# ❌ 잘못된 예 — 변하는 값이 캐시 블록 안에 섞임
system = [{
"type": "text",
"text": f"오늘은 {today}. 회사 매뉴얼: ...",
"cache_control": {"type": "ephemeral"}
}]
# → "오늘은 ..." 부분이 매일 바뀌어서 캐시가 매일 재생성됨
# ✅ 올바른 예 — 변하는 값은 메시지로, 고정 자료만 캐시
system = [{
"type": "text",
"text": "회사 매뉴얼: ...",
"cache_control": {"type": "ephemeral"}
}]
messages = [{"role": "user", "content": f"오늘은 {today}. 환불 정책 알려줘"}]⚠️ 함정 3: 도구 정의를 바꾸면 모든 캐시가 날아감 #
tools=[...]에서 도구 하나라도 추가·수정하면 시스템·메시지 캐시까지 전부 무효화됩니다. Tools → System → Messages 순서로 무효화가 전파됩니다.
캐시 효율을 유지하려면 도구 정의는 가능한 한 안정적으로 유지하세요. 자주 바꿔야 한다면 도구 정의를 별도 캐시 계층으로 분리하는 게 좋습니다.
캐시 동작 검증하기 #
캐시가 실제로 작동하는지 확인하는 가장 정확한 방법:
response = client.messages.create(...)
# response.usage 안에 캐시 통계가 들어있음
print(f"캐시 만든 토큰: {response.usage.cache_creation_input_tokens}")
print(f"캐시 읽은 토큰: {response.usage.cache_read_input_tokens}")
print(f"일반 입력 토큰: {response.usage.input_tokens}")정상 동작 패턴 #
- 첫 호출:
cache_creation> 0,cache_read= 0 → 캐시 만들기 성공 - 두 번째 호출:
cache_creation= 0,cache_read> 0 → 캐시 읽기 성공 - 둘 다 0: 캐싱 미적용 → 최소 토큰 미달 또는 cache_control 위치 문제
디버깅 팁 #
캐시가 안 먹힐 때 체크할 순서:
- 캐시할 자료가 4096토큰 이상인가? (
response.usage.input_tokens로 추정 가능) cache_control을 블록 안에 정확히 박았는가? (블록 외부에 두면 무시됨)- 두 번째 호출이 5분 안에 들어갔는가? (5분 지나면 캐시 만료)
- 도구 정의가 바뀌지 않았는가?
비교 / 대안 #
| 도구 | 언제 효과적 | 한 줄 비유 |
|---|---|---|
| Prompt Caching | 같은 자료를 자주 재사용 | 단골 식당 (재방문 할인) |
| Batch Processing | 같은 자료를 한꺼번에 1000개 처리 | 단체 주문 할인 |
| Token Counting | 호출 전 비용 미리 측정 | 주문 전 가격 확인 |
Caching과 Batch는 보완 관계입니다. “자주 + 실시간"은 Caching, “한꺼번에 + 비실시간"은 Batch. Token Counting은 둘 다 시작하기 전 비용 예측용으로 함께 씁니다 (시리즈 #3에서).
단계별 도입 가이드 — 체크리스트 #
이미 운영 중인 Claude 챗봇에 캐싱 도입할 때 순서:
- 1단계 — 후보 식별: 가장 자주 호출되는 엔드포인트의 system 프롬프트가 4096토큰 이상인가?
- 2단계 — 코드 수정:
system을 블록 배열로 바꾸고 캐시할 블록에cache_control한 줄 추가 - 3단계 — 검증:
cache_creation_input_tokens/cache_read_input_tokens출력해서 두 번째 호출에서 읽기가 0보다 큰지 확인 - 4단계 — 함정 회피: 캐시 블록 안에 타임스탬프·사용자명 같은 변하는 값 없는지 점검
- 5단계 — 비용 측정: 일주일 후 청구액 비교. 보통 50~90% 감소
- 다음에 익히면 좋을 관련 기능: Batch Processing(#2) — 캐싱이 “재방문 할인"이라면 Batch는 “단체 주문 할인”
한 마디 #
처음 캐싱을 적용했을 때 가장 인상 깊은 순간은 API 청구서가 줄어드는 것을 처음 본 날입니다. 큰 매뉴얼이나 RAG 문서가 들어가는 챗봇이라면 월 청구액이 절반 이하로 떨어지는 경험을 하게 됩니다. cache_control 한 줄 추가의 가성비가 이만큼 좋은 기능은 흔치 않습니다.
한 가지 더 — 처음 적용 시 캐싱이 안 먹히는 것처럼 보여도 당황하지 마세요. 99%의 경우 함정 1(최소 토큰 미달) 또는 함정 2(변하는 값 섞임) 둘 중 하나입니다. response.usage만 찍어보면 5분 안에 진단됩니다.
Claude API 공식 문서를 한국어로 풀어쓴 시리즈입니다. 원문 정확성이 가장 우선, 의역은 보조.