OpenClaw 스트리밍 및 청킹 설정 가이드
AI 응답이 올 때까지 하염없이 커서만 바라보고 있었던 적이 있나요? 특히 긴 답변을 생성할 때 답변이 다 완성될 때까지 아무것도 보이지 않는다면 사용자 경험은 답답해질 수밖에 없어요. 그렇다고 토큰 하나가 생성될 때마다 매번 메시지를 보내면 알림이 쏟아지는 ‘알림 지옥’에 빠지게 되죠.
OpenClaw는 이런 문제를 해결하기 위해 두 가지 영리한 스트리밍 레이어를 제공해요. 답변을 적절한 덩어리로 끊어서 보내는 블록 스트리밍과, 메시지 하나를 실시간으로 업데이트하는 프리뷰 스트리밍을 통해 사용자에게 가장 자연스러운 피드백을 전달할 수 있습니다.
블록 스트리밍 (채널 메시지)
섹션 제목: “블록 스트리밍 (채널 메시지)”블록 스트리밍은 어시스턴트의 출력을 사용 가능한 시점에 맞춰 큼직한 청크(chunk) 단위로 전송해요.
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? }(전송 전 스트리밍된 블록들을 병합해요).- 채널 하드 캡(Hard cap):
*.textChunkLimit(예:channels.whatsapp.textChunkLimit). - 채널 청크 모드:
*.chunkMode(length가 기본이며,newline은 길이에 따라 나누기 전 빈 줄(단락 경계)에서 먼저 나눕니다). - Discord 소프트 캡(Soft cap):
channels.discord.maxLinesPerMessage(기본값 17)는 UI가 잘리는 것을 방지하기 위해 세로로 긴 답장을 나눕니다.
경계 의미(Boundary semantics):
text_end: 청커가 블록을 내보내는 즉시 스트리밍하고, 각text_end마다 플러시(flush)해요.message_end: 어시스턴트 메시지가 끝날 때까지 기다렸다가 버퍼링된 출력을 한꺼번에 플러시해요.
message_end를 사용하더라도 버퍼링된 텍스트가 maxChars를 초과하면 청커가 작동하여 마지막에 여러 개의 청크로 나누어 보낼 수 있어요.
청킹 알고리즘 (최소/최대 범위)
섹션 제목: “청킹 알고리즘 (최소/최대 범위)”블록 청킹은 EmbeddedBlockChunker에 의해 구현됩니다.
- 최소 범위(Low bound): 버퍼가
minChars이상이 될 때까지는 내보내지 않아요 (강제 플러시 제외). - 최대 범위(High bound):
maxChars직전에서 끊는 것을 선호하며, 강제될 경우maxChars에서 나눕니다. - 줄 바꿈 선호도(Break preference):
paragraph→newline→sentence→whitespace→ 하드 브레이크 순서로 적용돼요. - 코드 펜스(Code fences): 코드 블록 내부에서는 절대 나누지 않아요.
maxChars때문에 어쩔 수 없이 나눠야 할 때는 Markdown 문법이 깨지지 않도록 펜스를 닫고 다시 열어줍니다.
maxChars는 채널의 textChunkLimit에 고정되므로, 채널별 제한을 초과할 걱정은 없어요.
Coalescing (스트리밍 블록 병합)
섹션 제목: “Coalescing (스트리밍 블록 병합)”블록 스트리밍이 활성화되었을 때, OpenClaw는 연속된 블록 청크를 전송하기 전에 하나로 병합할 수 있어요. 이렇게 하면 진행 상황을 보여주면서도 “한 줄씩 도배되는 스팸” 현상을 줄일 수 있습니다.
- Coalescing은 플러시하기 전에 유휴 시간(
idleMs)을 기다려요. - 버퍼는
maxChars로 제한되며, 이를 초과하면 즉시 플러시됩니다. minChars는 충분한 텍스트가 쌓일 때까지 아주 작은 파편이 전송되는 것을 방지해요 (최종 플러시 때는 남은 텍스트를 모두 보냅니다).- 결합 방식은
blockStreamingChunk.breakPreference에서 가져와요 (paragraph→\n\n,newline→\n,sentence→ 공백). *.blockStreamingCoalesce를 통해 채널별 오버라이드가 가능해요 (계정별 설정 포함).- Signal/Slack/Discord의 경우 별도 설정이 없으면 기본 coalesce
minChars가 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 전용:
streaming=partial일 때channels.slack.nativeStreaming을 통해 Slack 네이티브 스트리밍 API 호출 여부를 결정할 수 있어요 (기본값:true).
기존 키 마이그레이션:
- Telegram:
streamMode와 불리언(boolean) 값인streaming은 자동으로streaming열거형(enum)으로 마이그레이션됩니다. - Discord:
streamMode와 불리언 값인streaming은 자동으로streaming열거형으로 마이그레이션됩니다. - Slack:
streamMode는streaming열거형으로, 불리언 값인streaming은nativeStreaming으로 자동 마이그레이션됩니다.
런타임 동작
섹션 제목: “런타임 동작”Telegram:
- DM, 그룹, 토픽 전체에서
sendMessage+editMessageText를 사용하여 프리뷰를 업데이트해요. - Telegram 블록 스트리밍이 명시적으로 활성화된 경우, 중복 스트리밍을 피하기 위해 프리뷰 스트리밍은 건너뜁니다.
/reasoning stream명령으로 추론 과정을 프리뷰에 표시할 수 있어요.
Discord:
- 메시지 전송 후 수정(send + edit) 방식을 사용해요.
block모드는 드래프트 청킹(draftChunk)을 사용합니다.- Discord 블록 스트리밍이 활성화된 경우 프리뷰 스트리밍은 건너뜁니다.
Slack:
partial모드에서 사용 가능한 경우 Slack 네이티브 스트리밍(chat.startStream/append/stop)을 사용할 수 있어요.block모드는 추가 방식(append-style)의 드래프트 프리뷰를 사용합니다.progress모드는 상태 프리뷰 텍스트를 보여준 뒤 최종 답변을 표시해요.
관련 문서
섹션 제목: “관련 문서”다음 단계
섹션 제목: “다음 단계”OpenClaw Expert
아직 막혀 있나요?
이 문서에서 답을 못 찾았다면 OpenClaw Expert에게 바로 물어보세요.