Skip to content

Repository files navigation

AI Media Agents

License: MIT

Plataforma autónoma de medios tecnológicos impulsada por agentes de IA. Descubre noticias, detecta tendencias, genera artículos optimizados para SEO y los publica — todo sin intervención humana.

Demo en vivo: techblog.davidfdzmorilla.dev

┌──────────────────────────────────────────────────────────────────────┐
│                         AI MEDIA AGENTS                              │
│                                                                      │
│  Sources ──▶ Discovery ──▶ Trends ──▶ Chief Editor ──▶ Research     │
│                                          │    │                      │
│                                     reject  approve                  │
│                                                │                     │
│  Analytics ◀── Publisher ◀── SEO ◀── Chief Editor ◀── Writer        │
│       │                                  │    │          ▲           │
│       ▼                             approve  revise ─────┘           │
│  Optimization                                                        │
└──────────────────────────────────────────────────────────────────────┘

Tabla de Contenidos


Inicio Rapido

Requisitos previos

  • Docker y Docker Compose v2
  • Una API key de OpenAI o Anthropic

1. Clonar y configurar

git clone <repo>
cd ai-media-agents
cp .env.example .env

2. Configurar API keys

Editar .env con al menos una API key de LLM:

OPENAI_API_KEY=sk-...
# o
ANTHROPIC_API_KEY=sk-ant-...

3. Levantar todo el stack

docker compose up -d

Esto levanta 7 servicios:

Servicio Puerto URL
API (FastAPI) 8000 http://localhost:8000
Blog publico 3000 http://localhost:3000
Newsroom Dashboard 3001 http://localhost:3001
PostgreSQL 5432 -
Redis 6379 -
Qdrant 6333 http://localhost:6333/dashboard

4. Verificar que todo esta corriendo

# Health check del API
curl http://localhost:8000/health
# {"status": "healthy"}

# Estado del sistema
curl http://localhost:8000/status

# Ver logs
docker compose logs -f api

5. Ejecutar el primer pipeline

curl -X POST http://localhost:8000/pipeline/trigger \
  -H "Content-Type: application/json" \
  -d '{"max_articles": 3}'

O desde el Newsroom Dashboard en http://localhost:3001 con el boton Trigger Pipeline.


Arquitectura

El sistema sigue una arquitectura event-driven de multi-agentes:

┌─────────────────────────────────────────────────────────────────┐
│                          AGENT LAYER                             │
│                                                                  │
│  Discovery │ Trend │ Chief Editor │ Research │ Writer           │
│  SEO │ Publisher │ Analytics │ Optimization                     │
│                                                                  │
├─────────────────────────────────────────────────────────────────┤
│                     EVENT BUS (Redis)                             │
│  fire-and-forget dispatch │ asyncio.create_task()               │
├─────────────────────────────────────────────────────────────────┤
│                       CORE SERVICES                              │
│  LLM Service │ Embedding Service │ Vector Store │ Registry      │
├─────────────────────────────────────────────────────────────────┤
│                     KNOWLEDGE LAYER                              │
│  Editorial Memory (Qdrant) │ Content Scorer │ Topic History     │
├─────────────────────────────────────────────────────────────────┤
│                       DATA LAYER                                 │
│  PostgreSQL (articles, topics) │ Qdrant (embeddings) │ Redis   │
├─────────────────────────────────────────────────────────────────┤
│                      FRONTEND LAYER                              │
│  Blog Publico (Next.js SSR) │ Newsroom Dashboard (Next.js CSR) │
└─────────────────────────────────────────────────────────────────┘

Principios de diseno

Principio Implementacion
Event-driven Agentes se comunican solo via eventos a traves de Redis
Autonomia Cada agente opera independientemente con responsabilidades claras
Fire-and-forget asyncio.create_task() para procesamiento no-bloqueante
Editorial control ChiefEditorAgent como gatekeeper de calidad en 2 puntos
Observabilidad Structured logging, metricas por agente, dashboard en tiempo real
Resiliencia Max retries, revision loops con limite, error handling por agente

Servicios Docker

# docker-compose.yml
services:
  api         # FastAPI backend + 9 agentes IA
  postgres    # PostgreSQL 16 - articulos, topics, fuentes
  redis       # Redis 7 - event bus, cache
  qdrant      # Qdrant - embeddings vectoriales, memoria editorial
  site        # Blog publico - Next.js en puerto 3000
  newsroom    # Dashboard interno - Next.js en puerto 3001

Comandos utiles

# Levantar todo
docker compose up -d

# Solo el backend (sin frontends)
docker compose up -d api postgres redis qdrant

# Solo los frontends
docker compose up -d site newsroom

# Rebuild de un servicio especifico
docker compose build site --no-cache
docker compose up -d site

# Ver logs en tiempo real
docker compose logs -f api
docker compose logs -f site newsroom

# Detener todo
docker compose down

# Detener y borrar volumenes (reset completo)
docker compose down -v

Networking

Los frontends usan un patron de URL dual para resolver la comunicacion entre Docker y el navegador:

Variable Valor Uso
API_URL_INTERNAL http://api:8000 Server-side rendering (red interna Docker)
NEXT_PUBLIC_API_URL http://localhost:8000 Client-side (navegador del usuario)

Backend (FastAPI)

Stack

  • Python 3.12 con async/await
  • FastAPI con Uvicorn
  • SQLAlchemy 2.0 (async) + PostgreSQL
  • Redis para Event Bus pub/sub
  • Qdrant para vector search y memoria editorial
  • OpenAI gpt-4o (default) o Anthropic Claude para generacion; gpt-4o-mini para tareas auxiliares
  • text-embedding-ada-002 para embeddings (1536 dims)
  • HDBSCAN para clustering de tendencias

Modelos de base de datos

Tabla Descripcion Campos clave
articles Articulos generados title, slug, content, status, quality_score, keywords, meta_title, faqs, schema_markup
topics Temas/categorias name, slug, trend_score, article_count, is_active
topic_clusters Clusters de tendencias summary, entities, trend_score, is_actionable
raw_contents Contenido crudo descubierto title, url, source, relevance_score, content_hash
sources Fuentes de datos type (rss/hn/reddit/github), url, fetch_interval
article_analytics Metricas diarias page_views, clicks, ctr, bounce_rate, avg_position
publishing_jobs Jobs de publicacion target, status, external_url

Frontend - Blog Publico

Puerto: 3000 | Stack: Next.js 14, TypeScript, Tailwind CSS

Blog publico de tecnologia con diseno dark mode, glassmorphism y SEO completo.

Paginas

Ruta Descripcion Renderizado
/ Homepage - hero, articulo destacado, grid de recientes, trending topics, newsletter SSR
/articles/[slug] Detalle de articulo - contenido, TOC, FAQs, JSON-LD, share Dynamic SSR
/categories Listado de categorias con trend score y conteo SSR
/categories/[slug] Articulos filtrados por categoria Dynamic SSR
/tags/[tag] Articulos filtrados por keyword/tag Dynamic SSR
/feed.xml RSS 2.0 feed con todos los articulos publicados Route Handler
/sitemap.xml Sitemap dinamico con articulos y categorias Next.js Sitemap

Componentes

Componente Funcion
Header Nav responsive con logo, links, search, RSS, hamburger mobile
Footer Links rapidos, descripcion, "Powered by AI Agents"
ArticleCard Card con gradient border, quality badge, tags, excerpt
TableOfContents TOC sticky lateral extraido de headings
FAQAccordion Seccion expandible de preguntas frecuentes
TagBadge Pill de keyword que linkea a /tags/[tag]
NewsletterForm Formulario de suscripcion (client component)

SEO

  • Meta title/description dinamicos por pagina
  • OpenGraph y Twitter Card tags
  • JSON-LD structured data (TechArticle schema)
  • Canonical URLs
  • RSS feed auto-discovery
  • Sitemap.xml dinamico
  • Semantic HTML

Diseno

  • Dark background: #0a0a0f
  • Glass cards: backdrop-blur, bordes semi-transparentes
  • Gradient accent: indigo-500 → purple-500
  • Tipografia: Inter (next/font)
  • Responsive mobile-first

Frontend - Newsroom Dashboard

Puerto: 3001 | Stack: Next.js 14, TypeScript, Tailwind CSS, SWR, Recharts

Dashboard interno de operaciones para monitorear el sistema de agentes IA en tiempo real.

Paginas

Ruta Descripcion Datos
/ Dashboard overview - metricas, pipeline activo, grid de agentes, runs recientes useSystemStatus(), useAgents(), usePipelineHistory()
/articles Gestion de articulos - tabla filtrable, aprobar/rechazar/editar useArticles()
/articles/[id] Detalle - preview, edicion inline, metadata, SEO, keywords useArticle()
/trends Panel de tendencias - cards con score, entidades, filtro actionable useTrends()
/analytics Analiticas - graficas de views, top articles, tabla de performance useAnalyticsSummary()
/pipeline Control de pipeline - progreso por etapa, trigger, historial expandible useSystemStatus(), usePipelineHistory()

Componentes

Componente Funcion
Sidebar Nav lateral colapsable con iconos SVG y estado activo
TopBar Titulo, indicador de salud (dot verde/azul), boton trigger pipeline
AgentCard Status por agente: estado, eventos, errores, avg time, last active
StatusBadge Badge color-coded: idle(gris), processing(azul pulsante), error(rojo), completed(verde)
MetricCard Tarjeta de metrica grande con delta y trend arrow
PipelineProgress Nodos horizontales conectados: 8 stages con checkmarks y animacion
DataTable Tabla generica con sort, paginacion, loading skeleton, empty state
ViewsChart Line chart de page views (Recharts)
TopArticlesChart Bar chart horizontal de top articles (Recharts)

Funcionalidades

  • Real-time polling via SWR (agentes cada 5s, pipeline cada 10s, articulos cada 15s)
  • Gestion de articulos: aprobar, rechazar, editar titulo y contenido inline
  • Pipeline control: trigger con parametro max_articles, ver progreso stage-by-stage
  • Filtros: articulos por status (draft/published/archived), trends por actionable/all
  • Alertas visuales: errores en rojo, processing en azul con animacion pulsante

Diseno

  • Background: slate-900 (#0f172a)
  • Cards: slate-800/80 con borde slate-700
  • Accents: indigo-500 (primary), emerald-500 (success), amber-500 (warning), rose-500 (error)
  • Font monospace para metricas
  • Status dots con CSS animation

API Reference

Endpoints

Metodo Ruta Descripcion Response
GET /health Health check {"status": "healthy"}
GET /status Estado del sistema, pipeline activo, agentes PipelineStatusResponse
GET /agents Status de todos los agentes Record<agent_id, AgentStatus>
POST /pipeline/trigger Ejecutar pipeline {"message": "...", "pipeline_id": "..."}
POST /discovery/trigger Ejecutar solo discovery TriggerResponse
POST /analytics/trigger Ejecutar analytics TriggerResponse
GET /pipeline/history?limit=10 Historial de pipeline runs PipelineHistoryItem[]
GET /pipelines Listado de runs recientes con coste total PipelineCostItem[]
GET /pipelines/{id}/cost Desglose de coste LLM por agente para una run PipelineCostBreakdown

Ejemplo: Trigger Pipeline

curl -X POST http://localhost:8000/pipeline/trigger \
  -H "Content-Type: application/json" \
  -d '{"max_articles": 5}'

max_articles actua como tope duro: el ChiefEditor rechaza sin evaluar via LLM cualquier topic adicional una vez aprobados los N mejores. Las clusters de tendencia se ordenan por trend_score antes de la evaluacion editorial, asi que los N topics conservados son los mejor scored.

Ejemplo: Ver status del sistema

curl http://localhost:8000/status | jq
{
  "running": true,
  "pipeline_status": {
    "initialized": true,
    "current_run": {
      "pipeline_id": "abc-123",
      "status": "running",
      "stages_completed": ["discovery", "trend_analysis", "editorial_selection"],
      "topics_approved": 3,
      "topics_rejected": 1,
      "articles_published": 0,
      "articles_revised": 0
    },
    "agents": {
      "total_agents": 9,
      "status_distribution": {"idle": 6, "processing": 3},
      "total_events_processed": 47
    }
  }
}

Coste y telemetria

Cada llamada LLM se atribuye al pipeline_id y al agente que la realizo. Al terminar el pipeline se persiste un sidecar JSON con el desglose en output/pipelines/<pipeline_id>.json:

{
  "pipeline_id": "8308b220-72a1-4d56-b22c-cabb155463e0",
  "started_at":  "2026-05-07T17:05:46+00:00",
  "completed_at":"2026-05-07T17:23:22+00:00",
  "total_cost_usd": 0.153299,
  "by_agent": {
    "WriterAgent":     {"calls": 13, "input_tokens": 12000, "output_tokens": 11000, "cost_usd": 0.1225},
    "TranslatorAgent": {"calls": 30, "input_tokens": 9500,  "output_tokens": 9100,  "cost_usd": 0.0289},
    "...": "..."
  },
  "calls": [{ "agent": "...", "model": "gpt-4o", "input_tokens": ..., "...": "..." }]
}

El frontmatter del markdown publicado tambien incluye generation_cost, generation_model y pipeline_id para correlacion. La API expone GET /pipelines/{id}/cost y GET /pipelines para consultar lo mismo sin tocar el filesystem.

Ejemplos:

curl http://localhost:8000/pipelines/<pipeline_id>/cost | jq '.total_cost_usd, .by_agent'
curl http://localhost:8000/pipelines | jq '.[0]'

Los precios por modelo viven en MODEL_COSTS (src/services/llm/service.py). Si pipeline_id no esta en el contextvar (llamada fuera de un pipeline) la grabacion es no-op.


Agentes

El sistema opera con 9 agentes especializados:

# Agente Responsabilidad Escucha Emite
1 Discovery Descubrir noticias de RSS, HN, Reddit, GitHub PIPELINE_STARTED NEW_CONTENT_FOUND
2 Trend Detectar tendencias via HDBSCAN + LLM NEW_CONTENT_FOUND TREND_CONFIRMED
3 Chief Editor Control editorial: seleccion + review TREND_CONFIRMED, ARTICLE_DRAFT_READY TOPIC_APPROVED/REJECTED, ARTICLE_APPROVED/REVISION_REQUIRED
4 Research Investigar y crear briefs TOPIC_APPROVED ARTICLE_BRIEF_CREATED
5 Writer Generar y revisar articulos ARTICLE_BRIEF_CREATED, ARTICLE_REVISION_REQUIRED ARTICLE_DRAFT_READY
6 SEO Optimizar para buscadores ARTICLE_APPROVED ARTICLE_SEO_READY
7 Publisher Publicar en targets ARTICLE_SEO_READY ARTICLE_PUBLISHED
8 Analytics Recopilar metricas ARTICLE_PUBLISHED PERFORMANCE_ALERT
9 Optimization Mejorar contenido bajo rendimiento PERFORMANCE_ALERT ARTICLE_UPDATED

Chief Editor Agent

El agente mas critico. Interviene en 2 puntos del pipeline:

1. Seleccion de topics (despues de Trend):

  • Verifica deduplicacion semantica via Qdrant (threshold 0.82)
  • Detecta saturacion de keywords (>=3 usos)
  • Evaluacion LLM: relevancia, novedad, potencial SEO
  • Resultado: TOPIC_APPROVED o TOPIC_REJECTED

2. Review de articulos (despues de Writer):

  • Content scoring deterministico (7 dimensiones, threshold 0.6)
  • Review LLM para calidad editorial
  • Revision loop: max 2 revisiones antes de auto-aprobacion
  • Resultado: ARTICLE_APPROVED o ARTICLE_REVISION_REQUIRED

Pipeline de Contenido

Flujo completo de un pipeline run:

1. DISCOVERY        → Fetcha contenido de fuentes configuradas
2. TREND ANALYSIS   → Embeddings + HDBSCAN clustering + LLM naming
3. EDITORIAL SELECT → Chief Editor filtra topics (dedup + LLM eval)
4. RESEARCH         → Crea briefs con outline y key points
5. WRITING          → Genera articulo completo con LLM
6. EDITORIAL REVIEW → Chief Editor evalua calidad (score + LLM)
   └── REVISION     → Writer revisa si es rechazado (max 2 loops)
7. SEO              → Meta titles, keywords, FAQs, schema markup
8. PUBLISHING       → Guarda como markdown + actualiza DB

Duracion tipica: ~280 segundos para 3 articulos

Ejemplo de resultado:

Pipeline:           completed
Stages:             discovery → trend_analysis → editorial_selection →
                    research → writing → editorial_review → seo → publishing
Topics approved:    3
Topics rejected:    0
Articles published: 3
Duration:           277.9s

Knowledge Layer

Modulo src/knowledge/ que provee inteligencia editorial persistente:

Componente Archivo Funcion
Editorial Memory editorial_memory.py Memoria semantica en Qdrant. Deduplicacion por similitud vectorial (threshold 0.82). Tracking de keywords saturados.
Content Scorer content_scoring.py Scoring deterministico de articulos en 7 dimensiones: length (0.15), structure (0.15), info density (0.15), source diversity (0.05), tech depth (0.20), title quality (0.15), coherence (0.15). Threshold: 0.6
Topic History topic_history.py Registro de decisiones editoriales. Tracking de revisiones por articulo. Estadisticas de aprobacion/rechazo.

Estructura del Proyecto

ai-media-agents/
├── docker-compose.yml              # 7 servicios
├── .env.example                    # Variables de entorno
├── .dockerignore
│
├── docker/
│   ├── Dockerfile                  # Backend Python
│   ├── Dockerfile.site             # Blog Next.js (multi-stage)
│   └── Dockerfile.newsroom         # Dashboard Next.js (multi-stage)
│
├── src/                            # Backend Python
│   ├── main.py                     # FastAPI app + endpoints
│   ├── config.py                   # Settings (env vars)
│   │
│   ├── agents/
│   │   ├── discovery/agent.py      # + fetchers.py (RSS, HN, Reddit, GitHub)
│   │   ├── trend/agent.py          # HDBSCAN + LLM analysis
│   │   ├── chief_editor/agent.py   # Editorial control (2 intervention points)
│   │   ├── research/agent.py       # Brief generation
│   │   ├── writer/agent.py         # Article generation + revision
│   │   ├── seo/agent.py            # SEO optimization
│   │   ├── publisher/agent.py      # Multi-target publishing
│   │   ├── analytics/agent.py      # Performance tracking
│   │   └── optimization/agent.py   # Content improvement
│   │
│   ├── core/
│   │   ├── agent_framework/
│   │   │   ├── base.py             # Agent base class + capabilities
│   │   │   ├── registry.py         # Agent lifecycle management
│   │   │   ├── context.py          # Execution context
│   │   │   └── memory.py           # Agent memory
│   │   └── event_bus/
│   │       ├── events.py           # EventType enum (30+ events)
│   │       ├── bus.py              # Redis event bus (fire-and-forget)
│   │       └── handlers.py         # Event handlers
│   │
│   ├── knowledge/
│   │   ├── editorial_memory.py     # Qdrant semantic dedup
│   │   ├── content_scoring.py      # 7-dimension quality scorer
│   │   └── topic_history.py        # Decision tracking
│   │
│   ├── services/
│   │   ├── llm/service.py          # OpenAI/Anthropic unified client
│   │   ├── embedding/service.py    # ada-002 embeddings
│   │   └── vector_store/service.py # Qdrant wrapper
│   │
│   ├── database/
│   │   ├── models/                 # SQLAlchemy models
│   │   └── connection.py           # Async PostgreSQL
│   │
│   ├── pipelines/
│   │   ├── content_pipeline.py     # 8-stage pipeline orchestration
│   │   └── orchestrator.py         # Pipeline lifecycle
│   │
│   └── common/
│       ├── exceptions.py
│       ├── logging.py              # Structured logging
│       └── utils.py
│
├── frontend/
│   ├── shared/                     # Codigo compartido
│   │   ├── types/index.ts          # TypeScript interfaces (todos los modelos)
│   │   └── api/
│   │       ├── client.ts           # ApiClient class (dual URL: server/browser)
│   │       ├── hooks.ts            # SWR hooks (referencia)
│   │       └── index.ts
│   │
│   ├── site/                       # Blog publico (:3000)
│   │   ├── package.json
│   │   ├── next.config.js
│   │   ├── tailwind.config.ts
│   │   ├── tsconfig.json
│   │   └── src/
│   │       ├── app/
│   │       │   ├── layout.tsx      # Root layout (Inter, header/footer)
│   │       │   ├── page.tsx        # Homepage
│   │       │   ├── globals.css     # Dark theme + article prose
│   │       │   ├── sitemap.ts      # Dynamic sitemap
│   │       │   ├── feed.xml/route.ts # RSS 2.0
│   │       │   ├── articles/[slug]/page.tsx
│   │       │   ├── categories/page.tsx
│   │       │   ├── categories/[slug]/page.tsx
│   │       │   └── tags/[tag]/page.tsx
│   │       ├── components/
│   │       │   ├── Header.tsx
│   │       │   ├── Footer.tsx
│   │       │   ├── ArticleCard.tsx
│   │       │   ├── TableOfContents.tsx
│   │       │   ├── FAQAccordion.tsx
│   │       │   ├── TagBadge.tsx
│   │       │   └── NewsletterForm.tsx
│   │       └── lib/
│   │           ├── api.ts
│   │           └── format.ts
│   │
│   └── newsroom/                   # Dashboard (:3001)
│       ├── package.json
│       ├── next.config.js
│       ├── tailwind.config.ts
│       ├── tsconfig.json
│       └── src/
│           ├── app/
│           │   ├── layout.tsx      # Dashboard shell (sidebar)
│           │   ├── page.tsx        # Overview dashboard
│           │   ├── globals.css     # Dark slate theme
│           │   ├── articles/page.tsx
│           │   ├── articles/[id]/page.tsx
│           │   ├── trends/page.tsx
│           │   ├── analytics/page.tsx
│           │   └── pipeline/page.tsx
│           ├── components/
│           │   ├── Sidebar.tsx
│           │   ├── TopBar.tsx
│           │   ├── AgentCard.tsx
│           │   ├── StatusBadge.tsx
│           │   ├── MetricCard.tsx
│           │   ├── PipelineProgress.tsx
│           │   ├── DataTable.tsx
│           │   └── charts/
│           │       ├── ViewsChart.tsx
│           │       └── TopArticlesChart.tsx
│           └── lib/
│               ├── api.ts
│               ├── hooks.ts       # SWR hooks (local)
│               └── format.ts
│
├── scripts/
│   ├── run_pipeline.py             # CLI pipeline runner
│   └── setup.sh                    # Setup script
│
├── tests/
├── output/blog/                    # Articulos publicados (markdown)
├── docs/
│   ├── ARCHITECTURE.md             # Documento tecnico detallado
│   ├── ARCHITECTURE_AGENTS.md      # Especificacion de agentes
│   └── PROMPT.md                   # Brief original del proyecto
└── pyproject.toml                  # Dependencias Python

Configuracion

Variables de entorno

Copiar .env.example a .env y configurar:

Obligatorias

Variable Descripcion
OPENAI_API_KEY API key de OpenAI (para gpt-4o + ada-002)

Opcionales

Variable Default Descripcion
ANTHROPIC_API_KEY - API key de Anthropic (alternativa a OpenAI)
LLM_PROVIDER openai openai o anthropic
OPENAI_MODEL gpt-4o Modelo principal para generacion
OPENAI_MODEL_FAST gpt-4o-mini Modelo barato para tareas auxiliares (clasificacion, SEO, traduccion)
GITHUB_TOKEN - Token para fuente GitHub
REDDIT_CLIENT_ID - Reddit API credentials
REDDIT_CLIENT_SECRET - Reddit API credentials
NEWSAPI_KEY - NewsAPI key
DAILY_ARTICLE_LIMIT 10 Max articulos por dia
DAILY_LLM_BUDGET_USD 50 Presupuesto diario de LLM
MIN_ARTICLE_QUALITY_SCORE 0.7 Score minimo de calidad (0-1)
SITE_URL http://localhost:3000 URL publica del blog
DEBUG false Modo debug
LOG_LEVEL INFO Nivel de logging

Desarrollo Local

Backend (sin Docker)

# Instalar dependencias Python
pip install -e .

# Levantar solo infraestructura
docker compose up -d postgres redis qdrant

# Correr el API
python -m uvicorn src.main:app --host 0.0.0.0 --port 8000 --reload

# Ejecutar pipeline manualmente
python scripts/run_pipeline.py

Frontend Blog (sin Docker)

cd frontend/site
npm install
npm run dev
# → http://localhost:3000

Frontend Newsroom (sin Docker)

cd frontend/newsroom
npm install
npm run dev
# → http://localhost:3001

Ambos frontends necesitan el API corriendo en :8000.


Produccion

Variables de entorno para produccion

# Actualizar URLs para el dominio real
SITE_URL=https://tudominio.com
NEXT_PUBLIC_API_URL=https://api.tudominio.com
API_URL_INTERNAL=http://api:8000

# Seguridad
DEBUG=false
LOG_LEVEL=WARNING

Build y deploy

# Build de todas las imagenes
docker compose build

# Deploy
docker compose up -d

# Verificar
docker compose ps
docker compose logs -f

Persistencia

Los datos se persisten en Docker volumes:

Volume Servicio Datos
postgres_data PostgreSQL Articulos, topics, fuentes, analytics
redis_data Redis Event bus, cache
qdrant_data Qdrant Embeddings, memoria editorial
./output API (bind mount) Articulos publicados en markdown

Documentacion adicional

About

Plataforma multi-agente que descubre, escribe y publica artículos de tecnología de forma autónoma, con telemetría de coste LLM por pipeline.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages