Artículos en profundidad sobre la tecnología que da forma al futuro.

Agentes de IA con estado en serverless: el caso Talorys

¿Cómo ejecutar un agente de IA con estado en serverless? Talorys usa Cloudflare Workers, Durable Objects y SQLite, todo dentro del plan gratuito.

Ilustración de una pequeña casa atada a un cubo brillante en una cuadrícula infinita de bloques tipo servidor.
Un agente, un objeto, una cuenta: toda la aplicación vive dentro de un único Durable Object en la cuadrícula de otro.

Aquí va mi opinión contraria, y la voy a defender: un agente de IA personal encaja mejor en una infraestructura serverless que en la Raspberry Pi que tienes debajo de la mesa. El proyecto Talorys, un asistente personal de código abierto que se despliega en tu propia cuenta de Cloudflare con un solo npx create-talorys@latest, es la mejor prueba hasta ahora de que el problema de tener un agente de IA con estado sobre serverless sin estado no solo tiene solución, sino que encaja de forma natural. Y la gente de Hacker News que discute si eso cuenta como «self-hosted» está teniendo la discusión equivocada por completo.

Llevo años operando infraestructura y limpiando sus desastres. Lo que mata al software personal autoalojado no es el despliegue, sino el mes tres: el disco se llena de logs, el certificado TLS caduca y no recuerdas qué unidad de systemd se encarga de la programación. Talorys evita toda esa familia de fallos porque no tiene ningún servidor. Todo lo que necesita (chat, memoria, tareas y recordatorios programados) funciona en el plan gratuito de Cloudflare: Pages para el frontend, un Worker privado para la API, un Durable Object respaldado por SQLite para todo el estado y Workers AI para el modelo. Coste mensual total para un solo usuario: cero.

El problema real: los agentes tienen estado, y serverless no

Un agente de IA es un conjunto de estado de larga duración que se hace pasar por una aplicación de petición y respuesta. Necesita historial de conversación, memorias duraderas, una lista de tareas, trabajos programados que se ejecutan a las 7 de la mañana aunque nadie haya iniciado sesión y un lugar donde guardar las salidas de las herramientas mientras corre una cadena de varios pasos. Todo eso es hostil al modelo serverless clásico, donde tu función es un pez dorado: se despierta, atiende una petición y se olvida de todo.

La respuesta habitual de la industria es reconstruir el estado en los extremos: Redis para los datos de sesión, Postgres para los registros duraderos, una cola más un planificador para los cron y una base de datos vectorial para la recuperación semántica. Funciona, pero acabas de reconstruir una granja de servidores con servicios gestionados, con la factura y la superficie operativa que eso conlleva. He visto equipos dedicar más tiempo de ingeniería a conectar cinco servicios con estado para un agente que a escribir la lógica del propio agente. Como ya he defendido antes, los agentes basados en LLM son simplemente sistemas distribuidos, y los sistemas distribuidos son el lugar donde las buenas intenciones van a morir.

Talorys apuesta por lo contrario: poner todo el estado en un único lugar. Un solo Durable Object, llamado personal-agent, contiene el mundo entero (conversaciones, memorias, tareas, notas, proyectos, automatizaciones, sesiones, ajustes y seguimiento de uso) en su base de datos SQLite embebida. Nada de KV, D1, R2 ni Vectorize. El README deja claro que ninguno de esos servicios se aprovisiona. No es casualidad; es la arquitectura.

Los Durable Objects son el truco definitivo

Los Durable Objects son hoy la primitiva más silenciosamente revolucionaria de la computación en la nube, y no creo que sea exageración. Un Durable Object es una pieza de código de instancia única con almacenamiento transaccional y consistencia fuerte, físicamente colocado junto a ella. Cuando llega una petición dirigida al objeto personal-agent, Cloudflare despierta ese objeto en milisegundos, desde frío, ejecuta tu código contra su SQLite local y lo congela de nuevo cuando queda inactivo. Obtienes la ergonomía de un proceso de servidor de larga duración con el modelo de facturación de una Lambda.

Para un agente personal de un solo usuario, las conocidas limitaciones de este modelo se convierten en virtudes:

  • Un solo escritor es una ventaja. Un usuario implica un único escritor. Todo el horror de concurrencia del estado multiinquilino desaparece, y obtienes acceso serializado y transaccional a todo sin coste adicional.
  • La colocalización elimina la latencia. Las consultas de memoria del agente, las búsquedas de tareas y el historial de conversación son lecturas de SQLite en disco local, no viajes de ida y vuelta por red a una base de datos en otra zona de disponibilidad.
  • Las alarmas sustituyen al cron. Las alarmas de Durable Objects permiten que el objeto programe sus propios despertares. Los recordatorios, las rutinas recurrentes y los resúmenes diarios se disparan sin que ninguna máquina permanezca encendida: el objeto duerme, la alarma lo despierta, hace su trabajo y vuelve a dormir.
  • La hibernación es gratis. El tiempo de inactividad no cuesta nada. Un asistente personal que está inactivo 23 horas al día es exactamente la carga de trabajo para la que se inventó el precio serverless.

Esta es la idea que me gustaría que más gente se llevara de este proyecto. Si tu aplicación es naturalmente de un solo inquilino (una herramienta personal, un espacio de trabajo por cliente, un coordinador por dispositivo), el patrón de «un Durable Object por inquilino» te da algo que antes requería un VPS: un pequeño ordenador que conceptualmente siempre está en ejecución, no cuesta nada cuando está inactivo y nunca necesita un administrador de sistemas. Solo la historia de la programación ya vale lo que cuesta entrar. Quien haya mantenido una caja personal con cron conoce el modo de fallo: la caja se reinicia, el demonio de cron no vuelve a arrancar y dos semanas después descubres que tus recordatorios dejaron de funcionar sin avisar. Las alarmas son una programación gestionada por la propia infraestructura, y eso es una cosa menos que vigilar.

El modelo de red es mejor que la mayoría de configuraciones de producción

Esta es la parte que me hizo prestar atención, viniendo de un entorno de seguridad. El Worker del agente en Talorys se despliega con workers_dev: false y preview_urls: false. No tiene ninguna URL pública. El navegador solo habla con un sitio *.pages.dev; una Pages Function en /api/* reenvía las peticiones al Worker a través de un service binding, es decir, el cableado interno y privado de Cloudflare entre cómputos de la misma cuenta. La autenticación y la autorización ocurren en el Worker, no en el frontend.

Piensa en lo que esto elimina. No hay endpoint de API público que escanear. No hay reglas de firewall que configurar mal. No hay proxy inverso que olvidar parchear. La superficie de ataque del backend del agente es, en la práctica, «tienes que pasar por el flujo de autenticación del frontend». He revisado despliegues de producción en empresas reales, con presupuesto y equipos de seguridad, que tenían una postura de red más laxa que este proyecto personal. El patrón de incidente más común que vi en entornos cloud era un servicio interno «solo accesible desde dentro» que un día dejó de serlo, porque alguien se equivocó al configurar un balanceador de carga. No puedes equivocarte con un service binding hasta hacerlo público: la URL simplemente no existe.

El instalador también merece mención. Calcula el hash de la contraseña del propietario localmente con PBKDF2-SHA256 y guarda solo el hash como secreto de Cloudflare, genera un secreto de sesión de 256 bits, asigna nombres únicos a los recursos y después verifica el despliegue en vivo, incluyendo que las peticiones no autenticadas se rechacen de verdad, sin gastar cuota de inferencia de IA. Una comprobación posterior al despliegue que confirma que la autenticación deniega a los no autenticados es el tipo de cosa que yo he escrito en postmortems de incidentes. Verla en un instalador de un solo comando es una agradable sorpresa.

Fortaleza con una única puerta vigilada y una habitación interior sellada, accesible solo mediante un puente interno.
Una puerta pública, cero backend público: los service bindings hacen que el Worker del agente no tenga ninguna URL que atacar.

Vivir dentro del plan gratuito sin engañarte

El plan gratuito es real, pero es un presupuesto, no un bufet libre. Cloudflare ofrece a las cuentas gratuitas una asignación diaria de Workers AI medida en «Neurons», 10.000 al día, además de cuotas de peticiones y de uso de Durable Objects. Esas cifras las fija Cloudflare y pueden cambiar. Talorys gestiona esto de forma más honesta que la mayoría de proyectos de «plan gratuito» que he visto: cuando se agota la asignación de IA, el chat lo dice claramente y se reanuda tras el reinicio diario, mientras que las tareas, notas, memorias y recordatorios siguen funcionando porque ninguno necesita el modelo.

Las protecciones merecen que las copies en tus propios proyectos. Talorys incluye límites configurables de tokens de salida máximos, tokens de contexto máximos (el historial antiguo se resume en lugar de truncarse en silencio), llamadas a herramientas y pasos de razonamiento máximos por petición, peticiones de IA máximas al día y ejecuciones programadas de IA máximas al día. Es una postura madura. Los bucles de agente sin límite son la forma de despertar con una factura o con un corte por cuota, y «el agente decidió llamar a la herramienta 40 veces» es un modo de fallo que he visto quemar dinero real en producción. Relacionado con esto: la decisión del proyecto de que los recordatorios y resúmenes simples nunca usen IA es exactamente correcta. Si una ruta de código es determinista, no la hagas pasar por un modelo probabilístico. Es la misma disciplina que hay detrás de restringir la salida del modelo a decisiones estructuradas: usa el modelo solo donde realmente hace falta juicio.

Una advertencia de la comunidad: varias personas reportan sorpresas opacas en la facturación al combinar Workers AI con planes de pago de Workers, con una contabilidad de Neurons que no coincide con los límites documentados y tickets de soporte sin respuesta. No puedo verificar los detalles, pero encaja con un patrón que conozco bien: la facturación medida de la IA es confusa en todas partes, y «amigable con el plan gratuito» no es lo mismo que «imposible de facturar». Si despliegas esto en un plan de pago, configura una alerta de gasto en el panel de Cloudflare desde el primer día. Considera la interfaz de uso del proveedor como la fuente de verdad, no las estimaciones locales de la aplicación.

La pelea sobre «self-hosted» no entiende el punto

Ahora, la concesión que exige mi afirmación inicial. Los comentarios principales de este proyecto son una guerra de llamas sobre la palabra «self-hosted», y los puristas tienen un argumento real: esto depende por completo de Cloudflare. Tus datos viven en sus centros de datos, tu inferencia corre en sus GPU y, si mañana cambian el plan gratuito, tu asistente cambia con él. Llamar a eso autoalojamiento estira la palabra hasta romperla. La lectura caritativa (ningún tercero más allá de una cuenta de Cloudflare que ya controlas, ninguna telemetría hacia los desarrolladores, ningún operador intermedio) se describe mejor como «autopropiedad» o «autocustodia». Las palabras importan, y el proyecto recibiría menos críticas con mejores términos.

Pero aquí es donde los puristas me pierden. El modelo de amenazas real del software personal no es «los términos de servicio de una corporación podrían cambiar». Es la exfiltración de datos, la telemetría y que el desarrollador quiebre y cierre la versión alojada. En los tres puntos, Talorys es realmente sólido: no hay código de analítica ni de seguimiento, nada llama a casa a los autores y no hay una versión alojada que pueda cerrarse. Además, el código tiene licencia MIT y, como señaló un comentarista, apuntar las llamadas de IA a un servidor de modelo local es un parche pequeño; toda la pila incluso se ejecuta en local con wrangler dev y un proveedor de IA simulado. Si Cloudflare llegara a ser inaceptable, la salida es corta. Compáralo con la típica app «self-hosted» que en realidad es un archivo de Docker Compose que descarga imágenes del registro de alguien y que consulta a casa para validar licencias.

También hay una crítica más justa escondida en el hilo: no hay evidencia de que el asistente sea realmente bueno. Una interfaz de chat, un CRUD de memoria, embeddings y cron son triviales de construir por separado; el arnés, los prompts, la política de recuperación de memoria y los esquemas de herramientas son donde viven o mueren los asistentes personales, y nada de eso se demuestra con un diagrama de arquitectura limpio. Esto es cierto en casi todos los proyectos de este género, y es precisamente lo que conviene cuestionar. Juzga a Talorys como infraestructura, un chasis bien diseñado, y no como un copiloto probado. Si estás evaluando modelos para algo así, nuestro artículo sobre ejecutar LLM en tu propio hardware cubre el otro extremo del espectro de soberanía.

Balanza de latón que pesa un candado frente a una pequeña nube.
Control y comodidad están en platillos opuestos: el compromiso honesto es entre dependencia de proveedor y carga operativa.

Qué deberías copiar de este diseño

Aunque nunca despliegues Talorys, la arquitectura es una referencia que merece la pena interiorizar. Las ideas transferibles son:

  1. Un objeto por inquilino. Si tu app es de un solo usuario o se puede particionar limpiamente, coloca código y estado juntos en un Durable Object y elimina tu capa de caché, tu cola de mensajes y tu pool de conexiones.
  2. Sin URL pública para el backend. Los service bindings con workers_dev: false son la mejora de seguridad más barata del serverless. Un servicio al que no se puede llegar no se puede atacar.
  3. Alarmas en lugar de cajas con cron. La programación que vive con la infraestructura sobrevive a reinicios, redespliegues y a tus propios olvidos.
  4. Degradación consciente de la cuota. Diseña la app para que la dependencia costosa (el modelo) pueda fallar o agotarse mientras el producto principal sigue funcionando. La degradación debe ser una función, no una caída.
  5. Migraciones solo de adición. El namespace del Durable Object nunca se recrea en una actualización; las migraciones de esquema se ejecutan de forma transaccional en la primera petición. Así actualizas el serverless con estado sin jugar a la ruleta de la pérdida de datos.

La lección más amplia trata de hacia dónde va el software personal. Durante veinte años la elección era binaria: confiar tus datos a una empresa SaaS o convertirte en administrador de sistemas a tiempo parcial. Los Durable Objects, y las primitivas similares que otras nubes inevitablemente lanzarán, abren un tercer camino: software que solo tú controlas, operado por infraestructura que alquilas, con coste cero a escala personal. No es autoalojamiento. Puede que sea mejor.