ECHO — agent-orchestrator
Een persoonlijke Jarvis-achtige assistent, solo gebouwd, lokaal draaiend op mijn eigen hardware. Multi-brain LLM-routing, tool-dispatch, vault-backed memory, filesystem-watchers, drie-tier AI-fallback. Ongeveer 24+ Python-modules in de orchestrator, plus een React/Vite-HUD die alles in één dashboard surfacet.

Whiteboard-schets · de vorm van het systeem
Wat ECHO in de praktijk doet
Ik praat met haar, zij praat terug. Maar het interessante zit niet in de chat — het zit in wat er tussen turns gebeurt. ECHO observeert mijn filesystem, de recente commits over al mijn projecten, de open nudges in mijn vault, en synthetiseert dat tot ochtend-briefings, code-change-chronicles, time-tracking-aggregaten, en proactieve interventies als er iets niet klopt.
Concreet, in één turn kan ECHO:
- Beslissen welke model-tier ze gebruikt (
fast/main/think/local) op basis van de vorm van de request - Een tool dispatchen — vault-search, een database-query, een shell-command, een KPI-pulse van een aangesloten product
- Gestructureerde JSON updaten voor een persoonlijke dashboard
- Een notitie aan een lopende time-entry hangen zonder de timer te stoppen
- Een memory-worker triggeren die de daily-note van gisteren consolideert
De HUD laat alles zien: een "Brain Waves" trace, een token-burn-meter, een vault-graph, een CC-status-indicator, en project-specifieke panels (deels redacted in deze publieke versie).
Architectuur
┌─────────────────────────────────────────────────────────────┐
│ HUD (React + Vite) │
│ Presence · Vitals · TokenBurn · VaultGraph · Project │
│ panels · RailTabs · Identity │
└──────────────────────────────┬──────────────────────────────┘
│ HTTP polling + SSE
▼
┌─────────────────────────────────────────────────────────────┐
│ Orchestrator (FastAPI · Python 3.13) │
│ ───────────────────────────────────────────────────────── │
│ router.py — Multi-brain selection (heuristics + LLM) │
│ tools.py — 14+ tool dispatch │
│ skills.py — agentskills.io-compatible workflow layer │
│ vault_graph.py — Markdown vault + Wikilink edges │
│ time_track.py — Time entries, urencriterium, exports │
│ runway.py — Personal-finance runway dashboard │
│ social.py — Social-media accounts registry │
│ cc_status.py — Claude Code activity from JSONL │
│ ... + nudges, agenda, hue, intents, voice, tts, en een │
│ handvol product-specifieke integratie-modules │
└──────┬──────────────────────────────┬───────────────────────┘
│ │
▼ ▼
┌──────────────────┐ ┌────────────────────────────────┐
│ Memory Worker │ │ External LLMs │
│ (APScheduler) │ │ ───────────────────────────── │
│ ────────────── │ │ Anthropic (Claude API) │
│ Drafter │ │ Ollama local (Qwen, Llama) │
│ Curator │ │ ComfyUI local (Stable Diff) │
│ Consolidator │ │ │
│ Watchers │ │ 3-tier fallback: │
│ Reflector │ │ API → rules → hardcoded │
│ Daily-summary │ │ │
└──────────────────┘ └────────────────────────────────┘
De multi-brain router
De router bepaalt welke model-tier wordt aangesproken voordat de request de orchestrator verlaat. Eerst goedkope heuristieken, dan pas een LLM-classifier als die het niet weten.
async def decide(text: str, *, force: Brain | None = None) -> RouterDecision:
if force is not None:
return RouterDecision(force, "manual", "user-override")
# Goedkope regex-heuristieken eerst
h = _heuristic(text)
if h is not None:
return h
# Fallback op een klein model als classifier
return await _llm_classify(text)
Vier heuristiek-lagen draaien op volgorde: triviale-groet (sub-seconde
antwoorden gaan naar fast), business-keyword (alles wat een
project-context raakt gaat naar main zodat de juiste system-prompt
laadt), deep-keyword (architectuur / code-review naar think), en
shell-keyword (filesystem-vragen naar main waar shell-tools
beschikbaar zijn).
Die laatste laag doet meer dan je denkt: kleine modellen schrijven
PowerShell-commands routinematig uit als Markdown-block in plaats van
de shell-tool aan te roepen. Die queries naar main routeren fixt de
failure-mode aan de bron.
Tool-dispatch + skills-laag
ECHO biedt ~14 tools aan via het tool-use-protocol —
vault_read, vault_search, shell_check, list_skills /
run_skill, time_start / time_stop, time_summary,
note_learning, en een handvol product-specifieke tools.
De skills-laag is agentskills.io-compatibel: elke skill leeft op
memory/_skills/<skill-name>/SKILL.md met YAML-frontmatter voor
metadata en Markdown-body voor het recept. list_skills is goedkoop
(retourneert alleen frontmatter); run_skill(name) laadt de volledige
body en ECHO volgt de genummerde stappen, callt de tools in de juiste
volgorde.
Invocation-count, success-rate, en last-used-timestamp updaten zichzelf in de frontmatter — slow telemetry, geen aparte database.
Vault-backed memory
Het geheugen van ECHO is een Markdown-vault met WikiLink-edges. De vault
heeft folders voor People, Projects, Daily-notes, Knowledge, Tasks, en
System. De graph wordt live geparsed door vault_graph.py en gerenderd
in de HUD als 3D force-directed visualisatie met folder-clustering.
Wat er in de vault leeft: mijn eigen notities, een inbox waar ECHO
voorgestelde nudges in dropt, daily-notes die de consolidator schrijft,
een chronicle van elke Claude Code-commit over al mijn projecten, en
een CC-inbox.md-kanaal waar dev-Claude ECHO tussen turns kan briefen.
De watchers — Python-jobs gescheduled door APScheduler — monitoren commits, sentry, issues, project-state, agenda, idle. Elk emit een gestructureerde trigger als het iets ziet dat ECHO's aandacht waard is; de drafter maakt van triggers proposed nudges; de curator aggregeert periodiek.
Drie-tier AI-fallback
ECHO neemt nooit aan dat de API up is. Het patroon staat op WBSO-niveau in de technical-uncertainties-notes van het project:
- Tier 1 — API (primair, hoogste kwaliteit)
- Tier 2 — Rule-based reasoning (fallback als de API down of rate-limited is; minder vlot, maar nog steeds zinnig)
- Tier 3 — Hardcoded (offline minimum-viable response)
Dit patroon komt op meerdere lagen terug. Resultaat: ECHO blijft werken ook als externe services dat niet doen.
Lokale AI-infrastructuur
ECHO draait lokaal op mijn main werkplek — een Ryzen 7 3700X met AMD RX 6650 XT (8GB), Windows. De orchestrator, de HUD, de vault, de watchers en drafters, en ComfyUI voor image-generation draaien allemaal op dezelfde box. Een oudere AMD-machine staat ernaast als Linux-testbed voor side-projects, niet als onderdeel van het productie-ECHO-pad.
Voor zwaardere inference (grotere context-windows, model-fine-tuning, batch-image-werk) val ik terug op remote-toegang naar een meer capabele GPU-setup via TeamViewer of een direct port-forward.
Lokale LLMs draaien via Ollama (Qwen 2.5 7B, Llama 3.2 3B) voor routing, classificatie, en alles waar de API niet nodig is. De Anthropic Claude API is gereserveerd voor complex redeneerwerk waar lokale modellen de kwaliteit niet halen. Het meeste routine-werk draait op de main box; cloud-kosten blijven bescheiden.
Privacy-filter
De vault wordt elke turn in ECHO's persona geladen — wat betekent dat alles wat erin staat door de LLM gelezen wordt en naar Anthropic gestuurd. Een privacy-filter draait op elk write-entry-point (drafter, curator, extractor, commit-chronicles, daily-summarizer) en redact een kleine set lokaal-gevoelige programma-namen naar een generieke token. Het patroon werkt omdat de filter aan de write-kant zit, niet aan de read-kant.
Dit is het soort GDPR-by-design-beslissing dat niet bestaat als je een LLM achteraf op een bestaand systeem schroeft. Het moet erin ontworpen worden.
Hoe ECHO groeit
ECHO begon als een chatbot. Geleidelijk werd het meer.
Eerst kwam de geheugen-laag: een Obsidian-vault waar elk gesprek, elke beslissing en elke commit naartoe gaat. Die vault groeit elke dag. Na maanden gebruik herkent ECHO context die ik zelf alweer vergeten was — een experiment van zes weken terug, een uitspraak van een klant, een besluit dat ik op de fiets nam.
Daarna de watchers. Filesystem-events, git-commits, calendar-pings, sentry-issues — allemaal triggers waar ECHO autonoom op reageert. Een commit op een project? Drafted al een chronicle-regel terwijl ik koffie haal.
Daarna de drafters. Cron-jobs die 's nachts draaien: weekly recap, daily summary, time-tracking aggregaat, vault-consolidation. Als ik 's ochtends de HUD open ligt het al klaar — niet als "rapport", maar als proposed nudges in een inbox waar ik akkoord of weg-klik.
En nu zit ik in de fase waar ECHO meer voorstelt dan ik vraag. Niet alles is goed (een drafter mag soms gewoon stoppen met me wakker maken), maar de trend is duidelijk: ik typ minder, ECHO doet meer, en de output blijft op kwaliteit.
Wat de vault interessanter maakt dan een database: alles is Markdown. Geen lock-in, geen vendor, ik kan het zelf lezen zonder ECHO aan te zetten. Maar ECHO leest het ook elke turn. Een gesprek van vorige maand kan vandaag meegenomen worden in een beslissing — niet omdat ze het "herinnert" in de mensentaal-zin, maar omdat het in de vault staat en ECHO precies weet hoe ze daar moet zoeken.
De volgende laag in ontwikkeling: meer sleep-time-compute. Een goedkoop model dat 's nachts mee-leest in nieuwe vault-entries en zelf verbanden voorstelt. Niet om ECHO "slimmer" te maken — om de context die er al ligt beter benutbaar te maken.
Wat ik geleerd heb
Drie dingen die meer bleken te tellen dan de architectuur-diagrammen suggereerden:
-
Document-ketens werken beter dan losse docs. Core → afgeleide-voor-doelgroep-A → afgeleide-voor-doelgroep-B. Elk in zijn eigen toon. Grote plannen rotten snel; kleine gerichte versies overleven iteratie.
-
Watchers zijn ruis tot ze dat niet zijn. De eerste weken zaten vol false-positives en vroegen om een vier-niveau severity-taxonomy (info / action / critical / defcon) en DEFCON-only Explorer auto-reveal getrottled tot één per 10s. Signaal-ruis is meer design-werk dan ik dacht.
-
Skills > tools op een hoger abstractie-niveau. Tools zijn atomair. Skills zijn de recepten die het model nodig heeft om consistent dezelfde output te produceren voor hetzelfde type request. De skills-laag is het verschil tussen "het model doet dit waarschijnlijk goed" en "het model doet dit betrouwbaar goed".
Stack in één oogopslag
| Laag | Keuze | |---|---| | Orchestrator | Python 3.13, FastAPI, Uvicorn (SelectorEventLoop op Windows) | | Scheduling | APScheduler | | LLMs | Anthropic (Claude API), Perplexity voor onderzoek, ChatGPT voor prompt-werk, Ollama lokaal | | Memory | Markdown-vault, NDJSON event-streams, SQLite voor state | | HUD | React + Vite + Tailwind + Framer Motion + ForceGraph3D | | Voice | Whisper STT (lokaal), TTS via Edge / Kokoro | | Tools | Tool-use-protocol, 14+ geregistreerde tools | | Skills | agentskills.io-compatibel SKILL.md-format |