Desplegar agentes de IA con Cloudflare Workers: guía paso a paso
TL;DR
- Cloudflare tiene un Agents SDK nativo que corre sobre Workers + Durable Objects.
- Cada agente tiene su propia base de datos SQLite, WebSockets en tiempo real y scheduling.
- El plan gratuito incluye 100K requests/día; el de pago sale desde $5/mes con 10M requests.
- En 30 minutos tienes un agente con memoria persistente desplegado globalmente.
El problema
Tienes un agente de IA que funciona en local. Lo has probado con un script de Python, quizás con LangChain o con el SDK de OpenAI. Pero ahora necesitas que:
- Esté accesible vía HTTP/WebSocket desde cualquier sitio.
- Mantenga estado entre sesiones (memoria, contexto).
- Escale sin que tengas que gestionar servidores.
- Cueste lo razonable — no $200/mes por un agente que recibe 50 consultas al día.
Las opciones típicas son: montar un servidor (coste fijo + mantenimiento), usar una plataforma serverless genérica (Lambda, Cloud Functions — pero sin estado persistente), o usar un servicio managed de agentes (caro y opinionado).
Cloudflare Workers con el Agents SDK ofrece un punto medio interesante: serverless, stateful por diseño, y con un free tier generoso.
Qué es el Cloudflare Agents SDK
El Agents SDK es un framework de TypeScript que corre sobre Durable Objects — la primitiva de Cloudflare para objetos con estado persistente distribuido globalmente.
Cada agente que despliegues obtiene:
| Capacidad | Qué significa |
|---|---|
| Base de datos SQLite | Cada agente tiene su propia DB. Sobrevive reinicios y deploys. |
| WebSockets | Comunicación bidireccional en tiempo real. |
| Scheduling | Cron jobs, delays, tareas programadas sin infra extra. |
| Hibernación | El agente “duerme” cuando no hay actividad, se despierta bajo demanda. |
| Modelo agnóstico | Workers AI (sin API key), OpenAI, Anthropic, Google… |
No es un wrapper de LangChain. Es infraestructura de agentes como servicio — tú traes la lógica, Cloudflare trae el runtime.
Qué necesitas antes de empezar
- Node.js 24+ instalado.
- Una cuenta de Cloudflare (gratuita).
wranglerCLI (se instala con el template).- 30 minutos.
Paso 1: Scaffolding
Crea el proyecto desde el template oficial:
npm create cloudflare@latest -- --template cloudflare/agents-starter
cd agents-starter
npm install
Esto genera un proyecto con:
src/agent.ts— tu agente (extiendeAIChatAgent).src/tools.ts— herramientas del agente.src/client/— frontend React con hooks para conectar al agente.wrangler.jsonc— configuración de Cloudflare Workers.
Arranca el dev server:
npm run dev
Si todo va bien, verás un chat funcionando en http://localhost:5173 usando Workers AI por defecto — sin API key.
Paso 2: Entender la estructura del agente
El archivo principal src/agent.ts tiene esta pinta:
import { AIChatAgent } from "@cloudflare/ai-chat";
import { createWorkersAI } from "workers-ai-provider";
import { streamText } from "ai";
export class MyAgent extends AIChatAgent<Env> {
async onChatMessage() {
const model = createWorkersAI({ binding: this.env.AI });
const result = streamText({
model: model("@cf/zai-org/glm-4.7-flash"),
messages: await this.messages,
tools: this.tools,
});
return result.toUIMessageStreamResponse();
}
}
Cosas a notar:
AIChatAgentya gestiona persistencia de mensajes, streaming y reconexión.this.env.AIes el binding a Workers AI — no necesitas API key.this.toolsson las herramientas que defines ensrc/tools.ts.this.messagesse persiste automáticamente en la SQLite del agente.
Paso 3: Añadir herramientas
Las herramientas son funciones que el agente puede ejecutar. Van en src/tools.ts:
import { tool } from "ai";
import { z } from "zod";
export const tools = {
getWeather: tool({
description: "Obtiene el tiempo actual para una ciudad",
parameters: z.object({
city: z.string().describe("Nombre de la ciudad"),
}),
execute: async ({ city }) => {
const res = await fetch(
`https://api.open-meteo.com/v1/forecast?latitude=40.42&longitude=-3.70¤t_weather=true`
);
const data = await res.json();
return { city, temperature: data.current_weather.temperature };
},
}),
};
Las herramientas usan el estándar de Vercel AI SDK (tool() + Zod schemas). El modelo decide cuándo llamarlas basándose en la descripción.
Paso 4: Memoria persistente con estado
Más allá del chat, puedes tener estado personalizado:
import { Agent, callable } from "agents";
interface MyState {
tareas: string[];
ultimaActividad: string;
}
export class TaskAgent extends Agent<Env, MyState> {
initialState = { tareas: [], ultimaActividad: "" };
@callable()
addTarea(tarea: string) {
this.setState({
tareas: [...this.state.tareas, tarea],
ultimaActividad: new Date().toISOString(),
});
return this.state;
}
@callable()
getTareas() {
return this.state.tareas;
}
}
El decorador @callable() expone métodos como RPC sobre WebSocket. El cliente React puede llamarlos directamente:
const agent = useAgent({ agent: "TaskAgent" });
agent.stub.addTarea("Revisar PR #42");
El estado se guarda en la SQLite del Durable Object — sobrevive reinicios, deploys y caídas.
Paso 5: Configurar wrangler
El archivo wrangler.jsonc define cómo se despliega tu agente:
{
"name": "mi-agente",
"main": "src/agent.ts",
"compatibility_date": "2026-01-28",
"compatibility_flags": ["nodejs_compat"],
"durable_objects": {
"bindings": [
{ "name": "MyAgent", "class_name": "MyAgent" }
]
},
"migrations": [
{ "tag": "v1", "new_sqlite_classes": ["MyAgent"] }
]
}
Las migraciones solo se ejecutan una vez — Cloudflare las trackea. Si añades nuevos agentes, añades nuevas migraciones con tags incrementales (v2, v3…).
Paso 6: Desplegar a producción
npm run deploy
Esto ejecuta wrangler deploy, que sube tu código a la red de Cloudflare (300+ ubicaciones). Tu agente estará disponible en:
https://mi-agente.<tu-subdomain>.workers.dev
Si tienes un dominio en Cloudflare, puedes asignarlo directamente desde el dashboard.
Usar un modelo externo (OpenAI, Anthropic…)
El template usa Workers AI por defecto (gratuito, sin API key). Pero puedes usar cualquier provider:
import { createOpenAI } from "@ai-sdk/openai";
// En onChatMessage():
const model = createOpenAI({
apiKey: this.env.OPENAI_API_KEY, // definido como secret en wrangler
});
const result = streamText({
model: model("gpt-5.4"),
messages: await this.messages,
});
Para añadir el secret:
wrangler secret put OPENAI_API_KEY
Lo mismo funciona con @ai-sdk/anthropic, @ai-sdk/google, etc.
Costes: qué pagarás
El plan gratuito de Workers incluye:
- 100.000 requests/día — suficiente para pruebas y proyectos pequeños.
- 10ms de CPU por invocación.
- 5 GB de almacenamiento D1.
El plan de pago ($5/mes) incluye:
| Recurso | Incluido | Coste extra |
|---|---|---|
| Requests | 10M/mes | $0.30/M adicional |
| CPU time | 30M ms/mes | $0.02/M ms adicional |
| Durable Objects | 1M requests/mes | $0.15/M adicional |
| Almacenamiento SQLite | 5 GB | $0.20/GB-mes |
Para un agente de uso moderado (1.000-10.000 interacciones/día), el coste real está en el rango de $5-15/mes. Mucho menos que un VPS dedicado o un servicio managed de agentes.
Workers AI tiene su propio pricing por token, pero los modelos pequeños (como GLM-4.7 Flash) son prácticamente gratuitos en el free tier.
Qué hacer y qué no hacer
Hacer:
- Usar Workers AI para prototipos rápidos — sin API key, sin configuración.
- Persistir estado en la SQLite integrada en vez de depender de servicios externos.
- Aprovechar la hibernación: los agentes inactivos no consumen CPU.
- Usar
@callable()para lógica que no necesita pasar por el LLM (lecturas de estado, operaciones deterministas).
No hacer:
- Esperar latencias de 10ms para llamadas a modelos frontier. La latencia es la del modelo + red.
- Usar Durable Objects para datos que necesitan consultas complejas — para eso está D1.
- Desplegar sin probar localmente primero (
npm run devreplica el entorno completo). - Olvidar añadir migraciones cuando creas nuevos agentes — el deploy fallará si falta.
Limitaciones a tener en cuenta
- CPU time limitado: 10ms en free, 30s por defecto en paid (configurable hasta 5 min). Las llamadas a LLM son I/O, no CPU — no cuentan. Pero el post-procesamiento sí.
- Sin filesystem real: Usa la virtual FS de
@cloudflare/shellsi necesitas leer/escribir archivos. - Tamaño del bundle: El límite es 10MB comprimido. No metas modelos locales en el worker.
- Cold starts: Existen, pero son del orden de milisegundos (V8 isolates, no containers).
Comparación rápida
| Cloudflare Workers + Agents | VPS (Railway, Fly.io) | Lambda + DynamoDB | |
|---|---|---|---|
| Estado persistente | Nativo (SQLite) | Manual | Manual |
| WebSockets | Nativo | Manual | No nativo |
| Cold start | ~5ms | N/A (siempre on) | 100-500ms |
| Scaling | Automático | Manual / configurar | Automático |
| Coste base | $0-5/mes | $5-20/mes | $0-5/mes + DynamoDB |
| Complejidad | Baja | Media | Media-alta |
Siguientes pasos
- Añadir MCP: El Agents SDK soporta Model Context Protocol. Puedes exponer herramientas de tu agente a otros agentes.
- Scheduling: Usa
this.schedule()para tareas recurrentes sin cron externo. - Email: Conecta un Email Worker para que tu agente responda correos automáticamente.
- Multi-agente: Los agentes pueden crear sub-agentes y coordinarse.
Fuentes
- Cloudflare Agents SDK — Documentación oficial
- Cloudflare Agents — GitHub
- Workers Pricing
- Agent Starter Template