En vivo 18.11 · Cohorte 318 nov, 19:00 MSK — taller práctico gratuito de agentes IA · Cohorte 3 en vivo inicia 23.11Taller 18 nov →Cohorte 3 (23.11)
LanzamientoAnálisis · En radarHabr AI→ original

El agente terminó, pero Telegram no responde: una cola de entrega en agent-hub, escrito en Rust

Cuando el agente ya terminó su trabajo pero Telegram no está disponible, no se puede repetir la solicitud al modelo: cuesta tokens y puede volver a modificar archivos. El autor de agent-hub, escrito en Rust, separó la obtención del resultado de su entrega. El texto final se escribe primero en disco, y una tarea aparte lo envía por partes y reintenta tras un fallo o un reinicio.

Procesado por IA desde Habr AI; editado por Hamidun News
El agente terminó, pero Telegram no responde: una cola de entrega en agent-hub, escrito en Rust
Fuente: Habr AI. Collage: Hamidun News.
Escuchar artículo
Ficha técnica y cifras clave
ParámetroDatos
Fuente originalHabr AI ↗
Editor jefe
Dato clave #1La respuesta se guarda en un archivo, dividida de antemano en partes con seguimiento del progreso
Dato clave #2La pausa entre reintentos crece de 5 a 600 segundos
Dato clave #3Los duplicados son posibles, por eso cada parte lleva el ID del turno y un número

Una situación conocida: el agente leyó el código, corrigió los archivos, verificó el resultado y escribió una respuesta excelente. Y justo en ese momento Telegram no está disponible. Para el agente el trabajo está terminado; para el usuario no ha pasado nada. Lanzar la tarea de nuevo no apetece: cuesta tiempo, tokens y existe el riesgo de que el agente vuelva a cambiar algo. Esto es justo con lo que se topó el autor de agent-hub, una aplicación en Rust que ejecuta agentes de IA en local y se comunica con ellos mediante los temas de un grupo de Telegram.

Separar el resultado de la entrega

La idea principal es simple: recibir la respuesta y enviarla son dos eventos distintos. Cuando el turno del agente termina con éxito, el hub primero guarda el texto final en un archivo local, topics.results.json, y lo pone en cola, y solo después se dirige a Telegram. Una tarea independiente se encarga del envío y los reintentos. Tras un reinicio lee el estado del disco y continúa la entrega sin una nueva llamada al modelo.

A la cola no entra toda la conversación, sino los bloques de texto consecutivos posteriores a la última llamada visible a una herramienta. Los adjuntos, los mensajes intermedios, las preguntas y los botones de permisos no se repiten automáticamente.

Un detalle importante: el hub almacena las partes ya preparadas, no el Markdown original. Si tras actualizar la aplicación cambia la conversión del marcado, los límites de los mensajes seguirán siendo los mismos y el número guardado de la siguiente parte no se desplazará a otro fragmento de texto.

Cómo sobrevive a los fallos

El ciclo es así: encontrar una entrada lista, reservarla durante 60 segundos y guardarlo en disco, enviar la parte actual, registrar la confirmación y pasar a la siguiente. La reserva es necesaria por si el proceso se interrumpe en mitad de una petición de red: la entrada no quedará ocupada para siempre. La petición a Telegram está limitada a 20 segundos, y el envío va a no más de una parte por segundo.

Ante un error temporal las pausas crecen: 5, 15, 30, 60, 120, 300, 600 segundos. Tras ocho fallos seguidos, la entrega se detiene hasta un reintento manual. Si el propio Telegram pide esperar (RetryAfter), esa pausa se guarda para la cola de todo el grupo y no se acorta ni con un reintento manual ni con un reinicio. Si Telegram rechazó el HTML, el hub intenta enviar texto plano, y si tampoco pasa, espera la intervención de una persona.

La cola se puede gestionar desde el tema: /last muestra la última respuesta guardada sin llamar al modelo, /outbox muestra las entregas pendientes con los botones «Reintentar» y «Eliminar». Si falla la lectura del almacenamiento, la interfaz muestra «desconocido» en lugar de cero, para que un fallo del disco no parezca una cola vacía.

Dónde terminan las garantías

El autor, con honestidad, no promete la entrega exactamente una vez. Telegram pudo aceptar el mensaje y perderse la confirmación; o el hub no alcanzó a escribirlo en disco antes de detenerse. Entonces la parte se enviará de nuevo. Por eso al comienzo de cada parte figura el ID del turno y un número como «parte 2/3»: la etiqueta no elimina el duplicado, pero indica que es una repetición y no una respuesta nueva.

Hay también límites estrictos: hasta 50 respuestas pendientes y 8 MiB en la cola, conservación de hasta 7 días, hasta 64 KiB por texto. Si la cola está llena, las entradas antiguas no se desalojan, y la nueva respuesta se envía sin reintento automático y con una advertencia. El archivo se crea con permisos 0600, pero contiene las respuestas del agente, así que conviene tener presentes las copias de seguridad.

Las pruebas se hicieron en Linux con Telegram simulado y almacenamiento temporal: red no disponible, reinicio tras un envío parcial, pérdida de la confirmación, RetryAfter, error de HTML, desbordamiento, cambio de grupo. No se simuló un corte de energía.

Qué llevarse

El patrón es universal para cualquier herramienta de agentes: guarde el resultado antes de entregarlo, almacene el progreso por partes, dé identificadores a los reintentos y no prometa exactly-once donde no existe. Es, en esencia, un pequeño patrón outbox, conocido del backend, pero para agentes, donde repetir la ejecución es caro e inseguro. El código es abierto bajo licencia MIT.

Historia

Preguntas frecuentes sobre la noticia

¿Qué se sabe sobre Separar el resultado de la entrega?

La idea principal es simple: recibir la respuesta y enviarla son dos eventos distintos. Cuando el turno del agente termina con éxito, el hub primero guarda el texto final en un archivo local, topics.results.json, y lo pone en cola, y solo después se dirige a Telegram. Una tarea independiente se encarga del envío y los reintentos. Tras un reinicio lee el estado del disco y continúa la entrega sin una nueva llamada al modelo.

Cómo sobrevive a los fallos?

El ciclo es así: encontrar una entrada lista, reservarla durante 60 segundos y guardarlo en disco, enviar la parte actual, registrar la confirmación y pasar a la siguiente. La reserva es necesaria por si el proceso se interrumpe en mitad de una petición de red: la entrada no quedará ocupada para siempre. La petición a Telegram está limitada a 20 segundos, y el envío va a no más de una parte por segundo. Ante un error temporal las pausas crecen: 5, 15, 30, 60, 120, 300, 600 segundos.

Dónde terminan las garantías?

El autor, con honestidad, no promete la entrega exactamente una vez. Telegram pudo aceptar el mensaje y perderse la confirmación; o el hub no alcanzó a escribirlo en disco antes de detenerse. Entonces la parte se enviará de nuevo. Por eso al comienzo de cada parte figura el ID del turno y un número como «parte 2/3»: la etiqueta no elimina el duplicado, pero indica que es una repetición y no una respuesta nueva.

ZK
Zhemal Khamidun — CPO de Alpina Digital, product manager de AlpinaGPT. Crea productos de IA desde 2019. Hamidun News es un proyecto personal que creció hasta ser un agregador en producción con más de 6.000 lectores.
✦ Unified AI Workspace · Nomad

Test Frontier LLMs & Autonomous Agents in One Workspace

Run Claude Opus 5.5, GPT-6, Gemini 3.1, and DeepSeek side-by-side in Nomad AI (nomadnet.ai) — unified model routing, deep research, and multimodal workflows under one subscription.

Try Nomad AI →Launch Nomad Agent
¿Qué te parece?
Cargando comentarios…