CARA: Architettura Assistente AI Domestico Self-Hosted | Antonio Pedoto

CARA è un agente conversazionale self-hosted su ARM64 con interfaccia vocale, avatar espressivo, pipeline multimodale, ciclo cognitivo di auto-apprendimento e memoria stratificata persistente.

CARA: architettura di un assistente AI domestico self-hosted, multimodale e auto-apprendente

Cognitive Adaptive Reasoning Agent — design, stack e principi di sistema

---

Abstract

CARA è un agente conversazionale auto-ospitato progettato per il deployment domestico su hardware ARM64 a basso consumo. Il sistema combina un'interfaccia vocale primaria con avatar espressivo, una pipeline multimodale di ingestione (testo, immagini, audio, video, documenti, dati strutturati, codice), un ciclo cognitivo di auto-apprendimento basato su feedback, e un modello di memoria stratificato persistente. L'esposizione remota avviene tramite Cloudflare Tunnel + Zero Trust Access, eliminando la necessità di IP pubblico o port forwarding e mantenendo la sovranità del dato sul nodo locale. Questo articolo descrive l'architettura del sistema, le scelte progettuali e i compromessi tecnici.

--- Motivazione tecnica

Gli assistenti vocali commerciali (Alexa, Google Assistant, Siri) presentano tre limiti strutturali rilevanti per un uso domestico avanzato: Statelessness percepito: la memoria a lungo termine, dove esiste, è opaca, non ispezionabile e non correggibile dall'utente. Ingestione monomodale o limitata: l'interazione è prevalentemente vocale o testuale; documenti, immagini e audio non sono cittadini di prima classe nel ragionamento. Data residency esterna: telemetria, trascrizioni e modelli di personalizzazione risiedono su infrastruttura del fornitore, con limitate garanzie di portabilità e cancellazione.

CARA affronta questi tre limiti spostando inferenza, memoria e orchestrazione su un nodo locale, esponendo lo stato cognitivo in forma strutturata e ispezionabile, e trattando ogni input come un artefatto multimodale processabile da una pipeline dedicata.

--- Panoramica architetturale

I componenti sono accoppiati tramite contratti API stabili. L'orchestratore non assume la presenza di un LLM specifico: un layer di astrazione consente lo switch tra modello locale (Llama, Mistral su CPU/NPU del RK3588) e modello remoto via API quando la latenza o la qualità lo richiedono.

--- Modello cognitivo: il loop di auto-apprendimento

Il nucleo logico di CARA è un loop a sei fasi eseguito a ogni turno conversazionale.

3.1 Fasi del ciclo

Fase Funzione Output --- --- --- Observe Estrazione di intent esplicito, intent implicito, contesto, vincoli, segnali emotivi, allegati Vector di feature dell'input Recall Retrieval semantico dalla memoria a lungo termine via pgvector Top-k memorie rilevanti con score Hypothesize Generazione di N strategie candidate con confidenza associata Lista ordinata di action plan Act Esecuzione della strategia top-ranked, esplicitando le assunzioni Risposta multimodale (testo + audio + espressione facciale) Evaluate Monitoraggio dei segnali di feedback nel turno successivo Delta di confidenza per ogni memoria coinvolta Update Scrittura nelle memorie, aggiornamento dei pesi di confidenza Stato persistente aggiornato

3.2 Architettura della memoria

CARA mantiene quattro layer di memoria distinti, ciascuno con schema e politica di retention propria: Memoria episodica: registro append-only di tutti gli scambi, indicizzato temporalmente. Schema: {turnid, userid, timestamp, input_modalities[], response, signals[]}. Memoria semantica: fatti consolidati su utenti, dominio, ambiente. Promozione da episodica avviene su soglia di conferma. Schema: {fact, sourceturnids[], confidence, lastvalidatedat}. Memoria procedurale: workflow e strategie che hanno prodotto risultati validati. Indicizzata per intent class. Usata come few-shot prior nel reasoning. Memoria meta-cognitiva: traccia degli errori sistematici, dei bias rilevati, delle aree di bassa confidenza. È la memoria che permette a CARA di "sapere ciò che non sa".

Ogni elemento è soggetto a regole di aggiornamento parametriche:

Il punto saliente: gli errori non vengono cancellati, vengono archiviati. Questo trasforma il dataset di errori in materiale di training per il fine-tuning periodico del prior comportamentale.

--- Pipeline multimodale di ingestione

Ogni allegato attraversa una pipeline tipizzata. Il dispatcher seleziona il processore in base al MIME type e produce una rappresentazione unificata che alimenta il contesto LLM.

Tipo input Processore Output normalizzato --- --- --- PDF, DOCX, ODT unstructured, pdfplumber, mammoth Testo strutturato + tabelle + metadata Immagini raster Vision LLM (locale: LLaVA su NPU; remoto: Claude Vision) Descrizione + OCR + entity extraction Audio whisper.cpp (ARM64-optimized) Trascrizione + timestamp + diarization Video ffmpeg → split audio + keyframes Pipeline audio + pipeline immagine in parallelo CSV, XLSX pandas, polars Schema + statistiche + sample rows JSON, YAML Parser nativo + schema inference AST + tipi inferiti Codice Tree-sitter per linguaggio AST + import graph + complessità ciclomatica

Tutti gli artefatti processati vengono persistiti con hash SHA-256 per dedup, vector embedding per retrieval semantico, e flag persistent_relevance che decide la promozione in memoria semantica.

--- Interfaccia voice-first

5.1 Layout

L'UI principale abbandona il paradigma chat. Il volto animato di CARA occupa il centro della viewport (70% verticale). Sotto, una riga di sottotitoli sincronizzati word-by-word con il TTS. In basso al centro, un singolo pulsante microfono. Nessun header, nessuna sidebar di default.

5.2 Stati espressivi

Il volto è implementato come SVG modulare con animazioni CSS/Web Animations API. Stati discreti: idle, listening, thinking, speaking, happy, curious, confused, error. Le transizioni sono interpolate per evitare cambi bruschi. Il lip-sync utilizza l'ampiezza del segnale TTS in tempo reale per modulare l'apertura della bocca, senza pretendere precisione fonetica.

5.3 Attivazione

Due path di ingresso ortogonali: Tap-to-talk: pressione sul pulsante → apertura microfono → VAD (Voice Activity Detection) per chiusura automatica. Wake-word "CARA": ascolto passivo continuo on-device. Nessun audio inviato al backend prima della detection. Implementabile con Picovoice Porcupine (custom keyword), Vosk locale, o Web Speech API con matching server-side. La scelta dipende dal trade-off latenza/falsi positivi/privacy.

5.4 Output sincronizzato

La risposta viene emessa simultaneamente come: Audio TTS (cloud o locale, in funzione di latenza accettabile e qualità voce). Sottotitoli con highlight della parola corrente, basati sui timestamp del TTS engine (es. outputwordtimings di ElevenLabs o forced alignment con Whisper su Piper output). Animazione facciale coerente con il payload semantico ed emotivo.

L'utente può interrompere in qualsiasi momento via tap o comando vocale ("CARA stop"). Il backend riceve un segnale di abort che termina la generazione TTS e marca il turno come interrupted per il loop di apprendimento.

--- Architettura di rete e sicurezza

6.1 Modello di esposizione

CARA non apre porte sul router. La comunicazione con Internet è uscente, gestita da cloudflared (versione ≥ 2026.3.0, con supporto QUIC nativo). Il client cloudflared mantiene una connessione persistente con almeno due datacenter Cloudflare, che fungono da reverse proxy verso l'edge.

6.2 Authentication boundary

Cloudflare Access enforce le policy di accesso al livello edge. Le richieste non autenticate non raggiungono mai il NanoPC. Identity provider configurati: One-Time PIN via email come baseline, WebAuthn (passkey) come secondo fattore obbligatorio per gli account admin.

Ogni richiesta autorizzata viene firmata con un JWT (Cf-Access-Jwt-Assertion header) che il backend valida usando le chiavi pubbliche fornite da https:// .cloudflareaccess.com/cdn-cgi/access/certs. Questo previene attacchi di tipo bypass-tunnel: anche se un attaccante riuscisse a raggiungere il backend per altra via, l'assenza del JWT firmato bloccherebbe la richiesta a livello applicativo.

6.3 WebSocket e streaming audio

Cloudflare Tunnel proxy nativamente WebSocket sicuri (wss://), abilitati esplicitamente nella configurazione dell'Application. Il flusso audio dal client a Whisper passa via chunk Opus su WebSocket — design preferito al WebRTC nativo, che non è veicolabile attraverso il tunnel poiché richiede UDP/RTP diretti.

6.4 Defense in depth Backend in ascolto esclusivamente su 127.0.0.1 (mai su 0.0.0.0). Firewall locale (nftables) con default-deny inbound, eccetto SSH dalla LAN trusted. Permessi filesystem restrittivi sui blob utente e sul dump PostgreSQL. Backup cifrato con age o restic su storage offline. File credenziali del tunnel ( .json) trattato come segreto root: backup multipli, rotazione se compromesso.

--- Hardware e deployment

Il nodo target è un NanoPC-T6 (Rockchip RK3588, 8 core ARM64, fino a 32 GB LPDDR4, NVMe). Profilo termico passivo, consumo medio 8-12 W. La NPU integrata (6 TOPS) è utilizzabile per inferenza vision e wake-word locale; modelli LLM di taglia 7B Q4 girano in CPU con throughput di 4-6 token/s, sufficienti per uso conversazionale a basso traffico.

OS di riferimento: Debian 12 ARM64. Servizi gestiti via systemd. Persistenza su NVMe con snapshot ZFS giornalieri. Container Docker opzionali per isolamento delle pipeline di terze parti.

Per scenari con bassa tolleranza alla latenza, l'orchestratore può fallback su API remote (Anthropic, OpenAI, ElevenLabs) mantenendo invariata la memoria persistente locale: il dato rimane sul nodo, solo la chiamata di inferenza è esternalizzata.

--- Sovranità del dato

Il principio di design è esplicito: la memoria di CARA non lascia mai il nodo locale. I dati derivati (embedding, summary, metadata) sono calcolati e archiviati on-device. Le chiamate a modelli remoti, quando avvengono, trasmettono solo il payload del turno corrente, senza identificatori utente persistenti, e il risultato viene riportato nella memoria locale.

Questo modello consente: Cancellazione fisica: lo spegnimento del nodo termina ogni accesso, senza dipendenze da pannelli di controllo esterni. Portabilità: l'intero stato è esportabile come dump PostgreSQL + directory blob. Audit: ogni accesso, ogni inferenza, ogni mutation della memoria è loggato localmente e ispezionabile.

Trade-off accettato: la qualità dei modelli locali è inferiore allo state-of-the-art cloud. La policy attuale è ibrida — locale di default, remoto su richiesta esplicita o per task ad alta complessità.

--- Sfide aperte Speaker identification: distinguere automaticamente i diversi utenti in famiglia senza prompt esplicito. Modelli ECAPA-TDNN su NPU sono il candidato principale. Wake-word robustezza: ridurre falsi positivi e falsi negativi su parlato naturale italiano in ambienti rumorosi. Lip-sync fonetico: passaggio da modulazione di ampiezza a viseme reali via forced alignment in tempo reale. Concurrenza multi-utente: gestione di sessioni simultanee da dispositivi diversi con coerenza della memoria condivisa vs privata. Memoria a lungo termine scalabile: oltre il milione di turni, retrieval su pgvector richiede strategie di compaction e clustering gerarchico. Fine-tuning continuo: progettazione di un loop di RLHF lightweight che usi la memoria di feedback per aggiornare il prior comportamentale senza degradare la base.

--- Roadmap

Fase 1 (corrente): hardening del backend, completamento della pipeline multimodale, deployment Cloudflare Tunnel + Access in produzione.

Fase 2: speaker ID, wake-word locale ottimizzato, espressioni facciali estese, latenza voice-to-voice sub-secondo.

Fase 3: fine-tuning incrementale del prior con dati di feedback, integrazione con domotica (Home Assistant via MQTT), API pubblica documentata per estensioni di terze parti.

Fase 4: federazione tra nodi CARA in setup multi-residenza (es. casa + studio), con sincronizzazione selettiva della memoria semantica condivisibile.

---

Riferimenti tecnici Cloudflare Tunnel & Zero Trust: https://developers.cloudflare.com/cloudflare-one Whisper.cpp ARM64 builds: https://github.com/ggerganov/whisper.cpp pgvector: https://github.com/pgvector/pgvector Picovoice Porcupine: https://picovoice.ai/platform/porcupine Rockchip RK3588 NPU SDK: https://github.com/rockchip-linux/rknn-toolkit2

---

Antonio Pedoto — sviluppatore freelance, Ferrara. CARA è un progetto di ricerca personale a sorgente eventualmente apribile.

Antonio Pedoto - IT System Administrator & Full Stack Developer

25+ anni di esperienza in ambienti enterprise e high-security. Articoli tecnici, progetti e approfondimenti su System Administration, Full Stack Development, Cybersecurity e DevOps.

Ultimi articoli

Scopri gli ultimi articoli tecnici su Linux, DevOps, Cybersecurity, sviluppo web e molto altro.

Vedi tutti gli articoli

Progetti

Esplora i progetti realizzati nel campo dell'IT e dello sviluppo software.

Vedi tutti i progetti

Chi sono

Sono Antonio Pedoto e possiedo oltre 25 anni di esperienza professionale maturata in ambienti enterprise e ad alta sicurezza. Mi occupo principalmente di System Administration, Full Stack Development, Cybersecurity e DevOps.

Scopri di più

Contatti

Email: antonio.pedoto@gmail.com

Sede: Ferrara, Emilia-Romagna, Italia

LinkedIn: linkedin.com/in/antoniopedoto

GitHub: github.com/antoniopedoto