Community translations by veiseule.ai — Help improve them on Crowdin
Skip to main content

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

Этот документ объясняет, как 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 (точный токен) и что вы используете сборку, включающую исправление подавления потоковой передачи.