Messages and delivery
Потоковая передача и разбиение на фрагменты
OpenClaw имеет два независимых уровня потоковой передачи, и на сегодняшний день истинная потоковая передача дельт токенов в сообщения каналов отсутствует:
- Потоковая передача блоков (каналы): отправляет завершённые блоки по мере того, как ассистент формирует ответ. Это обычные сообщения канала, а не дельты токенов.
- Потоковая передача предпросмотра (Telegram/Discord/Slack/Matrix/Mattermost/MS Teams): обновляет временное сообщение предпросмотра во время генерации (отправка + редактирование/добавление).
Потоковая передача блоков (сообщения каналов)
Потоковая передача блоков отправляет вывод ассистента крупными фрагментами по мере их готовности.
Вывод модели └─ text_delta/events ├─ (blockStreamingBreak=text_end) │ └─ разбиение выдаёт блоки по мере заполнения буфера └─ (blockStreamingBreak=message_end) └─ разбиение сбрасывает буфер при message_end └─ отправка в канал (ответы блоками)text_delta/events: события потока модели (могут быть редкими для непотоковых моделей).chunker:EmbeddedBlockChunkerс применением минимальной и максимальной границ и предпочтительного места разрыва.channel send: фактически исходящие сообщения (ответы блоками).
Параметры управления (все находятся в agents.defaults, если не указано иное):
| Ключ | Значения / структура | По умолчанию |
|---|---|---|
blockStreamingDefault |
"on" / "off" |
"off" |
blockStreamingBreak |
"text_end" / "message_end" |
- |
blockStreamingChunk |
{ minChars, maxChars, breakPreference? } |
- |
blockStreamingCoalesce |
{ minChars?, maxChars?, idleMs? } (объединять потоковые блоки перед отправкой) |
- |
*.streaming.block.enabled (переопределение для канала) |
true / false, принудительно включает потоковую передачу блоков для канала (и отдельной учётной записи) |
- |
*.textChunkLimit (например, channels.whatsapp.textChunkLimit) |
число, жёсткое ограничение | 4000 |
*.streaming.chunkMode |
"length" / "newline" |
"length" |
channels.discord.maxLinesPerMessage |
число, мягкое ограничение строк, разбивающее высокие ответы во избежание обрезки в интерфейсе | 17 |
streaming.chunkMode: "newline" выполняет разбиение по пустым строкам (границам абзацев),
а не по каждому переводу строки, и только затем переходит к разбиению по длине, когда текст
превышает ограничение.
Встроенные каналы записывают эти переопределения как
channels.<id>.streaming.{chunkMode,block.enabled,block.coalesce}. Плоские варианты записи
*.chunkMode / *.blockStreaming / *.blockStreamingCoalesce являются
устаревшими для всех встроенных каналов: openclaw doctor --fix переносит их
во вложенную структуру, а схемы каналов отклоняют их. Конфигурации внешних плагинов SDK,
всё ещё использующие плоские варианты записи, продолжают работать через устаревший
резервный механизм (с предупреждением во время выполнения) до следующего цикла выпуска.
Семантика границ для blockStreamingBreak:
text_end: передавать блоки по мере их выдачи механизмом разбиения; сбрасывать буфер при каждомtext_end.message_end: дождаться завершения сообщения ассистента, затем сбросить накопленный вывод. Если накопленный текст превышаетmaxChars, механизм разбиения всё равно применяется, поэтому в конце может быть отправлено несколько фрагментов.
Доставка медиафайлов при потоковой передаче блоков
Для потоковой передачи медиафайлов необходимо использовать структурированные поля полезной нагрузки, такие как mediaUrl или
mediaUrls; потоковый текст не разбирается как команда вложения. Когда при потоковой
передаче блоков медиафайл отправляется заранее, OpenClaw запоминает эту доставку в рамках текущего хода. Если
итоговая полезная нагрузка ассистента повторяет тот же URL медиафайла, при окончательной доставке
дубликат медиафайла удаляется вместо повторной отправки вложения.
Полностью совпадающие итоговые полезные нагрузки не отправляются. Если итоговая полезная нагрузка добавляет отдельный текст вокруг уже переданного медиафайла, OpenClaw всё равно отправляет новый текст, сохраняя однократную доставку медиафайла. Это предотвращает дублирование голосовых сообщений или файлов в таких каналах, как Telegram.
Алгоритм разбиения (нижняя и верхняя границы)
Разбиение на блоки реализовано в EmbeddedBlockChunker:
- Нижняя граница: не отправлять, пока размер буфера не достигнет
minChars(кроме принудительной отправки). - Верхняя граница: по возможности выполнять разбиение до
maxChars; при принудительном разбиении — наmaxChars. - Цепочка предпочтений для разрыва:
paragraph->newline->sentence-> пробельный символ -> жёсткий разрыв. - Блоки кода: никогда не разбиваются внутри ограждений; при принудительном разбиении на
maxCharsограждение закрывается и открывается заново, чтобы сохранить корректность Markdown.
maxChars ограничивается значением textChunkLimit канала, поэтому превысить
ограничения конкретного канала невозможно.
Объединение (слияние потоковых блоков)
Когда потоковая передача блоков включена, OpenClaw может объединять последовательные фрагменты блоков перед отправкой, уменьшая количество отдельных однострочных сообщений и при этом сохраняя постепенную выдачу результата.
- Объединение ожидает периодов бездействия (
idleMs) перед сбросом. - Размер буферов ограничен значением
maxChars; при его превышении буферы сбрасываются. minCharsне позволяет отправлять небольшие фрагменты, пока не накопится достаточно текста (при окончательном сбросе оставшийся текст отправляется всегда).- Разделитель определяется значением
blockStreamingChunk.breakPreference:paragraph->\n\n,newline->\n,sentence-> пробел. - Переопределения для каналов доступны через
*.streaming.block.coalesce(включая конфигурации отдельных учётных записей). - Для Discord, Signal и Slack значение объединения по умолчанию —
{ minChars: 1500, idleMs: 1000 }, если оно не переопределено.
Человекоподобные паузы между блоками
Когда потоковая передача блоков включена, после первого блока между ответами блоками добавляется случайная пауза, чтобы ответы из нескольких сообщений выглядели естественнее.
agents.defaults.humanDelay.mode |
Поведение |
|---|---|
off (по умолчанию) |
Без паузы |
natural |
Случайная пауза 800-2500ms |
custom |
minMs/maxMs |
Переопределяется для отдельного агента через agents.list[].humanDelay. Применяется только к ответам
блоками, но не к итоговым ответам или сводкам инструментов.
«Передавать фрагменты или всё целиком»
- Передавать фрагменты:
blockStreamingDefault: "on"+blockStreamingBreak: "text_end"(отправлять по мере готовности). Для каналов, отличных от Telegram, также требуется*.streaming.block.enabled: true. - Передать всё в конце:
blockStreamingBreak: "message_end"(однократный сброс, возможно несколькими фрагментами для очень длинного текста). - Без потоковой передачи блоков:
blockStreamingDefault: "off"(только итоговый ответ).
Потоковая передача блоков отключена, если только *.streaming.block.enabled явно
не задано как true (исключение: у QQ Bot нет ключей streaming.block, и он передаёт
ответы блоками, если channels.qqbot.streaming.mode не равно "off"). Каналы могут
передавать интерактивный предпросмотр (channels.<channel>.streaming.mode) без ответов
блоками. Значения blockStreaming* по умолчанию находятся в agents.defaults, а не в
корне конфигурации.
Режимы потоковой передачи предпросмотра
Канонический ключ: channels.<channel>.streaming (вложенный { mode, ... }; устаревшие
логические/строковые варианты верхнего уровня преобразуются с помощью openclaw doctor --fix).
| Режим | Поведение |
|---|---|
off |
Отключить потоковую передачу предпросмотра |
partial |
Единый предпросмотр заменяется последней версией текста |
block |
Предпросмотр обновляется фрагментами или путём добавления текста |
progress |
Предпросмотр хода выполнения/состояния во время генерации, итоговый ответ после завершения |
streaming.mode: "block" — режим потоковой передачи предпросмотра для каналов
с поддержкой редактирования, таких как Discord и Telegram; сам по себе он не включает
доставку блоков в эти каналы. Для обычных ответов блоками используйте streaming.block.enabled.
Microsoft Teams является
исключением: в нём нет транспорта чернового предпросмотра блоков, поэтому streaming.mode: "block" полностью отключает нативную потоковую передачу, и ответ доставляется как обычные
блоки вместо нативной частичной потоковой передачи или передачи хода выполнения. Mattermost также
отличается: в режиме block предпросмотр поочерёдно отображает завершённый текст и
блоки активности инструментов, поэтому предыдущие блоки остаются видимыми как отдельные публикации,
а не перезаписываются в одном редактируемом черновике.
Сопоставление каналов
| Канал | off |
partial |
block |
progress |
|---|---|---|---|---|
| Telegram | Да | Да | Да | редактируемый черновик хода выполнения |
| Discord | Да | Да | Да | редактируемый черновик хода выполнения |
| Slack | Да | Да | Да | Да |
| Mattermost | Да | Да | Да | Да |
| MS Teams | Да | Да | Да | нативный поток хода выполнения |
Конфигурация фрагментов предпросмотра (streaming.preview.chunk.*, например в
channels.discord.streaming или channels.telegram.streaming) по умолчанию использует
minChars: 200, maxChars: 800 (ограничивается значением textChunkLimit канала) и
breakPreference: "paragraph".
Только для Slack:
channels.slack.streaming.nativeTransportвключает или отключает вызовы нативного API потоковой передачи Slack (chat.startStream/chat.appendStream/chat.stopStream), когдаchannels.slack.streaming.mode="partial"(по умолчанию:true).- Для нативной потоковой передачи Slack и состояния ветки ассистента Slack требуется целевая ветка ответа. Личные сообщения верхнего уровня не показывают такой предпросмотр в виде ветки, но по-прежнему могут использовать публикации чернового предпросмотра Slack и их редактирование.
Миграция устаревших ключей
| Канал | Устаревшие ключи | Состояние |
|---|---|---|
| Telegram | streamMode, скалярное/логическое streaming |
Преобразуется в streaming.mode с помощью openclaw doctor --fix; во время выполнения не считывается |
| Discord | streamMode, логическое streaming |
Преобразуется в streaming.mode с помощью openclaw doctor --fix; во время выполнения не считывается |
| Slack | streamMode; логическое streaming; устаревшее nativeStreaming |
Преобразуется в streaming.mode (и в streaming.nativeTransport для логической/устаревшей формы) с помощью openclaw doctor --fix; во время выполнения не считывается |
| Matrix | скалярное/логическое streaming |
Преобразуется в streaming.mode (включая режим "quiet" Matrix) с помощью openclaw doctor --fix; во время выполнения не считывается |
| Feishu | логическое streaming |
Преобразуется в streaming.mode с помощью openclaw doctor --fix; во время выполнения не считывается |
| QQ Bot | логическое streaming; streaming.c2cStreamApi |
Преобразуется в streaming.mode (и в streaming.nativeTransport для логической формы/формы c2cStreamApi) с помощью openclaw doctor --fix; во время выполнения не считывается |
Поведение во время выполнения
Telegram
- Использует обновления предпросмотра
sendMessage+editMessageTextв личных сообщениях и группах/темах; итоговый текст заменяет активный предпросмотр на месте. Эфемерные 30-секундные черновики Telegram «печатает» (sendMessageDraft) не используются для потоковой передачи ответа. - Короткие начальные предпросмотры по-прежнему отправляются с задержкой для удобства push-уведомлений, но появляются по истечении ограниченного времени, чтобы активные запуски не оставались визуально безмолвными.
- Для длинных итоговых ответов сообщение предпросмотра повторно используется для первого фрагмента, а отправляются только оставшиеся фрагменты.
- Режим
blockпереносит предпросмотр в новое сообщение приstreaming.preview.chunk.maxChars(по умолчанию 800, максимум — установленное Telegram ограничение редактирования 4096); в других режимах один предпросмотр увеличивается до 4096 символов. - Режим
progressсохраняет ход выполнения инструментов в редактируемом черновике состояния, отображает метку состояния, когда потоковая передача ответа активна, но строка инструмента ещё недоступна, очищает черновик после завершения и отправляет итоговый ответ обычным способом. - Если итоговое редактирование завершается ошибкой до подтверждения готового текста, OpenClaw использует обычную доставку итогового ответа и удаляет устаревший предпросмотр.
- Потоковая передача предпросмотра пропускается, когда потоковая передача блоков Telegram явно включена, чтобы избежать двойной потоковой передачи.
/reasoning streamможет выводить рассуждения во временный предпросмотр, который удаляется после доставки итогового ответа.- Ответы с выбранной цитатой в Telegram являются исключением: когда
replyToModeне равно"off"и присутствует текст выбранной цитаты, OpenClaw пропускает потоковую передачу предпросмотра ответа для этого хода (итоговый ответ должен пройти через нативный механизм ответа с цитатой), поэтому строки хода выполнения инструментов не отображаются. Для ответов на текущее сообщение без выбранного текста цитаты потоковая передача предпросмотра сохраняется. Подробности см. в документации канала Telegram.
Discord
- Использует отправку и редактирование сообщений предпросмотра.
- Режим
blockиспользует разбиение черновика на фрагменты (draftChunk). - Потоковая передача предпросмотра пропускается, когда потоковая передача блоков Discord явно включена.
- Режим
progressдобавляет к итоговому ответу небольшую квитанцию активности-#(количество рассуждений/вызовов инструментов и затраченное время) и удаляет черновик состояния после доставки ответа, поэтому в активных каналах над ответом не остаётся потерянного журнала инструментов. При итоговой ошибке черновик сохраняется как запись неудачного хода. - Итоговые данные с медиа, ошибками и явными ответами отменяют ожидающие предпросмотры, не записывая новый черновик, а затем используют обычную доставку.
Slack
partialможет использовать нативную потоковую передачу Slack (chat.startStream/append/stop), когда она доступна.blockиспользует черновые предпросмотры с добавлением текста.progressиспользует текст предпросмотра состояния, а затем итоговый ответ.- Личные сообщения верхнего уровня без ветки ответов используют публикации и редактирование черновых предпросмотров вместо нативной потоковой передачи Slack.
- Нативная и черновая потоковая передача предпросмотра подавляют ответы блоками для этого хода, поэтому ответ Slack передаётся потоком только по одному пути доставки.
- Итоговые данные с медиа/ошибками и итоговые данные о ходе выполнения не создают одноразовых черновых сообщений; ожидающий текст черновика записывается только для итоговых текстов/блоков, способных изменить предпросмотр.
Mattermost
- В режиме
partialрассуждения и частичный текст ответа передаются потоком в одну черновую публикацию предпросмотра, которая финализируется на месте, когда итоговый ответ можно безопасно отправить. - В режиме
progressрассуждения и действия инструментов передаются потоком в один предпросмотр состояния, который финализируется на месте, когда итоговый ответ можно безопасно отправить. - В режиме
blockвыполняется чередование публикаций готового текста и действий инструментов; параллельные и последовательные обновления инструментов используют текущую публикацию действий инструментов. - Если публикация предпросмотра удалена или по иной причине недоступна во время финализации, вместо неё отправляется новая итоговая публикация.
- Итоговые данные с медиа/ошибками отменяют ожидающие обновления предпросмотра перед обычной доставкой, не записывая временную публикацию предпросмотра.
Matrix
- Черновые предпросмотры финализируются на месте, когда итоговый текст может повторно использовать событие предпросмотра.
- Итоговые ответы только с медиа, с ошибками и с несовпадающей целью ответа отменяют ожидающие обновления предпросмотра перед обычной доставкой; уже видимый устаревший предпросмотр редактируется.
Обновления предпросмотра хода выполнения инструментов
Потоковая передача предпросмотра также может включать обновления хода выполнения инструментов: короткие строки состояния, например «поиск в интернете», «чтение файла» или «вызов инструмента», которые появляются в том же сообщении предпросмотра во время работы инструментов, перед итоговым ответом. В режиме сервера приложений Codex предварительные сообщения и комментарии Codex используют тот же путь предпросмотра, поэтому короткие заметки о ходе выполнения вроде «Я проверяю...» могут передаваться потоком в редактируемый черновик, не становясь частью итогового ответа. Благодаря этому многоэтапные ходы с инструментами остаются визуально активными и не выглядят безмолвными между первым предпросмотром рассуждений и итоговым ответом.
Долго работающие инструменты могут выводить типизированные данные о ходе выполнения до своего завершения. Например,
web_fetch при запуске устанавливает пятисекундный таймер: если получение данных всё ещё
ожидается, в предпросмотре отображается Fetching page content...; если получение данных завершается или
отменяется раньше, строка хода выполнения не выводится. Последующий итоговый результат инструмента
по-прежнему доставляется модели обычным способом.
Поддерживаемые поверхности:
- Discord, Slack, Telegram и Matrix по умолчанию передают ход выполнения инструментов и предварительные обновления Codex в текущий редактируемый предпросмотр, когда потоковая передача предпросмотра активна. Microsoft Teams использует собственный поток хода выполнения в личных чатах.
- Обновления предпросмотра хода выполнения инструментов включены в поставляемых версиях Telegram начиная с
v2026.4.22; сохранение их включёнными поддерживает это выпущенное поведение. - Mattermost объединяет действия инструментов в одну публикацию предпросмотра в режимах
partialиprogressили в одну публикацию действий инструментов между текстовыми блоками в режимеblock(см. выше). - Редактирования хода выполнения инструментов следуют активному режиму потоковой передачи предпросмотра; они
пропускаются, когда потоковая передача предпросмотра имеет значение
offили когда потоковая передача блоков взяла сообщение под управление. В Telegramstreaming.mode: "off"предназначен только для итоговых ответов: общие сообщения о ходе выполнения также подавляются, а не доставляются как отдельные сообщения состояния, при этом запросы подтверждения, данные с медиа и ошибки по-прежнему направляются обычным способом. - Чтобы сохранить потоковую передачу предпросмотра, но скрыть строки хода выполнения инструментов, задайте
для
streaming.preview.toolProgressзначениеfalseв этом канале (по умолчаниюtrue). Чтобы оставить строки хода выполнения инструментов видимыми, скрыв при этом текст команд/исполнения, задайте дляstreaming.preview.commandTextзначение"status"или дляstreaming.progress.commandTextзначение"status"; по умолчанию используется"raw", чтобы сохранить выпущенное поведение. Эта политика общая для каналов черновиков/хода выполнения, использующих компактный визуализатор хода выполнения OpenClaw, включая Discord, Matrix, Microsoft Teams, Mattermost, черновые предпросмотры Slack и Telegram. Чтобы полностью отключить редактирование предпросмотра, задайте дляstreaming.modeзначениеoff.
Отображение черновика хода выполнения
Размер черновиков в режиме хода выполнения (streaming.progress.*) ограничен и настраивается отдельно для каждого
канала:
| Ключ | По умолчанию | Поведение |
|---|---|---|
streaming.progress.maxLines |
8 |
Максимальное число компактных строк хода выполнения под меткой черновика |
streaming.progress.maxLineChars |
120 |
Максимальное число символов в компактной строке до усечения (с учётом слов) |
streaming.progress.label |
"auto" |
Заголовок черновика: пользовательская строка или false, чтобы скрыть его |
streaming.progress.labels |
встроенный набор | Возможные метки, используемые при label: "auto" |
Канал комментариев о ходе выполнения
Помимо хода выполнения инструментов, компактный визуализатор хода выполнения может отображать в черновике ещё один канал:
streaming.progress.commentary— отображает предварительный комментарий модели перед использованием инструмента (короткое повествование «Я проверю... затем...»), чередуя его со строками инструментов в черновике хода выполнения.
{ "channels": { "discord": { "streaming": { "mode": "progress", "progress": { "commentary": true } } } }}Оставить строки хода выполнения видимыми, но скрыть необработанный текст команд/исполнения:
{ "channels": { "telegram": { "streaming": { "mode": "partial", "preview": { "toolProgress": true, "commandText": "status" } } } }}Используйте ту же структуру под ключом другого канала компактного хода выполнения, например
channels.discord, channels.matrix, channels.msteams,
channels.mattermost или черновых предпросмотров Slack. Для режима черновика хода выполнения поместите
ту же политику в streaming.progress:
{ "channels": { "telegram": { "streaming": { "mode": "progress", "progress": { "toolProgress": true, "commandText": "status" } } } }}Связанные материалы
- Рефакторинг жизненного цикла сообщений — целевой общий дизайн предпросмотра, редактирования, потоковой передачи и финализации
- Черновики хода выполнения — видимые сообщения о незавершённой работе, обновляемые во время длительных ходов
- Сообщения — жизненный цикл и доставка сообщений
- Повторные попытки — поведение повторных попыток при сбое доставки
- Каналы — поддержка потоковой передачи для каждого канала