Сжатие контекста
В длинной беседе история сообщений рано или поздно становится слишком большой для контекстного окна модели. Велес решает это не удалением старых сообщений, а умным сжатием контекста: старые ходы сворачиваются в структурированное резюме, а системный промпт и свежие сообщения остаются дословными. Сжатие не переписывает стенограмму. Полная история остаётся в сохранённой сессии, а Велес только сдвигает границу уже свёрнутой части (last_consolidated)
и хранит накопительное резюме в метаданных сессии (contextSummary). При
следующих запросах модель получает не всю старую стенограмму, а это резюме плюс
несжатый свежий хвост беседы.
Главное в двух словах
Велес перед ответом оценивает размер текущего промпта. Если оценка стала больше порога, заданного как доляcontextWindowTokens, он выбирает старый безопасный
кусок истории, просит модель-резюмировщик обновить накопительное резюме,
выгружает этот кусок в долговременную память и убирает его из активного окна.
Например, при таких настройках:
75000 токенов:
150000 * 0.5. Защищённый свежий хвост по токенам будет около 15000 токенов:
75000 * 0.2, но Велес также постарается сохранить не меньше последних 20
сообщений дословно.
Сжатие внутри одного длинного ответа
Сжатие действует не только между сообщениями пользователя. Один ответ может сам состоять из десятков обращений к файлам, поиску и другим средствам. После каждого такого цикла Велес заново оценивает рабочий запрос. Обычно используется порогcontextWindowTokens * threshold. Если запас под следующий ответ, заданный maxTokens, оставляет модели меньше места, внутривызовный порог уменьшается до фактического бюджета запроса. Поэтому смысловое сжатие происходит раньше аварийного отсечения старой работы, даже если maxTokens настроен слишком большим.
При этом используются два разных представления:
- полный журнал вызовов и результатов остаётся неизменным для истории, восстановления и проверки;
- модель получает исходную задачу, накопительный контрольный снимок и свежий несжатый хвост работы.
compression: отдельной настройки для режима «Проект» нет. Изменение конфигурации во время работы применяется к следующим обычным ответам и исполнителям проекта.
Чем отличаются maxTokens и contextWindowTokens
Эти два поля часто путают, но они отвечают за разные части запроса.
contextWindowTokens должен быть реалистичной оценкой окна выбранной модели. Если
задать его выше фактического окна провайдера, Велес будет сжимать слишком поздно
и можно получить ошибку переполнения контекста. Если занизить значение, сжатие
будет срабатывать раньше, чем технически необходимо, зато с большим запасом.
Для одного длинного ответа эффективный порог считается так:
Когда срабатывает сжатие
Перед обычной обработкой сообщения Велес строит пробный промпт: системные инструкции, долговременная память, текущее резюме сжатой истории, несжатая часть диалога, новое сообщение пользователя и описания инструментов. Затем он оценивает размер этого промпта. Сжатие запускается, если:- в сессии есть сообщения;
contextWindowTokensбольше нуля;compression.enabledвключён;- оценка промпта больше
contextWindowTokens * compression.threshold.
threshold равен 0.5, то есть Велес начинает сжимать заранее,
когда занята примерно половина окна. Это оставляет место под новый ответ,
вызовы инструментов и небольшую погрешность оценки токенов.
Что происходит при сжатии
- Велес берёт блокировку сессии. Для одной сессии одновременно идёт только один цикл сжатия.
- Выбирается граница разреза. Велес ищет старую точку в истории, до которой сообщения можно свернуть. Граница ставится только перед сообщением пользователя, поэтому пары «вызов инструмента / результат инструмента» не разрываются.
- Защищается свежий хвост. Велес идёт от конца истории назад и оставляет
хвост не меньше бюджета
threshold * targetRatio. Дополнительно он старается сохранить последниеprotectLastNсообщений дословно. - Старый кусок резюмируется. Сообщения от
last_consolidatedдо найденной границы отправляются модели для резюме. Если резюме уже было, модель не пишет его заново, а обновляет прежнее. - Резюме сохраняется в метаданных. В
contextSummaryзаписываются текст, время обновления, счётчик сжатий и признак запасного резюме. - Сжатый кусок выгружается в долговременную память. Его можно будет найти
через
memory_search. - Граница
last_consolidatedсдвигается. При следующих запросах активная история начинается уже после сжатого куска, а старый контекст возвращается в промпт через резюме.
Как выглядит резюме
Резюме пишется как структурированный снимок предыдущей работы. В нём есть:- активная задача;
- цель пользователя;
- ограничения и предпочтения;
- выполненные действия;
- текущее состояние;
- незавершённая работа;
- блокеры и ошибки;
- важные решения;
- уже отвеченные вопросы;
- устаревшие открытые вопросы;
- затронутые файлы;
- критический контекст.
[REDACTED].
В системный промпт резюме вставляется с явной пометкой, что это только справка
по прошлой истории, а не новые инструкции. Это нужно, чтобы модель отвечала на
последнее сообщение пользователя и не пыталась продолжить уже завершённую или
отменённую старую задачу.
Что меняет каждая настройка
Подробности про отдельные поля
threshold
Формула порога:
contextWindowTokens = 150000:
Если указать значение ниже
0.2, Велес всё равно использует 0.2. Если указать
выше 0.95, будет использовано 0.95.
targetRatio
Формула хвоста:
contextWindowTokens = 150000 и threshold = 0.5 порог равен 75000.
Это не точное количество сообщений, а бюджет токенов. Если последние сообщения
длинные, в хвост попадёт меньше сообщений. Если короткие, больше.
protectLastN
protectLastN задаёт минимальное количество последних сообщений, которые Велес
старается оставить в активном окне дословно. Это защита поверх targetRatio.
Есть важная оговорка: если промпт уже достиг или превысил всё окно
contextWindowTokens, Велес считает это жёстким переполнением и может ослабить
защиту protectLastN, чтобы всё-таки освободить место. В этом аварийном режиме
он гарантированно сохраняет последний пользовательский ход, но может сжать
больше недавней истории, чем обычно.
maxSummaryTokens
Бюджет резюме считается от размера сжимаемого куска:
500 токенами и сверху
maxSummaryTokens. При maxSummaryTokens = 3000 резюме одного раунда обычно
будет не больше примерно 3000 токенов, а запрос к модели-резюмировщику даёт
ей немного больший лимит ответа, чтобы она могла завершить текст.
Если накопительное резюме становится слишком большим, Велес также ограничивает
его общий сохранённый текст: оставляет последние данные и добавляет пометку, что
самая старая часть резюме была обрезана.
summaryModel
summaryModel выбирает модель, которая пишет резюме. Если поле пустое, Велес
использует текущую модель беседы. Если поле задано, например
openrouter/deepseek/deepseek-v4-flash, резюме будет писать эта модель через тот
же провайдерский слой, который обрабатывает обычные вызовы моделей.
Практический смысл настройки:
- отдельная быстрая модель делает сжатие дешевле и быстрее;
- более сильная модель может лучше сохранять сложный контекст;
- если выбранная модель недоступна или возвращает пустой ответ, Велес не останавливает беседу, а использует запасное резюме.
Защита от сбоев
Если модель для резюме недоступна, вернула ошибку или пустой ответ, Велес создаёт детерминированное запасное резюме. В него попадают последние сообщения пользователя из сжимаемого куска и упомянутые пути к файлам. Если раньше уже было хорошее резюме, запасной блок дописывается к нему, а не заменяет его. После ошибки включается пауза на повторные обращения к модели-резюмировщику. Во время этой паузы Велес сразу использует запасное резюме, чтобы не тратить каждый ход на заведомо неудачный вызов. Есть и защита от «пробуксовки»: если очередной раунд сжатия уменьшил оценку промпта меньше чем примерно на 5 %, Велес прекращает дальнейшие раунды. В журнале он предложит начать новую беседу командой/new.
Что происходит при выключенном сжатии
Еслиcompression.enabled = false, Велес не вставляет накопительное резюме в
системный промпт. Вместо этого включается прежний режим: когда оценка промпта
доходит до contextWindowTokens, старые сообщения выгружаются в долговременную
память до тех пор, пока активная история не станет примерно вдвое меньше окна.
Такой режим экономит место, но хуже удерживает непрерывность длинной работы:
модель видит меньше связного контекста прямо в промпте и должна при
необходимости искать детали через память.
Связь с долговременной памятью
Сжатие контекста и долговременная память дополняют друг друга. Сжатие управляет активным окном беседы, а память хранит свёрнутые участки и устойчивые факты. При каждом сжатии старый кусок не только попадает в резюме, но и выгружается в память, поэтому подробности можно поднять инструментомmemory_search.
Команда /new очищает сообщения текущей беседы, сбрасывает last_consolidated
и удаляет накопительное contextSummary из метаданных сессии.