El Stack de Agentes que Uso para Correr 30+ Agentes en Producción (Sin Python)
Ejecuto más de 30 agentes de IA en producción usando TypeScript, Cloudflare Workers/Queues/KV y modelos Claude — sin Python, sin framework de agentes. El stack es deliberadamente aburrido: Workers manejan scheduling y colas, KV almacena el estado, y el Anthropic SDK maneja las llamadas al modelo directamente. La restricción que importa no es la capa de IA — es la infraestructura alrededor.
Cada miércoles. 28.400+ operadores. Sin relleno.
✓ Check your inbox — click the confirmation link to complete sign-up.
✓ You're subscribed!
✓ You're already on the list.
Tabla de contenidos
Actualizado mayo 2026.
TL;DR: Ejecuto más de 30 agentes de IA en producción usando TypeScript, Cloudflare Workers/Queues/KV y modelos Claude — sin Python, sin framework de agentes. El stack es deliberadamente aburrido: Workers manejan scheduling y colas, KV almacena el estado, y el Anthropic SDK maneja las llamadas al modelo directamente. La restricción que importa no es la capa de IA — es la infraestructura alrededor.
[Perspectiva del operador] Dirijo dos negocios: una marca de consultoría en IA y Pickleland — una instalación de pickleball en Pflugerville, TX. Entre los dos tengo más de 30 agentes corriendo en producción hoy. Este es el stack real, no una demo.
Por qué sin Python
La respuesta honesta: escribo TypeScript todos los días para mi trabajo en el sitio web y productos. Agregar un segundo lenguaje para agentes significa dos runtimes, dos árboles de dependencias, dos pipelines de deploy. El costo de productividad no es teórico — lo pagué en proyectos anteriores y decidí no volver a hacerlo.
La segunda razón es Cloudflare. Workers corre TypeScript de forma nativa en el edge, con Queues, KV, Durable Objects y Cron Triggers incorporados. Toda la infraestructura de agentes que necesito — scheduling, estado, procesamiento asíncrono de trabajos — está a un wrangler deploy de distancia. No existe un equivalente en Python con la misma superficie operativa.
La tercera razón es que la mayoría de los argumentos de “Python-es-mejor-para-IA” son realmente “Python tiene más librerías de ML.” Yo no entreno modelos. Llamo APIs. El Anthropic SDK es TypeScript de primera clase. LangChain y sus similares son complejidad que no quiero. Cuando estás desplegando agentes, no investigándolos, la simplicidad gana.
La infraestructura central: tres primitivos de Cloudflare
Cada agente que ejecuto toca al menos uno de estos tres:
Cloudflare Workers — la capa de cómputo. Un Worker es el runtime del agente: recibe un trigger (cron, mensaje de Queue, HTTP), ejecuta las llamadas al modelo y escribe outputs en algún lugar. Cold start bajo 5ms. Límite de ejecución 30 segundos de tiempo CPU en el plan gratuito, 15 minutos en el de pago. Casi todo lo que construyo cabe en 30 segundos; lo que no cabe usa Queues para hacer fan-out.
Cloudflare Queues — procesamiento asíncrono de trabajos. Cuando una tarea podría tardar más que una solicitud, o cuando necesito hacer fan-out (generar 12 traducciones en paralelo), empujo mensajes a una Queue y dejo que los consumers vinculados los procesen independientemente. Sin polling, sin hacks de setTimeout.
Cloudflare KV — estado ligero. Historial de ejecuciones de agentes, últimos timestamps procesados, respuestas de API en caché. KV es eventualmente consistente, lo cual está bien para agentes — no estoy ejecutando transacciones. Me da un store clave-valor simple que puedo leer/escribir desde cualquier Worker sin levantar una base de datos.
La capa del modelo: Anthropic SDK, dos modelos
Uso exactamente dos modelos Claude:
claude-sonnet-4-6— para tareas que necesitan razonamiento real: escribir posts de blog, analizar datos de eventos, generar copy social, planificar secuenciasclaude-haiku-4-5— para clasificación rápida/barata, decisiones de routing, extracciones cortas donde el razonamiento completo es excesivo
El Anthropic SDK en TypeScript es directo. Aquí está el patrón que uso para cada llamada al modelo:
import Anthropic from "@anthropic-ai/sdk";
const client = new Anthropic({ apiKey: env.ANTHROPIC_API_KEY });
async function runAgent(prompt: string, systemPrompt: string): Promise<string> {
const message = await client.messages.create({
model: "claude-sonnet-4-6",
max_tokens: 2048,
system: systemPrompt,
messages: [{ role: "user", content: prompt }],
});
const block = message.content[0];
if (block.type !== "text") throw new Error("Unexpected content type");
return block.text;
}Esa es toda la interfaz del modelo. Sin abstracciones encima. Cuando necesito tool use, agrego un array tools. Cuando necesito streaming, cambio messages.create por messages.stream. Ningún framework gestiona esto por mí — y no quiero que lo haga.
Un agente real: el pipeline de contenido
El agente más complejo que ejecuto es el pipeline de contenido. Genera posts de blog, los traduce a 12 idiomas, renderiza SVGs de tarjetas OG y redacta promos de LinkedIn — todo como borradores, bloqueados detrás de mi revisión antes de que se publique nada.
El entry point del Worker se ve así:
// src/workers/content-pipeline.ts
export default {
async fetch(request: Request, env: Env): Promise<Response> {
const { topic, slug } = await request.json<{ topic: string; slug: string }>();
// Paso 1: generar post EN
const enPost = await generatePost(topic, env);
await env.CONTENT_KV.put(`draft:${slug}:en`, enPost);
// Paso 2: fan-out de traducciones via Queue
const locales = ["ar", "de", "es", "fr", "hi", "it", "ja", "ko", "nl", "pt", "ru", "zh"];
for (const locale of locales) {
await env.TRANSLATION_QUEUE.send({ slug, locale, content: enPost });
}
return Response.json({ status: "queued", slug });
},
};Cada traducción corre en su propia invocación de Worker. Si una falla, la Queue la reintenta automáticamente. Obtengo 12 traducciones en paralelo sin gestionar threads, promises o rate-limit backoff yo mismo.
Un agente real: el promotor de eventos
Pickleland organiza eventos de pickleball. Construí un agente que escanea la plataforma de reservas para eventos en los próximos 4 días, redacta posts para grupos de Facebook por evento y los presenta para mi revisión antes de que salga nada.
El system prompt:
const systemPrompt = `You are a community manager for a pickleball facility.
Write Facebook group posts for upcoming events.
Rules:
- Max 150 words per post
- Lead with what's fun about the event, not the price
- Include the booking URL exactly as provided
- Do not use exclamation marks more than once per post
- Tone: friendly, local, not corporate`;La restricción que importa aquí no es el modelo — es el flujo de trabajo. El agente corre con un trigger cron a las 8am diariamente. Los posts borrador caen en una cola de revisión. Yo apruebo o edito, luego un Worker de publicación separado se dispara. Ningún evento se publica sin que un humano lo haya visto primero.
Cómo gestiono 30+ agentes sin perder la cabeza
El panel de Cloudflare es mi plano de control. Cada Worker me muestra conteo de invocaciones, tasa de errores y tiempo de CPU. Cada Queue muestra throughput de mensajes y fallos. KV muestra uso de almacenamiento.
Más allá de eso:
- Cada agente registra un objeto JSON estructurado al final de cada ejecución:
{ agent, status, durationMs, inputTokens, outputTokens, costUsd } - Rastro el gasto acumulado por agente por mes en una base de Airtable simple
- Los agentes que superan un umbral de costo se marcan para revisión — normalmente significa que un prompt es demasiado verboso o estoy usando Sonnet donde Haiku alcanzaría
La disciplina no es técnica. Es decidir qué puede hacer un agente de forma autónoma versus qué necesita mi aprobación. Borradores de contenido: autónomo. Cualquier cosa que toque a un cliente: revisión humana. Cualquier cosa que mueva dinero: no es trabajo de un agente.
Qué cambiaría si empezara hoy
Una cosa: habría configurado outputs estructurados (modo JSON) desde el primer día en lugar de añadirlos retroactivamente a agentes ya desplegados. Parsear texto libre de Claude es un impuesto. Cuando defines un esquema Zod y lo pasas como la forma de respuesta esperada, obtienes datos tipados de vuelta y tus Workers downstream no tienen que adivinar.
import { z } from "zod";
const EventPostSchema = z.object({
headline: z.string().max(80),
body: z.string().max(600),
bookingUrl: z.string().url(),
suggestedPostTime: z.enum(["morning", "afternoon", "evening"]),
});La conclusión del operador
El stack de agentes que funciona en producción es el que puedes debuggear a las 10pm cuando algo se rompe. Para mí, eso es TypeScript + Cloudflare + Anthropic SDK — no porque sea la combinación más glamorosa, sino porque cada capa es observable, desplegable y reemplazable independientemente. Los frameworks son apuestas en abstracciones. Prefiero ser dueño de la fontanería.
Cada miércoles. 28.400+ operadores. Sin relleno.
✓ Check your inbox — click the confirmation link to complete sign-up.
✓ You're subscribed!
✓ You're already on the list.
Recibe el manual de IA en tu buzón
Cada miércoles. 28.400+ operadores. Sin relleno.
Check your inbox.
We sent you a confirmation email — click the link inside to complete your subscription. Check spam if you don't see it within a minute.
You're subscribed.
Welcome — the next edition lands in your inbox soon.
You're already on the list — look for it every Wednesday.