Strumieniowanie + dzielenie na fragmenty
OpenClaw ma dwie oddzielne warstwy strumieniowania:- Strumieniowanie bloków (kanały): emituje ukończone bloki, gdy asystent pisze. Są to zwykłe wiadomości kanału (nie delty tokenów).
- Strumieniowanie podglądu (Telegram/Discord/Slack): aktualizuje tymczasową wiadomość podglądu podczas generowania.
Strumieniowanie bloków (wiadomości kanału)
Strumieniowanie bloków wysyła dane wyjściowe asystenta w większych fragmentach, gdy tylko stają się dostępne.text_delta/events: zdarzenia strumienia modelu (mogą być rzadkie dla modeli bez strumieniowania).chunker:EmbeddedBlockChunkerstosujący minimalne/maksymalne granice + preferencję podziału.channel send: rzeczywiste wiadomości wychodzące (odpowiedzi blokowe).
agents.defaults.blockStreamingDefault:"on"/"off"(domyślnie off).- Nadpisania kanałów:
*.blockStreaming(oraz warianty per konto), aby wymusić"on"/"off"dla każdego kanału. agents.defaults.blockStreamingBreak:"text_end"lub"message_end".agents.defaults.blockStreamingChunk:{ minChars, maxChars, breakPreference? }.agents.defaults.blockStreamingCoalesce:{ minChars?, maxChars?, idleMs? }(scala strumieniowane bloki przed wysłaniem).- Twardy limit kanału:
*.textChunkLimit(np.channels.whatsapp.textChunkLimit). - Tryb dzielenia kanału na fragmenty:
*.chunkMode(lengthdomyślnie,newlinedzieli po pustych liniach (granice akapitów) przed dzieleniem według długości). - Miękki limit Discord:
channels.discord.maxLinesPerMessage(domyślnie 17) dzieli długie odpowiedzi, aby uniknąć przycinania w interfejsie.
text_end: strumieniuje bloki, gdy tylko chunker je wyemituje; opróżnia przy każdymtext_end.message_end: czeka, aż wiadomość asystenta zostanie ukończona, a następnie opróżnia zbuforowane dane wyjściowe.
message_end nadal używa chunkera, jeśli zbuforowany tekst przekracza maxChars, więc na końcu może wyemitować wiele fragmentów.
Algorytm dzielenia na fragmenty (dolna/górna granica)
Dzielenie bloków na fragmenty jest implementowane przezEmbeddedBlockChunker:
- Dolna granica: nie emituje, dopóki bufor nie osiągnie
minChars(chyba że zostanie wymuszone). - Górna granica: preferuje podziały przed
maxChars; jeśli wymuszone, dzieli przymaxChars. - Preferencja podziału:
paragraph→newline→sentence→whitespace→ twardy podział. - Bloki kodu: nigdy nie dzieli wewnątrz bloków; przy wymuszeniu na
maxCharszamyka i ponownie otwiera blok, aby zachować poprawność Markdown.
maxChars jest ograniczane do textChunkLimit kanału, więc nie można przekroczyć limitów dla danego kanału.
Scalanie (łączenie strumieniowanych bloków)
Gdy strumieniowanie bloków jest włączone, OpenClaw może scalać kolejne fragmenty bloków przed ich wysłaniem. Zmniejsza to „spam pojedynczymi liniami”, nadal zapewniając postępowe wyjście.- Scalanie czeka na przerwy bezczynności (
idleMs) przed opróżnieniem. - Bufory są ograniczone przez
maxCharsi zostaną opróżnione, jeśli go przekroczą. minCharszapobiega wysyłaniu bardzo małych fragmentów, dopóki nie zgromadzi się wystarczająco dużo tekstu (końcowe opróżnienie zawsze wysyła pozostały tekst).- Separator łączenia jest wyprowadzany z
blockStreamingChunk.breakPreference(paragraph→\n\n,newline→\n,sentence→ spacja). - Nadpisania kanałów są dostępne przez
*.blockStreamingCoalesce(w tym konfiguracje per konto). - Domyślne
minCharsdla scalania jest zwiększane do 1500 dla Signal/Slack/Discord, chyba że zostanie nadpisane.
Tempo zbliżone do ludzkiego między blokami
Gdy strumieniowanie bloków jest włączone, możesz dodać losową przerwę między odpowiedziami blokowymi (po pierwszym bloku). Dzięki temu odpowiedzi w wielu dymkach wydają się bardziej naturalne.- Konfiguracja:
agents.defaults.humanDelay(nadpisanie per agent przezagents.list[].humanDelay). - Tryby:
off(domyślnie),natural(800–2500ms),custom(minMs/maxMs). - Dotyczy tylko odpowiedzi blokowych, nie odpowiedzi końcowych ani podsumowań narzędzi.
”Strumieniuj fragmenty albo wszystko”
To mapuje się na:- Strumieniuj fragmenty:
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"(opróżnij raz, ewentualnie w wielu fragmentach, jeśli odpowiedź jest bardzo długa). - Brak strumieniowania bloków:
blockStreamingDefault: "off"(tylko odpowiedź końcowa).
*.blockStreaming zostanie jawnie ustawione na true. Kanały mogą strumieniować podgląd na żywo
(channels.<channel>.streaming) bez odpowiedzi blokowych.
Przypomnienie o lokalizacji konfiguracji: domyślne ustawienia blockStreaming* znajdują się w
agents.defaults, a nie w głównej konfiguracji.
Tryby strumieniowania podglądu
Klucz kanoniczny:channels.<channel>.streaming
Tryby:
off: wyłącza strumieniowanie podglądu.partial: pojedynczy podgląd zastępowany najnowszym tekstem.block: aktualizacje podglądu wykonywane krokowo przez dzielenie na fragmenty/dodawanie.progress: podgląd postępu/statusu podczas generowania, odpowiedź końcowa po zakończeniu.
Mapowanie kanałów
| Kanał | off | partial | block | progress |
|---|---|---|---|---|
| Telegram | ✅ | ✅ | ✅ | mapuje do partial |
| Discord | ✅ | ✅ | ✅ | mapuje do partial |
| Slack | ✅ | ✅ | ✅ | ✅ |
channels.slack.streaming.nativeTransportprzełącza natywne wywołania API strumieniowania Slacka, gdychannels.slack.streaming.mode="partial"(domyślnie:true).- Natywne strumieniowanie Slacka i status wątku asystenta Slack wymagają docelowego wątku odpowiedzi; wiadomości prywatne najwyższego poziomu nie pokazują takiego podglądu w stylu wątku.
- Telegram:
streamMode+ logicznestreamingsą automatycznie migrowane do enumastreaming. - Discord:
streamMode+ logicznestreamingsą automatycznie migrowane do enumastreaming. - Slack:
streamModejest automatycznie migrowane dostreaming.mode; logicznestreamingjest automatycznie migrowane dostreaming.modeplusstreaming.nativeTransport; starszenativeStreamingjest automatycznie migrowane dostreaming.nativeTransport.
Zachowanie w czasie działania
Telegram:- Używa aktualizacji podglądu
sendMessage+editMessageTextw wiadomościach prywatnych oraz grupach/tematach. - Strumieniowanie podglądu jest pomijane, gdy strumieniowanie bloków Telegrama jest jawnie włączone (aby uniknąć podwójnego strumieniowania).
/reasoning streammoże zapisywać rozumowanie do podglądu.
- Używa wiadomości podglądu send + edit.
- Tryb
blockużywa roboczego dzielenia na fragmenty (draftChunk). - Strumieniowanie podglądu jest pomijane, gdy strumieniowanie bloków Discorda jest jawnie włączone.
partialmoże używać natywnego strumieniowania Slacka (chat.startStream/append/stop), gdy jest dostępne.blockużywa podglądów roboczych w stylu dodawania.progressużywa tekstu podglądu statusu, a następnie odpowiedzi końcowej.
Powiązane
- Wiadomości — cykl życia i dostarczanie wiadomości
- Ponawianie — zachowanie ponawiania przy błędzie dostarczenia
- Kanały — obsługa strumieniowania per kanał