Cómo Construí un Agente que Publica 20 Piezas de Contenido al Día (Sin Tocarlas)

Proyectos· 7 min de lectura

Cómo Construí un Agente que Publica 20 Piezas de Contenido al Día (Sin Tocarlas)

Hace unas semanas me hice una pregunta incómoda:

*¿Cuánto de mi tiempo como desarrollador-emprendedor lo estoy gastando en tareas que un agente podría hacer mejor que yo?*

La respuesta, en el caso de conversoriaecnae.es, era: mucho.

La herramienta tiene más de 2.000 códigos CNAE e IAE que necesitan contenido. Artículos educativos, guías, newsletters, posts en redes. Si lo hacía manual, tardaría años. Así que construí un sistema para hacerlo autónomamente.

Esto es lo que aprendí en el proceso.

---

El Problema Real: No Es Generar Contenido, Es Controlarlo

Cualquiera puede poner a Claude a escribir artículos en bucle. El problema es que sin control, terminas con contenido mediocre, títulos que se truncan en Google, artículos que contradicen lo que publicaste ayer, o posts que hablan de "este año 2024" cuando estamos en 2026.

El reto no es la generación. Es la fiabilidad en producción.

Por eso el sistema que construí no es "un agente que escribe". Es una orquestación de 6 agentes especializados coordinados por cron jobs de Vercel, cada uno con una responsabilidad clara y delimitada.

---

La Arquitectura: 6 Agentes, 5 Pipelines Diarias

El sistema corre 5 veces al día. Esto es lo que pasa en cada ejecución:

1. Agente Filtro — Monitoriza Google Alerts via Gmail, puntúa cada fuente de 0 a 100 según relevancia CNAE/IAE, y encola las mejores. Usa Claude Haiku 4.5 (no Sonnet) porque procesa en lotes de 10 y el volumen es alto. Haiku es más que suficiente para scoring estructurado.

2. Agente Planificador — Selecciona 4 temas óptimos del día: 2 códigos educativos y 2 artículos de actualidad. Lo hace basándose en opportunity scores de keywords, el calendario editorial, y los gaps de cobertura. La lógica es sencilla: primero los códigos con más volumen de búsqueda que aún no tienen contenido.

3. Agente Educativo — Genera guías completas de 800-1200 palabras para cada código CNAE o IAE. Aquí viene la parte interesante.

4. Agente Publisher — Convierte el markdown a Portable Text de Sanity. No HTML, no texto plano. Formato nativo de Sanity con bloques, FAQs extraídas, links internos a códigos relacionados, y gestión de assets de imagen via Unsplash.

5. Agente Newsletter — Genera resúmenes semanales con A/B testing de subject lines incluido.

6. Agente de Estadísticas — Pipeline semanal con charts via QuickChart.io, infografías con Puppeteer, y distribución en 6 plataformas: LinkedIn, Twitter/X, Facebook, Threads, Instagram, Reddit.

---

La Decisión Que Lo Cambió Todo: Auto-Publicación con Quality Score

Esta fue la decisión más importante del proyecto y la que más me costó tomar.

El agente educativo puntúa cada artículo en un checklist de 8 puntos antes de publicarlo. Si el score es ≥80, se publica solo. Sin revisión manual.

¿Por qué funciona esto? Porque el scoring es determinista, no subjetivo. El checklist evalúa cosas concretas y verificables:

  • Título entre 40-70 caracteres (truncación en SERP)
  • Meta description entre 50-60 palabras
  • Description entre 140-160 caracteres
  • Presencia de sección FAQ
  • Links internos a códigos relacionados
  • Imagen de portada con atribución correcta
  • Sin referencias temporales desactualizadas
  • Estructura de cabeceras correcta

Nada de "¿es buen contenido?". Métricas objetivas.

El resultado: la mayoría de artículos pasan el umbral en el primer intento. Los que no, quedan en cola para revisión manual. En la práctica, casi nunca tengo que revisar nada.

---

El Problema Técnico Que Casi Me Rompe: Vercel y los 300 Segundos

Vercel tiene un límite de 300 segundos en funciones serverless. Con 4 temas por pipeline y cada uno con múltiples pasos (generar, puntuar, convertir a Portable Text, publicar en Sanity, distribuir en redes), el procesamiento secuencial era imposible.

La solución: batch processing paralelo con 2 lotes concurrentes de 10 items.

El commit que lo arregló es [f82f3b2](https://github.com/brianMena/conversor-iae-cnae-v3), del 15 de febrero de 2026. Tardé más de lo que me gustaría en llegar a esa solución, pero después del fix el pipeline completa en tiempo.

La clave fue procesar los 4 temas en paralelo en lugar de secuencialmente, con correlation IDs únicos por topic para el audit log. Si un tema falla, no bloquea el resto.

```typescript // Antes: secuencial, timeout garantizado for (const topic of topics) { await processTopic(topic); }

// Después: paralelo, dentro del límite de Vercel await Promise.all( topics.map(topic => processTopic(topic).then(result => logAudit(topic.correlation_id, result) ) ) ); ```

---

El Ahorro Real: Prompt Caching

Sin entrar en cifras concretas, el sistema corre 5 veces al día con 6 agentes. El coste de tokens sin optimización sería prohibitivo.

La solución: prompt caching en todos los agentes con system prompts de 4096+ tokens.

El sistema prompt del agente educativo es largo: incluye el contexto completo de taxonomía CNAE/IAE, reglas de formato, directrices de SEO, ejemplos de artículos bien puntuados, y el calendario fiscal español para contextualizar el contenido. Cachear ese bloque ahorra aproximadamente un 80% de tokens de entrada en cada llamada repetida.

Para un sistema que hace cientos de llamadas diarias, eso es la diferencia entre rentable y no.

---

La Parte Que Nadie Implementa: Contexto Temporal

Este fue el último commit importante antes de publicar este artículo ([496b64e](https://github.com/brianMena/conversor-iae-cnae-v3), 16 de febrero de 2026): inyección dinámica de contexto temporal en todos los agentes.

El problema: los LLMs tienden a escribir como si el tiempo estuviera congelado. Sin contexto explícito, un agente puede mencionar fechas del año pasado, ignorar el trimestre fiscal actual, o escribir sobre el "próximo" modelo 303 cuando ya se presentó.

La solución es simple pero crítica: cada llamada a cada agente incluye un bloque de contexto temporal construido dinámicamente:

```typescript function buildTemporalContext(): string { const now = new Date(); const quarter = Math.ceil((now.getMonth() + 1) / 3);

return ` CONTEXTO TEMPORAL (usa esta información, no tus datos de entrenamiento): - Fecha actual: ${now.toISOString().split('T')[0]} - Año fiscal: 2026 - Trimestre: Q${quarter} - Temporada: ${getSeason(now)} - Próximas fechas fiscales relevantes: ${getUpcomingFiscalDates()} `; } ```

Desde ese commit, cero referencias desactualizadas en producción.

---

Qué Construir Si Quieres Replicar Esto

Lo que tengo ahora no lo construí de una vez. Lo fui añadiendo en capas:

Primera capa — filtrado + planificación: Define qué publicar antes de pensar en cómo generarlo. Un planner que elige mal temas hace que todo lo demás sea ruido.

Segunda capa — generación + calidad: Implementa el quality scoring desde el primer día. No como feature extra, como gate de publicación. Esto es lo que separa un sistema de juguete de uno en producción.

Tercera capa — distribución: Agentes específicos por plataforma, no un agente genérico que adapta. LinkedIn y Twitter tienen dinámicas tan distintas que un solo agente siempre va a ser mediocre en alguno de los dos.

Cuarta capa — contexto temporal: Inyéctalo en cada llamada. No lo asumas. Los modelos no saben qué día es.

---

El Resultado Actual

El agente publica de forma autónoma artículos educativos sobre códigos CNAE e IAE, distribuye en 6 plataformas, genera newsletters semanales con A/B testing de subject lines, y produce informes estadísticos con infografías.

Yo sigo en el loop para decisiones estratégicas y revisiones de los artículos que no superan el umbral. Pero el flujo diario de contenido ya no depende de mi tiempo.

Eso es lo que significa construir apalancamiento real con código.

---

¿Estás construyendo algo similar? Cuéntame qué parte del stack te está dando más problemas.

Brian Mena

Brian Mena

Ingeniero informatico construyendo productos digitales rentables: SaaS, directorios y agentes de IA. Todo desde cero, todo en produccion.

LinkedIn