Contents
see ListClaude API 프롬프트 캐싱이란?
Anthropic의 Claude API는 프롬프트 캐싱(Prompt Caching) 기능을 통해 동일한 컨텍스트를 반복 전송하는 비용을 획기적으로 줄여준다. 자주 사용하는 시스템 프롬프트, 긴 문서, 도구 정의(tool definitions)를 한 번 캐시해두면 이후 요청에서 최대 90%의 비용 절감과 85%의 지연 시간 단축 효과를 얻을 수 있다.
2024년 말 일반 공개(GA)된 이후 개발자 커뮤니티에서 가장 주목받는 API 기능 중 하나가 되었으며, 2026년 2월부터는 캐시 격리 단위가 조직(organization) 수준에서 워크스페이스(workspace) 수준으로 변경되어 더 세밀한 관리가 가능해졌다.
캐싱 동작 원리
프롬프트 캐싱은 요청 본문에 cache_control 필드를 추가하는 방식으로 동작한다. Claude는 캐시 가능한 블록 중 마지막 블록을 기준으로 캐시를 자동 생성하며, 대화가 길어질수록 캐시 포인트를 앞으로 이동시켜 관리한다.
캐시 TTL(Time To Live)은 기본 5분이며, 추가 비용을 지불하면 1시간 TTL을 선택할 수 있다. 1시간 TTL 옵션은 이제 별도의 베타 헤더 없이 일반 요청에서 사용 가능하다.
기본 사용법
import anthropic
client = anthropic.Anthropic()
# 시스템 프롬프트를 캐시하는 예제
response = client.messages.create(
model="claude-opus-4-5",
max_tokens=1024,
system=[
{
"type": "text",
"text": "당신은 Python 전문가입니다. 다음은 프로젝트 전체 코드입니다:\n\n" + long_codebase,
"cache_control": {"type": "ephemeral"} # 캐시 포인트 지정
}
],
messages=[
{"role": "user", "content": "이 코드에서 버그를 찾아주세요."}
]
)
print(response.usage) # cache_creation_input_tokens, cache_read_input_tokens 확인도구 정의(Tool Definitions) 캐싱
도구 정의는 캐시 계층 구조의 최상단에 위치한다. 도구 목록을 변경하면 하위의 모든 캐시가 무효화되므로, 전체 도구 집합을 한 번에 정의하고 일관되게 유지하는 것이 중요하다.
tools = [
{
"name": "get_weather",
"description": "특정 위치의 날씨 정보를 가져옵니다.",
"input_schema": {
"type": "object",
"properties": {
"location": {"type": "string", "description": "도시명"}
},
"required": ["location"]
}
},
# 추가 도구들...
]
response = client.messages.create(
model="claude-opus-4-5",
max_tokens=1024,
tools=tools,
# 마지막 도구 정의에 cache_control 추가
# tools 배열 자체에는 cache_control을 직접 추가 불가
# 대신 system prompt와 함께 캐싱 전략 수립
system=[
{
"type": "text",
"text": "당신은 날씨 정보 어시스턴트입니다.",
"cache_control": {"type": "ephemeral"}
}
],
messages=[{"role": "user", "content": "서울 날씨는?"}]
)캐시 무효화 주의사항
다음과 같은 경우 캐시가 무효화된다:
- 시스템 프롬프트에 현재 날짜/시간 등 동적 값이 포함된 경우.
"현재 날짜: 2026-04-12"형태의 문자열이 자정에 바뀌면 캐시 전체가 무효화된다. 이러한 동적 정보는 user message로 이동시켜야 한다. - JSON 직렬화 시 키 순서가 매번 달라지는 경우. 언어/라이브러리에 따라 JSON 객체의 키 순서가 랜덤으로 바뀔 수 있으므로, 키 순서를 고정해야 한다.
- 도구 정의가 요청마다 다른 경우. 전체 도구 집합을 상수로 정의하고 재사용해야 한다.
멀티턴 대화에서의 캐싱
conversation_history = []
def chat(user_message: str) -> str:
conversation_history.append({
"role": "user",
"content": user_message
})
response = client.messages.create(
model="claude-opus-4-5",
max_tokens=2048,
system=[
{
"type": "text",
"text": LARGE_SYSTEM_PROMPT, # 변경되지 않는 긴 시스템 프롬프트
"cache_control": {"type": "ephemeral"}
}
],
messages=conversation_history
)
assistant_message = response.content[0].text
conversation_history.append({
"role": "assistant",
"content": assistant_message
})
# 캐시 통계 출력
usage = response.usage
print(f"캐시 생성: {usage.cache_creation_input_tokens} 토큰")
print(f"캐시 읽기: {usage.cache_read_input_tokens} 토큰")
return assistant_message비용 계산 예시
claude-opus-4-5 기준으로 1,000,000 토큰짜리 시스템 프롬프트를 100번 요청한다고 가정하면:
- 캐싱 미사용: 100 * 1,000,000 * $15/1M = $1,500
- 캐싱 사용 (캐시 생성 1회 + 캐시 읽기 99회): $15 + 99 * $1.5 = $163.5
- 절감액: 약 89% 비용 절감
워크스페이스 격리 (2026년 2월 변경사항)
2026년 2월 5일부터 프롬프트 캐싱의 격리 단위가 조직(organization) 수준에서 워크스페이스(workspace) 수준으로 변경되었다. 같은 조직 내에서도 워크스페이스가 다르면 캐시를 공유하지 않으므로, 대규모 팀에서는 캐시 히트율을 최적화하기 위해 워크스페이스 구성을 전략적으로 설계해야 한다.
캐싱 적용 체크리스트
프롬프트 캐싱을 효과적으로 활용하기 위한 체크리스트:
- 시스템 프롬프트에서 동적 값(날짜, 사용자 ID 등)을 user message로 분리했는가?
- 도구 정의를 상수로 고정하고 매 요청마다 동일하게 전달하는가?
- JSON 직렬화 시 키 순서가 일관되게 유지되는가?
- cache_read_input_tokens를 모니터링하여 캐시 히트율을 측정하고 있는가?
- TTL 요구사항에 맞춰 5분 vs 1시간 옵션을 적절히 선택했는가?