프롬프트 캐싱 체크포인트 자동 주입

프롬프트 캐싱 체크포인트 자동 주입

LiteLLM을 사용해 프롬프트 캐싱 체크포인트를 자동 주입해서 비용을 최대 90% 절감할 수 있어요.

cache_control 마커를 지원하는 제공자:

  • Anthropic API (anthropic/)
  • AWS Bedrock - Claude (bedrock/)
  • Vertex AI - Claude and Gemini (vertex_ai/)
  • Google AI Studio - Gemini (gemini/)
  • Azure AI - Claude (azure_ai/)
  • OpenRouter - Claude, Gemini, MiniMax, GLM, z-ai routes (openrouter/)
  • Databricks - Claude (databricks/)
  • DashScope / Qwen (dashscope/)
  • MiniMax (minimax/)
  • Z.ai / GLM (zai/)

prompt_cache_breakpoint 마커를 지원하는 제공자:

  • OpenAI GPT-5.6 and newer (openai/), see OpenAI GPT-5.6 and newer

Provider Managed(자동, 마커 불필요):

  • OpenAI, models before GPT-5.6 (openai/)
  • DeepSeek (deepseek/)
  • xAI (xai/)

동작 방식

LiteLLM은 LLM 제공자에 보내는 요청에 프롬프트 캐싱 체크포인트를 자동으로 주입할 수 있어요. 이를 통해:

  • 비용 절감: 프롬프트의 길고 정적인 부분을 캐싱해 반복 처리를 피할 수 있어요.
  • 애플리케이션 코드 수정 불필요: 자동 캐싱 동작을 LiteLLM UI나 litellm config.yaml 파일에서 구성할 수 있어요.

캐시를 누구와 공유하나

이것은 제공자 측 프롬프트 캐싱으로, LiteLLM 응답 캐싱과는 다른 기능이에요. Redis가 필요 없습니다.

  • 제공자는 upstream credentials(상류 자격 증명)를 기준으로 프리픽스를 캐싱하며, LiteLLM 키, 팀, 최종 사용자 기준이 아니에요.
  • 그 프리픽스를 정확히 반복하는 누구든 재사용합니다. 이 공유가 요점이에요: 한 사용자가 캐싱한 긴 시스템 프롬프트를 같은 자격 증명의 다른 사람이 모두 재사용하고, 에이전트는 사용자가 이미 캐싱한 프리픽스를 활용하죠.
  • 반대 측면: 응답은 cache_read_input_tokens를 보고하며, 캐시 히트는 더 빠르므로 프리픽스를 정확히 반복하는 호출자는 그 자격 증명의 다른 사람이 최근에 보냈음을 알 수 있어요.
  • 그것은 제한적입니다. 프리픽스는 정확히 일치해야 하고, 제공자는 최소 크기 미만의 프리픽스를 캐싱하지 않으므로(Anthropic의 경우 모델에 따라 다르며 현재 1k~4k 토큰), 호출자가 이미 보유한 프롬프트가 보내졌는지 여부만 드러내지 내용은 드러내지 않아요.
  • 격리를 위해 테넌트에 별도 자격 증명을 주세요. 경계는 LiteLLM이 시행할 수 있는 것이 아니라 제공자 계정입니다.

Claude 모델을 위한 자동 체크포인트

info

LiteLLM v1.94.0 필요

아래 모든 내용은 체크포인트를 어디에 둘지 결정하라고 요구합니다. Claude의 흔한 경우만 필요하다면 플래그 하나로 해결됩니다.

config.yaml

litellm_settings:
  enable_anthropic_prompt_caching: true

또는 설정 파일 없이:

export LITELLM_ENABLE_ANTHROPIC_PROMPT_CACHING=true

이것은 Admin UI의 Router Settings 아래 General 탭의 스위치이기도 합니다.

실제로 무엇을 하는가

직접 작성했을 cache_control_injection_points를 추가해, 시스템 프롬프트에 하나, 마지막 턴에 하나를 넣어 안정적인 프리픽스가 캐싱되면서 체크포인트가 대화와 함께 진행되게 합니다. 이것이 Claude Code 같은 클라이언트가 필요로 하는 것이죠. cache_control을 스스로 설정하지 않기 때문이에요.

  • 기본적으로 꺼짐. 업그레이드는 활성화할 때까지 아무것도 바꾸지 않아요.
  • Claude 전용. 비용 맵이 프롬프트 캐싱을 지원한다고 표시하는 anthropic/bedrock/ 모델만 해당. vertex_ai/azure_ai/의 Claude는 적용되지 않으므로 cache_control_injection_points를 사용하세요.
  • 절대 이중 주입하지 않음. 요청이 이미 자체 cache_control을 가지고 있으면 LiteLLM은 물러나 클라이언트의 체크포인트가 이깁니다.
  • 명시적 설정이 우선. 플래그는 cache_control_injection_points가 설정되지 않았을 때만 채워집니다.
  • 4블록 제공자 한도 존중. 클라이언트 제공 블록도 한도에 포함해 계산합니다.
  • /v1/messages/chat/completions에서 동작.

캐시 수명

기본값은 Anthropic의 5분 임시 캐시로, Anthropic API 기본값이며 Claude Code가 사용하는 값이에요. 긴 에이전트 세션에서는 대신 1시간 캐시를 요청할 수 있습니다:

config.yaml

litellm_settings:
  enable_anthropic_prompt_caching: true
  anthropic_prompt_caching_ttl: "1h"

해당 환경 변수는 LITELLM_ANTHROPIC_PROMPT_CACHING_TTL이고, Admin UI는 드롭다운으로 노출합니다. 1시간 캐시 쓰기는 5분 것보다 비싸므로, 프리픽스를 더 긴 세션에서 재사용할 때만 가치가 있어요.

둘 다 설정되면 litellm_settings가 환경 변수보다 우선합니다. 설정이 시작 후 적용되기 때문이에요.

주입 지점을 대신 사용해야 할 때

아래 설명하는 cache_control_injection_points는 플래그가 다루지 않는 제공자, 시스템 프롬프트와 마지막 턴이 아닌 곳의 체크포인트, 게이트웨이 전체가 아닌 모델별 동작, 또는 도구 정의를 캐싱하기 위한 location: tool_config가 필요할 때 사용하세요.

구성

모델 구성에 cache_control_injection_points를 지정해야 해요. 이것은 LiteLLM에 다음을 알려줍니다:

  • 캐싱 지시문을 어디에 추가할지(location)
  • 어떤 메시지를 대상으로 할지(role)

그러면 LiteLLM이 요청의 지정된 메시지에 cache_control 지시문을 자동으로 추가합니다:

cache_control_directive.json

"cache_control": {
    "type": "ephemeral"
}

구성된 지점은 요청이 이미 지니고 있는 cache_control 옆에 추가됩니다. 클라이언트가 직접 표시한 메시지는 그대로 두고, 요청을 Anthropic의 4개 캐시 블록 한도를 넘게 할 지점은 클라이언트 표시를 먼저 계산한 뒤 건너뜁니다(도구 포함).

OpenAI GPT-5.6 및 이후 버전

같은 cache_control_injection_points가 배포가 명시적 프롬프트 캐시 브레이크포인트를 지원하는 OpenAI 모델로 해석될 때도 동작합니다. 비용 맵이 이를 supports_prompt_cache_breakpoint(GPT-5.6과 그 이후 openai/ 모델)로 표시해요. LiteLLM은 들어오는 요청의 형태가 아니라 해석된 배포를 보므로, 하나의 설정 패턴으로 Anthropic과 OpenAI가 섞인 fleet을 다루고 Anthropic 형태 클라이언트가 /v1/messages로 오는 경우에도 OpenAI 마커를 받습니다.

| Anthropic target | OpenAI GPT-5.6+ target | | "cache_control": {"type": "ephemeral"} on the targeted block | "prompt_cache_breakpoint": {"mode": "explicit"} on the targeted block | | nothing at the request level | "prompt_cache_options": {"mode": "explicit"} at the request root | | control.ttl picks the 5m or 1h cache | control is ignored; set prompt_cache_options yourself for ttl |

LiteLLM이 추가하는 요청 수준 prompt_cache_options는 OpenAI를 명시적 모드로 전환하므로, 구성된 체크포인트가 전체 캐싱 전략이 됩니다(Anthropic에서와 정확히 같음). 요청에 이미 있는 prompt_cache_options가 이기고 절대 덮어쓰지 않으며, 이것이 배포별로 모드를 바꾸거나 30분 캐시를 요청하는 방법이에요:

config.yaml

model_list:
  - model_name: gpt-5.6
    litellm_params:
      model: openai/gpt-5.6
      api_key: os.environ/OPENAI_API_KEY
      cache_control_injection_points:
        - location: message
          role: system
      prompt_cache_options:
        mode: implicit
        ttl: 30m

mode: implicit면 OpenAI는 LiteLLM이 놓은 명시적 체크포인트 옆에 최신 사용자 또는 도구 메시지의 자동 체크포인트를 유지하는데, 이는 긴 다중 턴 세션에 맞고, 기본 explicit에서는 구성된 체크포인트만 캐시에 쓰기 때문에 하나의 긴 시스템 프롬프트를 공유하는 많은 단일 턴 요청에 맞아요. 어느 쪽이든 OpenAI는 매치할 수 있는 가장 긴 캐시 프리픽스에서 읽기를 제공합니다.

OpenAI 매핑에 대해 알아야 할 점:

  • 블록 수준만. OpenAI는 텍스트, 이미지, 파일 블록에서 마커를 받아들입니다. 문자열 시스템 프롬프트나 메시지는 마커를 놓기 전에 한 블록 목록으로 감쌉니다. 어시스턴트 블록과 도구 결과는 브레이크포인트를 가질 수 없으므로 거기에 떨어지는 주입 지점은 건너뜁니다.
  • /v1/messages 시스템 프롬프트. OpenAI는 최상위 instructions 필드에 브레이크포인트를 받아들이지 않으므로, Anthropic system이 체크포인트를 지니면 LiteLLM은 이를 선행 developer 메시지로 보냅니다. OpenAI는 두 형태를 같은 캐시 프리픽스로 취급하므로 전환해도 캐시가 콜드 스타트하지 않아요.
  • 클라이언트 마커 옆에 적용. 자체 cache_control 또는 prompt_cache_breakpoint 마커를 이미 지닌 요청은 그것을 유지하고 구성된 지점이 그 옆에 추가됩니다. 클라이언트가 이미 표시한 대상은 그대로 둡니다. Claude Code는 자체 cache_control을 설정하는데 OpenAI는 이를 결코 보지 않으므로, 구성된 지점이 있는 GPT-5.6 배포의 Claude Code 세션은 구성한 명시적 체크포인트로 실행됩니다. 그 배포에 prompt_cache_options: {mode: implicit}를 설정하면 OpenAI의 자동 체크포인트를 옆에 유지할 수 있어요.
  • 4 브레이크포인트 한도 존중. 클라이언트 제공 마커를 먼저 계산하므로 구성된 지점이 다섯 번째가 되면 건너뜁니다.
  • OpenAI 자체로 가는 요청에만. 배포가 api.openai.com(또는 리전별 *.api.openai.com 호스트)과 통신할 때(GPT-5.6 이상 OpenAI 모델, 항목이 지니면 비용 맵의 supports_prompt_cache_breakpoint 플래그, 아니라면 모델 이름의 GPT 버전 기준) 매핑이 발동합니다. 즉 api_base(또는 base_url)가 없거나 그 호스트들에 있을 때예요. 커스텀 api_base로 다른 LiteLLM proxy나 OpenAI 앞의 게이트웨이를 쓰는 배포는, litellm_paramsprompt_cache_options도 설정해 옵트인하지 않는 한 현재 동작을 유지합니다. litellm_proxy/ 배포와 Azure OpenAI 배포는 아직 적용되지 않아요.
  • /v1/responses. 마커는 대상 메시지의 input_text 블록에 놓이고, 문자열 메시지는 먼저 한 블록 목록으로 감쌉니다. OpenAI는 최상위 instructions 필드에 마커를 받아들이지 않으므로 거기에 보내는 시스템 프롬프트는 암시적 캐싱에 남습니다. 체크포인트를 얻으려면 developer 또는 system 메시지로 보내세요. 클라이언트가 보내는 prompt_cache_options는 그대로 전달됩니다.
  • 비용 보고는 불변. OpenAI의 cached_tokenscache_write_tokens는 이미 /v1/messages에서 cache_read_input_tokenscache_creation_input_tokens로, /chat/completions에서 prompt_tokens_details로 돌아옵니다.

LiteLLM Python SDK 사용법

completion 호출에서 cache_control_injection_points 파라미터를 사용해 캐싱 지시문을 자동 주입하세요.

기본 예시 - 시스템 메시지 캐싱

cache_system_messages.py

from litellm import completionimport osos.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,
                },
            ],
        },
        {
            "role": "user",
            "content": "what are the key terms and conditions in this agreement?",
        },
    ],
    # Auto-inject cache control to system messages
    cache_control_injection_points=[
        {
            "location": "message",
            "role": "system",
        }
    ],
)print(response.usage)

핵심 포인트:

  • cache_control_injection_points 파라미터로 캐싱 주입 위치를 지정하세요.
  • location: "message"는 대화의 메시지를 대상으로 해요.
  • role: "system"은 모든 시스템 메시지를 대상으로 해요.
  • LiteLLM은 일치하는 메시지의 마지막 콘텐츠 블록cache_control을 자동으로 추가합니다(Anthropic API 스펙에 따라).

LiteLLM의 수정된 요청:

LiteLLM은 시스템 메시지의 마지막 콘텐츠 블록에 cache_control을 추가해 요청을 자동 변환합니다:

modified_request_system.json

{
    "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...",
                    "cache_control": {"type": "ephemeral"}  // Added by LiteLLM
                }
            ]
        },
        {
            "role": "user",
            "content": "what are the key terms and conditions in this agreement?"
        }
    ]
}

인덱스로 특정 메시지 대상 지정

messages 배열에서 인덱스로 특정 메시지를 대상으로 할 수 있어요. 음수 인덱스를 사용하면 끝에서부터 대상으로 합니다.

cache_by_index.py

from litellm import completionimport osos.environ["ANTHROPIC_API_KEY"] = ""response = completion(
    model="anthropic/claude-sonnet-5",
    messages=[
        {
            "role": "user",
            "content": "First message",
        },
        {
            "role": "assistant",
            "content": "Response to first",
        },
        {
            "role": "user",
            "content": [
                {"type": "text", "text": "Here is a long document to analyze:"},
                {"type": "text", "text": "Document content..." * 500},
            ],
        },
    ],
    # Target the last message (index -1)
    cache_control_injection_points=[
        {
            "location": "message",
            "index": -1,  # -1 targets the last message, -2 would target second-to-last, etc.
        }
    ],
)print(response.usage)

중요 참고:

  • 메시지에 여러 콘텐츠 블록(이미지나 여러 텍스트 블록)이 있으면 cache_control마지막 콘텐츠 블록에만 추가됩니다.
  • 이것은 Anthropic API 스펙을 따른 것인데, "여러 콘텐츠 블록을 사용할 때는 마지막 콘텐츠 블록만 cache_control을 가질 수 있다"고 요구합니다.
  • Anthropic은 요청당 cache_control이 있는 블록이 최대 4개입니다.

LiteLLM의 수정된 요청:

LiteLLM은 대상 메시지의 마지막 콘텐츠 블록(index -1 = 마지막 메시지)에 cache_control을 추가합니다:

modified_request_index.json

{
    "messages": [
        {
            "role": "user",
            "content": "First message"
        },
        {
            "role": "assistant",
            "content": "Response to first"
        },
        {
            "role": "user",
            "content": [
                {
                    "type": "text",
                    "text": "Here is a long document to analyze:"
                },
                {
                    "type": "text",
                    "text": "Document content...",
                    "cache_control": {"type": "ephemeral"}  // Added by LiteLLM to last content block only
                }
            ]
        }
    ]
}

LiteLLM Proxy 사용법

프록시 구성 파일에서 캐시 제어 주입을 구성할 수 있어요.

  • litellm config.yaml
  • LiteLLM UI

litellm config.yaml

model_list:
  - model_name: anthropic-auto-inject-cache-system-message
    litellm_params:
      model: anthropic/claude-sonnet-5
      api_key: os.environ/ANTHROPIC_API_KEY
      cache_control_injection_points:
        - location: message
          role: system
  - model_name: gpt-5.6
    litellm_params:
      model: openai/gpt-5.6
      api_key: os.environ/OPENAI_API_KEY
      cache_control_injection_points:
        - location: message
          role: system

두 번째 항목은 OpenAI GPT-5.6 모델로 해석되므로 같은 주입 지점이 나가는 요청에서 prompt_cache_breakpoint 마커와 prompt_cache_options가 됩니다(위의 OpenAI GPT-5.6 및 이후 버전 참조).

LiteLLM UI에서는 모델을 추가할 때 Advanced Settings 탭에서 cache_control_injection_points를 지정할 수 있어요.

상세 예시

1. LiteLLM에 대한 원본 요청

이 예시에서 매우 길고 정적인 시스템 메시지와 변화하는 사용자 메시지가 있습니다. 자주 바뀌지 않으므로 시스템 메시지를 캐싱하는 것이 효율적이에요.

original_request.json

{
    "messages": [
        {
            "role": "system",
            "content": [
                {
                    "type": "text",
                    "text": "You are a helpful assistant. This is a set of very long instructions that you will follow. Here is a legal document that you will use to answer the user's question."
                }
            ]
        },
        {
            "role": "user",
            "content": [
                {
                    "type": "text",
                    "text": "What is the main topic of this legal document?"
                }
            ]
        }
    ]
}

2. LiteLLM의 수정된 요청

LiteLLM은 설정에 따라 시스템 메시지에 캐싱 지시문을 자동 주입합니다:

modified_request.json

{
    "messages": [
        {
            "role": "system",
            "content": [
                {
                    "type": "text",
                    "text": "You are a helpful assistant. This is a set of very long instructions that you will follow. Here is a legal document that you will use to answer the user's question.",
                    "cache_control": {"type": "ephemeral"}
                }
            ]
        },
        {
            "role": "user",
            "content": [
                {
                    "type": "text",
                    "text": "What is the main topic of this legal document?"
                }
            ]
        }
    ]
}

모델 제공자가 이 요청을 처리할 때 캐싱 지시문을 인식하고 시스템 메시지를 한 번만 처리해 후속 요청을 위해 캐싱합니다.

3. OpenAI GPT-5.6 배포에서 같은 요청

배포가 대신 openai/gpt-5.6을 가리키면 같은 구성이 블록에 OpenAI의 명시적 브레이크포인트를, 요청 루트에 명시적 모드를 생성합니다:

modified_request_openai.json

{
    "prompt_cache_options": {"mode": "explicit"},
    "messages": [
        {
            "role": "system",
            "content": [
                {
                    "type": "text",
                    "text": "You are a helpful assistant. This is a set of very long instructions that you will follow. Here is a legal document that you will use to answer the user's question.",
                    "prompt_cache_breakpoint": {"mode": "explicit"}
                }
            ]
        },
        {
            "role": "user",
            "content": [
                {
                    "type": "text",
                    "text": "What is the main topic of this legal document?"
                }
            ]
        }
    ]
}

관련 문서

  • Manual Prompt Caching - 메시지에 cache_control 지시문을 수동으로 추가하는 방법 알아보기

더 알아보기 (Learn more)