POWRÓT_DO_BLOGA
AI & Automatyzacja 13 min

Optymalizacja kosztów OpenAI API: caching, routing i kompresja kontekstu

Jak zredukować rachunek za OpenAI API o 60–80% bez pogorszenia jakości — prompt caching, routing modeli i kompresja historii rozmowy.

Projekt AI działa, testy przeszły, deployment na produkcję — i po miesiącu rachunek za OpenAI API jest czterokrotnie wyższy od założonego budżetu. To nie jest rzadki przypadek. GPT-4o kosztuje 16x więcej niż GPT-4o mini przy tym samym zadaniu, a nieoptymalizowany kontekst agenta rośnie z każdym krokiem. Cztery techniki opisane poniżej redukują koszty o 60–80% bez żadnego pogorszenia jakości odpowiedzi.

Anatomia kosztu — co generuje rachunki

Każde wywołanie API ma dwie składowe: tokeny wejściowe (prompt + historia + system message + definicje narzędzi) i tokeny wyjściowe (odpowiedź modelu). Tokeny wyjściowe kosztują 2–4x więcej niż wejściowe — ale jest ich zwykle dużo mniej. Dlatego optymalizacja kosztów zaczyna się od tokenów wejściowych, które stanowią 70–85% kosztu typowego wywołania.

Ceny modeli OpenAI (2026)

Cztery modele używane najczęściej w produkcji różnią się ceną o rząd wielkości. Wybór właściwego do każdego zadania to największa dźwignia kosztowa:

ModelInput (per 1M)Output (per 1M)Cached inputKiedy używać
GPT-4o mini$0.15$0.60$0.075Proste zadania — 60–70% ruchu
GPT-4o$2.50$10.00$1.25Analiza, kod, złożone instrukcje
o3-mini$1.10$4.40Matematyka, algorytmy, rozumowanie
o1$15.00$60.00$7.50Najtrudniejsze zadania wieloetapowe

Co wchodzi w tokeny wejściowe

W typowej aplikacji agentowej większość kosztu wejściowego pochodzi z elementów wysyłanych przy każdym wywołaniu — nie z wiadomości użytkownika:

  • System message — 200–500 tokenów, stały dla każdego wywołania
  • Definicje narzędzi (tools) — 100–300 tokenów per narzędzie, wysyłane zawsze
  • Historia rozmowy — rośnie liniowo, 500–2000 tok/turn po kilku krokach agenta
  • Kontekst RAG — 500–4000 tokenów, zależnie od retrievalu
  • Wiadomość użytkownika — 20–200 tokenów, zwykle najmniejsza część

/// OPTYMALIZACJA KOSZTU WYWOŁANIA API

Koszt per 1000 wywołań — GPT-4o mini, przed i po optymalizacji

PRZED OPTYMALIZACJĄ
System message (2000 tok)$0.300
Tool definitions (400 tok)$0.060
Historia rozmowy (1500 tok)$0.225
Wiadomość użytkownika (100 tok)$0.015
SUMA / 1000 WYWOŁAŃ$0.600
PO OPTYMALIZACJI
System message — cachedcached$0.015
Tool definitions — cachedcached$0.006
Historia skompresowana (600 tok)$0.090
Wiadomość użytkownika$0.015
SUMA / 1000 WYWOŁAŃ$0.126
-79%
REDUKCJA KOSZTÓW
75%
TANIEJ CACHED TOKENS
10x
RÓŻNICA MINI VS FULL

Prompt Caching — największy quick win

Prompt caching obniża koszt powtarzających się prefiksów promptu o 75%. Dostępny w OpenAI (od GPT-4o) i Anthropic (od Claude 3.5). Cache tworzy się automatycznie gdy ten sam prefiks ma 1024+ tokenów i pojawia się w ciągu 5 minut od poprzedniego wywołania. Aplikacja nie musi nic konfigurować — wystarczy trzymać stałe elementy na początku promptu.

Jak strukturyzować prompt pod caching

Kolejność elementów w prompcie decyduje o cache hit rate. Właściwa kolejność — od najbardziej stałych do najczęściej zmieniających się:

  1. 1.System message — stały dla całej aplikacji, zawsze cache'owany
  2. 2.Definicje narzędzi — stałe, cache'owane razem z system message
  3. 3.Dokumenty kontekstowe — stałe per sesja użytkownika, cache'owane
  4. 4.Historia rozmowy — zmienia się z każdą turą, nie cache'owana
  5. 5.Wiadomość użytkownika — zawsze nowa, nie cache'owana

Częsty błąd: wstawianie daty, ID sesji lub imienia użytkownika do system message. Taka praktyka łamie cache dla każdego użytkownika i każdej sesji — przenieś te dane do wiadomości użytkownika lub osobnego bloku kontekstu po historii rozmowy.

prompt_caching.py
from openai import OpenAIclient = OpenAI()SYSTEM_PROMPT = """Jesteś asystentem obsługi klienta firmy Acme.Zasady: odpowiadaj wyłącznie na pytania dot. produktów Acme, eskaluj do człowieka gdy klient jest niezadowolony lub pyta o zwrot > 500 PLN.[...2000 tokenów opisu produktów, procedur i cennika — stały tekst, zawsze cache'owany...]"""def chat(history: list, user_message: str) -> tuple[str, dict]:    messages = [        {"role": "system", "content": SYSTEM_PROMPT},        *history,        {"role": "user", "content": user_message}    ]    resp = client.chat.completions.create(model="gpt-4o-mini", messages=messages)    details = getattr(resp.usage, "prompt_tokens_details", None)    cached_tokens = details.cached_tokens if details else 0    return resp.choices[0].message.content, {        "total_tokens": resp.usage.total_tokens,        "cached_tokens": cached_tokens,        "saved_usd": round(cached_tokens * 0.075 / 1_000_000, 6)    }

Cache hit rate w praktyce: aplikacja obsługująca 10 000 wywołań/dzień z system message 2000 tokenów oszczędza ~$22/dzień tylko na cachowaniu. Wynik dostępny w `resp.usage.prompt_tokens_details.cached_tokens` — loguj go i monitoruj hit rate.

Routing zapytań — właściwy model do właściwego zadania

60–70% zapytań w typowych aplikacjach biznesowych nie wymaga pełnego GPT-4o. Router klasyfikuje zapytanie i kieruje je do najtańszego modelu który poradzi sobie z zadaniem. Koszt klasyfikatora — jedno wywołanie GPT-4o mini z ~20 tokenami odpowiedzi — zwraca się z nawiązką gdy większość ruchu trafia na model 16x tańszy.

Kiedy GPT-4o mini (60–70% ruchu)

  • Klasyfikacja tekstu — sentiment, kategoria, intent użytkownika
  • Proste odpowiedzi na FAQ z dostarczonego kontekstu
  • Ekstrakcja danych ze strukturyzowanych tekstów (structured output)
  • Podsumowanie krótkich dokumentów — do 1000 słów
  • Tłumaczenie bez specjalistycznej terminologii

Kiedy GPT-4o (25–35% ruchu)

  • Analiza złożonych dokumentów — umowy, raporty finansowe, specyfikacje
  • Generowanie i code review
  • Zadania z wieloma narzędziami i zależnościami między wywołaniami
  • Odpowiedzi gdzie jakość bezpośrednio wpływa na revenue lub decyzję klienta
  • Generowanie treści wymagające spójności i kreatywności

Kiedy o3-mini lub o1 (5–10% ruchu)

  • Dowody matematyczne i zadania algorytmiczne
  • Złożone generowanie SQL, skryptów lub architektury systemu
  • Analiza ryzyka wymagająca wieloetapowego rozumowania
  • Zadania gdzie koszt błędu wielokrotnie przekracza koszt wywołania
model_router.py
import instructorfrom openai import OpenAIfrom pydantic import BaseModelfrom typing import Literalclient = OpenAI()ic = instructor.from_openai(OpenAI())class RouteDecision(BaseModel):    model: Literal["gpt-4o-mini", "gpt-4o", "o3-mini"]    reason: strdef classify_query(query: str) -> RouteDecision:    return ic.chat.completions.create(        model="gpt-4o-mini",        response_model=RouteDecision,        messages=[            {"role": "system", "content": "Zdecyduj który model OpenAI użyć. gpt-4o-mini: proste pytania, klasyfikacja, ekstrakcja, FAQ. gpt-4o: analiza, kod, złożone wnioskowanie. o3-mini: matematyka, algorytmy, rozumowanie wieloetapowe."},            {"role": "user", "content": f"Zapytanie: {query}"}        ]    )def smart_chat(query: str, history: list) -> str:    route = classify_query(query)    resp = client.chat.completions.create(        model=route.model,        messages=[*history, {"role": "user", "content": query}]    )    return resp.choices[0].message.content

Ważne: router to dodatkowe wywołanie API — dodaje 50–100ms latency. Jeśli latency jest krytyczne, uruchom routing równolegle z pierwszym wywołaniem i cache'uj decyzje routera per klasa zapytania (np. wszystkie "pytania o status zamówienia" → zawsze mini).

/// STRATEGIA ROUTINGU MODELI

Routing zapytań — rozkład ruchu w typowej aplikacji B2B

INPUT QUERYCLASSIFIER (GPT-4o mini, ~20 tok)ROUTE TO MODEL
65%
Proste zadaniaGPT-4o mini$0.15 / 1M tok
FAQ, klasyfikacja, ekstrakcja, podsumowanie krótkich tekstów
30%
Złożone zadaniaGPT-4o$2.50 / 1M tok
Analiza dokumentów, generowanie kodu, wieloetapowe instrukcje
5%
Rozumowanieo3-mini$1.10 / 1M tok
Matematyka, algorytmy, złożone generowanie kodu
$0.73
AVG KOSZT PER 1M TOK (Z ROUTINGIEM)
-71%
VS $2.50 FLAT (GPT-4o BEZ ROUTINGU)
<5ms
OVERHEAD KLASYFIKATORA

Kompresja kontekstu — zatrzymaj rosnący rachunek

W agentach i chatbotach historia rozmowy rośnie z każdym krokiem. Po 20 turach konwersacja może mieć 8000+ tokenów wysyłanych przy każdym wywołaniu. Trzy strategie, od najprostszej do najbardziej precyzyjnej:

Strategia 1: Sliding window

Zachowaj tylko ostatnie N wiadomości. Zalety: zero dodatkowych wywołań API, dwie linie kodu. Wady: utrata pamięci długoterminowej — model nie pamięta kontekstu z początku rozmowy. Dobra dla chatbotów gdzie kontekst starszy niż 10 tur ma małe znaczenie.

Strategia 2: Summarization

Co N tur skompresuj stary kontekst do 300-tokenowego podsumowania przez GPT-4o mini. Koszt kompresji: ~$0.002 per sesję. Oszczędność: 60–70% tokenów historii przy zachowaniu kluczowych faktów z całej rozmowy. Dobra dla długich sesji gdzie użytkownik wraca do wcześniejszych tematów.

Strategia 3: Semantic pruning

Oceń semantyczną odległość każdej historycznej wiadomości od bieżącego pytania (cosine similarity embeddingów). Usuń wiadomości powyżej progu. Najbardziej precyzyjna — zachowuje najbardziej relevantne fragmenty bez kompresji stratnej. Sensowna przy sesjach 50+ tur z dużą różnorodnością tematów.

context_compression.py
from openai import OpenAIclient = OpenAI()def compress_history(history: list[dict], keep_last: int = 6, max_tokens: int = 300) -> list[dict]:    if len(history) <= keep_last:        return history    old_msgs = history[:-keep_last]    recent = history[-keep_last:]    old_text = "".join(f"{m['role']}: {m['content']}" for m in old_msgs)    resp = client.chat.completions.create(        model="gpt-4o-mini",        messages=[            {"role": "system", "content": f"Skompresuj tę rozmowę do max {max_tokens} tokenów. Zachowaj kluczowe fakty, decyzje i kontekst. Usuń powitania i small talk."},            {"role": "user", "content": old_text}        ]    )    summary = resp.choices[0].message.content    return [        {"role": "system", "content": f"[Podsumowanie wcześniejszej rozmowy]: {summary}"},        *recent    ]

W praktyce: kompresja wywoływana co 10 tur redukuje rozmiar kontekstu o 65–70% przy zachowaniu 95%+ trafności odpowiedzi. Mierz jakość ROUGE-L między odpowiedziami z pełną historią a skompresowaną — jeśli spada poniżej 0.9, zwiększ parametr `max_tokens` lub zmniejsz `keep_last`.

Lista kontrolna — 10 szybkich wygranych

Wdróż w tej kolejności — każdy punkt to niezależna optymalizacja:

  1. 1.Sprawdź usage dashboard — znajdź 20% wywołań które generują 80% kosztów
  2. 2.Przenieś stałe elementy na początek promptu — prompt caching włącza się automatycznie
  3. 3.Ogranicz max_tokens — ustaw rozsądny limit zamiast zostawiać domyślny
  4. 4.Zastąp GPT-4o na mini wszędzie gdzie możliwe — przeprowadź A/B test jakości
  5. 5.Skróć system message — usuń powtórzenia i instrukcje które nie zmieniają wyników
  6. 6.Usuń nieużywane tool definitions z wywołań gdzie narzędzia nie są potrzebne
  7. 7.Wdróż sliding window dla historii konwersacji (keep_last=10)
  8. 8.Dodaj model routing dla zadań które dają się klasyfikować
  9. 9.Batch API dla zadań nieinteraktywnych — 50% taniej, asynchroniczne przetwarzanie
  10. 10.Monitoring per endpoint — alert gdy koszt/zapytanie przekroczy ustalony próg
OptymalizacjaTrudnośćOszczędnośćCzas wdrożenia
Prompt cachingNiska40–75% kosztu wejściowego2h
Ogranicz max_tokensNiska10–30%30 min
Routing — mini dla prostych zadańŚrednia80–90% na tych wywołaniach1–2 dni (A/B test)
Sliding window historiiNiska20–50% przy długich sesjach2h
Model routing (pełny)Średnia50–70% łącznych kosztów2–3 dni
Batch APINiska50% na zadaniach offline3h

---

Przeprowadzam audyty kosztów AI dla firm — analizuję logi wywołań API, identyfikuję punkty optymalizacji i wdrażam routing, caching i kompresję kontekstu. Typowy wynik: 50–70% redukcja kosztów w 2 tygodnie. Napisz do mnie — zaczynam od analizy Twoich logów API.

/// AUTHOR
Paweł Wiszniewski – AI & Web Engineer

Paweł Wiszniewski

Senior Full-Stack Engineer & AI Architect

8+ lat doświadczenia. Buduję systemy AI, automatyzacje i aplikacje webowe, które redukują koszty i zwiększają efektywność operacyjną firm.

Signal received?

Przerwij
Ciszę

Zainicjuj protokół. Nawiąż połączenie. Zbudujmy coś głośnego.

> OCZEKIWANIE_NA_SYGNAŁ...