Керування сесіями та ущільнення (глибокий розбір)
У цьому документі пояснюється, як OpenClaw керує сесіями наскрізно:- Маршрутизація сесій (як вхідні повідомлення зіставляються з
sessionKey) - Сховище сесій (
sessions.json) і що воно відстежує - Збереження транскрипту (
*.jsonl) та його структура - Гігієна транскрипту (виправлення для конкретних провайдерів перед запусками)
- Обмеження контексту (вікно контексту проти відстежуваних токенів)
- Ущільнення (ручне + автоущільнення) і куди підключати роботу перед ущільненням
- Тихі службові дії (наприклад, запис пам’яті, який не повинен створювати видимий для користувача вивід)
- /concepts/session
- /concepts/compaction
- /concepts/memory
- /concepts/memory-search
- /concepts/session-pruning
- /reference/transcript-hygiene
Джерело істини: Gateway
OpenClaw спроєктовано навколо єдиного процесу Gateway, який володіє станом сесій.- Інтерфейси (macOS app, веб-інтерфейс Control UI, TUI) мають запитувати в Gateway списки сесій і кількість токенів.
- У віддаленому режимі файли сесій розміщені на віддаленому хості; “перевірка локальних файлів на Mac” не покаже те, що використовує Gateway.
Два шари збереження
OpenClaw зберігає сесії у двох шарах:-
Сховище сесій (
sessions.json)- Мапа ключ/значення:
sessionKey -> SessionEntry - Маленьке, змінюване, безпечно редагувати (або видаляти записи)
- Відстежує метадані сесії (поточний id сесії, останню активність, перемикачі, лічильники токенів тощо)
- Мапа ключ/значення:
-
Транскрипт (
<sessionId>.jsonl)- Транскрипт лише з додаванням записів із деревоподібною структурою (записи мають
id+parentId) - Зберігає фактичну розмову + виклики інструментів + зведення ущільнення
- Використовується для відновлення контексту моделі для майбутніх ходів
- Транскрипт лише з додаванням записів із деревоподібною структурою (записи мають
Розташування на диску
Для кожного агента, на хості Gateway:- Сховище:
~/.openclaw/agents/<agentId>/sessions/sessions.json - Транскрипти:
~/.openclaw/agents/<agentId>/sessions/<sessionId>.jsonl- Сесії тем Telegram:
.../<sessionId>-topic-<threadId>.jsonl
- Сесії тем Telegram:
src/config/sessions.ts.
Обслуговування сховища та контроль диска
Збереження сесій має автоматичні механізми обслуговування (session.maintenance) для sessions.json і артефактів транскриптів:
mode:warn(типово) абоenforcepruneAfter: поріг віку застарілих записів для очищення (типово30d)maxEntries: обмеження кількості записів уsessions.json(типово500)rotateBytes: ротаціяsessions.json, коли файл стає завеликим (типово10mb)resetArchiveRetention: термін зберігання архівів транскриптів*.reset.<timestamp>(типово: такий самий, якpruneAfter;falseвимикає очищення)maxDiskBytes: необов’язковий бюджет каталогу sessions на дискуhighWaterBytes: необов’язкова ціль після очищення (типово80%відmaxDiskBytes)
mode: "enforce"):
- Спочатку видалити найстаріші архівовані або осиротілі артефакти транскриптів.
- Якщо все ще вище за ціль, витіснити найстаріші записи сесій і їхні файли транскриптів.
- Продовжувати, доки використання не стане на рівні або нижче
highWaterBytes.
mode: "warn" OpenClaw повідомляє про можливі витіснення, але не змінює сховище/файли.
Запустити обслуговування на вимогу:
Cron-сесії та журнали запусків
Ізольовані запуски cron також створюють записи сесій/транскрипти, і для них є окремі налаштування зберігання:cron.sessionRetention(типово24h) очищає старі сесії ізольованих запусків cron зі сховища сесій (falseвимикає).cron.runLog.maxBytes+cron.runLog.keepLinesобрізають файли~/.openclaw/cron/runs/<jobId>.jsonl(типові значення:2_000_000байтів і2000рядків).
Ключі сесій (sessionKey)
sessionKey визначає, у якому кошику розмови ви перебуваєте (маршрутизація + ізоляція).
Поширені шаблони:
- Основний/приватний чат (на агента):
agent:<agentId>:<mainKey>(типовоmain) - Група:
agent:<agentId>:<channel>:group:<id> - Кімната/канал (Discord/Slack):
agent:<agentId>:<channel>:channel:<id>або...:room:<id> - Cron:
cron:<job.id> - Webhook:
hook:<uuid>(якщо не перевизначено)
Ідентифікатори сесій (sessionId)
Кожен sessionKey вказує на поточний sessionId (файл транскрипту, який продовжує розмову).
Основні правила:
- Скидання (
/new,/reset) створює новийsessionIdдля цьогоsessionKey. - Щоденне скидання (типово о 4:00 ранку за місцевим часом на хості gateway) створює новий
sessionIdу наступному повідомленні після межі скидання. - Завершення через простій (
session.reset.idleMinutesабо застарілеsession.idleMinutes) створює новийsessionId, коли повідомлення надходить після вікна простою. Якщо налаштовано і щоденне скидання, і простій, спрацьовує те, що настане раніше. - Захист від форку батьківського ланцюжка (
session.parentForkMaxTokens, типово100000) пропускає форк батьківського транскрипту, коли батьківська сесія вже надто велика; новий потік починається з нуля. Установіть0, щоб вимкнути.
initSessionState() у src/auto-reply/reply/session.ts.
Схема сховища сесій (sessions.json)
Тип значення сховища — SessionEntry у src/config/sessions.ts.
Ключові поля (не вичерпний список):
sessionId: поточний id транскрипту (ім’я файлу виводиться з нього, якщо не заданоsessionFile)updatedAt: мітка часу останньої активностіsessionFile: необов’язкове явне перевизначення шляху транскриптуchatType:direct | group | room(допомагає інтерфейсам і політиці надсилання)provider,subject,room,space,displayName: метадані для позначення груп/каналів- Перемикачі:
thinkingLevel,verboseLevel,reasoningLevel,elevatedLevelsendPolicy(перевизначення для конкретної сесії)
- Вибір моделі:
providerOverride,modelOverride,authProfileOverride
- Лічильники токенів (best-effort / залежать від провайдера):
inputTokens,outputTokens,totalTokens,contextTokens
compactionCount: скільки разів автоущільнення завершувалося для цього ключа сесіїmemoryFlushAt: мітка часу останнього скидання пам’яті перед ущільненнямmemoryFlushCompactionCount: лічильник ущільнень, коли востаннє виконувався flush
Структура транскрипту (*.jsonl)
Транскриптами керує SessionManager з @mariozechner/pi-coding-agent.
Файл має формат JSONL:
- Перший рядок: заголовок сесії (
type: "session", міститьid,cwd,timestamp, необов’язковийparentSession) - Далі: записи сесії з
id+parentId(дерево)
message: повідомлення user/assistant/toolResultcustom_message: повідомлення, інжектовані розширенням, які потрапляють у контекст моделі (можуть бути приховані від UI)custom: стан розширення, який не потрапляє у контекст моделіcompaction: збережене зведення ущільнення зfirstKeptEntryIdіtokensBeforebranch_summary: збережене зведення під час навігації гілкою дерева
SessionManager для їх читання/запису.
Вікна контексту проти відстежуваних токенів
Важливі два різні поняття:- Вікно контексту моделі: жорстке обмеження для кожної моделі (токени, видимі моделі)
- Лічильники сховища сесій: ковзна статистика, що записується в
sessions.json(використовується для /status і панелей)
- Вікно контексту береться з каталогу моделей (і може бути перевизначене через конфігурацію).
contextTokensу сховищі — це оцінка/значення звітності під час виконання; не сприймайте його як сувору гарантію.
Ущільнення: що це таке
Ущільнення підсумовує старішу частину розмови в збережений записcompaction у транскрипті та залишає недоторканими недавні повідомлення.
Після ущільнення майбутні ходи бачать:
- Зведення ущільнення
- Повідомлення після
firstKeptEntryId
Межі чанків ущільнення та поєднання інструментів
Коли OpenClaw розбиває довгий транскрипт на чанки для ущільнення, він зберігає виклики інструментів асистента поєднаними з відповідними записамиtoolResult.
- Якщо поділ за часткою токенів припадає між викликом інструмента та його результатом, OpenClaw зміщує межу до повідомлення асистента з викликом інструмента, а не розділяє пару.
- Якщо кінцевий блок результатів інструмента інакше перевищив би цільовий розмір чанка, OpenClaw зберігає цей очікувальний блок інструмента і залишає неузагальнений хвіст недоторканим.
- Перервані/помилкові блоки викликів інструментів не утримують відкритим очікувальний поділ.
Коли відбувається автоущільнення (середовище Pi)
У вбудованому агенті Pi автоущільнення спрацьовує у двох випадках:- Відновлення після переповнення: модель повертає помилку переповнення контексту
(
request_too_large,context length exceeded,input exceeds the maximum number of tokens,input token count exceeds the maximum number of input tokens,input is too long for the model,ollama error: context length exceededта подібні варіанти, характерні для конкретних провайдерів) → ущільнити → повторити спробу. - Порогове обслуговування: після успішного ходу, коли:
contextTokens > contextWindow - reserveTokens
Де:
contextWindow— це вікно контексту моделіreserveTokens— це запас токенів, зарезервований для промптів + наступного виводу моделі
Налаштування ущільнення (reserveTokens, keepRecentTokens)
Налаштування ущільнення Pi зберігаються в налаштуваннях Pi:
- Якщо
compaction.reserveTokens < reserveTokensFloor, OpenClaw підвищує значення. - Типовий поріг —
20000токенів. - Установіть
agents.defaults.compaction.reserveTokensFloor: 0, щоб вимкнути цей поріг. - Якщо значення вже вище, OpenClaw залишає його без змін.
ensurePiCompactionReserveTokens() у src/agents/pi-settings.ts
(викликається з src/agents/pi-embedded-runner.ts).
Поверхні, видимі користувачу
Ви можете спостерігати ущільнення і стан сесії через:/status(у будь-якому чаті сесії)openclaw status(CLI)openclaw sessions/sessions --json- Режим verbose:
🧹 Auto-compaction complete+ кількість ущільнень
Тихі службові дії (NO_REPLY)
OpenClaw підтримує “тихі” ходи для фонових завдань, де користувач не повинен бачити проміжний вивід.
Умова:
- Асистент починає свій вивід з точного тихого токена
NO_REPLY/no_reply, щоб позначити “не доставляти відповідь користувачу”. - OpenClaw прибирає/приглушує це на рівні доставки.
- Приглушення точного тихого токена нечутливе до регістру, тож
NO_REPLYіno_replyобидва зараховуються, коли весь payload — це лише тихий токен. - Це лише для справді фонових ходів/ходів без доставки; це не скорочений шлях для звичайних практичних запитів користувача.
2026.1.10, OpenClaw також приглушує чернетковий/набірний стримінг, коли
частковий чанк починається з NO_REPLY, щоб тихі операції не видавали частковий
вивід посеред ходу.
”Скидання пам’яті” перед ущільненням (реалізовано)
Мета: перед тим як відбудеться автоущільнення, виконати тихий агентний хід, який записує стійкий стан на диск (наприклад,memory/YYYY-MM-DD.md у робочому просторі агента), щоб ущільнення не могло
стерти критичний контекст.
OpenClaw використовує підхід flush до порога:
- Відстежувати використання контексту сесії.
- Коли воно перетинає “м’який поріг” (нижчий за поріг ущільнення Pi), виконати тиху директиву “запиши пам’ять зараз” для агента.
- Використовувати точний тихий токен
NO_REPLY/no_reply, щоб користувач нічого не бачив.
agents.defaults.compaction.memoryFlush):
enabled(типово:true)softThresholdTokens(типово:4000)prompt(повідомлення user для ходу flush)systemPrompt(додатковий системний промпт, який додається для ходу flush)
- Типові значення prompt/system prompt містять підказку
NO_REPLYдля приглушення доставки. - Flush виконується один раз за цикл ущільнення (відстежується в
sessions.json). - Flush виконується лише для вбудованих сесій Pi.
- Flush пропускається, коли робочий простір сесії доступний лише для читання (
workspaceAccess: "ro"або"none"). - Див. Memory щодо структури файлів робочого простору та шаблонів запису.
session_before_compact в API розширень, але логіка flush в OpenClaw
сьогодні живе на боці Gateway.
Контрольний список усунення несправностей
- Неправильний ключ сесії? Почніть із /concepts/session і перевірте
sessionKeyу/status. - Невідповідність між сховищем і транскриптом? Перевірте хост Gateway і шлях до сховища з
openclaw status. - Спам ущільненням? Перевірте:
- вікно контексту моделі (замале)
- налаштування ущільнення (
reserveTokensзавелике для вікна моделі може спричиняти раніше ущільнення) - роздуття tool-result: увімкніть/налаштуйте очищення сесії
- Тихі ходи протікають? Переконайтеся, що відповідь починається з
NO_REPLY(нечутливий до регістру точний токен) і що у вас збірка, яка містить виправлення приглушення стримінгу.