블로그 목록으로
가이드·2026년 5월 24일·8분 분량

Anthropic 프롬프트 캐싱 — 30분 만에 입력 비용을 90% 절감하기

전체 내용: cache_control 작동 방식, OpenAI 형식에서 Kunavo가 중단 지점을 대신 설정해야 하는 이유, 에이전트 루프를 위한 4개 중단 지점 패턴, 캐싱을 조용히 중단시키는 요인, 적중률이 0이 아닌지 확인하는 방법. 모델별 Kunavo 캐시 요금도 포함합니다.

긴 시스템 프롬프트를 보내고 있다면(RAG 컨텍스트, 도구 카탈로그, 에이전트 규칙, 예시 등) 매 호출마다 입력 비용을 전액 지불하고 있을 가능성이 큽니다. Anthropic의 프롬프트 캐싱을 사용하면 캐시된 부분은 요금의 10%로 낮아집니다. OpenAI도 암묵적으로 동일한 기능을 제공합니다. 대부분의 팀은 30분 정도의 작업으로 입력 비용을 안정적으로 60–90% 줄일 수 있어 투자할 가치가 있다고 판단합니다.

Kunavo는 두 방식 모두 처리합니다. 자체 cache_control 중단점은 Messages API를 통해 변경 없이 전달됩니다. 해당 필드를 보낼 형식이 없는 Chat Completions 및 Responses API에서는 Kunavo가 대신 설정하고, 사용자가 보낸 내용 주변을 보충하되 상한 4를 절대 초과하지 않습니다. 이 글에서는 두 방식과 캐시를 조용히 무효화하는 함정, 적중률 확인 방법을 설명합니다.

전후 비교

동일한 18K-token 시스템 프롬프트를 열 번 보내는 단순한 루프:

naive.py
# What most people start with: every call re-pays for the whole prompt.
import anthropic

client = anthropic.Anthropic(
    api_key="sk-kn-...",
    base_url="https://api.kunavo.com",
)

SYSTEM = open("system-prompt.md").read()        # 18,000 tokens of rules + examples

# 10 user questions in a session. Every call sends the 18K-token system block.
for question in questions:
    resp = client.messages.create(
        model="claude-sonnet-4-6",
        max_tokens=600,
        system=SYSTEM,
        messages=[{"role": "user", "content": question}],
    )

# Cost per call (input only): 18,000 × $3 / 1M = $0.054
# 10 calls: $0.54 in input alone.

이제 시스템 블록을 캐시 가능으로 표시합니다. 필드 하나만 추가하면 됩니다:

cached.py
# The fix: mark the static prefix as cacheable. After the first call,
# subsequent calls within ~5 minutes pay 10% the input rate on the cached
# portion. Same answer, 89% cheaper.
resp = client.messages.create(
    model="claude-sonnet-4-6",
    max_tokens=600,
    system=[
        {
            "type": "text",
            "text": SYSTEM,
            "cache_control": {"type": "ephemeral"},  # mark cacheable
        }
    ],
    messages=[{"role": "user", "content": question}],
)

# First call (cache write):  18,000 × $3.75 / 1M = $0.0675  (1.25× input)
# Calls 2–10 (cache hit):    18,000 × $0.30 / 1M = $0.0054 each
# Total: $0.0675 + 9 × $0.0054 = $0.116  (was $0.54 — 78.5% saved)

이 세션에서 입력 비용의 78.5%를 절약했습니다. 첫 호출은 실제로 단순한 버전보다 약간 더 비쌉니다(캐시 기록을 위해 입력 요금의 약 1.25배). 2~10번째 호출은 요금의 10%만 지불합니다. 손익분기점은 2번째 호출이며, 3번째 호출 때는 이미 비용을 절약하고 있습니다. 10번째에는 큰 차이가 납니다.

OpenAI 방식: 할 일이 없음

OpenAI Chat Completions 형식에는 cache_control 필드가 없습니다. OpenAI가 자체 서버에서 암묵적으로 캐시하기 때문입니다. Claude는 그렇지 않으며 중단점으로 표시한 내용만 캐시합니다. 따라서 /v1/chat/completions 또는 /v1/responses를 통해 Claude 모델에 접근하면 Kunavo가 중단점을 대신 설정합니다. 대화에 assistant 턴이 하나 이상 있으면 마지막 메시지에 순환 중단점을 하나 설정하고, system 뒤와 tools 뒤에도 하나씩 설정합니다. 직접 설정한 항목은 정확히 그 위치에 그대로 두며 Kunavo는 비워 둔 위치만, 최대 4개까지 채웁니다. 설정할 것은 없고 Anthropic 경로와 OpenAI 경로 중 어느 쪽으로 들어오든 같은 모델의 비용은 동일합니다:

openai_style.py
# OpenAI Chat Completions style — Kunavo sets the breakpoints for you.
# No flag to set. The "usage" object tells you what was cached.
from openai import OpenAI

client = OpenAI(
    api_key="sk-kn-...",
    base_url="https://api.kunavo.com/v1",
)

resp = client.chat.completions.create(
    model="claude-sonnet-4-6",
    messages=[
        {"role": "system", "content": LONG_SYSTEM_PROMPT},  # >1024 tokens
        {"role": "user", "content": "Latest question…"},
    ],
)

# In the response:
#   resp.usage.prompt_tokens_details.cached_tokens  →  17,800
#   resp.usage.prompt_tokens                        →  18,200
# 17.8K/18.2K = 98% of input came from cache. Bill reflects that automatically.

usage.prompt_tokens_details.cached_tokens를 읽어 캐시에서 얼마나 제공되었는지 확인하세요. 고정 접두사가 클수록 절약액도 커집니다. 일반적인 기준은 다음과 같습니다. 시스템 프롬프트가 가변 사용자 콘텐츠보다 짧다면 캐싱 효과가 크지 않습니다. 정적 부분을 앞쪽에 크게 배치하도록 프롬프트를 재구성하세요.

다층 캐싱 — 최대 4개 중단점

일부 계층이 다른 계층보다 빠르게 변경되는 에이전트 루프에서는 여러 cache_control 중단점을 설정하세요. 각 중단점은 해당 위치까지의 모든 내용을 담은 스냅샷입니다:

breakpoints.py
# Anthropic supports up to 4 cache breakpoints per request — use them
# to keep the cache hot even as later layers change.
client.messages.create(
    model="claude-sonnet-4-6",
    max_tokens=600,
    system=[
        {"type": "text",
         "text": ROLE_AND_RULES,                      # ~3,000 tokens
         "cache_control": {"type": "ephemeral"}},     # breakpoint 1
        {"type": "text",
         "text": LARGE_KNOWLEDGE_BASE,                # ~15,000 tokens, rarely changes
         "cache_control": {"type": "ephemeral"}},     # breakpoint 2
    ],
    messages=[
        {"role": "user",
         "content": [
             {"type": "text",
              "text": CONVERSATION_HISTORY,           # grows each turn
              "cache_control": {"type": "ephemeral"}}, # breakpoint 3
             {"type": "text", "text": new_question},
         ]},
    ],
)

# When CONVERSATION_HISTORY changes, breakpoints 1+2 still hit cache.
# Only breakpoint 3 + the new question pay full input rate.

캐시 키는 전체 접두사입니다. N 위치에 token을 하나 추가하면 N 이후의 모든 중단점이 무효화됩니다. 순서가 중요합니다. 가장 안정적인 콘텐츠를 먼저 배치하세요. 규칙 계층은 거의 바뀌지 않아야 하고, 지식 기반은 매주 업데이트되며, 대화는 매 턴마다 늘어납니다.

캐시를 조용히 깨뜨리는 일반적인 방법

  • 프롬프트에 현재 날짜나 request_id를 넣기. 호출마다 새로운 접두사가 되어 캐시 적중률이 0%가 됩니다. 프롬프트 입력을 해시하고 호출 간 결과를 비교하세요.
  • 비결정적인 시스템 프롬프트 조립. dict에서 시스템 프롬프트를 만들면 일부 Python 버전에서는 dict 순회 순서가 중요합니다. 키를 명시적으로 정렬하세요.
  • 캐시 수명은 약 5분. 10분마다 한 번 호출하는 희소 트래픽 패턴에서는 적중이 0회입니다. 호출을 일괄 처리하거나 손실을 받아들이세요.
  • 1,024-token 최소 기준. 1K token 미만에서는 OpenAI 방식의 캐싱이 작동하지 않습니다. 작은 정적 조각을 하나의 더 긴 접두사로 합치세요.
  • 도구 / 함수 정의는 접두사의 일부. 카탈로그에 새 도구를 추가하면 모든 사용자의 캐시가 무효화됩니다. 도구 카탈로그를 안정적으로 유지하고 버전을 관리하세요.

적중률 확인

확인할 수 없는 캐싱은 엔지니어링이 아니라 희망입니다. 모든 호출에서 usage를 기록하세요:

observe.py
# Always read usage. If cached_tokens is 0 when you expected a hit,
# something's wrong — usually a non-deterministic prefix.
resp = client.messages.create(...)
u = resp.usage
print({
    "input_uncached":  u.input_tokens,
    "input_cache_read": u.cache_read_input_tokens,
    "input_cache_write": u.cache_creation_input_tokens,
    "output": u.output_tokens,
})

# A common gotcha: putting today's date or a request_id in the system prompt
# silently invalidates the cache. Hash your inputs; verify cache_read_input_tokens
# is non-zero on the 2nd identical call.

Kunavo 대시보드의 Usage 페이지에는 모델별·일별 캐시 분할이 표시됩니다. cache_read_input_tokens가 전체 입력에서 차지하는 비율로 증가하면 캐싱이 작동하는 것입니다. 0에 머물거나 크게 변동하면 위의 함정 목록을 확인하세요.

Kunavo에서 실제로 드는 비용

모든 모델의 캐시 요금은 가격 페이지에 공개되어 있습니다:

  • Anthropic 모델: 캐시 읽기는 입력 요금의 10%입니다 — 2.5% on Claude Fable 5.1, 5% on Claude Opus 5.5. 캐시 쓰기는 입력 요금의 1.25배입니다. 이는 Anthropic의 5분 배율이며, Kunavo는 1시간 쓰기에도 동일한 1.25배를 적용합니다. Anthropic의 2배보다 낮습니다.
  • OpenAI / Gemini 모델: 캐시 읽기는 입력 요금의 10%입니다(공급업체가 공개한 비율). 캐시 쓰기는 GPT-5.6 및 GPT-6 Astra에서 1.25배이고, 그 외 모든 모델에서는 일반 입력 요금과 동일합니다.
  • 캐시된 모든 가격에는 Kunavo의 모델 할인이 이미 포함되어 있습니다(모델별 원본 제공업체의 표시 가격보다 낮음). 따라서 Kunavo에서 Sonnet 4.6 캐시 읽기는 $3 × 0.40 × 0.10 = $0.12 per 1M tokens입니다. 캐시되지 않은 원본 제공업체의 요금보다 약 25배 저렴합니다.

캐싱이 답이 아닌 경우

작업할 가치가 없는 몇 가지 경우:

  • 짧은 프롬프트(총 <1K token). 오버헤드가 더 크므로 굳이 사용하지 마세요.
  • 반복 트래픽이 없는 일회성 작업. 첫 호출은 약간 더 비싸며 캐싱은 2번째 호출부터 비용을 회수합니다.
  • 출력은 많고 입력은 적은 작업(창작 글쓰기, 코드 생성). 입력이 이미 청구액에서 작은 비중을 차지합니다. 대신 출력 예산 상한에 집중하세요.

그 외의 모든 경우, 즉 RAG 챗봇, 고정 도구 카탈로그를 사용하는 에이전트, 정적 기준표를 실행하는 분류기, 일관된 few-shot을 사용하는 구조화 추출 파이프라인에서는 캐싱이 단일 오후에 배포할 수 있는 가장 높은 ROI의 최적화입니다. 이를 비용 최적화 가이드의 다른 네 가지 기법과 함께 사용하면 출력 품질을 전혀 희생하지 않고도 70% 비용 절감이 현실적입니다.

이미 Kunavo를 사용 중인가요? /app/usage를 열고 가장 큰 모델의 캐시 열을 확인하세요. 0이라면 비용을 절약할 기회를 놓치고 있는 것입니다. 전체 가이드: /docs/caching.