k
korAI
고급 전체
🔥 고급2026-06-255~7분

Prompt Caching 캐시 무효화 패턴: 히트율 90% 이상 유지하는 설계 전략

Anthropic Prompt Caching은 잘못 설계하면 히트율이 20% 이하로 떨어진다. 캐시 레이아웃 원칙과 무효화 트리거를 제어해 비용과 지연을 동시에 줄이는 운영 전략을 다룬다.

prompt-cachingcost-optimizationobservability

왜 캐시 히트율이 낮아지는가

Prompt Caching은 cache_control: {type: 'ephemeral'} 블록을 기준으로 prefix를 캐싱한다. 캐시 수명은 5분이며, prefix가 1토큰이라도 바뀌면 캐시 미스가 발생한다. 흔한 실패 모드는 세 가지다.

  1. 동적 콘텐츠를 캐시 앞에 배치 — 타임스탬프, 요청 ID, 사용자 이름을 system prompt 상단에 넣으면 매 요청마다 prefix가 달라진다.
  2. 캐시 경계를 여러 곳에 분산cache_control을 3개 이상 선언하면 Anthropic은 가장 긴 prefix 하나만 캐싱하므로 의도와 다르게 동작한다.
  3. 5분 TTL을 무시한 배치 설계 — 배치 간격이 6분이면 캐시가 매번 콜드 스타트된다.

캐시 레이아웃 설계 원칙

불변 → 준불변 → 가변 순서로 배치하는 것이 핵심이다.

  • 불변: 시스템 역할 정의, 도메인 지식 문서, 툴 스키마 전체 → 여기에만 cache_control 1개 부착
  • 준불변: 세션 내 대화 히스토리 (세션 단위 캐시가 필요하면 두 번째 cache_control 추가)
  • 가변: 현재 사용자 메시지, 실시간 컨텍스트

아래는 올바른 레이아웃 예시다.

import anthropic

client = anthropic.Anthropic()

SYSTEM_DOCS = """[500줄 분량의 도메인 지식 문서]"""

def call_with_cache(user_message: str, history: list[dict]) -> str:
    response = client.messages.create(
        model="claude-opus-4-5",
        max_tokens=1024,
        system=[
            {
                "type": "text",
                "text": SYSTEM_DOCS,
                "cache_control": {"type": "ephemeral"}  # 불변 블록에만 1개
            }
        ],
        messages=[
            *history,  # 준불변: 히스토리
            {"role": "user", "content": user_message}  # 가변
        ]
    )
    usage = response.usage
    hit = usage.cache_read_input_tokens
    miss = usage.cache_creation_input_tokens
    print(f"캐시 히트: {hit}tok / 미스(생성): {miss}tok")
    return response.content[0].text

cache_read_input_tokens이 0이면 미스다. 첫 요청은 항상 미스(캐시 워밍)이고 두 번째부터 히트가 발생한다.

수치 트레이드오프

| 시나리오 | 입력 비용 비율 | 지연 변화 | |---|---|---| | 캐시 미스 (캐시 생성) | 기본 가격 × 1.25 | +10~20% | | 캐시 히트 | 기본 가격 × 0.10 | -30~50% | | 히트율 90% 달성 시 전체 절감 | ~85% | 지연 개선 동반 |

캐시 생성 비용이 기본보다 25% 높으므로, 히트율 60% 미만이면 캐싱이 오히려 손해다. 최소 목표는 70% 이상이다.

운영 체크리스트

  • [ ] cache_control 블록이 전체 messages에서 2개 이하인지 확인
  • [ ] 불변 system 블록이 요청마다 바이트 단위로 동일한지 해시 비교
  • [ ] cache_read_input_tokens / (cache_read + cache_creation) 비율을 메트릭으로 기록
  • [ ] 5분 TTL 안에 트래픽이 재도달하는지 p95 요청 간격 모니터링
  • [ ] 타임스탬프·요청 ID는 반드시 user 메시지 또는 별도 변수로 분리