Почему ИИ-агент сжигает токены: как я снизил стоимость сессии с 48 до 8 рублей

На тридцатом шаге мой ИИ-агент отправлял нейросети 123 856 входных токенов. Один запрос весил как небольшой роман и стоил соответственно. При этом большая часть контекста уже приезжала раньше: логи, прочитанные файлы, старые ответы инструментов и описания тех инструментов, которые на этом шаге вообще не использовались.
Я начал резать повторный контекст. Сначала на сервере, потом на компьютере пользователя. За два дня вокруг простой идеи выросли локальный архив, оглавление сессии, загрузка схем инструментов по требованию и песочница для вычислений.
На одном и том же 30-шаговом сценарии стоимость снизилась с 48,26 до 8,40 рубля, а вход — с 2,4 миллиона до 419 тысяч токенов. Полный вариант решил 30 задач из 30.
Красиво. Даже слишком.
Стенд был синтетическим. Когда я вынес движок в живого агента, выяснилось, что на коротких задачах оптимизация может сделать всё дороже. Тут и начинаются границы красивой цифры.

Историческая оговорка. В сентябре 2026 года эта часть проекта называлась KD Context. Сейчас она не распространяется как отдельный продукт: механики развиваются внутри KD Code и KD Engine. В статье я сохраняю старое название, потому что описываю конкретные эксперименты 1–2 сентября.
Как работает ИИ-агент и почему один лог оплачивается снова
У большинства LLM API нет памяти о предыдущем обращении в человеческом смысле. Чтобы модель продолжила разговор, клиент снова передаёт ей историю. ИИ-агент добавляет к этой истории результаты своих действий: прочитанные файлы, выводы команд, найденные фрагменты кода, ошибки, диффы.
Если совсем коротко, токен — это фрагмент текста, который обрабатывает нейросеть. Слово может занимать один токен или несколько. Контекстное окно — максимальный объём токенов, который модель способна принять за один раз. Большое окно не делает повторную передачу бесплатной: вход по-прежнему учитывается при каждом обращении к API.
Первые несколько шагов выглядят безобидно. Потом история начинает расти сама.
Допустим, на третьем шаге агент прочитал лог на восемь тысяч строк. На четвёртом он исправил конфигурацию. На пятом проверил тесты. Если клиент каждый раз отправляет полный разговор, тот старый лог поедет в модель и на шестом, и на десятом, и на тридцатом шаге. Пользователь платит за него снова, хотя агенту давно нужна одна строчка: «в конфигурации был неверный адрес».
В моём контрольном сценарии это выглядело так:
первый шаг — 7 140 входных токенов;
тридцатый — 123 856;
все 30 шагов — 2 404 803 входных токена;
фактическое списание — 48,2588 рубля.
Рост получался почти линейным: каждый новый запрос наследовал груз предыдущих.

Тридцатый шаг. Агент снова привёз модели весь предыдущий разговор.
Первая оптимизация контекста: Trim на сервере
Сначала я полез в самое очевидное место — в шлюз между клиентом и моделью. Если в запросе накопилось несколько больших результатов инструментов, старые можно свернуть, а последние оставить целиком.
Механизм получил простое название Trim.
В первом тяжёлом тесте восемь циклов с логами дали 126 767 входных токенов. После Trim осталось 37 780. Биллинговая нагрузка снизилась с 299 472 до 85 904 условных единиц — примерно на 71%.
Результат обрадовал меня ровно до тех пор, пока я не посмотрел на границу системы.
Trim работал у меня на сервере. Но лишний контекст рождался раньше — на компьютере пользователя, где жил агент. Клиент сначала собирал огромный запрос, загружал его по сети, а уже потом мой шлюз пытался понять, что можно выкинуть.
Получалось, что я лечу последствия. Нужен был слой перед отправкой.
И ещё одна проблема: Trim ничего не доказывал про качество. Он показал, что умеет уменьшать конкретный тяжёлый вход. Не показал, что модель после этого сохранит нужные факты.
Сжатие контекста без удаления оригинала
Идея локального архива появилась из простой аналогии.
Представьте, что вы разговариваете с помощником по телефону, а между звонками он ничего не помнит. У вас на столе лежит длинный отчёт. Нет смысла зачитывать его целиком в начале каждого разговора. Достаточно сказать, о чём он, где лежит оригинал и какие места могут понадобиться. Если возникнет вопрос, помощник попросит нужную страницу.
Архив делал то же самое:
Полный результат инструмента оставался на компьютере пользователя.
В запрос попадало короткое представление и пометка о локальном оригинале.
Если модели не хватало деталей, агент мог дочитать нужный фрагмент через
kd_expand.
Это не «сжатие без потерь». Краткое представление неизбежно чего-то не содержит. Гарантия в другом: оригинал не уничтожается и не отправляется наружу целиком без необходимости.
На первом тяжёлом примере прямой вариант занял 79 400 входных токенов. Серверный Trim оставил 26 858. Локальный архив — 6 853. Стоимость одного сценария снизилась с 0,4766 до 0,0413 рубля.
Я перепроверил результат несколько раз. Потом взял сценарий длиннее.
Тридцать шагов: где архив окупился
В следующем тесте было 30 рабочих ходов и шесть отдельных проверок памяти. Каждый рабочий ход добавлял вывод объёмом от трёх до восьми тысяч символов. Модель оставалась одной и той же, сценарий тоже.
Прямой путь накопил 2 404 803 входных токена и стоил 48,26 рубля. Версия с архивом — 929 628 токенов и 18,71 рубля. На тридцатом шаге вместо 123 856 входных токенов уехало 35 710.
Но первые пять шагов с архивом были дороже прямого пути. Сводки и служебные ссылки тоже занимают место, а повторов в начале ещё мало. На четвёртом шаге накопленная стоимость архива превышала контроль в 1,36 раза. Окупился он только на шестом шаге, примерно после 27 тысяч токенов накопленного входа.
Вот здесь у меня впервые появилось правило, которое позже пришлось выучить ещё раз: оптимизация контекста сама расходует контекст. На короткой задаче она может быть чистым налогом.
Одного архива мало
Архив убрал большие повторные результаты, но в запросе оставалось ещё много постоянного груза. За вечер я нашёл несколько независимых источников.
1. Схемы инструментов по требованию
У coding-агента есть набор инструментов: прочитать файл, найти строку, выполнить команду, применить патч. Вместе с названием модели получает JSON Schema каждого инструмента — описание параметров и формата вызова.
В моём стенде было 20 подробных схем. Они приезжали на каждом шаге, даже если текущая задача требовала одного поиска.
Этот слой я назвал реестром инструментов. Полные описания подключались по мере необходимости. Модель по-прежнему понимала, какие возможности у неё есть, но не получала все подробности заранее.

Когда нужен один поиск, а в запрос уехали схемы двадцати инструментов.
2. Скелет сессии
Полная стенограмма нужна редко. Чаще модели достаточно оглавления:
Шаг 5: изучили конфигурацию API
Шаг 9: нашли неверный адрес
Шаг 12: исправили настройку
Шаг 14: тесты прошли
Скелет не заменяет исходную историю. Он помогает понять, где искать подробности, если они понадобятся.
3. Сворачивание закрытых тупиков
Агент попробовал один путь, получил ошибку и пошёл другим. Неудачная ветка уже выполнила свою работу: показала, что конкретный способ не годится. Дальше достаточно сохранить причину отказа, а не все команды и ответы внутри ветки.
В контексте остаётся короткая запись вроде: «вариант с наследуемой настройкой проверен; значение переопределяется уровнем выше».
4. Локальные вычисления
Если нужно посчитать ошибки в большом JSON или сумму по CSV, модель не обязана читать весь файл. Она может сформулировать вычисление, локальная песочница выполнит его рядом с данными, а в запрос вернётся результат.
Для этого появился kd_run. В тесте два совокупных вопроса были посчитаны локально: 75 ошибок по всем логам и сумма 4 956 843 по всем выгрузкам. Оба ответа совпали с контролем.
5. Реестр прочитанных файлов
Если агент повторно открывает неизменившийся файл, отправлять ту же копию бессмысленно. Реестр запоминает версию, которую агент уже видел. При следующем чтении можно вернуть изменения или ссылку на сохранённый оригинал.
Все эти механизмы работали вокруг одной границы: оригиналы остаются локально, а наружу отправляется минимальное самодостаточное представление текущей задачи.
Как был устроен финальный тест
Я повторил тот же 30-шаговый сценарий на gpt-5-6-sol. В нём было 30 рабочих ответов, шесть проверок памяти и 20 подробных схем инструментов. Серверный Trim выключил, чтобы он не смешивался с работой локального движка.
Полный вариант включал режим archive, скелет сессии, локальные kd_expand и kd_run, реестр прочитанных файлов и реестр инструментов. Здесь я намеренно описываю внешнюю роль слоёв, но не их внутренние правила и алгоритмы.
Валидных прогонов было два:
Прогон | Рабочие ответы | Память | Входные токены | Списано |
|---|---|---|---|---|
Первый | 30/30 | 6/6 | 419 452 | 8,4010 ₽ |
Второй | 30/30 | 6/6 | 419 423 | 8,3977 ₽ |
Среднее | 30/30 | 6/6 | 419 438 | 8,3994 ₽ |
Для сравнения:
Режим | Входные токены | Стоимость | Последний ход |
|---|---|---|---|
Прямой контроль | 2 404 803 | 48,2588 ₽ | 123 856 |
Только архив | 929 628 | 18,71 ₽ | 35 710 |
Полный набор, среднее двух прогонов | 419 438 | 8,3994 ₽ | 14 460–14 461 |
Относительно прямого контроля вход уменьшился на 82,56%, фактическое списание — на 82,60%. Один и тот же сценарий обошёлся примерно в 5,75 раза дешевле.
Первый шаг полного варианта занял 4 598 токенов против 7 140 у прямого контроля. То есть проблема дорогого старта, которую я увидел у одного архива, в этом сценарии исчезла.
И качество не просело. Прямой контроль дал 25 из 30 рабочих ответов и прошёл пять из шести проверок памяти. Полный вариант — 30 из 30 и шесть из шести.
Где заканчивается доказательство
Теперь неприятная, но необходимая часть.
Стенд был синтетическим. Нужные инструменты подставлял сценарий, а не выбирал живой агент. Поэтому я проверил механизм преобразования контекста, но не стоимость полного агентного цикла. В настоящей работе агент может выбрать не тот инструмент, сделать лишний круг или неправильно запросить оригинал.
Прямой контроль также не нёс дополнительные 20 схем, которые были в экспериментальном сценарии. Это делает денежное сравнение консервативным в пользу контроля, но не превращает тест в универсальный.
Я также не проверял вклад каждого слоя по отдельности. Результат 8,40 рубля относится к набору целиком. По этому эксперименту нельзя раздать экономию по компонентам и сказать, сколько отдельно принесли архив, реестр или локальные вычисления.
Наконец, это один класс тяжёлой длинной сессии. Он ничего не обещает коротким задачам.

Стенд: 30 из 30. Живая сессия: познакомься с накладными расходами.
Первый выход в реальную работу
В тот момент я считал техническую часть почти законченной. Оставалось завернуть её в приложение: убрать команды и флаги, показать обычное окно, дать открыть папку проекта и работать.
Через несколько дней живой тест на лёгкой сессии быстро остудил оптимизм. Прямой вариант сделал 42 обращения и набрал 251 тысячу входных токенов. Движок — 62 обращения и 664 тысячи. Качество на выбранной бесплатной модели нельзя было сравнивать честно, поэтому я не использую этот запуск как численную оценку штрафа. Но направление было очевидным: на малом контексте служебные механизмы создавали больше работы, чем экономили.
Пришлось перестать мыслить режимами «включено» и «выключено». Движок должен сначала оценить задачу и вмешиваться только там, где ожидаемая экономия выше его собственных накладных расходов.
Позже появились пороги, адаптивные правила и отдельные проверки для файлов, команд и поиска по проекту. Но решение выросло именно из того отрицательного теста, а не из красивых 82,6%.
Что я вынес из этих двух дней
Первое: считать нужно завершённую задачу. Число токенов само по себе ничего не говорит, если агент потерял факт или сделал десять дополнительных вызовов.
Второе: оригинал лучше хранить рядом с агентом. Краткая карта экономит контекст, но у модели должен оставаться путь к нужному фрагменту.
Третье: длинные и короткие сессии требуют разных решений. Механизм, который спасает на тридцатом шаге, способен навредить на первом.
И последнее. В сентябре я думал, что строю компрессор контекста. Получился скорее небольшой компилятор: он решает, какие части рабочего состояния нужны модели сейчас, какие можно представить короче, а какие лучше вообще обработать локально.
Слово «сжатие» для этого оказалось слишком маленьким.
Что именно подтверждают эти цифры
В статье приведены агрегаты зафиксированного сценария: модель, число шагов, объём входа, фактическое списание и результат проверок. Этого достаточно, чтобы увидеть масштаб эффекта и ограничения теста.
Внутренние файлы проекта, сырые журналы, промпты, пороги и алгоритмы обработки я не публикую. Они раскрыли бы реализацию, но почти ничего не добавили бы к главному выводу статьи. Если вы тестируете собственную оптимизацию контекста, важнее повторить сам подход к проверке: зафиксировать сценарий, отдельно измерять стоимость и качество, а затем обязательно прогнать решение на короткой живой сессии.
KioskNews shows a cleaned-up reading view extracted from the publisher’s page — the original always lives on their site, not ours.