Назад в блог

AI для новичковИнструкция

Почему длинный чат с ИИ дороже: API шлёт всю историю

Каждое новое сообщение отправляет в модель всю историю чата заново, поэтому вход растёт с каждым ходом. Расчёт и 3 способа сократить расход.

Автор: CheapTokens TeamОпубликовано Обновлено 5 мин чтения

Обложка: «Почему длинный чат с каждым сообщением дороже» — API отправляет всю историю на каждом ходу
Содержание
  1. Коротко
  2. Учебный расчёт на условных числах
  3. Сколько это стоит по живым ценам
  4. Три способа сдержать расход
  5. 1. Начинайте новый чат, когда тема сменилась
  6. 2. Обрезайте историю
  7. 3. Заменяйте старые ходы кратким пересказом
  8. Увидьте рост в своём коде
  9. Где запускать длинные чаты

Первые сообщения чата стоят совсем мало. Пятидесятое стоит заметно дороже десятого, хотя вы печатаете столько же. Ничего не сломалось: так устроены чат-API.

Коротко#

Модель не помнит ваши прошлые запросы. Документация OpenAI говорит прямо: «each text generation request is independent and stateless» («каждый запрос генерации текста независим и не хранит состояние»), а для диалога из нескольких ходов в следующий запрос нужно добавить прежние сообщения и предыдущий ответ модели. Messages API у Anthropic описывает тот же приём: диалог без хранения состояния, прежние реплики передаются в параметре messages.

Значит, окно чата в приложении — иллюзия, которую создаёт само приложение. За ним каждое новое сообщение — свежий запрос, в котором лежит весь разговор до этого момента. Входные токены оплачиваются в каждом запросе, а история входит во вход. Если термины незнакомы, сначала прочитайте Что такое токен и Входные и выходные токены.

OpenAI явно пишет о списании для своих цепочек ответов: все прежние входные токены цепочки тарифицируются как входные. Тот же принцип верен для любого API, где историю отправляете вы сами: считается то, что вы отправили.

Учебный расчёт на условных числах#

Числа ниже — пример для объяснения, а не замер. Допустим, ваше сообщение занимает около 200 токенов, ответ — около 300. Один законченный обмен добавляет в историю 500 токенов.

Ход Прежняя история, отправленная снова Новое сообщение Вход этого запроса Выход
1 0 200 200 300
5 500 × 4 = 2 000 200 2 200 300
10 500 × 9 = 4 500 200 4 700 300
20 500 × 19 = 9 500 200 9 700 300

Ответ остаётся той же длины, а вход на 20-м ходу почти в пятьдесят раз больше входа на первом. Выход не растёт, растёт вход.

Теперь итог для чата из 20 ходов. История пересылается 0, 1, 2 ... 19 раз по числу обменов — это простая сумма:

  • Старые обмены, отправленные снова: 500 × 190 = 95 000 токенов (190 — это 0 + 1 + 2 + ... + 19).
  • Новые сообщения: 200 × 20 = 4 000 токенов.
  • Весь вход чата: 95 000 + 4 000 = 99 000 токенов.
  • Весь выход: 300 × 20 = 6 000 токенов.

Если бы модель помнила всё сама, вход был бы только 200 × 20 = 4 000 токенов. Остальное — повторно отправленная история. Удвоение числа ходов не удваивает стоимость истории, а примерно учетверяет, потому что сумма растёт как квадрат числа ходов.

Сколько это стоит по живым ценам#

Тот же чат из 20 ходов (99 000 на вход, 6 000 на выход) по текущим ценам. Таблица живая и обновляется при смене тарифов; последний столбец — справочная цена OpenRouter для сравнения.

Модель Стоимость OpenRouter
GLM-5.3-Flash $0.0022 $0.0045
DeepSeek-V4-Flash $0.0021 $0.0056
MiniMax-M2.7 $0.0059 $0.0369

99 000 входных и 6 000 выходных токенов всего. Цены за 1M токенов актуальны и меняются вместе с нашими тарифами; столбец OpenRouter показывает справочные цены для той же нагрузки.

Коротко в тексте: на MiniMax-M2.7 весь этот разговор стоит $0.0059. В таком чате вход преобладает, поэтому важнее всего цена входа: у MiniMax-M2.7 она ниже справочной цены OpenRouter. За 1M токенов MiniMax-M2.7 стоит $0.05 за вход и $0.15 за выход.

Три способа сдержать расход#

1. Начинайте новый чат, когда тема сменилась#

Самая дешёвая история — пустая. Если вы закончили отладку функции и теперь хотите рецепт, новый чат отправит 200 токенов вместо 9 700. В приложении это одна кнопка, в коде — history = []. Делайте так, когда прежний контекст уже не помогает следующему вопросу.

2. Обрезайте историю#

Оставляйте несколько последних сообщений, остальное отбрасывайте. Пусть сохраняются три последних обмена, то есть история не больше 500 × 3 = 1 500 токенов:

  • Ходы 1–3 растут как обычно: 0 + 500 + 1 000 = 1 500 токенов истории.
  • Ходы 4–20 несут урезанные 1 500 каждый: 1 500 × 17 = 25 500 токенов.
  • История в сумме: 1 500 + 25 500 = 27 000 токенов, плюс 4 000 новых сообщений = 31 000 токенов входа.

Это 31 000 вместо 99 000 за те же 20 ходов, а на MiniMax-M2.7 выходит $0.0025. Цена обрезки — модель забывает начало разговора, поэтому системный промпт и факты, которые нельзя терять, держите вне обрезаемой части.

3. Заменяйте старые ходы кратким пересказом#

Когда история разрослась, один раз попросите модель её пересказать и дальше продолжайте с пересказом вместо полного текста. В примере выше девять обменов — это 4 500 токенов; пересказ примерно в 300 токенов несёт главное. Вы платите за один дополнительный запрос на пересказ, а каждый следующий запрос становится легче. Так сохраняется больше смысла, чем при простой обрезке, ценой части деталей.

Контекстное окно — отдельный лимит: он ограничивает, сколько токенов помещается в один запрос вместе с ответом. История рано или поздно упрётся в него; об этом — Почему ответ ИИ обрывается на полуслове?

Увидьте рост в своём коде#

В ответе есть объект usage, так что рост можно наблюдать самому. Это пример: подставьте свой ключ и возьмите id модели из документации CheapTokens — у разных провайдеров имена отличаются.

python
from openai import OpenAI

client = OpenAI(base_url='https://api.cheaptokens.dev/v1', api_key='YOUR_KEY')

system = {'role': 'system', 'content': 'You are a helpful assistant.'}
history = []
KEEP = 7  # new message + last 3 exchanges (6 messages); None keeps everything

def ask(text):
    history.append({'role': 'user', 'content': text})
    r = client.chat.completions.create(
        model='MODEL_ID_FROM_DOCS',
        messages=[system] + (history[-KEEP:] if KEEP else history),
    )
    answer = r.choices[0].message.content
    history.append({'role': 'assistant', 'content': answer})
    print(r.usage.prompt_tokens, r.usage.completion_tokens)
    return answer

Вызовите ask() несколько раз подряд и смотрите на prompt_tokens: при KEEP = None он растёт каждый ход, при KEEP = 7 выходит на плато. В агентах, которые идут по многим шагам, тот же эффект действует на каждом шаге; как заложить его в бюджет — в Как оценить стоимость ИИ-агента.

Где запускать длинные чаты#

Длинные диалоги и циклы агентов — именно та нагрузка, где преобладает объём входа, поэтому важны и большое контекстное окно, и запас на длинные ответы:

  • MiniMax-M2.7: контекст 180K, до 8 192 токенов в ответе, вход и выход дешевле справочной цены OpenRouter.
  • DeepSeek-V4-Flash: контекст 380K, до 32 768 токенов в ответе, выход дешевле справочной цены OpenRouter.

У CheapTokens один баланс на все модели, фиксированная цена каждой модели без пиковых часов и API, совместимый с OpenAI Chat Completions и Anthropic Messages, так что код выше работает после смены base URL. Пополните баланс и отправьте первый запрос по инструкции Ваш первый API-запрос в CheapTokens.