Seis publicaciones al día y el programador que aprendió a decir cuándo
Un pipeline social que publicaba un Reel al día y nada más, porque las cuotas por formato eran techos y nadie solicitaba los otros formatos.
Mi pipeline de contenido corto publica seis piezas al día en una cuenta, en cuatro formatos diferentes. Pasar de "se renderiza video" a "se llena un día" tomó más tiempo que construir el generador, y casi nada de ese trabajo fue creativo.
Cuatro formatos, no uno
La cuenta publica una tarjeta de verso en el feed, una story que es el gemelo de esa tarjeta, dos stories independientes, un carrusel y un Reel. Seis elementos, cuatro formatos, cada uno con su propia ruta de generación y su propia idea de qué significa "bueno".
El gemelo es el más complicado. Es el mismo verso y el mismo arte que la tarjeta del feed matutino, pero la API de la plataforma no reutiliza el medio del feed para una story — así que tiene que publicarse como un medio separado que por casualidad se ve idéntico. La obra de arte se reutiliza en lugar de regenerarse, así que el gemelo no consume tiempo de GPU. Esa distinción entre regenerar y reutilizar es la razón principal por la que es barato.
Las cuotas eran techos, y nada era piso
Durante semanas la cuenta publicó exactamente un Reel al día y nada más. Todas las cuotas estaban correctas. El scheduler funcionaba.
Las cuotas por formato solo fueron techos — evitaban que los formatos se robaran los espacios entre sí. Pero el único worker que producía algo era el worker de artículos, y solo hacía Reels. Nada en el sistema se encargaba de pedir una tarjeta o un carrusel. Un límite no es una solicitud, y yo había construido cinco límites y una solicitud.
La frecuencia del temporizador no es la cadencia
Tres cosas que parecen el mismo número y no lo son:
- El temporizador decide con qué frecuencia el scheduler despierta (tres veces al día).
- El plan decide cuántos de cada formato debe contener el día.
- La ventana decide a qué hora del día se publica el ítem.
El scheduler produce como máximo un ítem por formato por ejecución. Así que el temporizador limita silenciosamente el plan: pedir cuatro stories al día cuando el scheduler corre tres veces significa que la cuarta nunca sucede, y no hay error. Subir un número en un lugar requería subir un número en otro, y el modo de falla por olvido era un día con menos contenido que parecía perfectamente saludable en los logs.
Ventanas, y por qué una hora fija más jitter sigue pareciendo un robot
Cada formato declara una ventana, y la hora de publicación es un muestreo uniforme y aleatorio dentro de ella — no una hora fija con ruido añadido. Una hora fija más jitter sigue agrupándose en el mismo minuto, lo que se lee exactamente como lo que es.
Los formatos pueden declarar varias ventanas, separadas por comas, y el ítem N del día se saca de la ventana N. Esto existe porque tres stories no pueden compartir una ventana: la segunda ejecución del día encontraría la mayor parte de la ventana compartida ya en el pasado, movería la story a mañana y costaría una publicación mientras que todos los libros contables y dashboards parecían bien.
El muestreo también tiene que venir de la parte de la ventana que aún está más allá del mínimo tiempo de anticipación para agendar, no de toda la ventana con un rechazo posterior si es demasiado temprano. La versión con rechazo tiraba todo el día por un muestreo desafortunado — la corrida de las 11:45 abriendo una ventana de las 12:00 fallaba aproximadamente uno de cada ocho días. Mismo objetivo, misma ventana, confiabilidad completamente diferente.
Las ventanas son priors, no mediciones
Mañana para contenido devocional, tarde para el Reel y carrusel porque las sesiones son más largas y los Reels rankean por tiempo de visualización. Ambas son conjeturas razonables que inventé. Están etiquetadas en el runbook como conjeturas, y el plan es reemplazarlas con alcance segmentado por hora una vez que haya suficiente data recolectada para segmentar.
Escribir "esto es un prior, no una medición" junto a un número es el mecanismo de honestidad más barato que conozco. Cuesta una oración y evita que una conjetura se convierta en un hecho seis meses después.
Lo que realmente me equivoqué
El runbook de este pipeline se contradijo a sí mismo desde el día que lo escribí. Una tabla decía dos stories al día; una sección ciento cincuenta líneas antes argumentaba que una story al día era una elección deliberada; la configuración en vivo decía una. También describía el pipeline como que publicaba Reels sin supervisión, cuando la bandera que habría habilitado eso nunca se activó — así que el espacio para Reel había estado vacío todos los días que decía estar lleno.
La documentación se desvía del sistema. Eso es normal y esperado. Esto fue peor: el documento nunca fue cierto, y era internamente inconsistente de una forma que cualquiera que lo leyera de arriba a abajo lo habría notado. Yo no lo leí de arriba a abajo, porque lo escribí yo.
Escrito por
Adrian Romo
Ingeniero Backend Senior que diseña APIs escalables en Python, arquitecturas sobre AWS Lambda, sistemas de voz e integraciones empresariales.
Relacionado
Sigue leyendo
Primitivas Ensambladas vs. una Plataforma
Construí un agente de voz usando primitivas en la nube, y funcionó. Desde entonces, fue reemplazado por una plataforma de voz diseñada específicamente para ese fin, y creo que fue la decisión correcta.
Segundos de trabajo, horas de residencia
Mi informe matutino empezó a fallar. Ollama estaba activo y devolvía un HTTP 500, porque una renderización de imagen de 21 segundos seguía ocupando 6.6 GB de VRAM horas después.
¿Qué Merece Atención Hoy?
Mi homelab genera un veredicto cada mañana: algo te necesita, o nada lo hace. Conseguir que la segunda parte fuera honesta fue mucho más difícil que la primera.
Continúa
¿A dónde sigues?
Explora más textos técnicos, revisa los casos de estudio o escríbeme directo.