Technical reference

Гигиена транскрипта

OpenClaw применяет к транскриптам исправления, специфичные для провайдера, перед запуском (при формировании контекста модели). Большинство из них — это корректировки в памяти, необходимые для выполнения строгих требований провайдера. Отдельный этап исправления файла сеанса также может перезаписать сохранённый JSONL перед загрузкой сеанса, но только для некорректных строк или сохранённых реплик, которые не являются допустимыми долговременными записями. Доставленные ответы ассистента сохраняются на диске; удаление предварительно заполненного текста ассистента, специфичное для провайдера, выполняется только при формировании исходящих данных.

При исправлении исходный файл записывается во временный соседний файл *.bak-<pid>-<ts> перед атомарной заменой, а после успешной замены удаляется. Резервная копия сохраняется только в случае сбоя самой очистки; в этом случае возвращается путь к ней.

Область действия включает:

  • Контекст промпта, существующий только во время выполнения и не попадающий в видимые пользователю реплики транскрипта
  • Санитизация идентификаторов вызовов инструментов
  • Проверка входных данных вызовов инструментов
  • Исправление сопоставления результатов с вызовами инструментов
  • Проверка и упорядочивание реплик
  • Очистка сигнатур рассуждений
  • Очистка сигнатур процесса рассуждения
  • Санитизация данных изображений
  • Удаление пустых текстовых блоков перед повторным воспроизведением для провайдера
  • Удаление незавершённых реплик предельной длины, содержащих только рассуждения, перед повторным воспроизведением для провайдера
  • Маркировка происхождения пользовательского ввода (для промптов, маршрутизируемых между сеансами)
  • Исправление пустых ошибочных реплик ассистента при повторном воспроизведении через Bedrock Converse

Подробности о хранении транскриптов см. в разделе Подробное описание управления сеансами.


Общее правило: контекст среды выполнения не является пользовательским транскриптом

Контекст среды выполнения или системный контекст можно добавить в промпт модели для реплики, но он не является содержимым, созданным конечным пользователем. OpenClaw хранит отдельное тело промпта для транскрипта, используемое в ответах Gateway, последующих запросах в очереди, ACP, CLI и встроенных запусках OpenClaw. В сохранённых видимых пользовательских репликах используется это тело транскрипта, а не промпт, дополненный контекстом среды выполнения.

Для устаревших сеансов, в которых уже сохранены обёртки среды выполнения, поверхности истории Gateway применяют проекцию отображения перед возвратом сообщений клиентам WebChat, TUI, REST или SSE.


Где это выполняется

Вся обработка транскриптов централизована во встроенном средстве запуска:

  • Выбор политики: src/agents/transcript-policy.ts (resolveTranscriptPolicy, с ключами provider, modelApi и modelId)
  • Применение санитизации и исправлений: sanitizeSessionHistory в src/agents/embedded-agent-runner/replay-history.ts

Отдельно от обработки транскрипта файлы сеансов при необходимости исправляются перед загрузкой:

  • repairSessionFileIfNeeded в src/agents/session-file-repair.ts
  • Вызывается из src/agents/embedded-agent-runner/run/attempt.ts и src/agents/embedded-agent-runner/compact.ts

Общее правило: санитизация изображений

Данные изображений всегда санитизируются, чтобы провайдер не отклонил их из-за ограничений размера (слишком крупные изображения base64 уменьшаются и повторно сжимаются). Это также помогает контролировать расход токенов, обусловленный изображениями, для моделей с поддержкой компьютерного зрения: меньшие максимальные размеры сокращают расход токенов, а большие сохраняют детализацию.

Реализация:

  • sanitizeSessionMessagesImages в src/agents/embedded-agent-helpers/images.ts
  • sanitizeContentBlocksImages в src/agents/tool-images.ts
  • Максимальный размер стороны изображения настраивается через agents.defaults.imageMaxDimensionPx (по умолчанию: 1200)
  • При обходе содержимого для повторного воспроизведения на этом этапе удаляются пустые текстовые блоки. Реплики ассистента, ставшие пустыми, исключаются из копии для повторного воспроизведения; пользовательские реплики и реплики с результатами инструментов, ставшие пустыми, получают непустой заполнитель пропущенного содержимого.

Общее правило: некорректные вызовы инструментов

Блоки вызовов инструментов ассистента, в которых отсутствуют и input, и arguments, удаляются до формирования контекста модели. Это предотвращает отклонение провайдером частично сохранённых вызовов инструментов (например, после ошибки ограничения частоты запросов).

Реализация:

  • sanitizeToolCallInputs в src/agents/session-transcript-repair.ts
  • Применяется в sanitizeSessionHistory (src/agents/embedded-agent-runner/replay-history.ts)

Общее правило: незавершённые реплики, содержащие только рассуждения

Реплики ассистента, достигшие ограничения провайдера на объём вывода и содержащие только процесс рассуждения или отредактированный процесс рассуждения, исключаются из копии для повторного воспроизведения в памяти. Такие реплики содержат незавершённое состояние провайдера и могут включать частичную сигнатуру процесса рассуждения.

Пустые реплики предельной длины остаются без изменений, как и реплики предельной длины с видимым текстом, вызовами инструментов или неизвестными блоками содержимого. Сохранённые транскрипты не перезаписываются.

Реализация: normalizeAssistantReplayContent в src/agents/embedded-agent-runner/replay-history.ts


Общее правило: происхождение ввода из другого сеанса

Когда агент отправляет промпт в другой сеанс через sessions_send (включая этапы ответа или объявления между агентами), OpenClaw сохраняет созданную пользовательскую реплику с message.provenance.kind = "inter_session".

OpenClaw также добавляет перед текстом маршрутизированного промпта маркер [Inter-session message] ... isUser=false в той же реплике, чтобы активный вызов модели мог отличить вывод из другого сеанса от инструкций внешнего конечного пользователя. Этот маркер включает исходный сеанс, канал и инструмент, если они доступны. Для совместимости с провайдером в транскрипте по-прежнему используется role: "user", но видимый текст и метаданные происхождения обозначают реплику как данные из другого сеанса.

При перестроении контекста OpenClaw применяет тот же маркер к ранее сохранённым межсеансовым пользовательским репликам, у которых имеются только метаданные происхождения.


Матрица провайдеров (текущее поведение)

OpenAI / OpenAI Codex

  • Только санитизация изображений.
  • Удаляются потерянные сигнатуры рассуждений (отдельные элементы рассуждений без следующего блока содержимого) из транскриптов OpenAI Responses/Codex, а также воспроизводимые рассуждения OpenAI после переключения маршрута модели.
  • Сохраняются воспроизводимые данные элементов рассуждений OpenAI Responses, включая зашифрованные элементы с пустой сводкой, чтобы при ручном повторном воспроизведении или воспроизведении через WebSocket требуемое состояние rs_* оставалось сопоставленным с элементами вывода ассистента.
  • Нативный ChatGPT Codex Responses обеспечивает соответствие протоколу Codex, повторно воспроизводя предыдущие данные рассуждений, сообщений и функций Responses без прежних идентификаторов элементов, сохраняя при этом prompt_cache_key сеанса.
  • Повторное воспроизведение семейства OpenAI Responses сохраняет канонические пары рассуждений call_*|fc_* для той же модели, но детерминированно нормализует некорректные или слишком длинные идентификаторы элементов call_id/вызовов функций перед преобразованием данных pi-ai.
  • Исправление сопоставления результатов с вызовами инструментов может перемещать реальные совпавшие результаты и синтезировать результаты aborted в стиле Codex для отсутствующих вызовов инструментов.
  • Проверка и переупорядочивание реплик не выполняются; сигнатуры рассуждений не удаляются.

Chat Completions, совместимые с OpenAI

  • Исторические блоки процесса рассуждения ассистента удаляются перед повторным воспроизведением, чтобы локальные и прокси-серверы, совместимые с OpenAI, не получали поля рассуждений из предыдущих реплик, такие как reasoning или reasoning_content.
  • При продолжении вызовов инструментов в текущей реплике блок рассуждений ассистента остаётся прикреплённым к вызову инструмента до повторного воспроизведения результата инструмента.
  • Пользовательские и самостоятельно размещённые записи моделей с reasoning: true сохраняют воспроизводимые метаданные рассуждений.
  • Исключения, принадлежащие провайдерам, могут отключать это поведение, если их протокол требует повторного воспроизведения метаданных рассуждений.

Google (Generative AI / Gemini CLI / Antigravity)

  • Санитизация идентификаторов вызовов инструментов: только буквенно-цифровые символы.
  • Исправление сопоставления результатов с вызовами инструментов и синтетические результаты инструментов.
  • Проверка реплик (чередование реплик в стиле Gemini).
  • Исправление порядка реплик Google (добавление в начало небольшого начального пользовательского сообщения, если история начинается с ассистента).
  • Antigravity Claude: нормализация сигнатур процесса рассуждения; удаление неподписанных блоков процесса рассуждения.

Anthropic / Minimax (совместимые с Anthropic)

  • Исправление сопоставления результатов с вызовами инструментов и синтетические результаты инструментов.
  • Проверка реплик (объединение последовательных пользовательских реплик для соблюдения строгого чередования).
  • Конечные реплики предварительно заполненного ответа ассистента удаляются из исходящих данных Anthropic Messages при включённом процессе рассуждения, включая маршруты Cloudflare AI Gateway.
  • Сигнатуры процесса рассуждения ассистента, созданные до Compaction, удаляются перед повторным воспроизведением для провайдера, если сеанс прошёл Compaction. Сигнатуры процесса рассуждения криптографически связаны с префиксом беседы на момент создания; после Compaction префикс изменяется (исходное содержимое заменяется сводкой), поэтому повторное воспроизведение исходных сигнатур приводит к тому, что Anthropic отклоняет запрос с сообщением "Invalid signature in thinking block". Текст процесса рассуждения сохраняется как неподписанный блок, после чего обрабатывается приведённым ниже правилом.
  • Блоки процесса рассуждения с отсутствующими, пустыми или состоящими из пробелов сигнатурами повторного воспроизведения удаляются перед преобразованием для провайдера. Если в результате реплика ассистента становится пустой, OpenClaw сохраняет структуру реплики с непустым текстом о пропущенном рассуждении.
  • Более старые реплики ассистента, содержащие только процесс рассуждения и подлежащие удалению, заменяются непустым текстом о пропущенном рассуждении, чтобы адаптеры провайдеров не удаляли воспроизводимую реплику.

Amazon Bedrock (Converse API)

  • Пустые реплики ассистента с ошибками потока исправляются с использованием непустого резервного текстового блока перед повторным воспроизведением. Bedrock Converse отклоняет сообщения ассистента с content: [], поэтому сохранённые реплики ассистента с stopReason: "error" и пустым содержимым также исправляются на диске перед загрузкой.
  • Реплики ассистента с ошибками потока, содержащие только пустые текстовые блоки, удаляются из копии для повторного воспроизведения в памяти вместо воспроизведения недопустимого пустого блока.
  • Сигнатуры процесса рассуждения ассистента, созданные до Compaction, удаляются перед повторным воспроизведением Converse, если сеанс прошёл Compaction, по той же причине, что указана выше для Anthropic.
  • Блоки процесса рассуждения Claude с отсутствующими, пустыми или состоящими из пробелов сигнатурами повторного воспроизведения удаляются перед повторным воспроизведением Converse. Если в результате реплика ассистента становится пустой, OpenClaw сохраняет структуру реплики с непустым текстом о пропущенном рассуждении.
  • Более старые реплики ассистента, содержащие только процесс рассуждения и подлежащие удалению, заменяются непустым текстом о пропущенном рассуждении, чтобы повторное воспроизведение Converse сохраняло строгую структуру реплик.
  • При повторном воспроизведении отфильтровываются зеркальные реплики доставки OpenClaw и реплики ассистента, внедрённые Gateway.
  • Санитизация изображений применяется согласно общему правилу.

Mistral (включая обнаружение по идентификатору модели)

  • Санитизация идентификаторов вызовов инструментов: strict9 (буквенно-цифровые символы, длина 9).

OpenRouter Gemini

  • Очистка сигнатур рассуждений: удаление значений thought_signature, не являющихся base64 (значения base64 сохраняются).

OpenRouter Anthropic

  • Конечные реплики предварительно заполненного ответа ассистента удаляются из проверенных данных моделей Anthropic, совместимых с OpenAI через OpenRouter, при включённых рассуждениях, в соответствии с поведением повторного воспроизведения при прямом использовании Anthropic и Cloudflare Anthropic.

Всё остальное

  • Только санитизация изображений.

Историческое поведение (до версии 2026.1.22)

До выпуска версии 2026.1.22 OpenClaw применял несколько уровней обработки транскриптов:

  • Расширение санитизации транскрипта выполнялось при каждом формировании контекста и могло:
    • Исправлять сопоставление вызовов инструментов с их результатами.
    • Санитизировать идентификаторы вызовов инструментов (включая нестрогий режим, сохранявший _/-).
  • Средство запуска также выполняло санитизацию, специфичную для провайдера, что приводило к дублированию работы.
  • Дополнительные изменения выполнялись вне политики провайдера, включая удаление тегов <final> из текста ассистента перед сохранением, удаление пустых ошибочных реплик ассистента и обрезку содержимого ассистента после вызовов инструментов.

Эта сложность приводила к регрессиям при работе с разными провайдерами (особенно при сопоставлении openai-responses call_id|fc_id). В ходе очистки в версии 2026.1.22 расширение было удалено, логика централизована в средстве запуска, а для OpenAI установлен режим без изменений, за исключением санитизации изображений.

Связанные материалы

Was this useful?
On this page

On this page