mandrock-files / ai

context-rot

Чому довга сесія тупіє: з чого складається контекст, що з'їдає його насправді, що гине при компакції і чому /clear лікує краще за будь-яке формулювання.

Чому довга сесія тупіє

Перші пів години агент влучний. Потім починає забувати домовленості, вертати помилки, які ми вже разом виправили, і «оптимізувати» рівно те, що я просив не чіпати. Спокуса — списати на те, що модель отупіла. Не отупіла: це не деградація ваг, це те, що я сам зробив з її контекстом за цю годину роботи.


З чого складається контекст

Складова Хто її туди кладе Чи можна впливати
Системний промпт рантайм ні
Схеми інструментів (MCP, вбудовані) конфіг так — вимикати сервери, tool search
Пам'ять / CLAUDE.md / правила файли на диску так — і це найдешевший важіль
Однорядкові описи скілів список активних скілів так — вимикати невживані
Історія повідомлень сесія так — /clear, /compact
Вивід інструментів сама робота частково
Вміст прочитаних файлів сама робота так — читати діапазони, не файли цілком

Розподіл у живій агентній сесії — не той, який здається на око. Проза самої моделі — одиниці відсотків від вікна. Основна маса це вивід інструментів і вміст файлів, а не те, що вона тобі відписує. Тому шліфувати багатослівність відповідей — це вилизувати ту частину, якої в контексті майже нема; економія там, де нема на чому економити.


Що конкретно псує якість

1. Змішані теми. Контекст, де одночасно лежать баг у вебхуках, конфіг nginx і суперечка про назву змінної, — це контекст, де релевантне тоне в нерелевантному. Модель нічого не «забуває» — вона щоразу обирає з більшого стогу, і що вищий стіг, то частіше промахується.

2. Спіраль виправлень. Кожне моє «ні, не так» лишається в історії разом із версією, яку я щойно забракував. На третій ітерації в контексті вже три хибні варіанти й одна розмита вимога — і модель бачить їх усі нарівні. Шанс влучити падає з кожним колом, а не росте, хоч по відчуттю здається навпаки.

3. Простирадла виводу. Один cat великого лог-файлу, один npm test із повним трейсом, одна відповідь MCP на 20k токенів — і піввікна забито сміттям, яке більше ніколи не знадобиться, але висітиме до кінця сесії.

4. Протухлі інструкції. Правило, дописане пів року тому під задачу, якої давно нема, — не нейтральний баласт. Воно активно тягне модель не туди, і робить це з інтонацією авторитетного джерела, якому хочеться вірити.

5. Суперечності. У CLAUDE.md написано одне, в чаті сказано друге, у скілі третє. Модель обере щось одне з трьох — і за законом підлості це буде не той варіант, на який я розраховував.


Що гине при компакції, а що ні

Це найменш очевидна частина — і саме на ній довгі сесії ламаються найгучніше.

Переживає компакцію Гине
Кореневий CLAUDE.md Правила зі скоупом paths:
Нескоуплені правила Вкладені CLAUDE.md
Авто-пам'ять (реінжектиться з диска) Лістинг доступних скілів
Тіла викликаних скілів (з лімітом) Обмеження, сказані тільки словами в чаті

Останній рядок таблиці — джерело найкласичнішого інциденту. Сказано «не пушити в main», агент погодився, за годину сталася компакція, ще за годину він спокійно запушив. Формально він нічого не порушив: на момент пушу тієї заборони в контексті вже не існувало — вона жила тільки в тексті чату, який компакція й з'їла.

Висновок: усе, що мусить виконатись гарантовано, живе в конфізі — permissions.deny, PreToolUse-хук, — а не в тексті розмови. Домовленість словами це не механізм, а обіцянка; компакція забирає обіцянки першими.


Що з цим робити

Гігієна:

Структура роботи:

Інструменти:

Правило двох спроб: дві невдалі корекції поспіль → /clear і переписати задачу з нуля, вже знаючи, де саме воно спотикається. Третя спроба в отруєному контексті — найдорожча з усіх помилок, бо ззовні виглядає як прогрес, а насправді закопує глибше.


Симптоми, за якими видно, що пора стирати

Будь-які два з цього списку одночасно — досить, не чекай третього.


Чекліст

P.S. — крива якості
  якість
    ▲
100%│●───●───●
    │           ●──●
 75%│                ●─●
    │                    ●──●         ← "дивно, вона ж
 50%│                        ●───●       щойно нормально
    │                             ●──●   працювала"
 25%│                                 ●───●───●───●
    │
  0%└────┬────┬────┬────┬────┬────┬────┬────┬────▶
         10   30   50   70   90  110  130  150   повідомлень
                                  ▲
                          отут треба було /clear
                          (приблизно 120 повідомлень тому)


  ┌──────────────────────────────────────────────┐
  │  людський підхід:  ще одне уточнення         │
  │  правильний:       Ctrl+A, Del, почати знову │
  └──────────────────────────────────────────────┘

Контекст поводиться як переповнений буфер: що більше туди пхаєш, то менше шансів дістати саме те, по що ліз. І десь на дні вже другий тиждень тихо протухає рядок, про який усі забули.