oglabs · 2026

Sistemas Multi-Agente
en tu Homelab

LLMs locales · agentes reales · cero facturas de API
oglabs.info/blog/serie-multiagente-homelab/
Psyrax
José Luis Espinoza Cuevas
Data Scientist · Product Owner
Gamer · Melómano · Maker
github.com/psyrax
Esta presentación existe porque volví a la adicción de Pokémon TCG.
Necesitaba un bot que me avisara de torneos en CDMX.
Lo que empezó como un script de 50 líneas terminó siendo un sistema multi-agente.
Motivación · Post 1

¿Por qué no solo usar la API de OpenAI?

  • Una sesión de debugging de 4h puede costarte $10–30 sin producir nada útil
  • Los rate limits interrumpen el flujo justo cuando más necesitas iterar
  • Datos privados → enviarlos a un tercero puede ser un bloqueador legal
  • La API cae → tu demo cae

Con hardware local, cada llamada cuesta exactamente cero dólares.
El costo eléctrico mensual es menor que una sola sesión de debugging en GPT-4.

Hardware

Dos máquinas, roles separados

Orquestador
  • Raspberry Pi 5
  • OpenClaw gateway
  • Cron jobs · scripts Python
  • Chromium CDP
  • ~5W idle
Motor de inferencia
  • Ryzen 5 · 32 GB RAM
  • AMD RX 9070 XT · 16 GB VRAM
  • Ollama + 4 modelos
  • Postgres 18 (Docker)
  • Unraid OS

Separar el plano de control del plano de cómputo es lo que hace el sistema escalable.

Infraestructura · Post 2

Unraid: el OS del homelab

  • Array con paridad flexible — mezcla discos de cualquier tamaño; si uno falla, el resto sigue
  • Docker con GUI — Community Apps: Ollama, Postgres, Open WebUI en un clic
  • GPU passthrough — AMD RX 9070 XT directo al contenedor de Ollama, sin overhead
  • VMs KVM/QEMU — Windows para juegos, Linux para experimentos, en la misma máquina
ollama/ollama postgres:18 open-webui metabase uptime-kuma watchtower
Infraestructura · Post 3

Topología de red

flowchart TD subgraph PI["Pi 5"] GW["OpenClaw Gateway\n:18789 · systemd"] CH["Chromium CDP\n:18800 · Xvfb"] DB[("SQLite\ntools.db")] GW --- CH GW --- DB end subgraph SRV["Ryzen 5 · 9070 XT · 16GB"] OL["Ollama :11434\nqwen3.5 · gemma4 · qwen2.5vl"] PG[("Postgres 18\n:5432")] end GW -->|"HTTP"| OL GW -->|"TCP"| PG
OpenClaw · Post 4

Arquitectura de tres capas

flowchart TD C["Canal\nWhatsApp · Telegram · HTTP"] subgraph GW["Gateway :18789"] R["Router semántico"] LF["LLM · qwen3.5:9b"] end subgraph SK["Skills"] S1["mexico-noticias"] S2["cdmx-tcg-events"] S3["pokemon-dia"] S4["tcg-deck-analyst"] end C -->|mensajes| GW GW -->|invocación| SK
Skills · Post 5

Seis especialistas, dos modos

Pull — responde cuando preguntas
  • mexico-noticias — CDP · gemma4:26b
  • intl-noticias — CDP · gemma4:e4b
  • maker-noticias — RSS · gemma4:e4b
  • cdmx-tcg-events — CDP + API
  • pokemon-dia — PokeAPI
  • tcg-deck-analyst — scraping
Push — envía sin que lo pidas
  • 7am: fetch noticias (4 fuentes)
  • 8am: resumen → WhatsApp groups
  • 5pm / 6pm: segundo ciclo
  • Pokémon del día
  • Sync incremental → Postgres
Agentes de noticias · Post 6

El pipeline completo

flowchart TD F["Fuentes de datos\nRSS feeds · sitios web"] FE["Fetch — 7am y 5pm\nRSS parser + Chromium CDP"] SU["LLM Summary\ngemma4:e4b · Ollama local"] SE["Send — 8am y 6pm\nWhatsApp groups · notif. push"] FA["Fetch article completo\nanti-bot · qwen2.5vl · visión"] SY["Sync incremental\n→ Postgres Docker"] F --> FE --> SU --> SE --> FA --> SY
Persistencia · Post 7

SQLite → Postgres

flowchart TD subgraph PI["Pi 5"] AG["Agente"] -->|escribe| SQ SQ[("SQLite · 11 tablas\ncero latencia de red")] WM["trigger: synced_at = NULL\nen cada UPDATE"] SQ --> WM end WM -->|"sync ~1s post-send"| PG subgraph SRV["LLM Server"] PG[("Postgres 18 · Docker\nBI · dashboards · SQL analítico")] end
Lecciones · Post 8

Lo que aprendimos haciéndolo

  • Secuencial > paralelo — Ollama atiende una inferencia a la vez; el cuello de botella no es el orquestador
  • Separar fetch de send — si el send falla, el fetch no se repite innecesariamente
  • Watchdogs simples e idempotentes — si ya está corriendo, no lo inicies de nuevo
  • Reintentos tolerantes al contexto — anti-bot no es lo mismo que timeout de API
  • Los crons son agentes sin conversación — el reloj es el trigger, el script sabe exactamente qué hacer

La riqueza del sistema
no está en ningún
componente individual.