temporality
Изменить страницу↗
Инженерные документы

Компакция контекста: карточка состояния для длинных ранов

Статус: действующий механизм (v1).

#1. Проблема

История messages строго append-only (prompt cache на префиксе), поэтому контекст рана растёт на каждом ходе. Измерения (2026-11, 1067 ранов): p50 ≈ 56k токенов, p90 ≈ 151k, максимум 730k (~1.8–2.0 МБ пейлоада при 2.4–3.0 виртуальных байта на токен). Суммарно раны израсходовали ~1.76 млрд input-токенов. Два следствия:

#2. Принцип

Когда запрос перестаёт влезать в бюджет — не гони его. Сожми середину истории в карту состояния, оставь хвост дословно, работай дальше.

Компакция — оптимизация, а не гейт: её сбой никогда не останавливает ран (событие context.compaction_failed, а пейлоад-гард остаётся честным рубежом).

#3. Механика

  1. Триггер — на границе хода, перед планированием call_model: сериализованный запрос > compactionTriggerBytes (1.2 МБ ≈ 400–500k токенов: выше нормального рана (p90 ≈ 150k), ниже потолка 2 МиБ).
  2. Активити kernel.compact_context — один вызов дешёвой дефолтной модели (та же роль, что у генерации заголовков рана) над дайджестом истории (сообщения с head+tail капом, скриншоты — числом, без байт). На выход — строго структурированная карточка состояния (≤ 8 КБ): `## Task / ## Decisions / ## Files and artifacts / ## Verified /

    #Open questions / ## Next step`. Промпт требует идентификаторы

    (пути, id, хэши, числа) передавать дословно.
  3. Пересборка messages: system-промпт и исходный запрос юзера — всегда дословно (контракт с пользователем), карточка — одним system сообщением с рамкой («это запись вытесненной работы»), хвост — последние 2–8 целых групп хода (assistant + его tool-ответы; нарушать tool-contiguous контракт API нельзя), ≤ 256 КБ.
  4. Событие context.compacted (turn, bytes_before/after, card, kept/dropped) — карточка видна в просмотре рана: «что помнит агент».

#4. Согласованность

#5. Ограничения