Перейти к основному содержанию

Управление сеансами и уплотнение (подробный разбор)

Этот документ объясняет, как OpenClaw управляет сеансами от начала до конца:
  • Маршрутизация сеансов (как входящие сообщения сопоставляются с sessionKey)
  • Хранилище сеансов (sessions.json) и что в нём отслеживается
  • Сохранение транскриптов (*.jsonl) и их структура
  • Гигиена транскриптов (провайдер-специфичные исправления перед запусками)
  • Ограничения контекста (окно контекста vs отслеживаемые токены)
  • Уплотнение (ручное + автоуплотнение) и точки подключения предварительных работ
  • Тихая служебная обработка (например, записи памяти, которые не должны давать вывод, видимый пользователю)
Если вам сначала нужен обзор более высокого уровня, начните с:

Источник истины: Gateway (шлюз)

OpenClaw спроектирован вокруг одного процесса Gateway, который владеет состоянием сеансов.
  • UI (приложение для macOS, веб Control UI, TUI) должны запрашивать у Gateway списки сеансов и счётчики токенов.
  • В удалённом режиме файлы сеансов находятся на удалённом хосте; «проверка локальных файлов на Mac» не отражает то, что использует Gateway.

Два уровня сохранения

OpenClaw сохраняет сеансы на двух уровнях:
  1. Хранилище сеансов (sessions.json)
    • Карта ключ/значение: sessionKey -> SessionEntry
    • Небольшое, изменяемое, безопасно для редактирования (или удаления записей)
    • Отслеживает метаданные сеанса (текущий идентификатор сеанса, последнюю активность, переключатели, счётчики токенов и т. д.)
  2. Транскрипт (<sessionId>.jsonl)
    • Только добавляемый транскрипт с древовидной структурой (записи имеют id + parentId)
    • Хранит фактический диалог + вызовы инструментов + сводки уплотнения
    • Используется для восстановления контекста модели в будущих ходах

Расположения на диске

Для каждого агента, на хосте шлюза Gateway:
  • Хранилище: ~/.openclaw/agents/<agentId>/sessions/sessions.json
  • Транскрипты: ~/.openclaw/agents/<agentId>/sessions/<sessionId>.jsonl
    • Сеансы тем Telegram: .../<sessionId>-topic-<threadId>.jsonl
OpenClaw разрешает эти пути через src/config/sessions.ts.

Ключи сеансов (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> (если не переопределено)
Канонические правила задокументированы в /concepts/session.

Идентификаторы сеансов (sessionId)

Каждый sessionKey указывает на текущий sessionId (файл транскрипта, который продолжает разговор). Практические правила:
  • Сброс (/new, /reset) создаёт новый sessionId для данного sessionKey.
  • Ежедневный сброс (по умолчанию 4:00 утра по локальному времени на хосте шлюза Gateway) создаёт новый sessionId при следующем сообщении после границы сброса.
  • Истечение по бездействию (session.reset.idleMinutes или устаревший session.idleMinutes) создаёт новый sessionId, когда сообщение приходит после окна простоя. Если настроены и ежедневный сброс, и бездействие, срабатывает то, что истекает раньше.
Деталь реализации: решение принимается в 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, elevatedLevel
    • sendPolicy (переопределение на уровне сеанса)
  • Выбор модели:
    • providerOverride, modelOverride, authProfileOverride
  • Счётчики токенов (best-effort / зависят от провайдера):
    • inputTokens, outputTokens, totalTokens, contextTokens
  • compactionCount: как часто автоуплотнение завершалось для этого ключа сеанса
  • memoryFlushAt: отметка времени последнего предуплотнительного сброса памяти
  • memoryFlushCompactionCount: счётчик уплотнений на момент последнего сброса
Хранилище безопасно для редактирования, но Gateway является источником истины: он может перезаписывать или восстанавливать записи по мере выполнения сеансов.

Структура транскрипта (*.jsonl)

Транскрипты управляются @mariozechner/pi-coding-agent через SessionManager. Файл — JSONL:
  • Первая строка: заголовок сеанса (type: "session", включает id, cwd, timestamp, необязательный parentSession)
  • Далее: записи сеанса с id + parentId (дерево)
Заметные типы записей:
  • message: сообщения пользователя/ассистента/результата инструмента
  • custom_message: сообщения, внедрённые расширениями, которые входят в контекст модели (могут быть скрыты из UI)
  • custom: состояние расширений, которое не входит в контекст модели
  • compaction: сохранённая сводка уплотнения с firstKeptEntryId и tokensBefore
  • branch_summary: сохранённая сводка при навигации по ветви дерева
OpenClaw намеренно не «исправляет» транскрипты; Gateway использует SessionManager для чтения/записи.

Окна контекста vs отслеживаемые токены

Имеют значение два разных понятия:
  1. Окно контекста модели: жёсткий предел для модели (токены, видимые модели)
  2. Счётчики хранилища сеансов: скользящая статистика, записываемая в sessions.json (используется для /status и дашбордов)
Если вы настраиваете лимиты:
  • Окно контекста берётся из каталога моделей (и может быть переопределено через конфиг).
  • contextTokens в хранилище — это оценка/значение для отчётности во время выполнения; не воспринимайте его как строгую гарантию.
Подробнее см. /token-use.

Уплотнение: что это такое

Уплотнение суммирует более ранний диалог в сохранённую запись compaction в транскрипте и сохраняет недавние сообщения без изменений. После уплотнения будущие ходы видят:
  • Сводка компактности
  • Сообщения после firstKeptEntryId
Уплотнение персистентно (в отличие от прореживания сеансов). См. /concepts/session-pruning.

Когда происходит автоуплотнение (рантайм Pi)

Во встроенном агенте Pi автоуплотнение срабатывает в двух случаях:
  1. Восстановление после переполнения: модель возвращает ошибку переполнения контекста → уплотнение → повтор.
  2. Поддержание порога: после успешного хода, когда:
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 использует подход сброса до порога:
  1. Мониторинг использования контекста сеанса.
  2. При пересечении «мягкого порога» (ниже порога уплотнения Pi) — запуск тихой директивы агенту «записать память сейчас».
  3. Использование NO_REPLY, чтобы пользователь ничего не увидел.
Конфиг (agents.defaults.compaction.memoryFlush):
  • enabled (по умолчанию: true)
  • softThresholdTokens (по умолчанию: 4000)
  • prompt (сообщение пользователя для хода сброса)
  • systemPrompt (дополнительный системный промпт, добавляемый для хода сброса)
Примечания:
  • Промпт по умолчанию/системный промпт включает подсказку NO_REPLY для подавления доставки.
  • Сброс выполняется один раз за цикл уплотнения (отслеживается в sessions.json).
  • Сброс выполняется только для встроенных сеансов Pi (CLI-бэкенды его пропускают).
  • Сброс пропускается, когда рабочее пространство сеанса доступно только для чтения (workspaceAccess: "ro" или "none").
  • См. Memory для схемы файлов рабочего пространства и шаблонов записи.
Pi также предоставляет хук session_before_compact в API расширений, но логика сброса OpenClaw на сегодня находится на стороне Gateway.

Контрольный список устранения неполадок

  • Неверный ключ сеанса? Начните с /concepts/session и подтвердите sessionKey в /status.
  • Несоответствие хранилища и транскрипта? Проверьте хост шлюза Gateway и путь к хранилищу из openclaw status.
  • Спам уплотнений? Проверьте:
    • окно контекста модели (слишком маленькое)
    • настройки уплотнения (reserveTokens слишком высокое относительно окна модели может вызывать более раннее уплотнение)
    • раздувание результатов инструментов: включите/настройте прореживание сеансов
  • «Тихие» ходы протекают? Убедитесь, что ответ начинается с NO_REPLY (точный токен) и что вы используете сборку, включающую исправление подавления потоковой передачи.