Detrás de OscarCode Weekly News — el newsletter que cada viernes te cuenta lo más relevante de la inteligencia artificial en español y sin jerga — no hay una persona buscando noticias: hay un agente editorial autónomo que investiga, verifica, redacta y publica solo. Este post explica toda la ingeniería que lo hace posible.
1. La idea
El objetivo no es "publicar contenido automáticamente" sino: detectar lo verdaderamente importante de la semana → investigarlo bien → convertirlo en información útil → publicarlo solo. La automatización es el mecanismo; el producto es una edición semanal de alto valor editorial, generada sin intervención humana (RF-045: autonomía total, verificable porque no existe ningún paso de aprobación en el flujo).
2. El pipeline: 9 fases en orden
El corazón es un orquestador (weekly-news.orchestrator.ts) que ejecuta una máquina de estados con transiciones validadas y registradas en base de datos (news_run_events):
/news/2026-W32/.3. El LLM: multi-proveedor con fallback
El research profundo usa un cliente LLM propio (llm.client.ts) que intenta los proveedores en orden de prioridad (LLM_PROVIDERS) y salta al siguiente si uno falla o se pasa del timeout. Cada llamada pide al modelo un reporte JSON validado por schema Zod: qué pasó, fecha real del evento, actores, producto, impacto para la gente común, contexto, evidencia y fuentes — en dos idiomas (ES + EN) para alimentar el toggle del sitio. Si el JSON sale inválido o truncado, se reintenta antes de caer al fallback determinista (así la edición siempre queda en español).
Reglas editoriales forzadas en el prompt: nombrar siempre los modelos con su versión (GPT-5.6 Luna, Claude Opus 4.8, Gemini 4, DeepSeek…), nunca decir "un grupo de agentes" sin nombres, y redactar como una persona que le explica a un amigo, sin etiquetas tipo "Para la gente común:".
4. Sin noticias viejas: verificación de fechas
Tres capas se encargan de que nunca entre contenido de 2024:
- Ventana del buscador: solo candidatos con fecha de publicación dentro de los últimos días configurados.
- Veredicto del LLM (
isRecent): el modelo decide si la noticia es de las últimas 3 semanas, con margen de 6 meses sobre su fecha estimada. - Agente verificador de fechas (
dates.verify): lee la página real del artículo, extrae su fecha de publicación (JSON-LD de schema.org, metaarticle:published_timeo<time datetime>) y esa fecha tiene la última palabra.
5. Sin duplicados: dedupe por evento
Dos medios pueden cubrir la misma noticia con títulos distintos y URLs distintas. El agente detecta el evento con tres señales: solape de texto (tokens significativos), producto compartido extraído por el LLM, y entidades de modelo (gpt, luna, minimax, bytedance, kimi, qwen, glm…). Si dos historias son el mismo evento, se queda la de mayor impacto. Esto se aplica también dentro de la sección china y cruzado entre secciones.
6. La sección "IA de China"
Una búsqueda dedicada al ecosistema chino (DeepSeek, Qwen/Alibaba, Kimi/Moonshot, GLM/Zhipu, MiniMax, Baidu ERNIE, Tencent Hunyuan, SenseTime) con presupuesto de research separado y hasta 3 historias propias. Si una noticia china ya está en la sección general, no se repite: se queda la de mayor impacto. Cuando no hay chinas únicas esa semana, la sección se omite (calidad > volumen).
7. Bilingüe ES/EN con toggle
Cada edición se publica en español (por defecto) y en inglés: el research LLM genera los textos en ambos idiomas; la edición EN se construye con los campos *En y un fallback determinista si faltan. El sitio /news/ tiene un botón ES|EN en el nav que alterna entre /news/2026-W32/ y /news/2026-W32/en/.
8. Infraestructura y deploy
EC2 us-east-2 Contenedor news-agent (Bun/TypeScript) + PostgreSQL propio, con límites de CPU/memoria, usuario no-root y red aislada.
SearXNG Buscador web self-hosted del servidor, consultado por la red Docker interna (nunca expuesto).
AWS SES Envío de emails con dominio verificado (no-reply@oventlabs.net), configuration set y tags de campaña por edición.
GitHub Pages Publicación estática en oscarcode9.github.io/news con URLs permanentes por semana.
news.oventlabs.net API pública (suscripción, confirmación, baja, contador y detección de agentes) detrás del ALB con TLS wildcard.
Cron Viernes 08:00 (America/Mexico_City) dispara el pipeline completo; también corre manualmente con --dry-run.
9. Seguridad del formulario
- Rate limiting por IP (5 suscripciones/hora) con respuesta 429 +
retry-after— evita usar la bienvenida como cañón de spam. - Anti header-injection: el email nunca admite saltos de línea ni caracteres de control; longitud máx RFC (254).
- Honeypot anti-bots: un campo oculto que, si viene lleno, rechaza la petición en silencio.
- Límite de payload (1 KB), CORS restringido y TLS en todo el trayecto (ALB → API).
- Secrets fuera del repo: .env solo en el servidor, .dockerignore para la imagen y redacción de tokens en errores de git.
10. Contador y detección de agentes
El sitio registra cada visita en el sistema compartido de contadores (agents.oventlabs.net/api/visits, el mismo del portfolio) y además un beacon propio que guarda el user-agent de cada visitante. Así se detecta cuándo un agente de IA (GPTBot, ClaudeBot, Gemini, Perplexity…) o un crawler busca el sitio — útil para posicionamiento y para saber quién nos lee.
11. Calidad verificable por código
Toda la suite es de integración 100% local (390+ tests): mocks para SES, git, LLM y S3; PostgreSQL local real. Cada requerimiento funcional (RF-001…RF-045) tiene su prueba y el criterio de aceptación está documentado en agent.spec.md. El MVP se acepta con la suite completa en verde.
¿Quieres verlo funcionando? Suscríbete: al poner tu correo recibes al instante la última edición de bienvenida, sin confirmación ni vueltas.