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

Сообщения и доставка

Потоковая передача и разбиение на блоки

В OpenClaw есть два отдельных уровня потоковой передачи:

  • Потоковая передача блоков (каналы): отправка завершённых блоков по мере их написания ассистентом. Это обычные сообщения канала (не дельты токенов).
  • Потоковый предварительный просмотр (Telegram/Discord/Slack): обновление временного сообщения предварительного просмотра во время генерации.

На данный момент нет настоящей потоковой передачи дельт токенов в сообщения каналов. Потоковый предварительный просмотр основан на сообщениях (отправка + правки/дополнения).

Потоковая передача блоков (сообщения канала)​

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

Model output
└─ text_delta/events
├─ (blockStreamingBreak=text_end)
│ └─ chunker emits blocks as buffer grows
└─ (blockStreamingBreak=message_end)
└─ chunker flushes at message_end
└─ channel send (block replies)

Легенда:

  • text_delta/events: события потока модели (могут быть редкими для не потоковых моделей).
  • chunker: EmbeddedBlockChunker, применяющий минимальные/максимальные границы и предпочтения разрыва.
  • channel send: фактические исходящие сообщения (ответы блоками).

Управление:

  • agents.defaults.blockStreamingDefault: "on"/"off" (по умолчанию off).
  • Переопределения для канала: *.blockStreaming (и варианты для каждого аккаунта) для принудительного включения/выключения ("on"/"off") для каждого канала.
  • agents.defaults.blockStreamingBreak: "text_end" или "message_end".
  • agents.defaults.blockStreamingChunk: { minChars, maxChars, breakPreference? }.
  • agents.defaults.blockStreamingCoalesce: { minChars?, maxChars?, idleMs? } (объединение потоковых блоков перед отправкой).
  • Жёсткое ограничение канала: *.textChunkLimit (например, channels.whatsapp.textChunkLimit).
  • Режим разбиения канала: *.chunkMode (length по умолчанию, newline разбивает по пустым строкам (границам абзацев) перед разбиением по длине).
  • Мягкое ограничение Discord: channels.discord.maxLinesPerMessage (по умолчанию 17) разбивает длинные ответы, чтобы избежать обрезки в интерфейсе.

Семантика границ:

  • text_end: потоковая передача блоков, как только их отправляет chunker; сброс буфера при каждом text_end.
  • message_end: ожидание завершения сообщения ассистента, затем сброс буферизированного вывода.

message_end всё равно использует chunker, если буферизированный текст превышает maxChars, поэтому в конце может быть отправлено несколько фрагментов.

Алгоритм разбиения на блоки (нижняя/верхняя границы)​

Разбиение на блоки реализовано в EmbeddedBlockChunker:

  • Нижняя граница: не отправлять, пока буфер не станет >= minChars (если не принудительно).
  • Верхняя граница: предпочитать разрывы до maxChars; если принудительно, разбивать на maxChars.
  • Предпочтение разрыва: paragraph → newline → sentence → whitespace → жёсткий разрыв.
  • Блоки кода: никогда не разбивать внутри блоков кода; при принудительном разрыве на maxChars закрыть и заново открыть блок кода, чтобы сохранить валидность Markdown.

maxChars ограничивается значением textChunkLimit канала, поэтому нельзя превысить ограничения для конкретного канала.

Объединение (слияние потоковых блоков)​

Когда потоковая передача блоков включена, OpenClaw может объединять последовательные фрагменты блоков перед их отправкой. Это уменьшает "спам одиночными строками", сохраняя при этом прогрессивный вывод.

  • Объединение ожидает паузы в активности (idleMs) перед сбросом буфера.
  • Буферы ограничены maxChars и будут сброшены, если превысят его.
  • minChars предотвращает отправку крошечных фрагментов, пока не накопится достаточно текста (финальный сброс всегда отправляет оставшийся текст).
  • Разделитель определяется на основе blockStreamingChunk.breakPreference (paragraph → \n\n, newline → \n, sentence → пробел).
  • Переопределения для канала доступны через *.blockStreamingCoalesce (включая конфигурации для каждого аккаунта).
  • Значение minChars по умолчанию для объединения увеличено до 1500 для Signal/Slack/Discord, если не переопределено.

Естественные паузы между блоками​

Когда включена потоковая передача блоков, можно добавить рандомизированную паузу между ответами-блоками (после первого блока). Это делает многосообные ответы более естественными.

  • Конфигурация: agents.defaults.humanDelay (переопределить для каждого агента через agents.list[].humanDelay).
  • Режимы: off (по умолчанию), natural (800–2500 мс), custom (minMs/maxMs).
  • Применяется только к ответам-блокам, а не к финальным ответам или сводкам инструментов.

"Потоковые фрагменты или всё сразу"​

Это соответствует:

  • Потоковые фрагменты: blockStreamingDefault: "on" + blockStreamingBreak: "text_end" (отправлять по мере генерации). Для каналов, отличных от Telegram, также требуется *.blockStreaming: true.
  • Всё сразу в конце: blockStreamingBreak: "message_end" (сбросить один раз, возможно несколько фрагментов, если очень длинный).
  • Без потоковой передачи блоков: blockStreamingDefault: "off" (только финальный ответ).

Примечание для каналов: Потоковая передача блоков выключена, если *.blockStreaming явно не установлен в true. Каналы могут передавать живой предварительный просмотр (channels..streaming) без ответов-блоков. Напоминание о расположении конфигурации: значения по умолчанию blockStreaming* находятся в agents.defaults, а не в корневой конфигурации.

Режимы потокового предварительного просмотра​

Канонический ключ: channels..streaming Режимы:

  • off: отключить потоковый предварительный просмотр.
  • partial: единый предварительный просмотр, который заменяется последним текстом.
  • block: предварительный просмотр обновляется поэтапно/с дополнениями.
  • progress: предварительный просмотр прогресса/статуса во время генерации, финальный ответ по завершении.

Соответствие каналам​

Каналoffpartialblockprogress
Telegram✅✅✅соответствует partial
Discord✅✅✅соответствует partial
Slack✅✅✅✅

Только Slack:

  • channels.slack.nativeStreaming переключает использование нативных API-вызовов потоковой передачи Slack, когда streaming=partial (по умолчанию: true).

Миграция устаревших ключей:

  • Telegram: streamMode + булево streaming автоматически мигрируют в перечисление streaming.
  • Discord: streamMode + булево streaming автоматически мигрируют в перечисление streaming.
  • Slack: streamMode автоматически мигрирует в перечисление streaming; булево streaming автоматически мигрирует в nativeStreaming.

Поведение во время выполнения​

Telegram:

  • Использует Bot API sendMessageDraft в личных сообщениях, когда доступно, и sendMessage + editMessageText для обновлений предварительного просмотра в группах/топиках.
  • Потоковый предварительный просмотр пропускается, когда потоковая передача блоков в Telegram явно включена (чтобы избежать двойной потоковой передачи).
  • /reasoning stream может записывать рассуждения в предварительный просмотр.

Discord:

  • Использует отправку и редактирование сообщений предварительного просмотра.
  • Режим block использует разбиение на черновики (draftChunk).
  • Потоковый предварительный просмотр пропускается, когда потоковая передача блоков в Discord явно включена.

Slack:

  • partial может использовать нативную потоковую передачу Slack (chat.startStream/append/stop), когда доступно.
  • block использует предварительный просмотр черновиков с дополнениями.
  • progress использует текст предварительного просмотра статуса, затем финальный ответ.

СообщенияПолитика повтора