스트리밍 + 청킹
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) UI 클리핑을 방지하기 위해 긴 응답을 분할합니다.
경계 의미:
text_end: 청커가 내보내는 즉시 블록을 스트리밍하고 각text_end에서 플러시.message_end: 어시스턴트 메시지가 완료될 때까지 기다린 후 버퍼링된 출력을 플러시.
message_end도 버퍼링된 텍스트가 maxChars를 초과하면 청커를 사용하므로 끝에서 여러 청크를 내보낼 수 있습니다.
청킹 알고리즘 (하한/상한)
블록 청킹은 EmbeddedBlockChunker가 구현합니다:
- 하한: 버퍼 >=
minChars가 될 때까지 내보내지 않음(강제가 아닌 한). - 상한:
maxChars전에 분할을 선호하고, 강제 시maxChars에서 분할. - 분할 선호도:
paragraph→newline→sentence→whitespace→ 하드 분할. - 코드 펜스: 펜스 내부에서는 절대 분할하지 않음.
maxChars에서 강제 시 마크다운 유효성을 유지하기 위해 펜스를 닫고 다시 엽니다.
maxChars는 채널 textChunkLimit으로 제한되어 채널별 상한을 초과할 수 없습니다.
병합 (스트리밍된 블록 합치기)
블록 스트리밍이 활성화된 경우 OpenClaw은 전송 전에 연속된 블록 청크를 병합할 수 있습니다. 이렇게 하면 점진적 출력을 제공하면서도 “한 줄 스팸”을 줄입니다.
- 병합은 플러시 전에 유휴 간격(
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). - 블록 응답에만 적용되며 최종 응답이나 도구 요약에는 적용되지 않습니다.
”청크 스트리밍 또는 전체 스트리밍”
이것은 다음에 매핑됩니다:
- 청크 스트리밍:
blockStreamingDefault: "on"+blockStreamingBreak: "text_end"(생성되는 대로 내보냄). Telegram이 아닌 채널은*.blockStreaming: true도 필요합니다. - 끝에서 전체 스트리밍:
blockStreamingBreak: "message_end"(한 번 플러시, 매우 긴 경우 여러 청크 가능). - 블록 스트리밍 없음:
blockStreamingDefault: "off"(최종 응답만).
채널 참고: 블록 스트리밍은 *.blockStreaming이 명시적으로 true로 설정되지 않으면 비활성화됩니다. 채널은 블록 응답 없이 실시간 미리보기(channels.<channel>.streaming)를 스트리밍할 수 있습니다.
설정 위치 참고: blockStreaming* 기본값은 루트 설정이 아닌 agents.defaults 아래에 있습니다.
미리보기 스트리밍 모드
정규 키: channels.<channel>.streaming
모드:
off: 미리보기 스트리밍 비활성화.partial: 최신 텍스트로 대체되는 단일 미리보기.block: 청크/추가 단계로 업데이트되는 미리보기.progress: 생성 중 진행/상태 미리보기, 완료 시 최종 답변.
채널 매핑
| 채널 | off | partial | block | progress |
|---|---|---|---|---|
| Telegram | ✅ | ✅ | ✅ | partial로 매핑 |
| Discord | ✅ | ✅ | ✅ | partial로 매핑 |
| Slack | ✅ | ✅ | ✅ | ✅ |
Slack 전용:
channels.slack.nativeStreaming은streaming=partial일 때 Slack 네이티브 스트리밍 API 호출을 토글합니다(기본값:true).
레거시 키 마이그레이션:
- Telegram:
streamMode+ 불리언streaming이streaming열거형으로 자동 마이그레이션. - Discord:
streamMode+ 불리언streaming이streaming열거형으로 자동 마이그레이션. - Slack:
streamMode가streaming열거형으로 자동 마이그레이션, 불리언streaming이nativeStreaming으로 자동 마이그레이션.
런타임 동작
Telegram:
- DM과 그룹/토픽 전반에서
sendMessage+editMessageText미리보기 업데이트를 사용합니다. - Telegram 블록 스트리밍이 명시적으로 활성화된 경우 이중 스트리밍을 방지하기 위해 미리보기 스트리밍을 건너뜁니다.
/reasoning stream으로 추론을 미리보기에 쓸 수 있습니다.
Discord:
- 전송 + 편집 미리보기 메시지를 사용합니다.
block모드는 드래프트 청킹(draftChunk)을 사용합니다.- Discord 블록 스트리밍이 명시적으로 활성화된 경우 미리보기 스트리밍을 건너뜁니다.
Slack:
partial은 사용 가능한 경우 Slack 네이티브 스트리밍(chat.startStream/append/stop)을 사용할 수 있습니다.block은 추가 방식 드래프트 미리보기를 사용합니다.progress는 상태 미리보기 텍스트를 사용하고 최종 답변을 표시합니다.