Gestire decine di siti WordPress per un’agenzia significa rispondere ogni giorno alla stessa domanda: “Come sta andando il sito del cliente X?” La risposta richiede di aprire Google Analytics, Search Console, controllare gli uptime log, verificare i backup, leggere i security scan. Venti minuti persi per ogni cliente, moltiplicato per trenta clienti: un’intera giornata lavorativa evaporata in attività puramente meccaniche.
Quando abbiamo iniziato a costruire AgencyPilot, questo era il problema numero uno che volevamo eliminare. Non ridurre, eliminare. Il risultato è il sistema di report automatici AI che descrivo in questo articolo: architettura, scelte tecniche, errori commessi, e quello che abbiamo imparato dopo dodici mesi di produzione.
Perché i report manuali non scalano: il problema reale
Prima di descrivere la soluzione, vale la pena capire il problema nella sua forma concreta. Un’agenzia con trenta siti WordPress attivi produce ogni mese circa 900 “eventi” rilevanti: aggiornamenti plugin, alert di sicurezza, variazioni di traffico, errori 404, backup completati o falliti, downtime.
Il cliente non vuole vedere 900 eventi. Il cliente vuole sapere: “Il mio sito va bene? C’è qualcosa che devo sapere?” Trasformare 900 eventi in una risposta a questa domanda è esattamente ciò che un LLM sa fare meglio di qualsiasi template statico.
I report automatici WordPress di vecchia generazione — PDF generati da plugin come WP Activity Log o MainWP — risolvono il problema della raccolta dati, ma non quello della comunicazione. Producono tabelle zeppe di numeri che la maggior parte dei clienti non legge. Noi volevamo report che le persone leggessero davvero.
L’architettura del sistema: tre livelli distinti
Il sistema di report automatici AI di AgencyPilot è costruito su tre livelli separati, ognuno con una responsabilità precisa.
Livello 1: Raccolta dati (Data Collection Layer)
Ogni sito WordPress gestito da AgencyPilot ha installato un plugin leggero (~8KB) che espone un endpoint REST API autenticato:
GET /wp-json/agencypilot/v1/snapshot
Response:
{
"site_url": "https://example.com",
"snapshot_time": "2026-03-28T06:00:00Z",
"wordpress": {
"version": "6.7.2",
"updates_available": 3,
"plugins_total": 24,
"plugins_inactive": 2
},
"security": {
"last_scan": "2026-03-27T22:00:00Z",
"issues_critical": 0,
"issues_warning": 2,
"blocked_attempts_7d": 847
},
"uptime": {
"status": "up",
"uptime_30d_percent": 99.97,
"last_downtime_minutes": 3,
"last_downtime_date": "2026-03-15"
},
"backups": {
"last_backup": "2026-03-28T03:00:00Z",
"last_backup_status": "success",
"storage_gb": 4.2
}
}
A questi dati aggiungiamo le metriche di Search Console via Google API (impressioni, click, posizione media) e le performance da Core Web Vitals tramite PageSpeed Insights API. La raccolta avviene ogni notte alle 03:00 tramite un cron job FastAPI.
Livello 2: Elaborazione e contestualizzazione (Processing Layer)
I dati grezzi non vanno direttamente al LLM. Prima passano per un layer di elaborazione che li trasforma in delta semantici: non “il traffico è 1.847 sessioni” ma “il traffico è aumentato del 12% rispetto alla settimana scorsa, invertendo un calo di tre settimane consecutive”.
Questo passaggio è critico. Un LLM che riceve numeri assoluti tende a descriverli senza interpretarli. Un LLM che riceve delta contestualizzati può ragionare su tendenze, anomalie e priorità.
Il processing layer è scritto in Python (FastAPI + PostgreSQL). Il codice che calcola i delta è semplice:
def compute_delta(current: float, previous: float, label: str) -> dict:
if previous == 0:
return {"label": label, "current": current, "delta_pct": None, "trend": "new"}
delta_pct = ((current - previous) / previous) * 100
trend = "up" if delta_pct > 2 else "down" if delta_pct < -2 else "stable"
return {
"label": label,
"current": current,
"previous": previous,
"delta_pct": round(delta_pct, 1),
"trend": trend
}
Livello 3: Generazione del testo con Claude API
Il cuore del sistema. I dati elaborati vengono serializzati in JSON e passati a Claude API (claude-3-5-haiku-20241022 per il volume, claude-3-5-sonnet per report premium) con un prompt di sistema costruito su misura per ogni tipo di cliente.
Il prompt di sistema differenzia il tono in base al profilo del cliente: linguaggio tecnico per un e-commerce gestito internamente, linguaggio semplice per il comune che non ha un IT manager. Questo profilo viene configurato una sola volta durante l'onboarding.
Un esempio semplificato del prompt:
system = """
Sei il sistema di reporting di AgencyPilot. Genera un report settimanale
per il sito {site_name} ({site_url}).
Il cliente è: {client_profile}
Lingua: italiano
Tono: {tone} (tecnico|professionale|semplice)
Struttura il report in quattro sezioni:
1. Sintesi della settimana (2-3 frasi, evidenzia la cosa più importante)
2. Sicurezza e uptime (status, eventuali alert)
3. Performance e SEO (traffico, Core Web Vitals, posizioni)
4. Azioni raccomandate (max 3, ordinate per priorità)
Non usare gergo tecnico se il tono è 'semplice'.
Non inventare dati. Usa solo i dati forniti.
Sii diretto. Evita frasi come 'è importante notare che'.
"""
Le sfide che non avevamo previsto
Build in public significa anche raccontare gli errori. Eccone tre che ci hanno fatto perdere tempo.
Problema 1: Allucinazioni sui numeri
Nelle prime versioni, Claude a volte "arrotondava" i numeri in modo impreciso o combinava metriche diverse producendo affermazioni false. Un bug sottile: il modello era corretto dal punto di vista del ragionamento, ma la formulazione suggeriva dati che non avevamo fornito.
La soluzione è stata aggiungere una lista esplicita di vincoli nel prompt: "Usa SOLO i seguenti dati. Se un dato non è presente, scrivi 'dato non disponibile'. Non fare inferenze numeriche." In più, un layer di post-processing valida ogni numero nel testo generato confrontandolo con i dati di input. Se trova discrepanze, il report viene rigenerato (max 2 tentativi prima di fallback su template statico).
Problema 2: Latenza inaccettabile per report in batch
Con trenta siti, generare tutti i report in sequenza impiegava 4-6 minuti. Per email inviate il lunedì alle 8:00, non è un problema. Ma per report on-demand richiesti dal cliente via dashboard, era inaccettabile.
La soluzione: generazione asincrona con queue (implementata con PostgreSQL + asyncio, senza Redis per ridurre la complessità dell'infrastruttura). Il report viene generato in background e notificato via webhook quando pronto. La dashboard mostra "Generazione in corso..." e si aggiorna automaticamente. Tempo percepito dall'utente: 0 secondi di attesa bloccante.
Problema 3: Costi API che crescevano non linearmente
Il costo di Claude API scala con i token in input. Con trenta siti che passano ciascuno ~2000 token di dati + ~500 token di prompt, ogni ciclo di report consumava circa 75.000 token di input. Accettabile, ma volevamo ottimizzare.
L'ottimizzazione principale: cachare il contesto statico del cliente (profilo, storico di lungo periodo) e aggiornarlo solo settimanalmente. Il payload per ogni report è sceso da ~2500 a ~900 token di input. Il risparmio è stato del 64% sul costo mensile API.
I numeri dopo 12 mesi di produzione
Ecco i dati reali, non stimati, dalla nostra istanza di produzione (anonimizzati dove necessario):
| Metrica | Prima (report manuali) | Dopo (AgencyPilot AI) |
|---|---|---|
| Tempo medio per report | 18 minuti | 23 secondi (generazione) + 0 (revisione se no anomalie) |
| Tasso di apertura email report | 34% | 71% |
| Report con anomalie rilevate | Dipendeva dall'attenzione umana | 100% automatico, 0 falsi negativi gravi in 12 mesi |
| Costo infrastruttura per report | ~€0.40 (tempo umano) | ~€0.02 (API + compute) |
| Clienti che hanno ridotto il churn | — | Tasso di churn -28% nei clienti con report attivi |
Il dato sul churn è quello che ci ha sorpreso di più. Non avevamo costruito il sistema di report per ridurre il churn: l'obiettivo era risparmiare tempo. Ma i clienti che ricevono un report professionale ogni settimana percepiscono il valore dell'agenzia in modo completamente diverso da quelli che ricevono solo risposte ai ticket.
Come integrarsi con AgencyPilot: il setup in pratica
Per chi vuole implementare un sistema simile sul proprio stack, il flusso minimo richiede:
- Un endpoint di snapshot per ogni sito — Il plugin AgencyPilot lo installa automaticamente. Per installazioni custom, il formato dell'endpoint REST API è documentato nel nostro repo.
- Un database di serie storiche — PostgreSQL con una tabella
site_snapshots. Lo schema è open source nel repo di AgencyPilot. - Un'istanza FastAPI — Anche qui, la nostra architettura di automazione WordPress è descritta in dettaglio in un articolo dedicato.
- Una chiave API Anthropic — Il modello
claude-3-5-haiku-20241022è sufficiente per il 95% dei casi d'uso. Costa circa $0.0008 per report con la nostra configurazione attuale.
Per chi non vuole costruire questo stack da zero, AgencyPilot offre tutto questo come servizio gestito. La guida completa alla gestione siti WordPress per agenzie descrive l'onboarding completo.
Cosa cambierei se ripartissi da zero
La domanda che tutti fanno quando si racconta un sistema funzionante. Tre cose:
1. Inizierei con template parziali, non full AI. Nelle prime settimane, il 70% del testo di ogni report era uguale tra un sito e l'altro. Avremmo dovuto usare AI solo per le sezioni variabili (anomalie, raccomandazioni) e template statici per il resto. Avremmo risparmiato settimane di debugging del prompt.
2. Avrei investito prima nella validation layer. Il post-processing che valida i numeri nel testo generato è stato costruito dopo i primi bug in produzione. Avrei dovuto costruirlo prima ancora del sistema di generazione. È la parte più critica.
3. Avrei esposto un webhook prima di un'email. I clienti tech preferiscono ricevere i report su Slack o Teams, non via email. Abbiamo aggiunto l'integrazione webhook solo sei mesi dopo il lancio. Se l'avessimo fatto subito, avremmo acquisito tre clienti in più che alla fine non hanno fatto l'upgrade proprio per mancanza di integrazione Slack.
Il futuro: report predittivi
La prossima versione del sistema che stiamo sviluppando introduce un layer predittivo. L'idea è semplice: con dodici mesi di serie storiche per ogni sito, possiamo identificare pattern che precedono problemi specifici.
Ad esempio: nei nostri dati, un aumento del 40%+ dei blocked_attempts nelle ultime 48 ore precede un tentativo di brute force andato a segno nel 23% dei casi. Un plugin con vulnerabilità nota pubblica aumenta la probabilità di exploit del 340% nelle due settimane successive alla disclosure.
Non abbiamo ancora i numeri per pubblicare questi modelli come affidabili. Ciò che possiamo dire è che i report predittivi sono già in beta su un sottoinsieme di clienti, e il feedback iniziale è positivo. La sicurezza WordPress proattiva è il caso d'uso più promettente.
FAQ — Domande frequenti sui report automatici AI
Quanto costa implementare un sistema di report AI per un'agenzia WordPress?
Il costo dipende dalla scala. Per un'agenzia con 20-50 siti, il costo mensile di Claude API si aggira tra €30 e €80. Aggiungendo l'infrastruttura (un VPS Debian con FastAPI + PostgreSQL, circa €20/mese su Hetzner), il totale è inferiore a €100/mese. Il risparmio in tempo umano supera di gran lunga questo costo dalla prima settimana.
I clienti si accorgono che il report è generato da AI?
Nella nostra esperienza, no — se il sistema è configurato correttamente. I clienti non fanno questa domanda. Quello che notano è che il report è chiaro, puntuale, e parla specificamente del loro sito senza frasi generiche. Questo è esattamente l'obiettivo.
Come gestite la privacy dei dati dei clienti con Claude API?
I dati inviati all'API Anthropic non includono mai dati personali degli utenti finali dei siti. Passano solo metriche aggregate (traffico totale, non utenti individuali), stati tecnici (versioni, uptime), e configurazioni anonimizzate. Abbiamo verificato che questo è conforme al nostro DPA con Anthropic e alle linee guida GDPR per il trattamento di dati tecnici.
Il sistema funziona anche con siti WordPress multilingua?
Sì. Il layer di generazione supporta report in italiano, inglese, e spagnolo. Il profilo cliente include la lingua preferita. Per siti con traffico multilingua, le metriche Google Search Console vengono aggregate indipendentemente dalla lingua delle query.
Cosa succede se Claude API non è disponibile?
Il sistema ha un fallback su template statici. Se la generazione AI fallisce dopo due tentativi, viene inviato un report strutturato ma non narrativo con tutti i dati grezzi. Nella nostra esperienza di dodici mesi, il fallback si è attivato in tre occasioni, tutte durante manutenzioni programmate di Anthropic.