
Buforowanie promptów LLM: Obniż koszty API o 90% (Wszyscy 3 dostawcy)
Buforowanie promptów LLM pozwala na ponowne wykorzystanie wcześniej przetworzonych tokenów między wywołaniami API, obniżając koszty wejściowe nawet o 90% i skracając czas do pierwszego tokenu (TTFT) nawet o 85%. Jeśli przy każdym żądaniu wysyłasz ten sam prompt systemowy, definicje narzędzi lub przykłady few-shot, płacisz pełną cenę za pracę, którą GPU już wykonało.
Ten przewodnik omawia OpenAI, Anthropic i Gemini, implementując tego samego chatbota we wszystkich trzech SDK – czego nie robi żaden inny poradnik. Omówimy również aktualizację automatycznego buforowania Anthropic z lutego 2026 roku, rzeczywiste scenariusze kosztów produkcyjnych w dolarach oraz antywzorce, które cicho niszczą Twój wskaźnik trafień w cache (cache hit rate).
<!-- IMAGE: Schemat przepływu ponownego wykorzystania cache KV pokazujący dopasowanie prefiksu promptu, ścieżkę trafienia w cache (szybka, tania) i ścieżkę niepowodzenia (standardowe przetwarzanie) -->Szybkie podsumowanie: Wszyscy trzej dostawcy w pigułce
Zanim przejdziemy do szczegółów implementacji, oto pełne porównanie. Jeśli już wiesz, którego dostawcy używasz, przejdź do jego sekcji. Jeśli dokonujesz ewaluacji, ta tabela powie Ci wszystko w 10 sekund.
| Funkcja | OpenAI | Anthropic | Gemini |
|---|---|---|---|
| Typ buforowania | Automatyczne | Automatyczne + Jawne | Niejawne + Jawne |
| Minimalna liczba tokenów | 1024 | 1024 (większość modeli) | 1024 (Flash) / 4096 (Pro) |
| TTL (Czas życia) | 5-10 min (do 24h przy przedłużeniu) | 5 min lub 1 godzina | Konfigurowalny (domyślnie 1 godzina) |
| Koszt zapisu do cache | 1x (bez dodatkowych opłat) | 1.25x (5-min) / 2x (1-godz) | 1x (bez dodatkowych opłat) |
| Zniżka za odczyt z cache | 50% taniej za dane wejściowe | 90% taniej za dane wejściowe | ~90% taniej za dane wejściowe |
| Izolacja cache | Organizacja | Obszar roboczy (Workspace) | Projekt |
| Wsparcie streamingu | Tak | Tak | Tak |
| Pole odpowiedzi trafienia | cached_tokens | cache_read_input_tokens | cachedContentTokenCount |
| Jawna kontrola | Nie | Tak (cache_control) | Tak (nazwane obiekty cache) |
| Najnowsza duża aktualizacja | Październik 2024 | Luty 2026 (auto caching) | 2026 (niejawne buforowanie) |
Kluczowa wniosek: OpenAI jest najprostsze (zero konfiguracji, 50% zniżki). Anthropic oferuje największą zniżkę (90%) przy największej kontroli. Gemini oferuje konfigurowalny TTL i niejawne buforowanie w modelach 2.5+ ze zniżkami porównywalnymi do Anthropic.
Jak działa buforowanie promptów LLM?
Nie musisz rozumieć wnętrzności transformerów, aby skutecznie używać buforowania promptów. Musisz jednak zrozumieć jedną koncepcję: dopasowanie prefiksu.
Cache KV w 60 sekund
Gdy LLM przetwarza Twój prompt, oblicza stany uwagi (pary klucz-wartość) dla każdego tokenu. Te wpisy cache KV są kosztowną częścią – to one zużywają pamięć GPU i czas obliczeniowy. Buforowanie promptów przechowuje te obliczone stany, dzięki czemu kolejne żądanie z tym samym prefiksem całkowicie pomija ponowne obliczenia.
Kluczowym słowem jest prefiks. Cache dopasowuje od początku Twojego promptu do przodu. Jeśli pierwsze 2000 tokenów pasuje do wpisu w cache, ale token 2001 się różni, te pierwsze 2000 tokenów zostanie obsłużonych z cache. Wszystko po punkcie rozbieżności jest obliczane od nowa.
Dlatego kolejność w prompcie ma znaczenie. Strukturyzuj swoje prompty w ten sposób:
- Definicje narzędzi (najbardziej statyczne)
- Prompt systemowy
- Statyczne przykłady few-shot
- Pobrany kontekst (pół-dynamiczny)
- Historia rozmowy (rośnie z każdą turą)
- Zapytanie użytkownika (zawsze inne)
Treść statyczna na początku, dynamiczna na końcu. Im więcej tokenów pasuje do buforowanego prefiksu, tym większe oszczędności.
Buforowanie promptów vs buforowanie semantyczne vs buforowanie odpowiedzi
Te trzy terminy są często mylone. Buforowanie promptów (temat tego przewodnika) ponownie wykorzystuje obliczone stany KV na poziomie GPU dla identycznych prefiksów tokenów – zerowa utrata dokładności, taki sam wynik jak bez cache. Buforowanie semantyczne wykorzystuje podobność embeddingów do zwracania wcześniej wygenerowanych odpowiedzi dla „wystarczająco podobnych” zapytań – jest szybsze, ale może zwracać błędne odpowiedzi. Buforowanie odpowiedzi przechowuje dokładne pary wejście-wyjście i zwraca zbuforowaną odpowiedź dosłownie, działając tylko dla całkowicie identycznych żądań.
Buforowanie promptów to jedyna „darmowa optymalizacja” – redukuje koszty i opóźnienia bez żadnego kompromisu w zakresie dokładności. Dla głębokiej matematyki transformerów stojącej za buforowaniem KV, techniczne wyjaśnienie Hugging Face zmierzyło około 5,21-krotne przyspieszenie na GPU T4.
Jak OpenAI obsługuje buforowanie promptów?
Buforowanie promptów w OpenAI jest w pełni automatyczne. Od października 2024 roku każde wywołanie API z co najmniej 1024 tokenami wejściowymi automatycznie korzysta z buforowania. Nie musisz się zapisywać, nie dodajesz nagłówków, nie zmieniasz kodu.
Jak działa automatyczne buforowanie OpenAI
Gdy wysyłasz żądanie z co najmniej 1024 tokenami, OpenAI sprawdza, czy prefiks pasuje do niedawnego żądania z Twojej organizacji. Trafienia w cache kosztują 50% standardowej ceny tokenu wejściowego. Po przekroczeniu progu 1024 tokenów, cache dopasowuje w inkrementach po 128 tokenów.
Cache żyje przez 5-10 minut podczas normalnego użytkowania i może przetrwać do 24 godzin przy przedłużonym przechowywaniu w okresach mniejszego obciążenia. Jest ono ograniczone do poziomu organizacji, więc różne projekty w ramach tej samej organizacji korzystają ze wspólnych cache'ów.
Obsługiwane modele obejmują GPT-4o, GPT-4o-mini, GPT-4.1, o1, o3-mini i wszystkie nowsze modele.
Przykład Python SDK OpenAI
from openai import OpenAI
client = OpenAI()
# This system prompt is ~2,000 tokens -- well above the 1,024 minimum
SYSTEM_PROMPT = """You are a senior Python developer specializing in async programming.
You follow PEP 8, use type hints, and write comprehensive docstrings.
When reviewing code, check for: race conditions, resource leaks, error handling,
and performance bottlenecks. Always suggest specific fixes with code examples.
[... imagine 1,800 more tokens of coding guidelines, examples, and rules ...]"""
def chat(user_message: str) -> str:
response = client.chat.completions.create(
model="gpt-4o",
messages=[
{"role": "system", "content": SYSTEM_PROMPT},
{"role": "user", "content": user_message},
],
)
# Check if caching kicked in
usage = response.usage
cached = usage.prompt_tokens_details.cached_tokens
total_input = usage.prompt_tokens
print(f"Cached: {cached}/{total_input} tokens ({cached/total_input*100:.0f}%)")
return response.choices[0].message.content
# First call: cache miss (full price)
chat("Review this async function for race conditions...")
# Second call within 5-10 min: cache hit (50% off on cached tokens)
chat("Now optimize the same function for throughput...")Pierwsze wywołanie przetwarza wszystko w pełnej cenie i wypełnia cache. Drugie wywołanie ponownie wykorzystuje tokeny promptu systemowego z cache w połowie ceny. W danych wyjściowych zobaczysz coś w rodzaju Cached: 1920/2048 tokens (94%).
Werdykt: OpenAI jest najłatwiejsze na start, zero konfiguracji, buforowanie po prostu działa. Zniżka 50% jest najniższa spośród trzech dostawców, ale prostoty nie da się pokonać.
Jak Anthropic/Claude obsługuje buforowanie promptów?
Anthropic oferuje dwa tryby: automatyczne buforowanie (włączone domyślnie od lutego 2026) oraz jawne buforowanie z punktami przerwania cache_control. Liczba, której nie można ignorować, to fakt, że odczyty z cache kosztują tylko 10% standardowej ceny wejściowej, czyli 90% zniżki.
Automatyczne vs jawne buforowanie (Aktualizacja 2026)
Od 5 lutego 2026 roku Anthropic włącza automatyczne buforowanie domyślnie dla wszystkich kwalifikujących się promptów. Nie potrzebujesz już starego nagłówka beta. System automatycznie określa optymalne punkty przerwania cache.
Jawne buforowanie jest nadal dostępne, gdy chcesz mieć drobiazgową kontrolę. Umieszczasz cache_control: {"type": "ephemeral"} na konkretnych blokach treści, aby dokładnie zaznaczyć, gdzie powinna znajdować się granica cache. Jest to przydatne, gdy Twój prompt ma określoną strukturę i chcesz zagwarantować buforowanie pewnych sekcji.
Istnieją dwie opcje TTL:
- Cache 5-minutowy (domyślny): zapisy kosztują 1.25x podstawowej ceny wejściowej, odczyty kosztują 0.1x. Zwraca się po 1 trafieniu w cache.
- Cache 1-godzinny: zapisy kosztują 2x podstawowej ceny wejściowej, odczyty kosztują 0.1x. Zwraca się po 2 trafieniach w cache. Dostępne w modelach Claude 4.5+.
Izolacja cache zmieniła się z poziomu organizacji na poziom obszaru roboczego (workspace) 5 lutego 2026 roku. Oznacza to, że różne obszary robocze w ramach tej samej organizacji utrzymują oddzielne cache'e.
Pracując z buforowaniem Anthropic, pomaga strukturyzacja promptu pod kątem optymalnego buforowania, umieszczanie treści statycznych przed dynamicznymi jest tutaj jeszcze ważniejsze, ponieważ płacisz premię za zapis.
Przykład Python SDK Anthropic
import anthropic
client = anthropic.Anthropic()
SYSTEM_PROMPT = """You are a senior Python developer specializing in async programming.
You follow PEP 8, use type hints, and write comprehensive docstrings.
When reviewing code, check for: race conditions, resource leaks, error handling,
and performance bottlenecks. Always suggest specific fixes with code examples.
[... imagine 1,800 more tokens of coding guidelines, examples, and rules ...]"""
def chat(user_message: str) -> str:
response = client.messages.create(
model="claude-sonnet-4-5-20250514",
max_tokens=1024,
system=[
{
"type": "text",
"text": SYSTEM_PROMPT,
"cache_control": {"type": "ephemeral"}, # Explicit breakpoint
}
],
messages=[
{"role": "user", "content": user_message},
],
)
# Read cache metrics from the response
usage = response.usage
created = usage.cache_creation_input_tokens
read = usage.cache_read_input_tokens
standard = usage.input_tokens
print(f"Cache write: {created}, Cache read: {read}, Standard: {standard}")
return response.content[0].text
# First call: cache_creation_input_tokens = ~1920 (write at 1.25x)
chat("Review this async function for race conditions...")
# Second call: cache_read_input_tokens = ~1920 (read at 0.1x -- 90% off!)
chat("Now optimize the same function for throughput...")Zrozumienie cen zapisu do cache vs odczytu z cache
Tutaj cennik Anthropic staje się interesujący. Używając Claude Sonnet 4.5 (3 USD/MTok za dane wejściowe) jako przykładu:
- Standardowe wejście: 3,00 USD za milion tokenów
- Zapis do cache (5-min): 3,75 USD za milion tokenów (1.25x), płacisz więcej za pierwszym razem
- Odczyt z cache: 0,30 USD za milion tokenów (0.1x) -- 90% taniej przy każdym kolejnym trafieniu
Cache 5-minutowy zwraca się już po 1 odczycie. Cache 1-godzinny (6,00 USD/MTok za zapis) zwraca się po 2 odczytach. Jeśli wykonujesz więcej niż kilka żądań na minutę z tym samym prefiksem, matematyka jest przytłaczająco po Twojej stronie.
Werdykt: Anthropic oferuje największą zniżkę (90%) i największą kontrolę. Najlepszy dla obciążeń o dużej objętości i wrażliwych na koszty.
Jak Google Gemini obsługuje buforowanie promptów?
Gemini stosuje inne podejście z dwoma distinct mechanizmami buforowania: jawnym buforowaniem kontekstu (nazwane obiekty cache, które tworzysz i referencjonujesz) oraz niejawnym buforowaniem (automatyczne, zero-konfiguracji, dodane w 2026 roku dla modeli Gemini 2.5+).
Jawne buforowanie kontekstu (Nazwane cache'e)
W przeciwieństwie do OpenAI i Anthropic, gdzie buforowanie jest przezroczyste, jawne buforowanie Gemini wymaga najpierw utworzenia nazwanego obiektu cache, a następnie odwoływania się do niego w kolejnych żądaniach. Minimalny próg tokenów to 1024 tokeny dla modeli Gemini Flash i 4096 tokenów dla modeli Pro. TTL jest konfigurowalny, domyślnie 1 godzina, ale możesz ustawić go według potrzeb.
Zbuforowane tokeny w Gemini 2.5 Pro są wyceniane na 0,125 USD/MTok w porównaniu do standardowej ceny wejściowej 1,25 USD/MTok, co daje 90% zniżki. Istnieje również koszt przechowywania wynoszący 4,50 USD za milion tokenów na godzinę dla Pro i 1,00 USD dla Flash.
Niejawne buforowanie w Gemini 2.5 (2026)
Począwszy od Gemini 2.5 Pro i Flash, Google dodało niejawne buforowanie, automatyczne buforowanie działające podobnie jak w podejściu OpenAI. Nie wymaga konfiguracji. Umieść dużą, wspólną treść na początku swojego promptu i wysyłaj żądania z podobnymi prefiksami w szybkiej kolejności. System automatycznie wykrywa treść kwalifikującą się do buforowania i przekazuje oszczędności.
Przykład Python SDK Gemini
from google import genai
from google.genai import types
client = genai.Client()
SYSTEM_PROMPT = """You are a senior Python developer specializing in async programming.
You follow PEP 8, use type hints, and write comprehensive docstrings.
When reviewing code, check for: race conditions, resource leaks, error handling,
and performance bottlenecks. Always suggest specific fixes with code examples.
[... imagine 1,800 more tokens of coding guidelines, examples, and rules ...]"""
# Step 1: Create a named cache object
cache = client.caches.create(
model="gemini-2.5-flash",
config=types.CreateCachedContentConfig(
display_name="python-review-guidelines",
system_instruction=SYSTEM_PROMPT,
ttl="3600s", # 1 hour
),
)
print(f"Cache created: {cache.name}, expires: {cache.expire_time}")
# Step 2: Use the cache in requests
response = client.models.generate_content(
model="gemini-2.5-flash",
contents="Review this async function for race conditions...",
config=types.GenerateContentConfig(
cached_content=cache.name,
),
)
# Check cache usage in the response
metadata = response.usage_metadata
print(f"Cached tokens: {metadata.cached_content_token_count}")
print(f"Total input tokens: {metadata.prompt_token_count}")Podejście jawne ma jedną dużą zaletę: precyzyjnie kontrolujesz TTL. Jeśli wiesz, że Twoje zadanie wsadowe trwa 4 godziny, ustaw 4-godzinny TTL i uniknij wygaśnięcia cache w trakcie przetwarzania.
Werdykt: Konfigurowalny TTL Gemini i podwójne tryby buforowania (jawne + niejawne) czynią go wszechstronnym. Minimalny próg jest teraz porównywalny z innymi dostawcami, a 90% zniżki za odczyty z cache dorównuje Anthropic.
Porównanie kodu side-by-side, ten sam przypadek użycia, wszyscy 3 dostawcy
Oto ten sam chatbot z zbuforowanym promptem systemowym, zaimplementowany we wszystkich trzech SDK. Porównaj bezpośrednio doświadczenie dewelopera.
# --- OpenAI: Zero config, just call the API ---
from openai import OpenAI
client = OpenAI()
response = client.chat.completions.create(
model="gpt-4o",
messages=[
{"role": "system", "content": SYSTEM_PROMPT}, # Cached automatically
{"role": "user", "content": user_message},
],
)
cached = response.usage.prompt_tokens_details.cached_tokens# --- Anthropic: Explicit cache_control breakpoint ---
import anthropic
client = anthropic.Anthropic()
response = client.messages.create(
model="claude-sonnet-4-5-20250514",
max_tokens=1024,
system=[{
"type": "text",
"text": SYSTEM_PROMPT,
"cache_control": {"type": "ephemeral"}, # Mark cache boundary
}],
messages=[{"role": "user", "content": user_message}],
)
cached = response.usage.cache_read_input_tokens# --- Gemini: Named cache object ---
from google import genai
from google.genai import types
client = genai.Client()
cache = client.caches.create(
model="gemini-2.5-flash",
config=types.CreateCachedContentConfig(
system_instruction=SYSTEM_PROMPT,
ttl="3600s",
),
)
response = client.models.generate_content(
model="gemini-2.5-flash",
contents=user_message,
config=types.GenerateContentConfig(cached_content=cache.name),
)
cached = response.usage_metadata.cached_content_token_count| Aspekt | OpenAI | Anthropic | Gemini |
|---|---|---|---|
| Złożoność konfiguracji | Brak | Dodaj blok cache_control | Najpierw utwórz obiekt cache |
| Kontrola cache | Tylko automatyczna | Automatyczna lub jawna | Niejawna lub jawna |
| Zniżka za odczyt z cache | 50% | 90% | ~90% |
| Min. tokeny | 1024 | 1024 | 1024 (Flash) / 4096 (Pro) |
| Werdykt DX | Najprostsze | Największa kontrola | Najbardziej elastyczny TTL |
Jeśli chcesz oszczędności bez wysiłku, wybierz OpenAI. Jeśli chcesz największą zniżkę i drobiazgową kontrolę, wybierz Anthropic. Jeśli potrzebujesz konfigurowalnych czasów życia cache lub jesteś już w Google Cloud, wybierz Gemini.
Kalkulator kosztów produkcyjnych, realne oszczędności w skali
Abstrakcyjne procenty nie podejmują decyzji. Kwoty w dolarach tak. Oto trzy scenariusze produkcyjne z realnymi szacunkami kosztów przy użyciu Claude Sonnet 4.5 (3 USD/MTok wejściowe), GPT-4o (2,50 USD/MTok wejściowe) i Gemini 2.5 Pro (1,25 USD/MTok wejściowe).
Ceny zweryfikowane w marcu 2026. Sprawdź cennik Anthropic, cennik OpenAI i cennik Gemini dla aktualnych stawek.
Założenia: 80% wskaźnik trafień w cache (realistyczny dla dobrze zbudowanych promptów), tokeny wyjściowe wykluczone, ponieważ buforowanie wpływa tylko na koszty wejściowe.
| Scenariusz | Bez buforowania (Miesięcznie) | Z buforowaniem OpenAI | Z buforowaniem Anthropic | Z buforowaniem Gemini |
|---|---|---|---|---|
| Chatbot hobbystyczny: 100 req/dzień, 2K prompt systemowy | OpenAI: 15 USD / Anthropic: 18 USD / Gemini: 7,50 USD | 12 USD (oszczędź 3 USD) | 5,40 USD (oszczędź 12,60 USD) | 2,25 USD (oszczędź 5,25 USD) |
| API wzrostowe: 10K req/dzień, 8K zbuforowany prefiks | OpenAI: 600 USD / Anthropic: 720 USD / Gemini: 300 USD | 360 USD (oszczędź 240 USD) | 144 USD (oszczędź 576 USD) | 60 USD (oszczędź 240 USD) |
| Pipeline enterprise: 100K req/dzień, 10K zbuforowany prefiks | OpenAI: 7500 USD / Anthropic: 9000 USD / Gemini: 3750 USD | 4500 USD (oszczędź 3000 USD) | 1800 USD (oszczędź 7200 USD) | 750 USD (oszczędź 3000 USD) |
Na poziomie Growth, buforowanie Anthropic oszczędza 576 USD/miesiąc mimo wyższej ceny bazowej niż OpenAI. W skali Enterprise mówimy o 7200 USD/miesiąc oszczędności z Anthropic, czyli 86 400 USD rocznie. To oszczędności równe pensji starszego inżyniera, wynikające ze zmiany konfiguracji.
Wzór jest jasny: im większa objętość żądań i im dłuższy statyczny prefiks, tym więcej oszczędza buforowanie. 90% zniżka Anthropic dominuje w skali, ale niższa cena bazowa Gemini czyni go konkurencyjnym, gdy bierzesz pod uwagę całkowity koszt.
Antywzorce buforowania promptów, kiedy NIE buforować
Buforowanie wydaje się proste, dopóki Twój wskaźnik trafień w cache tajemniczo nie spadnie do 0%. Oto błędy, które cicho łamią buforowanie promptów, i jak je naprawić.
Błędy niszczące cache (z poprawkami)
Znaczniki czasu w promptach systemowych, Najczęstszy błąd. Jeśli Twój prompt systemowy zawiera datetime.now(), klucz cache zmienia się co sekundę.
# BAD: Cache misses every single request
system_prompt = f"""You are a helpful assistant.
Current time: {datetime.now().isoformat()}
Always be helpful and accurate."""
# GOOD: Move the timestamp to the user message
system_prompt = """You are a helpful assistant.
Always be helpful and accurate."""
user_message = f"[Current time: {datetime.now().isoformat()}]\n{user_query}"Treść specyficzna dla użytkownika przed treścią statyczną, Jeśli umieścisz session_id lub preferencje użytkownika na początku, każdy użytkownik otrzymuje unikalny prefiks.
# BAD: Unique prefix per user = zero cache reuse
messages = [
{"role": "system", "content": f"User ID: {user_id}\nPreferences: {prefs}\n{GUIDELINES}"},
{"role": "user", "content": query},
]
# GOOD: Static content first, user context at the end
messages = [
{"role": "system", "content": GUIDELINES}, # Same for all users -> cached
{"role": "user", "content": f"Context: User {user_id}, prefs: {prefs}\n{query}"},
]| Antywzorzec | Dlaczego łamie cache | Poprawka |
|---|---|---|
| Znaczniki czasu w prompcie systemowym | Prefiks zmienia się co sekundę | Przenieś znacznik czasu do wiadomości użytkownika |
| ID sesji/użytkownika w prefiksie | Unikalny prefiks dla każdego użytkownika | Przenieś kontekst użytkownika po treści statycznej |
| Rotujące przykłady few-shot | Różne przykłady = różny prefiks | Użyj stałego zestawu przykładów |
| Dynamiczne definicje narzędzi | Zmiana narzędzi = niedopasowanie prefiksu | Zachowaj statyczne schematy narzędzi |
| Krótkie prompty (poniżej minimum) | Cache po prostu się nie uruchomi | Skonsoliduj kontekst, aby przekroczyć 1024 tokeny |
| Personalizacja per żądanie w prompcie systemowym | Prompt systemowy zmienia się przy każdym wywołaniu | Użyj wspólnego promptu systemowego + wiadomości użytkownika specyficzne dla użytkownika |
Kiedy buforowanie promptów naprawdę nie pomaga
Niektóre scenariusze nie skorzystają z buforowania, nawet jeśli idealnie zbudujesz swoje prompty:
- Prompty jednorazowe: Jeśli każde żądanie ma całkowicie unikalny kontekst i brak wspólnego prefiksu, nie ma nic do zbuforowania.
- Bardzo krótkie prompty: Poniżej 1024 tokenów (OpenAI/Anthropic) lub 4096 tokenów (Gemini Pro), buforowanie nie aktywuje się.
- Rzadkie żądania: Jeśli żądania są oddalone o godziny, cache wygasa, zanim dotrze drugie żądanie. Okno 5-10 minut OpenAI i domyślne 5-minutowe TTL Anthropic oznaczają, że potrzebujesz stałego ruchu.
Czy buforowanie promptów działa ze streamingiem?
Tak. Buforowanie promptów i streaming są niezależne, buforowanie działa na tokenach wejściowych, streaming wpływa na dostarczanie danych wyjściowych. Rozwiązują różne problemy na różnych etapach cyklu życia żądania.
Cache obsługuje fazę prefill (przetwarzanie Twojego promptu wejściowego). Streaming obsługuje fazę dekodowania (generowanie i wysyłanie tokenów wyjściowych przyrostowo). Otrzymujesz obie korzyści jednocześnie: szybszy prefill dzięki trafieniu w cache oraz progresywną dostawę danych wyjściowych dzięki streamingowi.
Oto przykład streamingu z włączonym buforowaniem:
import anthropic
client = anthropic.Anthropic()
with client.messages.stream(
model="claude-sonnet-4-5-20250514",
max_tokens=1024,
system=[{
"type": "text",
"text": SYSTEM_PROMPT,
"cache_control": {"type": "ephemeral"},
}],
messages=[{"role": "user", "content": "Explain Python's GIL..."}],
) as stream:
for text in stream.text_stream:
print(text, end="", flush=True)
# After streaming completes, check cache metrics
usage = stream.get_final_message().usage
print(f"\nCache read: {usage.cache_read_input_tokens} tokens")Poprawa TTFT dzięki buforowaniu jest właściwie najbardziej zauważalna przy streamingu. Bez buforowania czekasz na pełny prefill, zanim pierwszy token wróci strumieniowo. Z buforowaniem prefill jest niemal natychmiastowy, więc tokeny zaczynają płynąć prawie od razu.
Jak monitorować wskaźniki trafień w cache w produkcji
Skonfigurowanie buforowania to połowa bitwy. Wiedza, czy faktycznie działa, to druga połowa. Jeśli Twój wskaźnik trafień w cache spadnie poniżej 50%, coś zmieniło się w strukturze Twojego promptu i zostawiasz pieniądze na stole.
Metryki cache specyficzne dla dostawcy
| Dostawca | Pole odczytu cache | Pole zapisu cache | Całkowite pole wejściowe |
|---|---|---|---|
| OpenAI | usage.prompt_tokens_details.cached_tokens | N/A (automatyczne) | usage.prompt_tokens |
| Anthropic | usage.cache_read_input_tokens | usage.cache_creation_input_tokens | usage.input_tokens |
| Gemini | usageMetadata.cachedContentTokenCount | N/A (jawny obiekt cache) | usageMetadata.promptTokenCount |
Prosty logger wskaźnika trafień w cache
Oto funkcja pomocnicza, którą możesz wdrożyć w dowolnym projekcie, aby śledzić wskaźniki trafień w cache poprzez pola odpowiedzi API:
import logging
logger = logging.getLogger("cache_monitor")
def log_cache_metrics(provider: str, usage: dict) -> float:
"""Extract and log cache metrics from any provider's response. Returns hit rate."""
if provider == "openai":
cached = getattr(usage.prompt_tokens_details, "cached_tokens", 0)
total = usage.prompt_tokens
elif provider == "anthropic":
cached = usage.cache_read_input_tokens
created = usage.cache_creation_input_tokens
total = cached + created + usage.input_tokens
elif provider == "gemini":
cached = getattr(usage, "cached_content_token_count", 0)
total = usage.prompt_token_count
else:
raise ValueError(f"Unknown provider: {provider}")
hit_rate = (cached / total * 100) if total > 0 else 0
logger.info(f"[{provider}] Cache hit rate: {hit_rate:.1f}% ({cached}/{total} tokens)")
if hit_rate < 50:
logger.warning(f"[{provider}] Low cache hit rate! Check prompt structure.")
return hit_rateZdrowy system produkcyjny powinien utrzymywać 70-90% wskaźnik trafień w cache. Jeśli jesteś poniżej 50%, wróć do sekcji antywzorców. Możesz też zintegrować to z automatycznymi metrykami ewaluacji, aby wychwytywać regresje w swoim pipeline promptów.
Buforowanie promptów w rzeczywistych przypadkach użycia
Powyższe przykłady chatbotów ilustrują mechanikę, ale buforowanie promptów naprawdę błyszczy w określonych wzorcach architektonicznych.
Pipelines RAG
W ustawieniu RAG, Twój prompt systemowy i przykłady few-shot są statyczne dla wszystkich zapytań. Pobrane dokumenty zmieniają się za każdym razem. Strukturyzuj swój prompt, aby zmaksymalizować zbuforowany prefiks:
- Prompt systemowy (buforowany)
- Przykłady few-shot (buforowane)
- Pobrane dokumenty (dynamiczne, idą na koniec)
- Zapytanie użytkownika (zawsze unikalne)
Przy 5000-tokenowym prompcie systemowym i 3000 tokenach przykładów few-shot, to 8000 tokenów buforowanych przy każdym żądaniu. Przy 1000 żądań/dzień w Anthropic, oszczędziłbyś około 6,50 USD/dzień tylko na samym zbuforowanym prefiksie. Gdy pobierasz i buforujesz bloki kontekstu, upewnij się, że wynik pobierania znajduje się po statycznym prefiksie.
Chatboty wieloturkowe
Rozmowy wieloturkowe to wymarzone miejsce dla buforowania promptów. Każda tura dodaje do historii rozmowy, ale cała poprzednia rozmowa jest już zbuforowana z poprzednich tur. Korzyść z cache kumuluje się, przy turze 10 możesz mieć 15 000 tokenów zbuforowanej historii z tylko 200 świeżymi tokenami z najnowszej wiadomości użytkownika.
Systemy agentowe i definicje narzędzi MCP
Jeśli budujesz agentów z wykorzystaniem narzędzi, Twoje definicje narzędzi to statyczne schematy JSON powtarzane przy każdym pojedynczym wywołaniu API. Typowy agent może mieć 20+ narzędzi totaling 3000-5000 tokenów definicji. To doskonały materiał do buforowania.
Jest to szczególnie istotne dla architektur opartych na MCP, gdzie definicje narzędzi serwera są wysyłane przy każdym wywołaniu. Dzięki jawnemu cache_control Anthropic, możesz oznaczyć tablicę tools do buforowania i zagwarantować ponowne wykorzystanie tych tokenów.
Którego dostawcę wybrać?
| Jeśli potrzebujesz... | Najlepszy wybór | Dlaczego |
|---|---|---|
| Zero-konfiguracji, chcę tylko oszczędności | OpenAI | Automatyczne buforowanie, brak zmian w kodzie |
| Maksymalnej redukcji kosztów (90%) | Anthropic | Cena odczytu z cache 0.1x, największa zniżka |
| Drobiazgowej kontroli cache | Anthropic | Jawne punkty przerwania + konfigurowalny TTL (5-min lub 1-godz) |
| Analizy długich dokumentów | Gemini | Konfigurowalny TTL z jawnymi nazwanymi cache'ami |
| Prostoty czatu wieloturkowego | OpenAI | Automatyczne dopasowanie prefiksu w rosnącej historii rozmowy |
| Systemów agentowych z definicjami narzędzi | Anthropic | Jawne buforowanie definicji narzędzi za pomocą cache_control |
| Elastyczności wielu dostawców | LiteLLM | Ujednolicona składnia buforowania dla wszystkich dostawców |
Jeśli już używasz jednego dostawcy, zacznij od niego, buforowanie promptów nie wymaga zmiany. LiteLLM działa jako warstwa proxy, która normalizuje parametry buforowania między dostawcami, co jest przydatne, jeśli kierujesz żądania do wielu modeli.
FAQ, Buforowanie promptów LLM
Co to jest buforowanie promptów w LLM?
Buforowanie promptów przechowuje obliczone stany uwagi (cache KV) z wcześniej przetworzonych prefiksów promptów. Gdy kolejne żądanie zaczyna się od tej samej sekwencji tokenów, dostawca ponownie wykorzystuje te przechowywane stany zamiast je przeliczać, redukując zarówno koszt, jak i opóźnienie bez wpływu na jakość wyniku.
Ile oszczędza buforowanie promptów na kosztach API?
Oszczędności wahają się od 50% do 90% w zależności od dostawcy. OpenAI oferuje 50% zniżki na zbuforowane tokeny wejściowe. Anthropic oferuje do 90% zniżki (odczyty z cache po 0.1x ceny bazowej). Gemini oferuje około 90% zniżki na odczyty z cache. Rzeczywiste oszczędności zależą od wskaźnika trafień w cache, długości promptu i częstotliwości żądań.
Czy buforowanie promptów w OpenAI dzieje się automatycznie?
Tak, od października 2024 roku. Każde wywołanie API z co najmniej 1024 tokenami wejściowymi automatycznie korzysta z buforowania. Brak konieczności opt-in, brak nagłówków, brak wymaganych zmian w kodzie. Cache dopasowuje prefiksy tokenów od początku promptu.
Jaka jest różnica między buforowaniem promptów a buforowaniem semantycznym?
Buforowanie promptów dopasowuje dokładne prefiksy tokenów na poziomie GPU, nie ma utraty dokładności, a wyniki są identyczne jak w żądaniach bez cache. Buforowanie semantyczne wykorzystuje podobność embeddingów do znalezienia „wystarczająco bliskich” poprzednich zapytań i zwraca zbuforowane odpowiedzi, jest szybsze, ale może zwracać niepoprawne lub nieaktualne odpowiedzi. Rozwiązują one fundamentalnie różne problemy.
Jak długo trwa cache promptu?
To zależy od dostawcy. OpenAI: 5-10 minut (do 24 godzin przy przedłużonym przechowywaniu). Anthropic: 5 minut (domyślnie) lub 1 godzina (dostępne w modelach Claude 4.5+, kosztuje 2x zapis). Gemini: konfigurowalny, domyślnie 1 godzina dla jawnych cache'ów. TTL niejawnego buforowania jest zarządzane automatycznie przez Google.
Jaka jest minimalna długość tokenów dla buforowania promptów?
OpenAI: 1024 tokeny. Anthropic: 1024 tokeny dla większości obecnych modeli. Gemini: 1024 tokeny dla modeli Flash, 4096 dla modeli Pro. Prompty poniżej tych progów nie aktywują buforowania, to najczęstszy haczyk „to nie działa”.
Czy buforowanie promptów działa ze streamingowymi odpowiedziami?
Tak. Buforowanie i streaming działają na różnych fazach żądania. Buforowanie przyspiesza fazę prefill wejścia; streaming dostarcza tokeny wyjściowe przyrostowo. Obie działają jednocześnie, a poprawę TTFT zauważysz właściwie bardziej przy włączonym streamingu.
Kiedy NIE powinienem używać buforowania promptów?
Unikaj polegania na buforowaniu, gdy Twoje prompty są poniżej minimalnego progu tokenów, gdy zawierają znaczniki czasu lub ID sesji w prompcie systemowym, gdy rotujesz przykłady few-shot między wywołaniami lub gdy żądania są zbyt rzadkie, aby trafić w cache przed jego wygaśnięciem (okno 5-10 minut dla OpenAI/Anthropic).
Czy mogę używać buforowania promptów z LangChain lub LiteLLM?
Tak. LangChain przekazuje parametry buforowania specyficzne dla dostawcy przez swoje wrappery API. LiteLLM zapewnia ujednoliconą składnię buforowania, która normalizuje cache_control across Anthropic, OpenAI, Gemini, Vertex AI i Bedrock, szczególnie przydatne w setupach multi-dostawców.
Co to jest trafienie w cache (hit) vs niepowodzenie (miss)?
Trafienie w cache oznacza, że dostawca znalazł pasujący prefiks w pamięci i ponownie wykorzystał przechowywane stany KV, płacisz obniżoną stawkę za zbuforowane tokeny i otrzymujesz szybsze TTFT. Niepowodzenie w cache oznacza, że nie znaleziono dopasowania, więc cały prompt jest przetwarzany od zera po standardowej cenie. Sprawdź pola cached_tokens (OpenAI), cache_read_input_tokens (Anthropic) lub cachedContentTokenCount (Gemini) w odpowiedzi API, aby zobaczyć, co wystąpiło.
Ostateczny werdykt
| Kategoria | Zwycięzca | Kluczowy powód |
|---|---|---|
| Najłatwiejsza konfiguracja | OpenAI | Automatyczne, zero konfiguracji |
| Najgłębsza zniżka | Anthropic | 90% zniżki za odczyty z cache (0.1x bazy) |
| Największa kontrola | Anthropic | Jawne punkty przerwania + TTL 5-min lub 1-godz |
| Najlepsze dla długich dokumentów | Gemini | Konfigurowalny TTL z nazwanymi obiektami cache |
| Najlepsze dla czatu wieloturkowego | OpenAI | Automatyczne dopasowanie prefiksu w historii rozmowy |
| Najlepsze dla Agentic/MCP | Anthropic | Jawne buforowanie definicji narzędzi |
Buforowanie promptów to optymalizacja o najmniejszym wysiłku i najwyższym zwrocie w stosie API LLM. Nie zmieniasz modelu, nie poświęcasz jakości, a implementacja waha się od „nic nie rób” (OpenAI) do „dodaj jedno pole” (Anthropic) do „utwórz obiekt cache” (Gemini).
Zacznij od automatycznego buforowania obecnego dostawcy. Zmierz swój wskaźnik trafień w cache za pomocą powyższego narzędzia logującego. Jeśli jesteś poniżej 70%, przebuduj swoje prompty (statyczne najpierw, dynamiczne na końcu) i wyeliminuj antywzorce. Większość zespołów widzi redukcję kosztów o 50-80% w ciągu dnia od wdrożenia tych zmian.