Prompt Caching 캐시 무효화 전략: TTL·버전 해시·비용 회수 설계
Anthropic Prompt Caching은 잘못 설계하면 캐시 히트율 0%로 수렴한다. 캐시 경계 배치, 버전 해시 기반 무효화, 비용 회수 시뮬레이션까지 운영 관점에서 정리한다.
왜 캐시 히트율이 낮은가
Prompt Caching은 cache_control: {type: 'ephemeral'} 마커 이전 토큰이 동일할 때만 캐시를 재사용한다. 실패하는 가장 흔한 패턴은 동적 콘텐츠를 캐시 경계 앞에 두는 것이다. 예를 들어 system prompt 앞부분에 timestamp나 user_id를 주입하면 매 요청마다 캐시가 깨진다. Anthropic 공식 문서 기준으로 캐시 최소 토큰 수는 Claude 3.5 기준 1,024 토큰이며, 이 이하는 캐싱 자체가 적용되지 않는다.
캐시 TTL은 5분(beta 기준)이다. 요청 간격이 5분을 초과하면 캐시 재작성 비용(write)이 발생한다. 캐시 write는 일반 입력 토큰 대비 25% 추가 비용, read는 90% 절감이다. 따라서 히트율이 78% 미만이면 캐싱이 오히려 손해다. (write_cost × miss_rate) < (read_savings × hit_rate) 부등식으로 손익분기를 사전에 계산해야 한다.
버전 해시 기반 무효화 설계
시스템 프롬프트가 배포마다 바뀌는 환경에서는 컨텐츠 해시를 메타데이터로 추적해야 한다. 프롬프트 변경 시 의도적으로 캐시를 무효화하고 새 write를 유도한다.
import anthropic
import hashlib
client = anthropic.Anthropic()
SYSTEM_PROMPT = """당신은 결제 도메인 전문 어시스턴트입니다.
[...1500토큰 이상의 도메인 지식...]"""
prompt_hash = hashlib.sha256(SYSTEM_PROMPT.encode()).hexdigest()[:8]
response = client.messages.create(
model="claude-opus-4-5",
max_tokens=1024,
system=[
{
"type": "text",
"text": SYSTEM_PROMPT,
"cache_control": {"type": "ephemeral"}
}
],
messages=[{"role": "user", "content": "환불 정책 설명해줘"}],
extra_headers={"anthropic-beta": "prompt-caching-2024-07-31"}
)
usage = response.usage
cache_hit = usage.cache_read_input_tokens > 0
print(f"prompt_hash={prompt_hash} | cache_hit={cache_hit} | "
f"write={usage.cache_creation_input_tokens} | "
f"read={usage.cache_read_input_tokens}")
이 해시를 로깅 시스템에 인덱싱하면 배포 단위로 캐시 write 이벤트를 추적할 수 있다. Datadog 등에서 cache_hit 비율을 알람으로 걸어 히트율이 60% 아래로 떨어지면 캐시 경계 설계를 재검토하도록 트리거한다.
운영 체크리스트
- [ ] 시스템 프롬프트 앞부분에 동적 값(timestamp, request_id) 절대 금지
- [ ] 캐시 경계 이전 토큰 수 ≥ 1,024 검증 (배포 시 단위 테스트)
- [ ] 요청 간격 분포 측정 → 평균 간격 > 4분이면 캐싱 비효율 경고
- [ ]
cache_creation_input_tokens/cache_read_input_tokens비율 모니터링 - [ ] 히트율 78% 미만 시 손익분기 재계산 후 캐싱 비활성화 검토
- [ ] 프롬프트 버전 해시를 로그에 포함하여 배포-캐시 write 상관관계 추적