Architettura
Il flusso va dalle fonti ai formati generati, passando per una classificazione deterministica e un motore di contenitori a dati derivati. Ogni passo è raggiungibile anche dalla riga di comando, e la stessa catena è orchestrata da n8n dietro le quinte: la demo non mostra i flussi n8n, ma la catena orchestrata è identica a quella da riga di comando. Un terzo modo di eseguire scarico e aggregazione è il bottone "Raccogli notizie" nell'interfaccia: stessa catena, sincrona, con un limite d'uso proprio (la riga di comando e n8n restano senza limiti, sono preparazione).
Il flusso, passo per passo
fonti -> scarico -> archivio notizie -> classificazione ->
motore dei contenitori -> strumenti di generazione -> gate umano ->
registri append-only
1. Fonti e scarico
Un adattatore per fonte: nessun altro modulo conosce i dettagli di una
fonte specifica. Lo scarico è sempre e solo GET, con cortesia verso il
portale remoto (intestazione dedicata, almeno un secondo fra richieste
consecutive alla stessa fonte). Dettaglio delle fonti in Fonti.
2. Classificazione deterministica
Il tema di una notizia non si chiede mai al modello linguistico. Si assegna con una cascata di quattro meccanismi:
- Categorie della fonte. Quando la fonte dichiara il tema, ci si fida della fonte.
- Parole chiave sul titolo e sul sommario. È il meccanismo che rende utilizzabile una fonte che non espone categorie.
- Tema di base della fonte: una fonte monotematica dichiara il tema in cui ricadono le sue notizie quando i due meccanismi precedenti non hanno detto nulla.
- "Altro", quando nessuno dei tre meccanismi precedenti ha prodotto un tema.
Il primo meccanismo che produce almeno un tema decide, e gli altri non si consultano. Guardando una notizia classificata si sa sempre quale meccanismo ha deciso e perché.
Le tre tabelle della cascata sono dati da tarare, non codice: si riscrivono senza toccare il motore dei contenitori, come i prompt e le regole di aggregazione.
3. Il motore dei contenitori
I contenitori sono dati derivati: una funzione pura li ricalcola sempre dall'archivio delle notizie, senza stato nascosto. Se le notizie di un contenitore cambiano, il contenitore lo dichiara e propone la rigenerazione dei formati.
Le regole che decidono quando un tema diventa un contenitore visibile sono dati e non codice: una regola generale fissa il numero minimo di notizie e la finestra temporale per qualunque tema, e il tema "altro" ha una regola propria, con una soglia più alta delle altre.
Il motore riceve l'orologio come parametro: è una funzione pura anche rispetto al tempo, non legge l'ora di sistema di nascosto.
La coda non classificata si vede. Il tema "altro" forma un contenitore visibile in home, in fondo all'elenco, con soglia più alta e senza sintesi: è un raccoglitore, non un tema. Non si nasconde per fare bella figura in demo: serve a mostrare quanto copre davvero la classificazione, invece di dichiararlo a voce.
4. Gli strumenti di generazione
Un unico punto del codice parla con il modello linguistico. I prompt sono file Markdown versionati, modificabili senza toccare il codice. Lo sforzo di ragionamento richiesto al modello si dichiara sempre, per formato: mai lasciato al valore di difetto del modello.
I formati si generano da un contenitore: sull'intero contenitore, oppure su una selezione di notizie scelta dentro quel contenitore, fino al caso limite di una sola notizia:
sintesi: il testo che racconta il tema a partire dalle notizie raccolte;post_social: varianti per piattaforma;carosello: slide con titolo e testo breve;reel: scene costruite dai titoli già pubblicati e approvati. Il reel non parla col modello: funziona anche senza credenziali. Si genera sempre prima della demo, mai in diretta.
L'impronta entra nell'identificativo dei formati. È calcolata sulla selezione di notizie che ha generato quella proposta, non necessariamente su tutto il contenitore: così un contenitore le cui notizie sono cambiate, o una selezione diversa dentro lo stesso contenitore, propongono formati nuovi invece di sovrascrivere proposte già decise, e le vecchie restano in archivio con la loro storia.
5. Il gate umano
Ogni proposta, sintesi compresa, entra nella coda di lavorazione. Un umano decide formato per formato: approva, corregge o scarta. Solo dopo l'approvazione un formato è pronto; niente esce mai da solo. Ogni decisione resta nel registro con autore, momento, oggetto ed esito, e il registro delle decisioni non cambia forma: le decisioni già registrate restano leggibili anche quando il codice evolve.
6. I registri append-only
Tre registri, tutti append-only, nessuno riscritto: il registro delle decisioni (chi ha approvato, corretto o scartato cosa, e quando), il registro delle generazioni (conta le generazioni chieste dall'interfaccia, per applicare i limiti d'uso) e il registro dei consumi (una riga per ogni chiamata al modello, con token, latenze, esito e costo stimato).
Nessuna base dati: solo file su disco e questi registri.
Struttura del codice
- fonti: un adattatore per fonte, il pezzo sostituibile del sistema.
- contenitori: la tassonomia (classificazione) e il motore (aggregazione in contenitori).
- scrittura: il cliente del modello, i prompt, i generatori per formato.
- app: l'interfaccia web, l'accesso, i template.
Funzioni pure dove si decide
Il motore dei contenitori e i calcoli dei consumi sono scritti come funzioni pure: l'orologio entra come parametro, i prezzi e le tariffe sono dati esterni. È anche il motivo per cui i test non hanno bisogno di rete né di stato condiviso.