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 │
└──────────────────────────────────────────────────────────────────────┘
- Inicio Rapido
- Arquitectura
- Servicios Docker
- Backend (FastAPI)
- Frontend - Blog Publico
- Frontend - Newsroom Dashboard
- API Reference
- Coste y telemetria
- Agentes
- Pipeline de Contenido
- Knowledge Layer
- Estructura del Proyecto
- Configuracion
- Desarrollo Local
- Produccion
- Docker y Docker Compose v2
- Una API key de OpenAI o Anthropic
git clone <repo>
cd ai-media-agents
cp .env.example .envEditar .env con al menos una API key de LLM:
OPENAI_API_KEY=sk-...
# o
ANTHROPIC_API_KEY=sk-ant-...docker compose up -dEsto 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 |
# 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 apicurl -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.
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) │
└─────────────────────────────────────────────────────────────────┘
| 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 |
# 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# 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 -vLos 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) |
- 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-minipara tareas auxiliares - text-embedding-ada-002 para embeddings (1536 dims)
- HDBSCAN para clustering de tendencias
| 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 |
Puerto: 3000 | Stack: Next.js 14, TypeScript, Tailwind CSS
Blog publico de tecnologia con diseno dark mode, glassmorphism y SEO completo.
| 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 |
| 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) |
- 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
- Dark background:
#0a0a0f - Glass cards:
backdrop-blur, bordes semi-transparentes - Gradient accent: indigo-500 → purple-500
- Tipografia: Inter (next/font)
- Responsive mobile-first
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.
| 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() |
| 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) |
- 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
- 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
| 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 |
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.
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
}
}
}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.
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 |
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_APPROVEDoTOPIC_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_APPROVEDoARTICLE_REVISION_REQUIRED
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
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. |
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
Copiar .env.example a .env y configurar:
| Variable | Descripcion |
|---|---|
OPENAI_API_KEY |
API key de OpenAI (para gpt-4o + ada-002) |
| 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 |
# 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.pycd frontend/site
npm install
npm run dev
# → http://localhost:3000cd frontend/newsroom
npm install
npm run dev
# → http://localhost:3001# 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 de todas las imagenes
docker compose build
# Deploy
docker compose up -d
# Verificar
docker compose ps
docker compose logs -fLos 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 |
- docs/ARCHITECTURE.md - Documento tecnico completo del sistema
- docs/ARCHITECTURE_AGENTS.md - Especificacion detallada de agentes, eventos y flujos
- docs/PROMPT.md - Brief original del proyecto