コンテンツにスキップ

OpenClawのストリーミングとチャンク設定:出力を最適化する

LLMからの回答を待っている間、ユーザーが何も表示されない画面をじっと見つめるのはストレスですよね。しかし、チャットプラットフォームごとに異なる制限や仕様に合わせてストリーミングを実装するのは、開発者にとって非常に手間がかかる作業です。

OpenClawを使えば、こうした複雑な処理をスマートに管理できます。ユーザー体験を向上させるためのストリーミングとチャンキングの設定方法について見ていきましょう。

ブロックストリーミング(チャネルメッセージ)

Section titled “ブロックストリーミング(チャネルメッセージ)”

OpenClawには、2つの独立したストリーミングレイヤーがあります。

  • Block streaming (channels): アシスタントが回答を書くのと並行して、完成したブロックを送信します。これらは通常のチャネルメッセージであり、トークン単位の差分(token deltas)ではありません。
  • Preview streaming (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)。UIでの表示切れを防ぐため、長い返信を分割します。

境界のセマンティクス:

  • text_end: チャンカーがブロックを出力次第ストリームし、各 text_end でフラッシュします。
  • message_end: アシスタントのメッセージが完了するまで待ち、バッファリングされた出力をフラッシュします。

message_end を使用している場合でも、バッファリングされたテキストが maxChars を超える場合はチャンカーが使用されるため、最後に複数のチャンクが送信されることがあります。

チャンキングアルゴリズム(最小/最大境界)

Section titled “チャンキングアルゴリズム(最小/最大境界)”

ブロックのチャンキングは EmbeddedBlockChunker によって実装されています。

  • 最小境界 (Low bound): バッファが minChars 以上になるまで出力しません(強制時を除く)。
  • 最大境界 (High bound): maxChars の直前での分割を優先します。強制される場合は maxChars で分割します。
  • 区切り設定 (Break preference): paragraph → newline → sentence → whitespace → ハードブレイクの順で優先されます。
  • コードフェンス: フェンス内では分割しません。maxChars で強制分割される場合は、Markdown の整合性を保つためにフェンスを一度閉じてから再開します。

maxChars はチャネルの textChunkLimit に固定されるため、各チャネルの制限を超えることはありません。

コアレッシング(ストリームブロックの結合)

Section titled “コアレッシング(ストリームブロックの結合)”

ブロックストリーミングが有効な場合、OpenClawは連続するブロックチャンクを送信前にマージできます。これにより、段階的な出力を維持しつつ、「1行ずつのメッセージスパム」を減らすことができます。

  • コアレッシングは、フラッシュする前にアイドル時間 (idleMs) を待ちます。
  • バッファは maxChars によって制限され、それを超えるとフラッシュされます。
  • minChars により、十分なテキストが蓄積されるまで小さな断片が送信されるのを防ぎます(最後のフラッシュでは残りのテキストが必ず送信されます)。
  • 結合文字は blockStreamingChunk.breakPreference から派生します(paragraph → \n\n, newline → \n, sentence → スペース)。
  • *.blockStreamingCoalesce(アカウントごとの設定を含む)を介してチャネルごとのオーバーライドが可能です。
  • デフォルトのコアレッシング minChars は、オーバーライドされない限り Signal/Slack/Discord では 1500 に設定されています。

ブロックストリーミングが有効な場合、ブロック返信の間(最初のブロックの後)にランダムな一時停止を追加できます。これにより、複数の吹き出しによるレスポンスがより自然に感じられるようになります。

  • 設定: agents.defaults.humanDelay(agents.list[].humanDelay でエージェントごとにオーバーライド可能)。
  • モード: off(デフォルト)、natural(800–2500ms)、custom(minMs/maxMs)。
  • ブロック返信にのみ適用され、最終的な返信やツールの要約には適用されません。

「チャンクでストリーム」か「最後にまとめて」か

Section titled “「チャンクでストリーム」か「最後にまとめて」か”

これは以下の設定に対応します。

  • チャンクでストリーム: blockStreamingDefault: "on" + blockStreamingBreak: "text_end"(生成しながら出力)。Telegram 以外のチャネルでは *.blockStreaming: true も必要です。
  • 最後にまとめてストリーム: blockStreamingBreak: "message_end"(一度にフラッシュ。非常に長い場合は複数チャンクになる可能性があります)。
  • ブロックストリーミングなし: blockStreamingDefault: "off"(最終的な返信のみ)。

チャネルに関する注意: ブロックストリーミングは、*.blockStreaming が明示的に true に設定されない限り off です。チャネルは、ブロック返信なしでライブプレビュー(channels.<channel>.streaming)をストリームできます。

設定場所のリマインダー:blockStreaming* のデフォルト設定は、ルート設定ではなく agents.defaults の下にあります。

プレビューストリーミングモード

Section titled “プレビューストリーミングモード”

標準キー: channels.<channel>.streaming

モード:

  • off: プレビューストリーミングを無効にします。
  • partial: 最新のテキストで置換される単一のプレビュー。
  • block: チャンク化または追記形式で更新されるプレビュー。
  • progress: 生成中は進捗/ステータスを表示し、完了時に最終回答を表示します。
チャネルoffpartialblockprogress
Telegram✅✅✅partial にマップ
Discord✅✅✅partial にマップ
Slack✅✅✅✅

Slack 専用設定:

  • streaming=partial の際、channels.slack.nativeStreaming で Slack ネイティブストリーミング API コールの使用を切り替えます(デフォルト: true)。

レガシーキーの移行:

  • Telegram: streamMode + boolean の streaming は streaming 列挙型に自動移行されます。
  • Discord: streamMode + boolean の streaming は streaming 列挙型に自動移行されます。
  • Slack: streamMode は streaming 列挙型に、boolean の streaming は nativeStreaming に自動移行されます。

Telegram:

  • DM、グループ、トピックを問わず、sendMessage + editMessageText を使用してプレビューを更新します。
  • 二重ストリーミングを避けるため、Telegram のブロックストリーミングが明示的に有効な場合、プレビューストリーミングはスキップされます。
  • /reasoning stream を使用すると、推論プロセスをプレビューに書き込むことができます。

Discord:

  • 送信 + 編集によるプレビューメッセージを使用します。
  • block モードではドラフトチャンキング(draftChunk)を使用します。
  • Discord のブロックストリーミングが明示的に有効な場合、プレビューストリーミングはスキップされます。

Slack:

  • partial では、利用可能な場合に Slack ネイティブストリーミング(chat.startStream/append/stop)を使用できます。
  • block では、追記スタイルのドラフトプレビューを使用します。
  • progress では、ステータスプレビューテキストを表示した後、最終回答を表示します。
  • Messages — メッセージのライフサイクルと配信
  • Retry — 配信失敗時のリトライ挙動
  • Channels — チャネルごとのストリーミングサポート

設定についてさらに詳しく知りたい場合は、AI Setup Assistant を活用してください。

OpenClaw

OpenClaw Expert

まだ解決しませんか?

このページで解決しない場合は、OpenClaw Expertに直接質問してください。