Подробный разбор управления сессиями
В этом документе объясняется, как OpenClaw управляет сессиями от начала до конца:
- Маршрутизация сессий (как входящие сообщения сопоставляются с
sessionKey) - Хранилище сессий (
sessions.json) и что оно отслеживает - Сохранение транскрипта (
*.jsonl) и его структура - Гигиена транскрипта (исправления, специфичные для провайдера, перед запусками)
- Лимиты контекста (контекстное окно vs отслеживаемые токены)
- Компрессия (ручная + автоматическая) и где подключить работу перед компрессией
- Фоновая служебная работа (например, запись в память, которая не должна создавать видимый пользователю вывод)
Если вам сначала нужен обзор высокого уровня, начните с:
Единый источник истины: Шлюз
OpenClaw построен вокруг единого процесса Шлюза (Gateway), который владеет состоянием сессий.
- Пользовательские интерфейсы (приложение для macOS, веб-интерфейс Control UI, TUI) должны запрашивать у Шлюза списки сессий и счетчики токенов.
- В удаленном режиме файлы сессий находятся на удаленном хосте; «проверка ваших локальных файлов на Mac» не будет отражать то, что использует Шлюз.
Два уровня сохранения состояния
OpenClaw сохраняет сессии на двух уровнях:
- Хранилище сессий (
sessions.json)- Карта ключ/значение:
sessionKey -> SessionEntry - Небольшое, изменяемое, безопасно для редактирования (или удаления записей)
- Отслеживает метаданные сессии (текущий идентификатор сессии, последняя активность, переключатели, счетчики токенов и т.д.)
- Карта ключ/значение:
- Транскрипт (
<sessionId>.jsonl)- Дополняемый транскрипт с древовидной структурой (записи имеют
id+parentId) - Хранит фактический разговор + вызовы инструментов + сводки компрессии
- Используется для восстановления контекста модели для будущих ходов
- Дополняемый транскрипт с древовидной структурой (записи имеют
Расположение на диске
Для каждого агента на хосте Шлюза:
- Хранилище:
~/.openclaw/agents/<agentId>/sessions/sessions.json - Транскрипты:
~/.openclaw/agents/<agentId>/sessions/<sessionId>.jsonl- Сессии тем Telegram:
.../<sessionId>-topic-<threadId>.jsonl
- Сессии тем Telegram:
OpenClaw разрешает эти пути через 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: опциональный бюджет для директории сессийhighWaterBytes: опциональная цель после очистки (по умолчанию80%отmaxDiskBytes)
Порядок принудительной очистки для соблюдения бюджета диска (mode: "enforce"):
- Сначала удалить самые старые архивные или потерянные артефакты транскриптов.
- Если все еще выше цели, удалить самые старые записи сессий и их файлы транскриптов.
- Продолжать, пока использование не будет на уровне или ниже
highWaterBytes.
В режиме mode: "warn" OpenClaw сообщает о потенциальных удалениях, но не изменяет хранилище/файлы. Запустите обслуживание по требованию:
openclaw sessions cleanup --dry-run
openclaw sessions cleanup --enforce
Сессии 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> - Вебхук:
hook:<uuid>(если не переопределено)
Канонические правила задокументированы по адресу /concepts/session.
Идентификаторы сессий (sessionId)
Каждый sessionKey указывает на текущий sessionId (файл транскрипта, который продолжает разговор). Эмпирические правила:
- Сброс (
/new,/reset) создает новыйsessionIdдля этогоsessionKey. - Ежедневный сброс (по умолчанию 4:00 по местному времени на хосте шлюза) создает новый
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: текущий идентификатор транскрипта (имя файла выводится из него, если не заданsessionFile)updatedAt: временная метка последней активностиsessionFile: опциональное явное переопределение пути к транскриптуchatType:direct | group | room(помогает UI и политике отправки)provider,subject,room,space,displayName: метаданные для маркировки групп/каналов- Переключатели:
thinkingLevel,verboseLevel,reasoningLevel,elevatedLevelsendPolicy(переопределение для конкретной сессии)
- Выбор модели:
providerOverride,modelOverride,authProfileOverride
- Счетчики токенов (приблизительные / зависящие от провайдера):
inputTokens,outputTokens,totalTokens,contextTokens
compactionCount: как часто автоматическая компрессия завершалась для этого ключа сессииmemoryFlushAt: временная метка последней записи памяти перед компрессиейmemoryFlushCompactionCount: счетчик компрессии, когда выполнялась последняя запись
Хранилище безопасно для редактирования, но Шлюз является авторитетом: он может перезаписывать или восстанавливать записи по мере выполнения сессий.
Структура транскрипта (*.jsonl)
Транскриптами управляет SessionManager из @mariozechner/pi-coding-agent. Файл имеет формат JSONL:
- Первая строка: заголовок сессии (
type: "session", включаетid,cwd,timestamp, опциональноparentSession) - Далее: записи сессии с
id+parentId(дерево)
Примечательные типы записей:
message: сообщения пользователя/ассистента/toolResultcustom_message: сообщения, внедренные расширениями, которые попадают в контекст модели (могут быть скрыты от UI)custom: состояние расширения, которое не попадает в контекст моделиcompaction: сохраненная сводка компрессии сfirstKeptEntryIdиtokensBeforebranch_summary: сохраненная сводка при навигации по ветке дерева
OpenClaw намеренно не «исправляет» транскрипты; Шлюз использует SessionManager для их чтения/записи.
Контекстные окна vs отслеживаемые токены
Имеют значение две разные концепции:
- Контекстное окно модели: жесткое ограничение для каждой модели (токены, видимые модели)
- Счетчики в хранилище сессий: накапливаемая статистика, записываемая в
sessions.json(используется для /status и дашбордов)
Если вы настраиваете лимиты:
- Контекстное окно берется из каталога моделей (и может быть переопределено через конфигурацию).
contextTokensв хранилище — это оценка/отчетное значение времени выполнения; не рассматривайте его как строгую гарантию.
Подробнее см. /token-use.
Компрессия: что это такое
Компрессия суммирует старую часть разговора в сохраненную запись compaction в транскрипте и оставляет последние сообщения нетронутыми. После компрессии будущие ходы видят:
- Сводку компрессии
- Сообщения после
firstKeptEntryId
Компрессия является постоянной (в отличие от удаления сессий). См. /concepts/session-pruning.
Когда происходит автоматическая компрессия (среда выполнения Pi)
Во встроенном агенте Pi автоматическая компрессия запускается в двух случаях:
- Восстановление после переполнения: модель возвращает ошибку переполнения контекста → компрессия → повторная попытка.
- Профилактическое обслуживание по порогу: после успешного хода, когда:
contextTokens > contextWindow - reserveTokens Где:
contextWindow— контекстное окно моделиreserveTokens— запас места, зарезервированный для промптов + следующего вывода модели
Это семантика среды выполнения Pi (OpenClaw потребляет события, но Pi решает, когда выполнять компрессию).
Настройки компрессии (reserveTokens, keepRecentTokens)
Настройки компрессии Pi находятся в настройках Pi:
{
compaction: {
enabled: true,
reserveTokens: 16384,
keepRecentTokens: 20000,
},
}
OpenClaw также обеспечивает минимальный безопасный порог для встроенных запусков:
- Если
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- Подробный режим:
🧹 Auto-compaction complete+ счетчик компрессии
Фоновая служебная работа (NO_REPLY)
OpenClaw поддерживает «тихие» ходы для фоновых задач, где пользователь не должен видеть промежуточный вывод. Соглашение:
- Ассистент начинает свой вывод с
NO_REPLY, чтобы указать «не доставлять ответ пользователю». - OpenClaw удаляет/подавляет это на уровне доставки.
Начиная с версии 2026.1.10, OpenClaw также подавляет потоковую передачу черновика/печати, когда частичный чанк начинается с NO_REPLY, чтобы тихие операции не просачивались в виде частичного вывода в середине хода.
«Запись памяти» перед компрессией (реализовано)
Цель: до того, как произойдет автоматическая компрессия, выполнить тихий агентский ход, который записывает устойчивое состояние на диск (например, memory/YYYY-MM-DD.md в рабочей области агента), чтобы компрессия не могла стереть критический контекст. OpenClaw использует подход записи перед порогом:
- Мониторинг использования контекста сессии.
- Когда оно пересекает «мягкий порог» (ниже порога компрессии Pi), выполнить тихую директиву «записать память сейчас» для агента.
- Использовать
NO_REPLY, чтобы пользователь ничего не видел.
Конфигурация (agents.defaults.compaction.memoryFlush):
enabled(по умолчанию:true)softThresholdTokens(по умолчанию:4000)prompt(сообщение пользователя для хода записи)systemPrompt(дополнительный системный промпт, добавляемый для хода записи)
Примечания:
- Промпт и системный промпт по умолчанию содержат подсказку
NO_REPLYдля подавления доставки. - Запись выполняется один раз за цикл компрессии (отслеживается в
sessions.json). - Запись выполняется только для встроенных сессий Pi (бэкенды CLI пропускают ее).
- Запись пропускается, когда рабочая область сессии доступна только для чтения (
workspaceAccess: "ro"или"none"). - См. Память для структуры файлов рабочей области и шаблонов записи.
Pi также предоставляет хук session_before_compact в API расширений, но логика записи OpenClaw сегодня находится на стороне Шлюза.
Контрольный список для устранения неполадок
- Неправильный ключ сессии? Начните с /concepts/session и подтвердите
sessionKeyв/status. - Несоответствие между хранилищем и транскриптом? Подтвердите хост Шлюза и путь к хранилищу из
openclaw status. - Спам компрессии? Проверьте:
- контекстное окно модели (слишком маленькое)
- настройки компрессии (слишком высокий
reserveTokensдля окна модели может вызывать раннюю компрессию) - раздувание tool-result: включите/настройте удаление сессий
- Утечка тихих ходов? Убедитесь, что ответ начинается с
NO_REPLY(точный токен) и вы используете сборку, которая включает исправление подавления потоковой передачи.