- ブロックストリーミング(チャンネル): アシスタントが書き込みながら、完了したブロックを送信します。これらは通常のチャンネルメッセージであり、トークン差分ではありません。
- プレビューストリーミング(Telegram/Discord/Slack/Matrix/Mattermost/MS Teams): 生成中に一時的なプレビューメッセージを更新します(送信 + 編集/追記)。
ブロックストリーミング(チャンネルメッセージ)
ブロックストリーミングは、アシスタント出力が利用可能になった時点で大きめのチャンクとして送信します。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? }(送信前にストリーミングされたブロックを結合) | - |
*.blockStreaming(チャンネル上書き) | true / false、チャンネルごと(およびアカウントごと)にブロックストリーミングを強制 | - |
*.textChunkLimit(例: channels.whatsapp.textChunkLimit) | 数値、ハード上限 | 4000 |
*.chunkMode | "length" / "newline" | "length" |
channels.discord.maxLinesPerMessage | 数値、UI のクリッピングを避けるために長い返信を分割するソフト行上限 | 17 |
chunkMode: "newline" はすべての改行ではなく空行(段落境界)で分割し、テキストが上限を超えると長さによるチャンク化へフォールバックします。
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 は送信前に連続するブロックチャンクを結合できます。これにより、進行中の出力を提供しつつ、1 行のスパムを減らせます。- 結合はフラッシュ前にアイドル間隔(
idleMs)を待ちます。 - バッファは
maxCharsで上限が設定され、超過するとフラッシュされます。 minCharsは、十分なテキストが蓄積するまで小さな断片の送信を防ぎます(最終フラッシュでは残りのテキストを常に送信します)。- 結合子は
blockStreamingChunk.breakPreferenceから導出されます:paragraph->\n\n、newline->\n、sentence-> スペース。 - チャンネル上書きは
*.blockStreamingCoalesce(アカウントごとの設定を含む)で利用できます。 - 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 以外のチャンネルでは*.blockStreaming: trueも必要です。 - 最後にすべてをストリーミング:
blockStreamingBreak: "message_end"(1 回フラッシュし、非常に長い場合は複数チャンクになる可能性があります)。 - ブロックストリーミングなし:
blockStreamingDefault: "off"(最終返信のみ)。
*.blockStreaming が明示的に true に設定されない限りオフです。チャンネルはブロック返信なしでライブプレビュー(channels.<channel>.streaming)をストリーミングできます。blockStreaming* のデフォルトは設定ルートではなく agents.defaults 配下にあります。
プレビューストリーミングモード
正規キー:channels.<channel>.streaming(ネストされた { mode, ... }。トップレベルの真偽値はレガシーエイリアスです)。
| モード | 動作 |
|---|---|
off | プレビューストリーミングを無効化 |
partial | 単一プレビューを最新テキストで置き換え |
block | プレビューをチャンク化/追記されたステップで更新 |
progress | 生成中に進行状況/ステータスプレビューを表示し、完了時に最終回答を送信 |
streaming.mode: "block" は、Discord や Telegram など編集可能なチャンネル向けのプレビューストリーミングモードです。それ自体では、そのチャンネルでのチャンネルブロック配信を有効にしません。通常のブロック返信には streaming.block.enabled(またはレガシーの blockStreaming チャンネルキー)を使います。Microsoft Teams は例外です。下書きプレビューブロックのトランスポートがないため、streaming.mode: "block" はネイティブストリーミングを完全に無効化し、返信はネイティブの partial/progress ストリーミングではなく通常のブロック配信として到着します。
チャンネルマッピング
| チャンネル | 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は、channels.slack.streaming.mode="partial"のときに Slack ネイティブストリーミング API 呼び出し(chat.startStream/chat.appendStream/chat.stopStream)を切り替えます(デフォルト:true)。- Slack ネイティブストリーミングと Slack アシスタントスレッドステータスには返信スレッドターゲットが必要です。トップレベルの DM ではそのスレッド形式のプレビューは表示されませんが、Slack の下書きプレビュー投稿と編集は引き続き使用できます。
レガシーキー移行
| チャンネル | レガシーキー | ステータス |
|---|---|---|
| Telegram | streamMode、スカラー/真偽値 streaming | doctor/設定互換パスによって検出され、streaming.mode へ移行されます |
| Discord | streamMode、真偽値 streaming | streaming enum のランタイムエイリアス。永続化された設定を書き換えるには openclaw doctor --fix を実行してください |
| Slack | streamMode、真偽値 streaming、レガシー nativeStreaming | streaming.mode(および真偽値/レガシー形式では streaming.nativeTransport)のランタイムエイリアス。永続化された設定を書き換えるには openclaw doctor --fix を実行してください |
ランタイム動作
Telegram
- DM とグループ/トピック全体で
sendMessage+editMessageTextのプレビュー更新を使います。最終テキストはアクティブなプレビューをその場で編集します。Telegram の一時的な 30 秒「入力中」下書き(sendMessageDraft)は回答ストリーミングには使われません。 - 短い初期プレビューはプッシュ通知 UX のため引き続きデバウンスされますが、アクティブな実行が視覚的に無音のままにならないよう、境界付き遅延の後に実体化されます。
- 長い最終回答では、最初のチャンクにプレビューメッセージを再利用し、残りのチャンクのみ送信します。
blockモードは、streaming.preview.chunk.maxChars(デフォルト 800、Telegram の 4096 編集上限でキャップ)でプレビューを新しいメッセージへローテーションします。他のモードでは、1 つのプレビューを最大 4096 文字まで伸ばします。progressモードは、ツール進行状況を編集可能なステータス下書きに保持し、回答ストリーミングがアクティブだがツール行がまだ利用できない場合にステータスラベルを実体化し、完了時に下書きをクリアして、通常の配信を通じて最終回答を送信します。- 完了したテキストが確認される前に最終編集が失敗した場合、OpenClaw は通常の最終配信を使い、古いプレビューをクリーンアップします。
- 二重ストリーミングを避けるため、Telegram ブロックストリーミングが明示的に有効な場合、プレビューストリーミングはスキップされます。
/reasoning streamは、最終配信後に削除される一時プレビューへ reasoning を書き込めます。- Telegram の選択引用返信は例外です。
replyToModeが"off"ではなく、選択引用テキストが存在する場合、そのターンでは OpenClaw は回答プレビューストリームをスキップします(最終回答はネイティブの引用返信パスを通る必要があります)。そのため、ツール進行状況のプレビュー行はレンダリングできません。選択引用テキストがない現在メッセージへの返信では、プレビューストリーミングは維持されます。詳細は Telegram チャンネルドキュメント を参照してください。
Discord
- send + edit プレビュー メッセージを使用します。
blockモードはドラフトのチャンク化 (draftChunk) を使用します。- Discord のブロック ストリーミングが明示的に有効化されている場合、プレビュー ストリーミングはスキップされます。
- 最終メディア、エラー、明示的な返信ペイロードは、新しいドラフトをフラッシュせずに保留中のプレビューをキャンセルし、その後通常の配信を使用します。
Slack
partialは、利用可能な場合に Slack ネイティブ ストリーミング (chat.startStream/append/stop) を使用できます。blockは追記スタイルのドラフト プレビューを使用します。progressはステータス プレビュー テキストを使用し、その後に最終回答を送信します。- 返信スレッドのないトップレベル DM は、Slack ネイティブ ストリーミングの代わりにドラフト プレビュー投稿と編集を使用します。
- ネイティブおよびドラフト プレビュー ストリーミングは、そのターンのブロック返信を抑制するため、Slack の返信は 1 つの配信パスだけでストリーミングされます。
- 最終メディア/エラー ペイロードと進行状況の最終結果は、使い捨てのドラフト メッセージを作成しません。プレビューを編集できるテキスト/ブロックの最終結果だけが、保留中のドラフト テキストをフラッシュします。
Mattermost
- 思考、ツール アクティビティ、部分返信テキストを単一のドラフト プレビュー投稿にストリーミングし、最終回答を安全に送信できるときにその場で確定します。
- プレビュー投稿が削除されたか、確定時に何らかの理由で利用できない場合は、新しい最終投稿の送信にフォールバックします。
- 最終メディア/エラー ペイロードは、一時的なプレビュー投稿をフラッシュする代わりに、通常の配信前に保留中のプレビュー更新をキャンセルします。
Matrix
- 最終テキストがプレビュー イベントを再利用できる場合、ドラフト プレビューはその場で確定します。
- メディアのみ、エラー、返信先不一致の最終結果は、通常の配信前に保留中のプレビュー更新をキャンセルします。すでに表示されている古いプレビューは編集削除されます。
ツール進行状況のプレビュー更新
プレビュー ストリーミングには、ツール進行状況 の更新も含めることができます。ツールの実行中、最終返信の前に、同じプレビュー メッセージ内に表示される「ウェブを検索中」、「ファイルを読み取り中」、「ツールを呼び出し中」のような短いステータス行です。Codex app-server モードでは、Codex の前置き/コメンタリー メッセージもこの同じプレビュー パスを使用するため、「確認しています…」のような短い進行状況メモを、最終回答の一部にせずに編集可能なドラフトへストリーミングできます。これにより、複数ステップのツール ターンは、最初の思考プレビューと最終回答の間で沈黙するのではなく、視覚的に動き続けます。 長時間実行されるツールは、返る前に型付きの進行状況を出力することがあります。たとえば、web_fetch は開始時に 5 秒のタイマーを設定します。フェッチがまだ保留中の場合、プレビューには Fetching page content... が表示されます。その前にフェッチが完了またはキャンセルされた場合、進行状況行は出力されません。後続の最終ツール結果は、通常どおりモデルに配信されます。
サポートされるサーフェス:
- Discord、Slack、Telegram、Matrix は、プレビュー ストリーミングが有効な場合、デフォルトでツール進行状況と Codex の前置き更新をライブ プレビュー編集にストリーミングします。Microsoft Teams は個人チャットでネイティブの進行状況ストリームを使用します。
- Telegram は
v2026.4.22以降、ツール進行状況プレビュー更新を有効にした状態で出荷されています。有効のままにすることで、そのリリース済みの動作を維持できます。 - Mattermost は、すでにツール アクティビティを単一のドラフト プレビュー投稿に組み込んでいます(上記を参照)。
- ツール進行状況の編集は、アクティブなプレビュー ストリーミング モードに従います。プレビュー ストリーミングが
offの場合、またはブロック ストリーミングがメッセージを引き継いでいる場合はスキップされます。Telegram では、streaming.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" のときに使用される候補ラベル |
コメンタリー進行状況レーン
ツール進行状況に加えて、コンパクト進行状況レンダラーはドラフト内にもう 1 つのレーンを表示できます。streaming.progress.commentary- モデルのツール実行前の コメンタリー(短い「確認してから…」のようなナレーション)を、進行状況ドラフト内でツール行と交互にレンダリングします。
channels.discord、channels.matrix、channels.msteams、channels.mattermost、または Slack ドラフト プレビューです。進行状況ドラフト モードでは、同じポリシーを streaming.progress の下に置きます。
関連
- メッセージ ライフサイクル リファクタリング - 共有プレビュー、編集、ストリーム、確定設計の対象
- 進行状況ドラフト - 長いターン中に更新される、作業中であることが見えるメッセージ
- メッセージ - メッセージ ライフサイクルと配信
- 再試行 - 配信失敗時の再試行動作
- チャネル - チャネルごとのストリーミング サポート