프롬프트 캐싱

프롬프트 캐싱 (Prompt Caching)

지원 프로바이더:

  • OpenAI (openai/)
  • Anthropic API (anthropic/)
  • Google AI Studio (gemini/)
  • Vertex AI (vertex_ai/, vertex_ai_beta/)
  • Bedrock (bedrock/, bedrock/invoke/, bedrock/converse) (Bedrock이 프롬프트 캐싱을 지원하는 모든 모델)
  • Deepseek API (deepseek/)
  • xAI (xai/)

입력이 프로바이더의 최소값보다 낮으면 프롬프트 캐싱이 조용히 건너뛰어지며 오류는 반환되지 않습니다. 응답의 cache_creation_input_tokens 을 확인해 캐싱이 실제로 발생했는지 항상 검증하세요.

프로바이더 최소 입력 토큰
OpenAI 1,024
Anthropic (Claude 3.x) 1,024
Anthropic (Claude Sonnet/Opus 4.x) 2,048
Anthropic (Claude Haiku 4.5+, Opus 4.5+) 4,096
Bedrock (Claude 3.5, 3.7) 1,024
Bedrock (Claude Sonnet 4.x) 2,048
Google Gemini 1,024

지원 프로바이더의 경우 LiteLLM은 OpenAI 프롬프트 캐싱 사용량 객체 형식을 따릅니다:

"usage": {
  "prompt_tokens": 2006,
  "completion_tokens": 300,
  "total_tokens": 2306,
  "prompt_tokens_details": {
    "cached_tokens": 1920
  },
  "completion_tokens_details": {
    "reasoning_tokens": 0
  }
  # ANTHROPIC_ONLY #
  "cache_creation_input_tokens": 0
}
  • prompt_tokens : 이는 cache-miss와 cache-hit 입력 토큰을 모두 포함한 모든 프롬프트 토큰.
  • completion_tokens : 모델이 생성한 출력 토큰.
  • total_tokens : prompt_tokens + completion_tokens 의 합.
  • prompt_tokens_details : cached_tokens 를 포함하는 객체. cached_tokens : 그 호출에서 cache-hit된 토큰.
  • completion_tokens_details : reasoning_tokens 을 포함하는 객체.
  • ANTHROPIC_ONLY : cache_creation_input_tokens 은 캐시에 기록된 토큰 수. (Anthropic은 이를 청구합니다)

빠른 시작

참고: OpenAI 캐싱은 1024개 이상의 토큰이 포함된 프롬프트에서만 사용 가능합니다.

  • SDK
  • PROXY
from litellm import completion 
import os

os.environ["OPENAI_API_KEY"] = ""

for _ in range(2):
    response = completion(
        model="gpt-5.6-terra",
        messages=[
            # System Message
            {
                "role": "system",
                "content": [
                    {
                        "type": "text",
                        "text": "Here is the full text of a complex legal agreement"
                        * 400,
                    }
                ],
            },
            {
                "role": "user",
                "content": [
                    {
                        "type": "text",
                        "text": "What are the key terms and conditions in this agreement?",
                    }
                ],
            },
            {
                "role": "assistant",
                "content": "Certainly! the key terms and conditions are the following: the contract is 1 year long for $10/mo",
            },
            {
                "role": "user",
                "content": [
                    {
                        "type": "text",
                        "text": "What are the key terms and conditions in this agreement?",
                    }
                ],
            },
        ],
        temperature=0.2,
        max_tokens=10,
    )

print("response=", response)
print("response.usage=", response.usage)

assert "prompt_tokens_details" in response.usage
assert response.usage.prompt_tokens_details.cached_tokens > 0
  1. config.yaml 설정
model_list:
    - model_name: gpt-5.6-terra
      litellm_params:
        model: openai/gpt-5.6-terra
        api_key: os.environ/OPENAI_API_KEY
  1. 프록시 시작
litellm --config /path/to/config.yaml
  1. 테스트!
from openai import OpenAI
import os

client = OpenAI(
    api_key="LITELLM_PROXY_KEY", # sk-<your-litellm-api-key>
    base_url="LITELLM_PROXY_BASE" # http://0.0.0.0:4000
)

for _ in range(2):
    response = client.chat.completions.create(
        model="gpt-5.6-terra",
        messages=[
            # System Message
            {
                "role": "system",
                "content": [
                    {
                        "type": "text",
                        "text": "Here is the full text of a complex legal agreement"
                        * 400,
                    }
                ],
            },
            {
                "role": "user",
                "content": [
                    {
                        "type": "text",
                        "text": "What are the key terms and conditions in this agreement?",
                    }
                ],
            },
            {
                "role": "assistant",
                "content": "Certainly! the key terms and conditions are the following: the contract is 1 year long for $10/mo",
            },
            {
                "role": "user",
                "content": [
                    {
                        "type": "text",
                        "text": "What are the key terms and conditions in this agreement?",
                    }
                ],
            },
        ],
        temperature=0.2,
        max_tokens=10,
    )

print("response=", response)
print("response.usage=", response.usage)

assert "prompt_tokens_details" in response.usage
assert response.usage.prompt_tokens_details.cached_tokens > 0

OpenAI prompt_cache_key 및 prompt_cache_retention

OpenAI 프롬프트 캐싱은 자동입니다. cache_control 메시지 주석이 필요 없어요. 1024개 이상의 프롬프트 토큰이 있는 요청은 캐싱 대상입니다.

OpenAI는 캐싱 동작을 더 제어하기 위한 두 가지 선택 파라미터도 지원합니다:

  • prompt_cache_key (string): 긴 공통 접두사를 공유하는 요청의 캐시 적중률을 개선하는 라우팅 힌트. 같은 캐시 키를 가진 요청은 같은 백엔드로 라우팅되어 캐시 적중 가능성을 높입니다.

  • prompt_cache_retention ("in_memory" 또는 "24h"): 캐시 TTL을 제어합니다. 기본은 "in_memory"(5~10분). KV 텐서를 GPU 로컬 저장소로 오프로드하는 확장 캐싱에는 "24h" 로 설정.

  • SDK

  • PROXY

from litellm import completion
import os

os.environ["OPENAI_API_KEY"] = ""

response = completion(
    model="gpt-5.6-terra",
    messages=[
        {
            "role": "system",
            "content": "You are an AI assistant tasked with analyzing legal documents. "
            + "Here is the full text of a complex legal agreement " * 400,
        },
        {
            "role": "user",
            "content": "What are the key terms and conditions?",
        },
    ],
    prompt_cache_key="legal-doc-analysis",
    prompt_cache_retention="24h",
)
print(response.usage)
from openai import OpenAI

client = OpenAI(
    api_key="LITELLM_PROXY_KEY",
    base_url="LITELLM_PROXY_BASE",
)

response = client.chat.completions.create(
    model="gpt-5.6-terra",
    messages=[
        {
            "role": "system",
            "content": "You are an AI assistant tasked with analyzing legal documents. "
            + "Here is the full text of a complex legal agreement " * 400,
        },
        {
            "role": "user",
            "content": "What are the key terms and conditions?",
        },
    ],
    extra_body={
        "prompt_cache_key": "legal-doc-analysis",
        "prompt_cache_retention": "24h",
    },
)
print(response.usage)

OpenAI 명시적 브레이크포인트 (GPT-5.6 이상)

GPT-5.6 이상은 명시적 캐시 브레이크포인트도 허용합니다: 콘텐츠 블록의 prompt_cache_breakpoint 마커 + 모드를 고르는 요청 수준 prompt_cache_options(implicit 은 최신 메시지에 대한 OpenAI 자동 브레이크포인트를 함께 유지, explicit 은 당신 것만 사용) 및 캐시 ttl(30m). LiteLLM은 /chat/completions, /responses, 그리고 Anthropic 형태 클라이언트를 위한 /v1/messages 에서 둘 다 패스스루합니다. 이 마커를 허용하는 모델은 비용 맵에 supports_prompt_cache_breakpoint: true 를 담고, 맵이 아직 플래그하지 않은 GPT-5.6 이상 OpenAI 모델 이름은 같은 방식으로 취급됩니다. 배포 config에서 LiteLLM이 대신 마커를 배치하게 하려면 auto-inject 튜토리얼 참고.

  • SDK
  • PROXY
from litellm import completion
import os

os.environ["OPENAI_API_KEY"] = ""

response = completion(
    model="openai/gpt-5.6",
    messages=[
        {
            "role": "system",
            "content": [
                {
                    "type": "text",
                    "text": "You are an AI assistant tasked with analyzing legal documents. "
                    + "Here is the full text of a complex legal agreement " * 400,
                    "prompt_cache_breakpoint": {"mode": "explicit"},
                }
            ],
        },
        {
            "role": "user",
            "content": "What are the key terms and conditions?",
        },
    ],
    prompt_cache_options={"mode": "explicit", "ttl": "30m"},
)
print(response.usage.prompt_tokens_details)
from openai import OpenAI

client = OpenAI(
    api_key="LITELLM_PROXY_KEY",
    base_url="LITELLM_PROXY_BASE",
)

response = client.responses.create(
    model="gpt-5.6",
    input=[
        {
            "type": "message",
            "role": "developer",
            "content": [
                {
                    "type": "input_text",
                    "text": "You are an AI assistant tasked with analyzing legal documents. "
                    + "Here is the full text of a complex legal agreement " * 400,
                    "prompt_cache_breakpoint": {"mode": "explicit"},
                }
            ],
        },
        {
            "type": "message",
            "role": "user",
            "content": [{"type": "input_text", "text": "What are the key terms and conditions?"}],
        },
    ],
    extra_body={"prompt_cache_options": {"mode": "explicit", "ttl": "30m"}},
)
print(response.usage.input_tokens_details)

출처: 문서

본문

Anthropic 예시

Anthropic은 캐시 쓰기를 청구합니다.

캐시할 콘텐츠를 "cache_control": {"type": "ephemeral"} 로 지정하세요.

이 같은 형식은 Gemini/Vertex AI 에서도 동작합니다. 다른 프로바이더에서는 무시됩니다.

  • SDK
  • PROXY
from litellm import completion 
import litellm 
import os 

litellm.set_verbose = True # 👈 SEE RAW REQUEST
os.environ["ANTHROPIC_API_KEY"] = "" 

response = completion(
    model="anthropic/claude-sonnet-5",
    messages=[
        {
            "role": "system",
            "content": [
                {
                    "type": "text",
                    "text": "You are an AI assistant tasked with analyzing legal documents.",
                },
                {
                    "type": "text",
                    "text": "Here is the full text of a complex legal agreement" * 400,
                    "cache_control": {"type": "ephemeral"},
                },
            ],
        },
        {
            "role": "user",
            "content": "what are the key terms and conditions in this agreement?",
        },
    ]
)

print(response.usage)
  1. config.yaml 설정
model_list:
    - model_name: claude-sonnet-5
      litellm_params:
        model: anthropic/claude-sonnet-5
        api_key: os.environ/ANTHROPIC_API_KEY
  1. 프록시 시작
litellm --config /path/to/config.yaml
  1. 테스트!
from openai import OpenAI 
import os

client = OpenAI(
    api_key="LITELLM_PROXY_KEY", # sk-<your-litellm-api-key>
    base_url="LITELLM_PROXY_BASE" # http://0.0.0.0:4000
)

response = client.chat.completions.create(
    model="claude-sonnet-5",
    messages=[
        {
            "role": "system",
            "content": [
                {
                    "type": "text",
                    "text": "You are an AI assistant tasked with analyzing legal documents.",
                },
                {
                    "type": "text",
                    "text": "Here is the full text of a complex legal agreement" * 400,
                    "cache_control": {"type": "ephemeral"},
                },
            ],
        },
        {
            "role": "user",
            "content": "what are the key terms and conditions in this agreement?",
        },
    ]
)

print(response.usage)

최소값보다 낮은 프롬프트는 캐싱 없이 처리되며 오류는 반환되지 않습니다. 응답의 cache_creation_input_tokens 을 확인하세요.

모델 최소 토큰
Claude 3 Haiku, 3 Sonnet, 3 Opus 1,024
Claude 3.5 Sonnet, 3.7 Sonnet 1,024
Claude 3.5 Haiku 2,048
Claude Sonnet 4.5, Sonnet 4.6, Opus 4 2,048
Claude Haiku 4.5, Opus 4.5+ 4,096

Bedrock 예시

LiteLLM은 OpenAI 형식의 cache_control 마커를 Bedrock 네이티브 cachePoint 형식으로 자동 변환하므로, 이미 cache_control 을 사용 중이라면 기존 코드에 변경이 필요 없습니다.

최소값보다 낮은 프롬프트는 캐싱 없이 처리되며 오류는 반환되지 않습니다. 응답의 cache_creation_input_tokens 을 확인하세요.

모델 계열 요청당 최소 토큰
Claude 3.5 Sonnet v2, Claude 3.7 Sonnet 1,024
Claude Sonnet 4.5, Sonnet 4.6 2,048
  • SDK
  • PROXY
import litellm

response = litellm.completion(
    model="bedrock/us.anthropic.claude-sonnet-5",
    messages=[
        {
            "role": "system",
            "content": [
                {
                    "type": "text",
                    "text": "<your large system prompt here — min 1,024 tokens for Claude 3.x, 2,048 for Claude Sonnet 4.x>",
                    "cache_control": {"type": "ephemeral"}
                }
            ]
        },
        {"role": "user", "content": "What is prompt caching?"}
    ]
)

print(response.usage)
# cache_creation_input_tokens > 0 on first call (cache written)
# cache_read_input_tokens > 0 on subsequent calls (cache hit)
  1. config.yaml 설정
model_list:
  - model_name: bedrock-claude-sonnet
    litellm_params:
      model: bedrock/us.anthropic.claude-sonnet-5
  1. 프록시 시작
litellm --config /path/to/config.yaml
  1. 테스트!
curl -X POST http://localhost:4000/chat/completions \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $LITEL..._KEY" \
  -d '{
    "model": "bedrock-claude-sonnet",
    "messages": [
      {
        "role": "system",
        "content": [
          {
            "type": "text",
            "text": "<your large system prompt here — min 1,024 tokens for Claude 3.x, 2,048 for Claude Sonnet 4.x>",
            "cache_control": {"type": "ephemeral"}
          }
        ]
      },
      {"role": "user", "content": "What is prompt caching?"}
    ]
  }'

지원되는 Bedrock 모델:

모델 Bedrock Model ID 최소 토큰 TTL 옵션
Claude 3.5 Sonnet v2 anthropic.claude-3-5-sonnet-20241022-v2:0 1,024 5 min, 1 hour
Claude 3.7 Sonnet anthropic.claude-3-7-sonnet-20250219-v1:0 1,024 5 min, 1 hour
Claude Opus 4 anthropic.claude-opus-4-20250514-v1:0 1,024 5 min, 1 hour
Claude Sonnet 4.5, 4.6 us.anthropic.claude-sonnet-4-5-*, us.anthropic.claude-sonnet-4-6-* 2,048 5 min, 1 hour

크로스 리전 추론 프로파일도 위 모델에서 지원됩니다.

전체 지원 모델과 리전 목록은 AWS Bedrock 프롬프트 캐싱 문서 참고.

Google AI Studio / Vertex AI (Gemini) 예시

같은 Anthropic 스타일 cache_control 형식을 사용하세요. LiteLLM이 이를 Google의 context caching API 로 자동 변환합니다.

내부 동작 원리:

  1. cache_control이 있는 메시지를 분리해 Google의 cachedContents API로 전송
  2. 캐시된 콘텐츠 ID를 Gemini 요청 본문의 cachedContent 로 전달
  3. 세 프로바이더 모두에서 동작: gemini/ (Google AI Studio), vertex_ai/, vertex_ai_beta/
  4. 캐시된 콘텐츠의 최소 1024 토큰 필요. 그 이하는 캐싱이 조용히 건너뜀
  • SDK
  • PROXY
from litellm import completion
import os

os.environ["GEMINI_API_KEY"] = ""

response = completion(
    model="gemini/gemini-3.8-flash",
    messages=[
        {
            "role": "system",
            "content": [
                {
                    "type": "text",
                    "text": "You are an AI assistant tasked with analyzing legal documents.",
                },
                {
                    "type": "text",
                    "text": "Here is the full text of a complex legal agreement" * 400,
                    "cache_control": {"type": "ephemeral"},
                },
            ],
        },
        {
            "role": "user",
            "content": "what are the key terms and conditions in this agreement?",
        },
    ],
)

print(response.usage)

Proxy/OpenAI SDK 사용법도 위 Anthropic 예시와 같은 패턴을 따릅니다.

Vertex AI

Vertex AI는 vertex_ai/ 접두사를 사용하세요:

  • SDK
  • PROXY
from litellm import completion

response = completion(
    model="vertex_ai/gemini-3.8-flash",
    vertex_project="my-gcp-project",
    vertex_location="us-central1",
    messages=[
        {
            "role": "system",
            "content": [
                {
                    "type": "text",
                    "text": "You are an AI assistant tasked with analyzing legal documents.",
                },
                {
                    "type": "text",
                    "text": "Here is the full text of a complex legal agreement" * 400,
                    "cache_control": {"type": "ephemeral"},
                },
            ],
        },
        {
            "role": "user",
            "content": "what are the key terms and conditions in this agreement?",
        },
    ],
)

print(response.usage)

Deepseek 예시

OpenAI와 동일하게 동작합니다.

from litellm import completion 
import litellm
import os 

os.environ["DEEPSEEK_API_KEY"] = "" 

litellm.set_verbose = True # 👈 SEE RAW REQUEST

model_name = "deepseek/deepseek-chat"
messages_1 = [
    {
        "role": "system",
        "content": "You are a history expert. The user will provide a series of questions, and your answers should be concise and start with `Answer:`",
    },
    {
        "role": "user",
        "content": "In what year did Qin Shi Huang unify the six states?",
    },
    {"role": "assistant", "content": "Answer: 221 BC"},
    {"role": "user", "content": "Who was the founder of the Han Dynasty?"},
    {"role": "assistant", "content": "Answer: Liu Bang"},
    {"role": "user", "content": "Who was the last emperor of the Tang Dynasty?"},
    {"role": "assistant", "content": "Answer: Li Zhu"},
    {
        "role": "user",
        "content": "Who was the founding emperor of the Ming Dynasty?",
    },
    {"role": "assistant", "content": "Answer: Zhu Yuanzhang"},
    {
        "role": "user",
        "content": "Who was the founding emperor of the Qing Dynasty?",
    },
]

message_2 = [
    {
        "role": "system",
        "content": "You are a history expert. The user will provide a series of questions, and your answers should be concise and start with `Answer:`",
    },
    {
        "role": "user",
        "content": "In what year did Qin Shi Huang unify the six states?",
    },
    {"role": "assistant", "content": "Answer: 221 BC"},
    {"role": "user", "content": "Who was the founder of the Han Dynasty?"},
    {"role": "assistant", "content": "Answer: Liu Bang"},
    {"role": "user", "content": "Who was the last emperor of the Tang Dynasty?"},
    {"role": "assistant", "content": "Answer: Li Zhu"},
    {
        "role": "user",
        "content": "Who was the founding emperor of the Ming Dynasty?",
    },
    {"role": "assistant", "content": "Answer: Zhu Yuanzhang"},
    {"role": "user", "content": "When did the Shang Dynasty fall?"},
]

response_1 = litellm.completion(model=model_name, messages=messages_1)
response_2 = litellm.completion(model=model_name, messages=message_2)

# Add any assertions here to check the response
print(response_2.usage)

비용 계산

cache-hit 프롬프트 토큰의 비용은 cache-miss 프롬프트 토큰과 다를 수 있습니다.

비용 계산에는 completion_cost() 함수를 사용하세요 (프롬프트 캐싱 비용 계산도 처리합니다). 더 많은 헬퍼 함수 참고.

cost = completion_cost(completion_response=response, model=model)

사용법

  • SDK
  • PROXY
from litellm import completion, completion_cost
import litellm 
import os 

litellm.set_verbose = True # 👈 SEE RAW REQUEST
os.environ["ANTHROPIC_API_KEY"] = "" 
model = "anthropic/claude-sonnet-5"
response = completion(
    model=model,
    messages=[
        {
            "role": "system",
            "content": [
                {
                    "type": "text",
                    "text": "You are an AI assistant tasked with analyzing legal documents.",
                },
                {
                    "type": "text",
                    "text": "Here is the full text of a complex legal agreement" * 400,
                    "cache_control": {"type": "ephemeral"},
                },
            ],
        },
        {
            "role": "user",
            "content": "what are the key terms and conditions in this agreement?",
        },
    ]
)

print(response.usage)

cost = completion_cost(completion_response=response, model=model) 

formatted_string = f"${float(cost):.10f}"
print(formatted_string)

LiteLLM은 계산된 비용을 응답 헤더 x-litellm-response-cost 로 반환합니다:

from openai import OpenAI
client = OpenAI(
    api_key="LITELLM_PROXY_KEY",   # sk-<your-litellm-api-key>..
    base_url="LITELLM_PROXY_BASE"   # http://0.0.0.0:4000
)
response = client.chat.completions.with_raw_response.create(
    messages=[
        {
            "role": "user",
            "content": "Say this is a test",
        }
    ],
    model="gpt-5.6-luna",
)
print(response.headers.get('x-litellm-response-cost'))
completion = response.parse()  # get the object that `chat.completions.create()` would have returned
print(completion)

모델 지원 확인

supports_prompt_caching() 으로 모델이 프롬프트 캐싱을 지원하는지 확인해요.

  • SDK
  • PROXY
from litellm.utils import supports_prompt_caching

supports_pc: bool = supports_prompt_caching(model="anthropic/claude-sonnet-5")

assert supports_pc

프록시의 모델이 프롬프트 캐싱을 지원하는지 확인하려면 /model/info 엔드포인트를 사용하세요. config.yaml에서 model_list 정의 후 프록시를 시작하고, curl -L -X GET 'http://0.0.0.0:4000/v1/model/info' -H "Authorization: Bearer ***" 를 호출합니다. 응답의 model_info"supports_prompt_caching": true 가 있는지 확인하세요.

이는 LiteLLM이 유지관리하는 모델 정보/비용 맵을 확인합니다.

더 읽기

LiteLLM이 코드를 수정하지 않고 cache_control 지시문을 자동으로 추가하길 원하시나요? Auto-Inject Prompt Caching Tutorial 에서 cache_control_injection_points 로 시스템 메시지, 인덱스로 특정 메시지, 또는 커스텀 주입 패턴을 자동 캐시하는 방법을 배우세요.

더 알아보기 (Learn more)