Pi объяснил, как устроено сжатие контекста в кодинг-агенте

Технический разбор на сайте earendil.com объясняет, как в кодинг-агенте Pi устроено сжатие (compaction), то, что происходит с историей диалога, когда она подходит к пределу контекстного окна модели. У языковых моделей ограниченный размер контекстного окна, то, что модель может «видеть» при формировании ответа. Каждый запрос кодинг-агента вроде Pi, Claude Code или Codex включает системный промпт, загруженные файлы (например, AGENTS.md), описания инструментов и всю историю диалога вместе с результатами вызовов инструментов. С каждым новым ходом эта история растёт: в неё добавляются очередной ответ модели, результаты вызовов инструментов и новое сообщение пользователя. Рано или поздно история превышает предел контекстного окна, и очередной запрос к модели возвращается с ошибкой вроде «Request exceeds the maximum size» (запрос превышает максимальный размер).
Когда работать с текущей историей диалога дальше нельзя, есть два пути. Первый, начать новый, пустой диалог: это отбрасывает всю историю, включая принятые решения и незавершённую работу, но так тоже может быть разумно поступить, поскольку качество ответов модели снижается по мере роста контекста. Второй путь, сжать историю до меньшего представления и продолжить тот же диалог; именно это делает сжатие (compaction). Теоретически сжатие можно реализовать как детерминированную функцию, которая просто отбрасывает часть истории, но на практике реализации сжатия вместо этого делают отдельный запрос к языковой модели с просьбой суммировать историю диалога.
В Pi сжатие запускается, когда объём истории приближается к пределу контекстного окна, а также вручную, командой /compact. Проверка на необходимость авто-сжатия происходит после завершения каждого хода: до этого момента новый запрос просто продолжает существующий промпт и может переиспользовать его закэшированную часть. Если же запрос всё-таки превышает лимит контекста прямо посреди хода, Pi может запустить сжатие и в этот момент. При сжатии Pi сохраняет без изменений некоторое количество последних сообщений, их число зависит от настраиваемого бюджета токенов; сейчас бюджет по умолчанию составляет 20 тысяч токенов, что соответствует примерно 5, 20 ходам диалога. Всё, что было до этой отметки, извлекается, сериализуется и отправляется на суммаризацию.
Сам запрос на сжатие в Pi отличается от обычных запросов в диалоге. Системный промпт для него другой: вместо «ты, опытный кодинг-ассистент» модели говорят «ты, ассистент по суммаризации контекста». Отличается и пользовательское сообщение, оно просит «структурированную сводку этой ветки диалога для контекста при возвращении к работе позже» с фиксированными разделами: цель, прогресс и ключевые решения. Поскольку это отдельный запрос, не использующий остальную историю диалога, для него можно взять другую модель, без лишних затрат. Результат сжатия добавляется в сессию Pi как обычная текстовая запись, а не в каком-то служебном формате: это делает сжатый контекст читаемым и переносимым, поэтому в Pi можно сменить модель прямо по ходу работы и продолжать использовать ту же сводку.
У сжатия есть побочный эффект, оно ломает кэширование промпта. Провайдеры моделей кэшируют повторяющиеся части запроса, чтобы в рамках одного диалога такие части обходились дешевле, но для этого начало запроса (префикс) должно точно совпадать с уже закэшированным. После сжатия сохранённые последние сообщения остаются теми же токенами, но теперь идут после другого префикса, сводки вместо полной старой истории, поэтому их прежнее закэшированное состояние переиспользовать нельзя, и первый запрос после сжатия идёт уже без скидки за кэш. Начиная со следующих запросов кэширование снова начинает работать.
Отдельно авторы отмечают, что Pi расширяем: стандартный механизм сжатия можно заменить своим, создав для Pi расширение с собственным промптом для сжатия.
Ключевые факты
- Сжатие в Pi запускается, когда история диалога приближается к пределу контекстного окна модели, а также вручную, командой /compact; если запрос превышает лимит прямо посреди хода, сжатие может сработать и в этот момент.
- По умолчанию Pi сохраняет без изменений последние сообщения в пределах бюджета 20 тысяч токенов, это примерно 5, 20 ходов диалога; всё, что старше, идёт на суммаризацию.
- Суммаризация делается отдельным ИИ-запросом с другим системным промптом («ассистент по суммаризации контекста» вместо «кодинг-ассистента») и просьбой оформить сводку по разделам: цель, прогресс, ключевые решения.
- Запрос на сжатие не использует остальную историю диалога, поэтому для него можно взять другую модель без лишних затрат; сводка хранится как обычный текст, что позволяет переключать модель в Pi и продолжать работу с той же сводкой.
- Сжатие ломает кэширование промпта, потому что провайдерам нужен точно совпадающий префикс запроса: первый запрос после сжатия идёт без скидки за кэш, а со следующих запросов кэш снова начинает работать.
Почему это важно
У любого кодинг-агента, который работает поверх языковой модели, есть жёсткий предел, контекстное окно модели. Чем дольше сессия, тем больше в истории диалога системных сообщений, инструментов и результатов их вызовов, и рано или поздно очередной запрос просто отклоняется с ошибкой переполнения. У разработчика агента есть выбор: начать всё заново, потеряв контекст задачи, или сжать историю и продолжить работу. Ценность статьи в том, что она показывает не абстрактную теорию, а то, как этот механизм устроен внутри конкретного продукта, какой у него бюджет удержания последних сообщений, каким запросом формируется сводка и почему сжатие имеет побочный эффект в виде разрушения кэша промпта.
Кому это важно
В первую очередь, разработчикам, которые сами строят или дорабатывают ИИ-агентов для кода: статья даёт конкретный образец того, как устроить сжатие истории диалога, с бюджетом токенов, отдельным промптом для суммаризации и текстовым форматом сводки. Полезна она и тем, кто просто пользуется кодинг-агентами вроде Pi, Claude Code или Codex в долгих сессиях: понимание того, когда и как срабатывает сжатие, объясняет, почему после долгой работы агент вдруг теряет часть деталей истории или почему конкретный запрос после паузы идёт без обычной скидки за кэш.
Как это применить
Для пользователей Pi путь прямой: агент расширяем, и стандартный механизм сжатия можно заменить своим, попросить Pi создать расширение с собственным промптом для сжатия под конкретную задачу. Для тех, кто проектирует похожую инфраструктуру у себя, статья даёт переносимый паттерн: держать «хвост» из последних ходов в рамках токенового бюджета без изменений, а всё более старое сворачивать отдельным недорогим ИИ-запросом с другим системным промптом и фиксированной структурой сводки (цель / прогресс / решения), храня результат простым текстом, чтобы сводка не зависела от конкретной модели.
Можно ли доверять
Материал написан от первого лица множественного числа («мы») о собственном продукте, судя по всему, это блог самой команды, которая делает Pi; ни имени автора, ни даты публикации в тексте статьи нет. Это описание архитектуры от лица её создателей, а не независимая проверка или бенчмарк со стороны: изложенные детали, бюджет токенов, структура промпта, стоит воспринимать как заявленное поведение системы, а не как измеренное третьими лицами.
Риски и подводные камни
Сжатие, это суммаризация языковой моделью, а значит, часть деталей истории неизбежно теряется при переходе к сводке. Первый запрос после сжатия идёт без скидки от кэша промпта, потому что сжатие меняет начало запроса, статья прямо об этом говорит. Часть сжатий происходит не по плану, а реактивно, посреди хода, когда запрос уже превысил лимит контекста, то есть это ещё и подстраховка на крайний случай, а не только плановая операция. При этом статья не называет модель, которая выполняет суммаризацию, не приводит общий размер контекстного окна и не показывает ни одного реального примера итоговой сводки или того, как часто сжатие срабатывает в обычной сессии, оценить качество результата по одной только статье нельзя.