Zbudowałeś pętlę agentową. Narzędzia się wywołują, wyniki wracają, model rozkminia co dalej — całość mruczy jak mały autonomiczny mózg. Potem otwierasz dashboard zużycia Anthropic po dniu testów. Ta liczba to nie literówka. To koszt wysyłania tego samego system prompta i schematów narzędzi przy każdej iteracji, w pełnej cenie, do bezstanowego API, które nie pamięta co wysłałeś trzy sekundy temu.
A jeśli przesiadłeś się na Opus 4.7 z 16 kwietnia 2026 — a pewnie tak — Simon Willison zmierzył, że nowy tokenizer generuje 1,46× więcej tokenów dla identycznych system promptów. Twoje koszty skoczyły o 35-40% z dnia na dzień za dosłownie ten sam tekst. Analiza Finout (27 kwietnia 2026) potwierdza ten wzorzec na różnych workloadach.
Dlaczego "po prostu zoptymalizuj prompty" nie wystarczy
Oczywista odpowiedź: skróć prompty. Jasne, wytnij zbędne słowa. Ale w prawdziwej pętli agentowej twój statyczny prefix — system prompt, definicje narzędzi (schematy opisujące modelowi jakie narzędzia może wywoływać i jakie parametry przyjmują) oraz narastająca historia konwersacji — spokojnie przekracza 10 000 tokenów. Z 6 narzędziami i porządnym system promptem patrzysz na ~11 000 tokenów identycznej treści wysyłanej przy każdym turnie.
Przez 10 iteracji to 110 000 tokenów czystej powtórki po $5/MTok na Opus 4.7. To $0.55 samych kosztów wejściowych — za bajty, które serwer już widział. Skaluj do 50 turnów i palisz dolary na jednej konwersacji.
Żadne przycinanie promptów nie naprawi fundamentalnie bezstanowego protokołu. Potrzebujesz, żeby serwer pamiętał.
Rozwiązanie: prompt caching
API prompt cachingu Anthropic (GA od 17 grudnia 2024) pozwala oznaczyć bloki wiadomości breakpointem cache_control — markerem mówiącym serwerowi "zapamiętaj wszystko do tego miejsca". Przy kolejnych requestach, jeśli bajty zgadzają się dokładnie, serwer czyta z cache i liczy ci 10% normalnej ceny za input. Według dokumentacji Anthropic, 5-minutowy cache (domyślny) kosztuje 1,25× przy pierwszym zapisie; godzinny cache kosztuje 2×.
Matematyka jest prosta: zapłać 25% premii raz, dostań 90% zniżki na każde kolejne trafienie. W 10-turnowej pętli to 1 zapis + 9 odczytów. Zwraca się już po pierwszym trafieniu cache.
Krok 1: Cachuj system prompt
System prompt to najbardziej stabilna treść w twojej pętli. Nigdy się nie zmienia między iteracjami. Zrób go cachowalnym:
response = client.messages.create(
model="claude-opus-4-7",
max_tokens=4096,
system=[{
"type": "text",
"text": "Twój długi system prompt z instrukcjami...",
"cache_control": {"type": "ephemeral"}, # 5-min TTL
}],
messages=[...],
)
Kluczowy szczegół: na Opus 4.7 (oraz Opus 4.5, Haiku 4.5) minimalny cachowalny blok to 4096 tokenów. Jeśli twój system prompt jest krótszy, Anthropic po cichu ignoruje marker cache_control — żadnego błędu, żadnego cache, tylko zmarnowana intencja. Na Sonnet minimum to 1024 tokeny.
/faion to parasol umiejętności faion-network — ściąga odpowiednią metodologię z 12 specjalistycznych domen do konwersacji, więc zanim zaprojektujesz strategię cache, zapytaj go:
/faion
I'm implementing Anthropic prompt caching for a multi-tool agentic loop.
What's the best strategy for placing cache_control breakpoints when I have
a system prompt, 6 tool schemas, and growing conversation history?
Krok 2: Cachuj definicje narzędzi
Schematy narzędzi — opisy JSON z nazwą, parametrami i przeznaczeniem każdego narzędzia — siedzą w tablicy tools i są przetwarzane przed system promptem w hierarchii cache. Umieść cache_control na ostatnim narzędziu w tablicy, żeby zcachować je wszystkie jednym breakpointem:
tools = [
{"name": "search_web", "description": "...", "input_schema": {...}},
{"name": "read_file", "description": "...", "input_schema": {...}},
{"name": "run_code", "description": "...", "input_schema": {...}},
{"name": "write_file", "description": "...", "input_schema": {...}},
{"name": "list_dir", "description": "...", "input_schema": {...}},
{"name": "submit_result", "description": "...", "input_schema": {...},
"cache_control": {"type": "ephemeral"}}, # cachuje WSZYSTKIE powyższe narzędzia
]
Krytyczna zasada: hierarchia cache to tools → system → messages. Zmiana dowolnej definicji narzędzia między iteracjami (dodanie narzędzia, zmiana nazwy parametru) unieważnia cache dla narzędzi, systemu I wiadomości. W pętli agentowej utrzymuj zestaw narzędzi zamrożony.
Krok 3: Cachuj prefix historii konwersacji
W miarę jak konwersacja rośnie, starsze wiadomości stają się statyczne — nie zmienią się. Umieść breakpoint na ostatniej wiadomości w "stabilnej" części:
messages = [
{"role": "user", "content": "Początkowe zadanie..."},
{"role": "assistant", "content": "Zacznę od..."},
{"role": "user", "content": [{ # ostatnia stabilna wiadomość
"type": "text",
"text": "Wynik narzędzia z kroku 3...",
"cache_control": {"type": "ephemeral"},
}]},
{"role": "assistant", "content": "Teraz przetwarzam..."}, # nowe, niescachowane
]
Masz teraz 3 breakpointy (narzędzia, system, historia). API dopuszcza maksymalnie 4. Ostatni slot zachowaj na edge case'y.
Krok 4: Sztuczka z przeniesieniem
Ten trik pochodzi od zespołu inżynierów ProjectDiscovery, którzy opublikowali wyniki 10 kwietnia 2026. Odpalają 26-krokowy, 40-wywołaniowy agentowy skaner bezpieczeństwa. Ich początkowy cache hit rate był żałosne 7%.
Problem: ich system prompt zawierał timestampy, pamięć roboczą i zmienne runtime'owe zmieniające się przy każdym wywołaniu. Dopasowanie cache wymaga dokładnej zgodności bajtowej — jeden inny znak i cały blok nie trafia.
Fix: przenieś całą dynamiczną treść z system prompta do wiadomości user-role na końcu konwersacji. System prompt staje się bajt-po-bajcie identyczny między wywołaniami. Ich cache hit rate skoczył z 7% do 74% z dnia na dzień, ostatecznie osiągając 84% po dalszym tuningu — 70% redukcji kosztów.
/faion
How should I separate static vs. dynamic content in an agentic system
prompt to maximize cache hit rates? What patterns exist for the
static-system-prompt + dynamic-user-reminder split?
Krok 5: Sprawdź, czy to naprawdę działa
Trafienia cache są niewidoczne, dopóki nie sprawdzisz. Większość wrapperów SDK i frameworków logowania nie wyciąga metryk cache. Musisz to sprawdzić jawnie:
usage = response.usage
print(f"Cache zapisany: {usage.cache_creation_input_tokens}")
print(f"Cache odczytany: {usage.cache_read_input_tokens}")
print(f"Niescachowane: {usage.input_tokens}")
hit_rate = usage.cache_read_input_tokens / (
usage.cache_read_input_tokens +
usage.cache_creation_input_tokens +
usage.input_tokens
) * 100
print(f"Cache hit rate: {hit_rate:.1f}%")
Przy drugiej iteracji pętli cache_read_input_tokens powinno być duże. Jeśli jest zero, coś unieważnia cache — sprawdź różnice na poziomie bajtów w swojej "statycznej" treści.
Pułapki, które zjedzą ci portfel
1. Klif 5 minut. Domyślny TTL (time-to-live — jak długo serwer pamięta twój zcachowany content) to 5 minut. Jeśli wywołanie narzędzia trwa 6 minut (timeout zewnętrznego API, długie obliczenia), cache wygasa. Płacisz premię za zapis ponownie. Fix: użyj "ttl": "1h" dla wolnych workflow'ów, ale wiedz, że kosztuje 2× zamiast 1,25× na zapisie. I dłuższe TTL muszą pojawić się przed krótszymi w requeście — odwrotna kolejność rzuca błąd.
2. Kolejność kluczy JSON. Niektóre języki randomizują kolejność kluczy JSON przy serializacji. Inna kolejność kluczy = inne bajty = cache miss. Ustal kolejność serializacji albo użyj sort_keys=True.
3. Lookback 20 bloków. System przeszukuje maksymalnie 20 bloków treści wstecz szukając zcachowanych wpisów. W długich konwersacjach (>20 bloków) stare breakpointy cache wypadają poza okno wyszukiwania. Dodawaj świeże breakpointy co ~18 bloków. Badanie PwC ze stycznia 2026 wykazało, że to właśnie stąd bierze się większość "tajemniczych cache missów".
4. Cachowanie krótkich treści kosztuje więcej. PwC zmierzyło, że prompty poniżej 500 tokenów wykazują 10-18% gorsze opóźnienia z cachingiem z powodu narzutu. Nie cachuj swojego 200-tokenowego system prompta. I tak musi przejść minimum 4096 tokenów na Opus.
Co możesz zrobić teraz
Masz trzy breakpointy — narzędzia, system, prefix historii — i jeden wzorzec monitoringu. Ta sama pętla agentowa, która paliła $0.55 za 10-turnową konwersację na Opus 4.7, teraz kosztuje ~$0.12. To nie błąd zaokrąglenia; to różnica między prototypem, który pokażesz raz na demo, a systemem, który faktycznie wdrożysz. 35% podatek tokenizera z Opus 4.7? Nadal jest, ale płacisz go raz przy zapisie cache zamiast przy każdym turnie. Witaj w części, w której strona z rachunkami przestaje straszyć.





