Optymalizacja kosztówPrzewodnik
Przycinaj historię rozmowy, aby obniżyć koszty: okno przesuwne czy podsumowanie
Ogranicz to, co wysyłasz ponownie w każdej turze: zachowaj kilka ostatnich wiadomości lub krótkie podsumowanie. Arytmetyka tokenów dla 50-turowej rozmowy i helper w Pythonie.

Na tej stronie
Twój bot wsparcia prowadzi rozmowę od 50 tur, a każda nowa wiadomość kosztuje więcej niż poprzednia. API niczego nie pamięta, więc twój kod przy każdym wywołaniu wysyła całą rozmowę od nowa. Rozwiązaniem jest ograniczenie tego, co wysyłasz: zachowaj system prompt i kilka ostatnich tur (okno przesuwne) albo zamień stare tury na krótkie podsumowanie. Poniżej arytmetyka dla 50-turowej rozmowy i gotowy do skopiowania helper.
Przewodnik DeepSeek po rozmowach wieloturówych (api-docs.deepseek.com, sprawdzony 1 listopada 2026) mówi to wprost: serwer nie zapisuje kontekstu wcześniejszych żądań, więc klient przy każdym wywołaniu wysyła pełną listę messages. Format zgodny z OpenAI na CheapTokens działa tak samo. Jeśli to dla ciebie nowość, zacznij od dlaczego długa rozmowa kosztuje więcej i jak działa tablica messages.
Co faktycznie wysyła tura 50#
Załóżmy, że prowadzisz bota wsparcia z system promptem o długości 400 tokenów. W typowej turze użytkownik pisze około 60 tokenów, a bot odpowiada około 190. Jedna pełna tura dodaje do historii 250 tokenów. To założenia: zastąp je liczbami z pola usage własnych odpowiedzi.
W turze 50 żądanie niesie system prompt, 49 wcześniejszych tur i nową wiadomość: 400 + 49 × 250 + 60 = 12,710 tokenów wejściowych, żeby dostać odpowiedź o długości 190 tokenów. Zsumuj całą rozmowę. System prompt i nowa wiadomość są wysyłane za każdym razem: 50 × 460 = 23,000. Powtarzana historia dodaje 250 × 1,225 = 306,250. Razem: 23,000 + 306,250 = 329,250 tokenów wejściowych wobec 50 × 190 = 9,500 tokenów wyjściowych.
Historia w każdym żądaniu rośnie o jedną turę, więc suma rośnie z kwadratem długości rozmowy. Przejdź z 50 do 100 tur, a część z powtarzaną historią wzrośnie mniej więcej czterokrotnie.
Spróbuj samSprawdź się: gdybyś wysyłał tylko system prompt, ostatnie 4 tury i nową wiadomość, ile tokenów wejściowych niósłby w turze 50?Pokaż odpowiedź
1 460 (400 + 4 × 250 + 60) wobec 12 710 przy pełnej historii. To samo pytanie, ta sama długość odpowiedzi, ułamek wejścia.
Opcja 1: okno przesuwne#
Idea: zawsze wysyłaj system prompt, odrzuć wszystko poza ostatnimi N turami. Pełną historię trzymasz we własnym magazynie i przycinasz tylko kopię, którą wysyłasz.
def trim_history(messages, keep_pairs=4):
"""System prompt + the last keep_pairs turns + the new user message."""
system = [m for m in messages if m["role"] == "system"]
rest = [m for m in messages if m["role"] != "system"]
return system + rest[-(keep_pairs * 2 + 1):]Wywołaj to po dodaniu nowej wiadomości użytkownika. Przy keep_pairs=4 to 4 pary użytkownik/asystent plus nowa wiadomość, 9 wiadomości, a wycinek zawsze zaczyna się od wiadomości użytkownika. Oto jak to podłączyć do prawdziwego wywołania:
import os
from openai import OpenAI
client = OpenAI(
base_url="https://api.cheaptokens.dev/v1",
api_key=os.environ["CHEAPTOKENS_API_KEY"],
)
MODEL = "deepseek-ai/DeepSeek-V4-Flash-0731"
history = [{"role": "system", "content": "You are a concise support assistant."}]
def ask(text):
history.append({"role": "user", "content": text})
resp = client.chat.completions.create(
model=MODEL,
messages=trim_history(history),
max_tokens=500,
)
answer = resp.choices[0].message.content
history.append({"role": "assistant", "content": answer})
print(resp.usage.prompt_tokens, resp.usage.completion_tokens)
return answerPrzydatna jest linia print: obserwuj pierwszą liczbę. Bez przycinania rośnie z każdą turą. Z oknem przestaje rosnąć, gdy rozmowa przekroczy turę 4.

W liczbach: od tury 5 wzwyż każde żądanie to 400 + 4 × 250 + 60 = 1,460 tokenów wejściowych. Pierwsze cztery tury nadal rosną normalnie i sumują się do 3 340. Cała rozmowa: 3,340 + 46 × 1,460 = 70,500 tokenów wejściowych, około jednej piątej z 329 250 wysyłanych przy pełnej historii. Wyjście pozostaje 50 × 190 = 9,500.

W kodzie cała zmiana to jeden argument w wywołaniu:
Porównaj
Zmiana w jednej linii
Przed
messages=historyPo
messages=trim_history(history)Haczyk: okno zapomina. Jeśli użytkownik w turze 40 zapyta „jaki był mój numer zamówienia?”, a numer pojawił się w turze 3, model go nigdy nie widział. Dwa tanie rozwiązania. Wyciągnij trwałe fakty (imię, numer zamówienia, plan) z rozmowy we własnym kodzie i dopisz je do system promptu, gdzie okno nigdy ich nie odetnie. Albo dodaj podsumowanie, czyli następną opcję.
Opcja 2: podsumowanie starych tur#
Zamiast odrzucać stare tury, kompresujesz je. Co kilka tur wysyłasz do modelu tury, które właśnie wypadły z okna, plus bieżące podsumowanie, i prosisz o nowe, krótkie podsumowanie. Potem umieszczasz to podsumowanie w wiadomości systemowej.
def summarize(summary, old_messages):
transcript = "\n".join(f"{m['role']}: {m['content']}" for m in old_messages)
prompt = (
f"Summary so far:\n{summary}\n\nNew turns:\n{transcript}\n\n"
"Rewrite the summary in under 200 words. "
"Keep names, numbers, decisions and open questions."
)
resp = client.chat.completions.create(
model=MODEL,
messages=[{"role": "user", "content": prompt}],
max_tokens=400,
)
return resp.choices[0].message.content
def build_messages(history, summary, keep_pairs=4):
system = history[0]["content"]
if summary:
system += "\n\nEarlier in this chat: " + summary
recent = history[1:][-(keep_pairs * 2 + 1):]
return [{"role": "system", "content": system}] + recentPodsumowanie nie jest darmowe: to dodatkowe wywołanie modelu. Załóż podsumowanie o długości około 300 tokenów, odświeżane co 5 tur (9 razy w 50 turach), przy czym każde odświeżenie czyta około 1 600 tokenów (stare podsumowanie plus pięć tur plus instrukcja) i zapisuje 300. Żeby być po bezpiecznej stronie, licz podsumowanie w każdym żądaniu od tury 5 wzwyż (w rzeczywistości pojawia się po pierwszym odświeżeniu, więc to lekkie przeszacowanie): 400 + 300 + 4 × 250 + 60 = 1,760 tokenów wejściowych.
Sumy dla rozmowy: główne żądania 3,340 + 46 × 1,760 = 84,300 tokenów wejściowych, wywołania podsumowania 9 × 1,600 = 14,400 wejściowych i 9 × 300 = 2,700 wyjściowych. Łącznie 84,300 + 14,400 = 98,700 tokenów wejściowych i 9,500 + 2,700 = 12,200 wyjściowych.
Podsumowanie kosztuje nieco więcej niż samo okno, a w zamian model nadal wie, co się stało w turze 3.
Ile kosztują trzy konfiguracje#
Oto ta sama 50-turowa rozmowa na DeepSeek-V4-Flash, wyceniona na żywo na podstawie powyższych sum:
Ceny pochodzą z bieżącego cennika, więc liczby aktualizują się wraz z taryfą. Kolejność się nie zmieni: okno wysyła najmniej, podsumowanie jest pośrodku, pełna historia jest najdroższa.
Dla takiej rozmowy modelem CheapTokens na start jest DeepSeek-V4-Flash. Ma okno kontekstu 380K (50-turowa rozmowa mieści się nawet bez przycinania), do 32 768 tokenów wyjściowych na odpowiedź, jedną stałą cenę o każdej porze dnia i łącznie, licząc wejście i wyjście razem, jest tańszy niż OpenRouter. Identyfikator modelu to deepseek-. Jeśli chcesz porównać modele w konfiguracji z oknem (średnio 1 410 tokenów wejściowych na żądanie, 190 wyjściowych, 50 żądań), oto bieżąca tabela:
| Model | Wejście $/1M | Wyjście $/1M | Za żądanie | 50 żądań | OpenRouter, 50 żądań |
|---|---|---|---|---|---|
| GLM-5.3-Flash | $0.02 | $0.04 | $0.000036 | $0.0018 | $0.0032 |
| DeepSeek-V4-Flash | $0.015 | $0.10 | $0.00004 | $0.002 | $0.0063 |
| MiniMax-M2.7 | $0.05 | $0.15 | $0.000099 | $0.005 | $0.0594 |
1410 tokenów wejściowych i 190 tokenów wyjściowych na żądanie. Ceny za 1 mln tokenów są aktualne i zmieniają się wraz z naszymi taryfami; kolumna OpenRouter pokazuje ceny referencyjne dla tego samego obciążenia.
GLM-5.3-Flash ma kontekst 390K, a MiniMax-M2.7 ma 180K, co wystarcza na przyciętą rozmowę. Aktualne ceny są na stronie cennika, a dokumentacja pokazuje, jak wysłać pierwsze żądanie.
Co wybrać#
Okno jest domyślnym wyborem: trzy linie kodu, bez dodatkowych wywołań, bez dodatkowego trybu awarii. Używaj go do botów wsparcia, korepetytorów i odgrywania ról, gdzie kilka ostatnich tur niesie rozmowę, a system prompt niesie zasady. Dodaj podsumowanie, gdy użytkownicy odwołują się do rzeczy powiedzianych dawno temu, jak w osobistym asystencie z jedną niekończącą się rozmową. Trzymaj okno na tyle małe, żeby model nadal widział bezpośredni kontekst, i na tyle duże, żeby zmieściła się pełna wymiana pytania i odpowiedzi. Ile w ogóle się mieści, to osobny limit, opisany w czym jest okno kontekstu.
Szybkie sprawdzenie
Użytkownik w turze 40 pyta o numer zamówienia podany w turze 3. Używasz okna 4 tur bez podsumowania. Co się dzieje?
Pokaż odpowiedź
Odpowiedź: Model go nie widzi, bo tura 3 została odcięta z żądania
API jest bezstanowe. Model widzi tylko to, co jest w żądaniu, więc fakty, których nadal potrzebujesz, muszą pozostać w system promptcie lub w podsumowaniu.



