Миллион токенов — не память
Сегодня я поймал неприятный эффект в работе с кодовым агентом: большой контекст создаёт ощущение, что можно расслабиться и больше не думать о гигиене сессии.
Работал с Opus-моделью в агентной среде. Заявленный контекст — около миллиона токенов, размышления выкручены на максимум. Задача при этом была простая: наш Pomodoro-таймер, который мы сегодня правили и выкатывали. Проект маленький, вся программа занимает смешную часть такого окна.
Я решил вести одну длинную сессию, чтобы каждый раз заново не объяснять агенту, что мы делаем, какие правки уже внесены и где что лежит. Казалось логично: если есть миллион токенов, можно просто продолжать один чат.
Но на практике всё сломалось раньше, чем я ожидал.
Миллион токенов — не память
Проблемы начались примерно на 20–30% заполнения контекста. По индикатору вроде бы ещё огромный запас. Но если перевести это в абсолютные числа, получается уже примерно 200–300 тысяч токенов истории.
И вот на этом объёме агент начал заметно тупить на простых вещах.
Я прошу поменять небольшую деталь — он меняет. Но не думает, какие последствия это потянет. Чинит в одном месте, ломает в другом. Потом чинит второе — снова ломает первое. Вместо нормальной причинно-следственной цепочки появляется хождение по кругу: здесь поправил, там сломал, потом опять вернулся к тому же месту.
Самое неприятное — проект не был большим. Это не сложная промышленная система с сотнями модулей. Это маленькое приложение, которое должно помещаться в контекст с огромным запасом. Значит, проблема не в том, что модель «не увидела» код. Она его видела. Но видеть — не значит держать актуальную рабочую модель проекта.
Контекстное окно — это не память. Это длинный входной буфер.
Память должна уметь отбирать главное, забывать устаревшее, различать факт, гипотезу и ошибку. А длинный чат просто хранит всё подряд: старые решения, логи, неудачные попытки, отменённые идеи, промежуточные версии кода и мои же уточнения по ходу работы.
Если это не чистить, контекст превращается не в память, а в свалку.
Почему длинный чат начинает вредить
У короткой сессии есть полезное свойство: почти всё, что в ней лежит, относится к текущей задаче. Сигнала больше, шума меньше.
В длинной сессии всё наоборот. Там лежит не только актуальное состояние проекта, но и вся история того, как мы к нему пришли. Для человека это иногда полезно. Для модели — не всегда.
Кодовый агент начинает работать не с текущим проектом, а со смесью:
- текущего кода;
- старых версий файлов;
- прошлых ошибок;
- уже отменённых решений;
- логов, которые давно потеряли значение;
- моих промежуточных объяснений, которые были актуальны только десять сообщений назад.
Формально всё это находится внутри окна. Но внутри окна нет автоматической сортировки на «актуальное», «устаревшее» и «мусор». Модель каждый раз должна сама понять, что важно сейчас.
И чем больше чат, тем выше шанс, что она выберет не тот кусок истории.
Что говорит наука
Это хорошо ложится на то, что уже видно в исследованиях длинного контекста.
В работе Lost in the Middle: How Language Models Use Long Contexts показали, что модели используют длинный контекст неравномерно. Они лучше держат начало и конец, а информация в середине часто проседает. Для длинного агентного чата это болезненно: важные решения легко оказываются как раз где-то в середине.
Бенчмарк RULER от NVIDIA прямо задаёт вопрос: какой реальный размер контекста у длинноконтекстных моделей? Вывод там неприятный: заявленное окно и реально полезный контекст — разные вещи.
LongBench показывает похожую проблему на длинных задачах: большой вход не гарантирует глубокого понимания, агрегации и рассуждения.
А простые тесты в стиле «иголка в стоге сена» вообще плохо описывают разработку. Найти одну фразу в миллионе токенов — это не то же самое, что понять, почему правка в одном компоненте ломает другой.
Есть ещё удачный термин context rot — гниение контекста. Чем больше в сессии лишнего, старого и противоречивого, тем сильнее падает качество. Я сегодня увидел это руками.
Как я теперь буду с этим работать
Главный вывод для себя: большой контекст полезен как возможность, но опасен как стиль работы.
Не надо вести один бесконечный чат на весь проект. Особенно в разработке. Лучше работать короткими итерациями:
- Маленькая задача.
- Короткий план.
- Изменение.
- Проверка.
- Коммит.
- Краткое резюме текущего состояния.
- Новая чистая сессия.
Git должен быть внешней памятью. Тесты — арбитром. Резюме — мостом между сессиями. А чат — временным рабочим буфером, который можно выбрасывать.
Я всё больше прихожу к мысли, что модель с меньшим окном, но понятным контролем заполнения, иногда практичнее, чем миллионный контекст, который создаёт иллюзию безопасности. На 20% кажется, что всё ещё впереди. А по факту там уже сотни тысяч токенов, и агент начинает плыть.
Теперь мой ориентир простой: если агент начал повторяться, чинить одно и ломать другое, спорить с фактическим состоянием файлов или забывать только что принятые решения — не надо продолжать давить в ту же сессию.
Нужно сохранить актуальное состояние, очистить историю и начать следующую итерацию с компактного контекста.
Потому что длинный контекст — это не интеллект и не память. Это просто много текста. А много текста без отбора быстро превращается в шум.