Оптимізація витратПосібник
Обрізайте історію чату, щоб зменшити витрати: ковзне вікно чи резюме
Обмежте те, що ви надсилаєте заново на кожному ході: збережіть останні кілька повідомлень або коротке резюме. Арифметика токенів для 50-ходової розмови та хелпер Python.

На цій сторінці
Ваш бот підтримки спілкується вже 50 ходів, і кожне нове повідомлення коштує дорожче за попереднє. API нічого не пам'ятає, тож ваш код щоразу надсилає всю розмову заново. Рішення — обмежити те, що ви надсилаєте: зберегти системний промпт і останні кілька ходів (ковзне вікно) або замінити старі ходи коротким резюме. Нижче — арифметика для 50-ходової розмови та хелпер, який можна скопіювати.
Посібник DeepSeek з багатораундового чату (api-docs.deepseek.com, перевірено 1 листопада 2026 року) каже прямо: сервер не зберігає контекст попередніх запитів, тож клієнт надсилає повний список messages під час кожного виклику. Формат, сумісний з OpenAI, на CheapTokens працює так само. Якщо це для вас нове, почніть з чому довгий чат коштує дорожче та як працює масив messages.
Що насправді надсилає хід 50#
Припустімо, ви запускаєте бота підтримки із системним промптом на 400 токенів. У типовому ході користувач пише близько 60 токенів, а бот відповідає приблизно 190. Один повний хід додає 250 токенів до історії. Це припущення: замініть їх числами з поля usage ваших власних відповідей.
На ході 50 запит містить системний промпт, 49 попередніх ходів і нове повідомлення: 400 + 49 × 250 + 60 = 12,710 вхідних токенів, щоб отримати відповідь на 190 токенів. Підсумуймо всю розмову. Системний промпт і нове повідомлення надсилаються щоразу: 50 × 460 = 23,000. Повторювана історія додає 250 × 1,225 = 306,250. Разом: 23,000 + 306,250 = 329,250 вхідних токенів проти 50 × 190 = 9,500 вихідних токенів.
Історія в кожному запиті зростає на один хід, тож загальна сума зростає як квадрат довжини розмови. Перейдіть з 50 на 100 ходів — і частина з повторюваною історією приблизно зросте вчетверо.
Спробуйте саміСпробуйте: якби ви надсилали лише системний промпт, останні 4 ходи та нове повідомлення, скільки вхідних токенів ніс би хід 50?Показати відповідь
1 460 (400 + 4 × 250 + 60) проти 12 710 з повною історією. Те саме питання, та сама довжина відповіді, крихта від входу.
Варіант 1: ковзне вікно#
Ідея: завжди надсилати системний промпт, відкидати все, крім останніх N ходів. Повну історію ви зберігаєте у власному сховищі й обрізаєте лише ту копію, яку надсилаєте.
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):]Викликайте її після того, як додали нове повідомлення користувача. З keep_pairs=4 це 4 пари користувач/асистент плюс нове повідомлення, 9 повідомлень, і зріз завжди починається з повідомлення користувача. Ось як це вбудовано в реальний виклик:
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 answerРядок print — корисний: стежте за першим числом. Без обрізання воно зростає з кожним ходом. З вікном воно перестає зростати, щойно розмова переходить за хід 4.

У числах: починаючи з ходу 5, кожен запит — це 400 + 4 × 250 + 60 = 1,460 вхідних токенів. Перші чотири ходи все ще зростають нормально й у сумі дають 3 340. Уся розмова: 3,340 + 46 × 1,460 = 70,500 вхідних токенів, приблизно п'ята частина від 329 250, які ви надсилаєте з повною історією. Вихід залишається 50 × 190 = 9,500.

У коді вся зміна — це один аргумент у виклику:
Порівняйте
Зміна в один рядок
До
messages=historyПісля
messages=trim_history(history)Підступ: вікно забуває. Якщо на ході 40 користувач запитає «який був мій номер замовлення?», а номер був на ході 3, модель його ніколи не бачила. Два дешеві виправлення. Витягніть сталі факти (ім'я, номер замовлення, тариф) із розмови у власному коді й додайте їх до системного промпту, де вікно їх ніколи не обріже. Або додайте резюме — це наступний варіант.
Варіант 2: резюме старих ходів#
Замість відкидання старих ходів ви їх стискаєте. Кожні кілька ходів надсилайте ходи, що щойно випали з вікна, разом з поточним резюме моделі й просіть нове коротке резюме. Потім вставляйте це резюме в системне повідомлення.
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}] + recentРезюме не безкоштовне: це додатковий виклик моделі. Припустімо, резюме на близько 300 токенів, оновлюване кожні 5 ходів (9 разів за 50 ходів), кожне оновлення читає близько 1 600 токенів (старе резюме плюс п'ять ходів плюс інструкція) і пише 300. Щоб бути на безпечному боці, рахуйте резюме в кожному запиті починаючи з ходу 5 (насправді воно з'являється після першого оновлення, тож це трохи завищена оцінка): 400 + 300 + 4 × 250 + 60 = 1,760 вхідних токенів.
Підсумки для розмови: основні запити 3,340 + 46 × 1,760 = 84,300 вхідних токенів, виклики резюме 9 × 1,600 = 14,400 вхідних і 9 × 300 = 2,700 вихідних. Усього 84,300 + 14,400 = 98,700 вхідних і 9,500 + 2,700 = 12,200 вихідних токенів.
Резюме коштує трохи більше за голе вікно, а натомість модель усе ще знає, що сталося на ході 3.
Скільки коштують три конфігурації#
Ось та сама 50-ходова розмова на DeepSeek-V4-Flash, порахована за живими цінами з підсумків вище:
Ціни беруться з живого прайс-листа, тож числа оновлюються, коли змінюється тариф. Порядок не зміниться: вікно надсилає найменше, резюме посередині, повна історія найдорожча.
Для такої розмови модель CheapTokens, з якої варто почати, — DeepSeek-V4-Flash. Вона має контекстне вікно 380K (50-ходова розмова вміщується навіть необрізаною), до 32 768 вихідних токенів на відповідь, одну фіксовану ціну в будь-яку годину доби, і загалом, з урахуванням входу й виходу разом, вона дешевша за OpenRouter. Ідентифікатор моделі — deepseek-. Якщо хочете порівняти моделі на конфігурації з вікном (у середньому 1 410 вхідних токенів на запит, 190 вихідних, 50 запитів), ось жива таблиця:
| Модель | Вхід $/1М | Вихід $/1М | За запит | 50 запитів | OpenRouter, 50 запитів |
|---|---|---|---|---|---|
| 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 |
1 410 вхідних і 190 вихідних токенів на запит. Ціни за 1 млн токенів актуальні та змінюються разом із нашими тарифами; стовпець OpenRouter показує довідкові ціни для того самого навантаження.
GLM-5.3-Flash має контекст 390K, а MiniMax-M2.7 — 180K, чого достатньо для обрізаної розмови. Актуальні ціни — на сторінці цін, а документація показує, як надіслати перший запит.
Що вибрати#
Вікно — це типовий варіант: три рядки коду, жодних додаткових викликів, жодного додаткового режиму відмови. Використовуйте його для ботів підтримки, репетиторів і рольових ігор, де останні кілька ходів несуть розмову, а системний промпт несе правила. Додавайте резюме, коли користувачі посилаються на сказане давно, як у персональному асистенті з однією нескінченною розмовою. Тримайте вікно достатньо малим, щоб модель усе ще бачила безпосередній контекст, і достатньо великим, щоб умістити повний обмін питанням-відповіддю. Скільки взагалі вміщується — це окрема межа, розглянута в що таке контекстне вікно.
Швидка перевірка
На ході 40 користувач запитує про номер замовлення, наданий на ході 3. Ви використовуєте 4-ходове вікно без резюме. Що станеться?
Показати відповідь
Відповідь: Модель його не побачить, бо хід 3 було вирізано із запиту
API не має стану. Модель бачить лише те, що є в запиті, тож факти, які вам ще потрібні, мають залишатися в системному промпті або в резюме.



