Strumieniowanie + chunking
OpenClaw ma dwie oddzielne warstwy „strumieniowania”:- Strumieniowanie blokowe (kanały): emituje ukończone bloki w miarę pisania przez asystenta. Są to zwykłe wiadomości kanału (nie delty tokenów).
- Strumieniowanie quasi-tokenowe (tylko Telegram): aktualizuje dymek wersji roboczej częściowym tekstem podczas generowania; końcowa wiadomość jest wysyłana na końcu.
Strumieniowanie blokowe (wiadomości kanału)
Strumieniowanie blokowe wysyła odpowiedź asystenta w grubych porcjach, gdy stają się dostępne.text_delta/events: zdarzenia strumienia modelu (mogą być rzadkie dla modeli niestrumieniujących).chunker:EmbeddedBlockChunkerz zastosowaniem minimalnych/maksymalnych granic + preferencji podziału.channel send: faktyczne wiadomości wychodzące (odpowiedzi blokowe).
agents.defaults.blockStreamingDefault:"on"/"off"(domyślnie wyłączone).- Nadpisania kanału:
*.blockStreaming(oraz warianty per-konto), aby wymusić"on"/"off"na kanał. agents.defaults.blockStreamingBreak:"text_end"lub"message_end".agents.defaults.blockStreamingChunk:{ minChars, maxChars, breakPreference? }.agents.defaults.blockStreamingCoalesce:{ minChars?, maxChars?, idleMs? }(scalanie strumieniowanych bloków przed wysyłką).- Twardy limit kanału:
*.textChunkLimit(np.channels.whatsapp.textChunkLimit). - Tryb porcjowania kanału:
*.chunkMode(lengthdomyślnie,newlinedzieli po pustych liniach (granice akapitów) przed porcjowaniem długości). - Miękki limit Discorda:
channels.discord.maxLinesPerMessage(domyślnie 17) dzieli wysokie odpowiedzi, aby uniknąć przycinania UI.
text_end: strumieniuje bloki, gdy tylko porcjownik je wyemituje; opróżnia bufor przy każdymtext_end.message_end: czeka do zakończenia wiadomości asystenta, a następnie opróżnia zbuforowane wyjście.
message_end nadal używa porcjownika, jeśli zbuforowany tekst przekracza maxChars, więc może wyemitować wiele porcji na końcu.
Algorytm porcjowania (dolna/górna granica)
Porcjowanie bloków jest realizowane przezEmbeddedBlockChunker:
- Dolna granica: nie emituj, dopóki bufor >=
minChars(chyba że wymuszone). - Górna granica: preferuj podziały przed
maxChars; jeśli wymuszone, podziel przymaxChars. - Preferencja podziału:
paragraph→newline→sentence→whitespace→ twardy podział. - Bloki kodu: nigdy nie dziel wewnątrz bloków; gdy wymuszone przy
maxChars, zamknij i ponownie otwórz blok, aby zachować poprawność Markdown.
maxChars jest ograniczane przez textChunkLimit kanału, więc nie można przekroczyć limitów per-kanał.
Scalanie (łączenie strumieniowanych bloków)
Gdy strumieniowanie blokowe jest włączone, OpenClaw może scalać kolejne porcje bloków przed ich wysłaniem. Zmniejsza to „spam jednolinijkowy”, zachowując jednocześnie postępowe wyjście.- Scalanie czeka na przerwy bezczynności (
idleMs) przed opróżnieniem bufora. - Bufory są ograniczone przez
maxCharsi zostaną opróżnione po jego przekroczeniu. minCharszapobiega wysyłaniu drobnych fragmentów, dopóki nie zbierze się wystarczająca ilość tekstu (końcowe opróżnienie zawsze wysyła pozostały tekst).- Łącznik jest wyprowadzany z
blockStreamingChunk.breakPreference(paragraph→\n\n,newline→\n,sentence→ spacja). - Nadpisania kanału są dostępne przez
*.blockStreamingCoalesce(w tym konfiguracje per-konto). - Domyślna wartość scalania
minCharsjest podniesiona do 1500 dla Signal/Slack/Discord, o ile nie zostanie nadpisana.
Ludzkie tempo między blokami
Gdy strumieniowanie blokowe jest włączone, można dodać losową pauzę między odpowiedziami blokowymi (po pierwszym bloku). Sprawia to, że odpowiedzi z wieloma dymkami wydają się bardziej naturalne.- Konfiguracja:
agents.defaults.humanDelay(nadpisanie per agent przezagents.list[].humanDelay). - Tryby:
off(domyślny),natural(800–2500 ms),custom(minMs/maxMs). - Dotyczy tylko odpowiedzi blokowych, nie odpowiedzi końcowych ani podsumowań narzędzi.
„Strumieniować porcje czy wszystko”
Mapowanie:- Strumieniuj porcje:
blockStreamingDefault: "on"+blockStreamingBreak: "text_end"(emituj na bieżąco). Kanały inne niż Telegram wymagają także*.blockStreaming: true. - Strumieniuj wszystko na końcu:
blockStreamingBreak: "message_end"(jednorazowe opróżnienie, możliwie w wielu porcjach, jeśli bardzo długie). - Brak strumieniowania blokowego:
blockStreamingDefault: "off"(tylko odpowiedź końcowa).
*.blockStreaming zostanie jawnie ustawione na true. Telegram może strumieniować wersje robocze
(channels.telegram.streamMode) bez odpowiedzi blokowych.
Przypomnienie o lokalizacji konfiguracji: domyślne wartości blockStreaming* znajdują się pod
agents.defaults, a nie w konfiguracji głównej.
Strumieniowanie projektu Telegram (token ish)
Telegram jest jedynym kanałem ze strumieniowaniem wersji roboczej:- Używa API Bota
sendMessage(pierwsza aktualizacja) +editMessageText(kolejne aktualizacje). channels.telegram.streamMode: "partial" | "block" | "off".partial: aktualizacje wersji roboczej z najnowszym tekstem strumienia.block: aktualizacje wersji roboczej w porcjowanych blokach (te same reguły porcjownika).off: brak projektu streamingu.
- Konfiguracja porcji wersji roboczej (tylko dla
streamMode: "block"):channels.telegram.draftChunk(domyślne:minChars: 200,maxChars: 800). - Strumieniowanie podglądu jest oddzielone od strumieniowania bloków.
- Gdy strumieniowanie bloków Telegram jest jawnie włączone, strumieniowanie podglądu jest pomijane, aby uniknąć podwójnego strumieniowania.
- Końcowe odpowiedzi zawierające wyłącznie tekst są stosowane poprzez edycję wiadomości podglądu w miejscu.
- Końcowe odpowiedzi nietekstowe/złożone wracają do standardowego sposobu dostarczania wiadomości końcowej.
/reasoning streamzapisuje rozumowanie do dymka wersji roboczej (tylko Telegram).
preview message: tymczasowa wiadomość Telegram aktualizowana podczas generowania.final edit: edycja w miejscu tej samej wiadomości podglądu (tylko tekst).