Ir al contenido

Configura el streaming y chunking en OpenClaw

Seguro que te ha pasado: lanzas una petición a un modelo de IA y te quedas mirando la pantalla esperando a que aparezca todo el bloque de texto de golpe. Esa espera rompe la experiencia del usuario y hace que la herramienta se sienta lenta o desconectada.

Para solucionar esto, OpenClaw maneja el flujo de datos de una forma inteligente. No se trata de soltar tokens sin control, sino de cómo esos fragmentos llegan a aplicaciones como Slack o Discord de manera que la interacción sea fluida y natural.

OpenClaw tiene dos capas de streaming separadas:

  • Streaming de bloques (canales): emite bloques completados mientras el asistente escribe. Son mensajes de canal normales (no deltas de tokens).
  • Streaming de vista previa (Telegram/Discord/Slack): actualiza un mensaje de vista previa temporal durante la generación.

Hoy en día no existe un streaming real de deltas de tokens hacia los mensajes de los canales. El streaming de vista previa se basa en mensajes (envío + ediciones/anexos).

El streaming de bloques envía la salida del asistente en fragmentos gruesos a medida que están disponibles.

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)

Leyenda:

  • text_delta/events: eventos de stream del modelo (pueden ser escasos para modelos que no son de streaming).
  • chunker: EmbeddedBlockChunker que aplica límites mínimos/máximos + preferencia de salto.
  • channel send: mensajes de salida reales (respuestas de bloque).

Controles:

  • agents.defaults.blockStreamingDefault: "on"/"off" (por defecto desactivado).
  • Sobrescrituras de canal: *.blockStreaming (y variantes por cuenta) para forzar "on"/"off" por canal.
  • agents.defaults.blockStreamingBreak: "text_end" o "message_end".
  • agents.defaults.blockStreamingChunk: { minChars, maxChars, breakPreference? }.
  • agents.defaults.blockStreamingCoalesce: { minChars?, maxChars?, idleMs? } (fusiona bloques transmitidos antes del envío).
  • Límite estricto del canal: *.textChunkLimit (por ejemplo, channels.whatsapp.textChunkLimit).
  • Modo de fragmento del canal: *.chunkMode (length por defecto, newline divide en líneas en blanco antes de fragmentar por longitud).
  • Límite flexible de Discord: channels.discord.maxLinesPerMessage (por defecto 17) divide respuestas largas para evitar que la interfaz las corte.

Semántica de límites:

  • text_end: transmite bloques tan pronto como el chunker los emite; limpia el búfer en cada text_end.
  • message_end: espera hasta que el mensaje del asistente termine y luego envía el contenido almacenado.

message_end sigue usando el chunker si el texto acumulado supera maxChars, por lo que puede emitir varios fragmentos al final.

Algoritmo de fragmentación (límites bajos/altos)

Sección titulada «Algoritmo de fragmentación (límites bajos/altos)»

La fragmentación de bloques la implementa EmbeddedBlockChunker:

  • Límite bajo: no emite hasta que el búfer sea >= minChars (a menos que se fuerce).
  • Límite alto: prefiere dividir antes de maxChars; si se fuerza, divide en maxChars.
  • Preferencia de salto: paragraph → newline → sentence → whitespace → salto forzado.
  • Bloques de código (code fences): nunca divide dentro de los bloques; si se fuerza en maxChars, cierra y reabre el bloque para mantener el Markdown válido.

maxChars se ajusta al textChunkLimit del canal, así que no puedes superar los límites por canal.

Coalescencia (fusionar bloques transmitidos)

Sección titulada «Coalescencia (fusionar bloques transmitidos)»

Cuando el streaming de bloques está activo, OpenClaw puede fusionar fragmentos de bloques consecutivos antes de enviarlos. Esto reduce el spam de mensajes de una sola línea y permite ofrecer una salida progresiva.

  • La coalescencia espera a que haya pausas de inactividad (idleMs) antes de enviar.
  • Los búferes están limitados por maxChars y se enviarán si lo superan.
  • minChars evita que se envíen fragmentos diminutos hasta que se acumule suficiente texto (el envío final siempre manda el texto restante).
  • El conector se deriva de blockStreamingChunk.breakPreference (paragraph → \n\n, newline → \n, sentence → espacio).
  • Las sobrescrituras de canal están disponibles mediante *.blockStreamingCoalesce (incluyendo configuraciones por cuenta).
  • El minChars por defecto para la coalescencia sube a 1500 para Signal/Slack/Discord a menos que se cambie.

Si activas el streaming de bloques, puedes añadir una pausa aleatoria entre las respuestas de bloque (después del primer bloque). Esto hace que las respuestas con múltiples burbujas se sientan más naturales.

  • Configuración: agents.defaults.humanDelay (sobrescribible por agente mediante agents.list[].humanDelay).
  • Modos: off (por defecto), natural (800–2500ms), custom (minMs/maxMs).
  • Se aplica solo a las respuestas de bloque, no a las respuestas finales ni a los resúmenes de herramientas.

Esto se configura así:

  • Transmitir fragmentos: blockStreamingDefault: "on" + blockStreamingBreak: "text_end" (emite sobre la marcha). Los canales que no son Telegram también necesitan *.blockStreaming: true.
  • Transmitir todo al final: blockStreamingBreak: "message_end" (envía todo de una vez, posiblemente en varios fragmentos si es muy largo).
  • Sin streaming de bloques: blockStreamingDefault: "off" (solo la respuesta final).

Nota sobre canales: El streaming de bloques está desactivado a menos que *.blockStreaming se configure explícitamente como true. Los canales pueden transmitir una vista previa en vivo (channels.<channel>.streaming) sin usar respuestas de bloque.

Recordatorio de ubicación: los valores por defecto de blockStreaming* están bajo agents.defaults, no en la raíz de la configuración.

Clave canónica: channels.<channel>.streaming

Modos:

  • off: desactiva el streaming de vista previa.
  • partial: una única vista previa que se reemplaza con el texto más reciente.
  • block: la vista previa se actualiza en pasos fragmentados o añadidos.
  • progress: vista previa de progreso/estado durante la generación, respuesta final al terminar.
Canaloffpartialblockprogress
Telegram✅✅✅mapea a partial
Discord✅✅✅mapea a partial
Slack✅✅✅✅

Solo para Slack:

  • channels.slack.nativeStreaming activa las llamadas a la API de streaming nativo de Slack cuando streaming=partial (por defecto: true).

Migración de claves antiguas:

  • Telegram: streamMode + booleano streaming se migran automáticamente al enum streaming.
  • Discord: streamMode + booleano streaming se migran automáticamente al enum streaming.
  • Slack: streamMode se migra al enum streaming; el booleano streaming se migra a nativeStreaming.

Telegram:

  • Usa actualizaciones de vista previa con sendMessage + editMessageText en mensajes directos, grupos y temas.
  • El streaming de vista previa se omite si el streaming de bloques de Telegram está activado explícitamente (para evitar el doble streaming).
  • /reasoning stream puede escribir el razonamiento en la vista previa.

Discord:

  • Usa mensajes de vista previa de tipo enviar + editar.
  • El modo block usa fragmentación de borrador (draftChunk).
  • El streaming de vista previa se omite si el streaming de bloques de Discord está activado explícitamente.

Slack:

  • partial puede usar el streaming nativo de Slack (chat.startStream/append/stop) cuando esté disponible.
  • block usa vistas previa de borrador de tipo anexo.
  • progress usa un texto de vista previa de estado y luego la respuesta final.
  • Messages — ciclo de vida y entrega de mensajes
  • Retry — comportamiento de reintento en fallos de entrega
  • Channels — soporte de streaming por canal

¿Quieres ajustar cómo se ven tus mensajes? Te recomiendo revisar la documentación de Channels para ver las capacidades específicas de cada plataforma o profundizar en el ciclo de vida de los mensajes en Messages.

AI Setup Assistant

OpenClaw

OpenClaw Expert

Sigues atascado?

Si esta pagina no resolvio tu caso, pregunta a OpenClaw Expert para pasos concretos.