Ти вже кілька годин вбиваєш у модель деталі проєкту: ідеї, бачення, як ти хочеш, щоб усе працювало. Файли, залежності, рішення. Вона киває, відповідає по суті.
Потім — БАМ, повідомлення 40, і вона пропонує саме те, що ти відкинув у повідомленні 5.
Ну й око та око за цими LLM-ами, що тут скажеш!
Вітаю — ви вперлися в контекстне вікно.
Це все, що модель «бачить» у процесі розмови: ваші повідомлення, її відповіді, системні інструкції, описи інструментів, вміст прочитаних файлів. Один великий шматок тексту, який вимірюється в токенах.
Але все має межу, і контекстне вікно теж. Деякі моделі зараз підтримують розмір контекстного вікна до ~1M токенів в окремих конфігураціях API. Звучить вражаюче, доки не усвідомлюєш: один файл на 2000 рядків — це вже ~20k токенів. П’ять файлів… і ви вже витратили 100k на контекст.
Також LLM нічого не пам’ятає між викликами. Щоразу, коли ти надсилаєш повідомлення, клієнт (Claude Code, Cursor, ChatGPT) збирає всю історію і надсилає її моделі одним шматком. Модель читає, генерує відповідь і забуває все.
Те, що виглядає як «пам’ять», — це пам’ять клієнта, а не моделі. Він просто пересилає історію.
sequenceDiagram participant Client as Client<br/>(Claude Code / Cursor / ChatGPT) participant LLM as LLM<br/>(stateless) Note over Client: Stores history rect rgb(197, 224, 203) Note left of Client: Call 1 Client->>LLM: system prompt + tools + project files + msg1 LLM-->>Client: resp1 Note right of LLM: Forgets everything end Note over Client: History: msg1 + resp1 rect rgb(197, 224, 203) Note left of Client: Call 2 Client->>LLM: system prompt + tools + project files + msg1 + resp1 + msg2 LLM-->>Client: resp2 Note right of LLM: Forgets everything end Note over Client: History: msg1 + resp1 + msg2 + resp2 rect rgb(197, 224, 203) Note left of Client: Call 3 Client->>LLM: system prompt + tools + project files + msg1 + resp1 + msg2 + resp2 + msg3 LLM-->>Client: resp3 Note right of LLM: Forgets everything end Note over Client: Stores everything Note over LLM: Stores nothing
Окей, історія надсилається повністю. Тоді чому модель усе одно «забуває»?
Причин три:
1. Розмиття уваги.
Модель розподіляє увагу між усіма токенами. При 1000 токенах кожен має свою вагу. При 500 000 — вага розмазується, і якщо все однаково важливе, то нічого не важливе. Ключова інструкція фізично є в контексті, але модель на неї просто не звертає уваги. Приблизно як ти перестаєш помічати деталі у величезному документі.
2. Ефект “lost in the middle”.
Модель найкраще «пам’ятає» початок і кінець контексту. Середина — сліпа зона. Якщо твоє ключове рішення опинилося на токені 200 000 із мільйона… ну що ж, удачі тобі з цим.
3. Накопичення сміття.
Кожна невдала спроба, кожен прочитаний файл, кожен довгий вивід команди залишається в контексті. Після години роботи значна частина вікна, умовні 60%, це мотлох від провалених спроб. Модель бачить усе це разом і не може відрізнити корисне від сміття.
Коли вікно заповнюється повністю, відбувається одне з двох: або найстаріші повідомлення обрізаються, або починається компакція. У Claude Code це компакція: окремий LLM-виклик, який стискає стару історію в коротке резюме.
Але деталі втрачаються назавжди: точні значення, конкретні рядки коду, причини, через які ті чи інші підходи були відкинуті, — усе зникає.
Після компакції модель може впевнено галюцинувати за обривками. І найнеприємніше: вона не знає, чого вона не знає.
Гаразд, тепер зрозуміло, чому контекст розвалюється. Що з цим робити?
У мене є кілька правил:
- Додавай файл лише тоді, коли він потрібен для поточного завдання, — не «про всяк випадок». Зайвий контекст не допомагає, він розмиває увагу.
- Якщо інструкція має закріпитися — помісти її в головний конфіг-файл клієнта:
CLAUDE.md,.cursorrulesі подібні.
Так не доведеться повторювати моделі одне й те саме знову і знову. Можна спокійно перезапускати сесії, оскільки клієнт завантажить ці інструкції заново на початку наступної.
Ці файли зазвичай опиняються на самому початку контексту. Якщо цей початок не змінюється, сервер може повторно використати вже виконані обчислення (якщо час кешу ще не закінчився). Що економить і час, і токени. - Перемикаєшся на інше завдання? Почни нову сесію. Шум від попереднього завдання просочується в якість відповідей на наступне.
- Компакція — це не обов’язково погано. Якщо ти працюєш над тим самим завданням і розмова просто затягнулася — нехай компакція робить свою справу. Суть завдання залишається в резюме. Втрачаються невдалі спроби й конкретні деталі. Але ти ж дотримуєшся правила 2 — тож усе гаразд!
- Уся агентна архітектура — субагенти, MCP, ліниве завантаження інструментів, файли пам’яті — це різні способи обійти одну й ту саму проблему: контекст скінченний, і з часом він псується. Детальніше — в mcp і agents.
- Бачиш дивну поведінку в довгій сесії? Це симптом зіпсованого контексту. Почисть контекст або почни нову сесію.
Але що щодо кешу?
Тут часто плутаються: клієнт (Claude Code, Cursor і подібні) усе одно щоразу надсилає повний контекст мережею. Кешується не передача даних. Кешуються обчислення на стороні сервера.
Коли модель отримує 100k токенів, вона не читає їх як текст. Вона виконує величезну кількість матричних обчислень. Сервер перевіряє, що вже було пораховано минулого разу, і перераховує лише нове. Під капотом провайдери можуть повторно використовувати вже обчислені частини промпта через механізми prompt caching / KV-cache. Тож та частина контексту, яка не змінилася, може не перераховуватися з нуля щоразу.
flowchart TD A["User / Client (Claude Code, Cursor)<br/>sends full context, every request over the network"] --> B["Server receives N tokens"] B --> C{"Is cached prefix<br/>still valid? TTL not expired?"} C -->|"No — expired or prefix changed"| F["Recompute context<br/>(full matrix pass)"] C -->|"Yes — same prefix, still within TTL"| D["Reuse cached K/V<br/>for the unchanged prefix"] D --> G["Compute only new tokens<br/>added after the cached prefix"] F --> H["Generate response"] G --> H classDef client fill:#dee3c6,stroke:#758879,stroke-width:1.5px,color:#2d2d30 classDef server fill:#e3d7c6,stroke:#8b7e7a,stroke-width:1.5px,color:#2d2d30 classDef decision fill:#ddc6e3,stroke:#7e7a8b,stroke-width:1.5px,color:#2d2d30 classDef cached fill:#c5e0cb,stroke:#758879,stroke-width:1.5px,color:#2d2d30 classDef compute fill:#e3c6d2,stroke:#8b7a87,stroke-width:1.5px,color:#2d2d30 classDef response fill:#c5e0cb,stroke:#758879,stroke-width:1.5px,color:#2d2d30 class A client class B server class C decision class D,G cached class F compute class H response
Це важливо на практиці: провайдери реалізують кеш по-різному. Варто стежити за тим, як довго кеш зберігається на сервері. Це може змінюватися з часом, але розуміння цих обмежень може зіграти тобі на руку.
Якщо кеш живе годину або п’ять хвилин, можна постаратися не йти на довгу каву прямо посеред сесії, щоб зекономити. Але не жертвуй якістю сесії заради грошей.
Бо планування, читання власних планів і чітке формулювання думок та ідей — значно важливіші, а зрештою можуть бути й дешевшими, ніж пояснювати LLM, що вона робить не те, і намагатися підштовхнути її в правильний бік.
Одна порада щодо цього: збережи плани, вийди із сесії, уважно їх перечитай, сформулюй думки і почни нову сесію з чистого аркуша.
У всього є своя користь і свій компроміс — треба просто знайти правильний.