Grafo del Parlamento italiano: perché Camera e Senato non parlano la stessa lingua

Risposta diretta: Camera dei Deputati e Senato della Repubblica pubblicano i loro dati come Linked Open Data, ma usano due ontologie diverse e solo parzialmente allineate — OCD per la Camera, OSR per il Senato. Lo stesso concetto (il cognome di un parlamentare, la legislatura, l'inizio di un mandato, un atto legislativo) è modellato con proprietà, formati e perfino namespace differenti. Per costruire un grafo unico e interrogabile da un agente AI non basta «unire i dati»: servono due query builder separati e un layer di normalizzazione. Qui spieghiamo i problemi concreti che abbiamo trovato mappando le relazioni, con esempi di codice.
TL;DR
- Cognome: la Camera usa
foaf:surname, il Senatofoaf:lastName. Stesso dato, proprietà diversa. - Legislatura: la Camera la esprime come URI completo, il Senato come numero intero. Una query che funziona su un endpoint fallisce sull'altro.
- Date di mandato:
ocd:startDate/ocd:endDate(Camera) controosr:inizio/osr:fine(Senato). - Gruppi parlamentari: il Senato riusa le classi della Camera (
ocd:gruppoParlamentare) ma con proprietà OSR. Un ibrido che confonde. - Atti:
ocd:atto(Camera) controosr:Ddl(Senato) — classi e namespace diversi. - Documentazione: l'ontologia del Senato non ha una documentazione ufficiale completa: l'abbiamo ricostruita per reverse engineering dalle query d'esempio.
- Conclusione: le due ontologie sono coordinate ma non identiche. Servono query builder separati per istituzione.
Perché conta: il grafo è solo buono quanto le sue relazioni
Stiamo costruendo Open·Parlamento, un agente che risponde su legge e dati pubblici citando sempre la fonte. Il cuore è un knowledge graph: nodi (parlamentari, atti, gruppi, votazioni) e relazioni tipizzate tra loro (presenta, aderisce, vota, modifica). Un agente AI può dare risposte affidabili solo se quelle relazioni sono pulite e coerenti.
Il problema è che, prima ancora di entrare nel grafo, i dati arrivano da due sorgenti SPARQL che modellano la realtà in modo diverso. Tutto è nato da RepublicMCP, il connettore open source che espone Camera e Senato come strumenti agentici: mappando le due ontologie sono emerse le incompatibilità che descriviamo qui.
Qual è la differenza tra OCD e OSR?
OCD (Ontologia Camera dei Deputati) e OSR (Ontologia Senato della Repubblica) sono i due vocabolari RDF con cui le due Camere pubblicano i propri dati. Condividono l'impostazione generale (FOAF per le persone, classi per mandati, gruppi, atti) ma divergono nei dettagli che contano per chi scrive query.
| Concetto | Camera (OCD) | Senato (OSR) | Compatibile? |
|---|---|---|---|
| Cognome | foaf:surname |
foaf:lastName |
❌ |
| Legislatura | URI (…/repubblica_19) |
intero (19) |
❌ |
| Inizio mandato | ocd:startDate |
osr:inizio |
❌ |
| Fine mandato | ocd:endDate |
osr:fine |
❌ |
| Relazione mandato | ocd:rif_mandatoCamera |
osr:mandato |
❌ |
| Atto legislativo | ocd:atto |
osr:Ddl |
❌ |
| Gruppo parlamentare | ocd:gruppoParlamentare |
ocd:gruppoParlamentare (riuso) |
⚠️ ibrido |
Il caso più insidioso: la legislatura
Sembra un dettaglio, ma rompe le query. La Camera vuole l'URI completo della legislatura; il Senato un numero intero.
# Camera — serve l'URI completo
?mandato ocd:rif_leg <http://dati.camera.it/ocd/legislatura.rdf/repubblica_19> .
# Senato — basta il numero
?mandato osr:legislatura 19 .
Alla Camera il formato breve non funziona: ?mandato ocd:rif_leg 19 non restituisce nulla. È il tipo di incompatibilità silenziosa che non solleva errori — semplicemente ti dà zero risultati, ed è difficile da diagnosticare.
Le date: stesso significato, proprietà e formato diversi
Oltre ai nomi diversi (startDate/endDate vs inizio/fine), la Camera codifica le date come interi in formato YYYYMMDD:
# Camera: confronto come intero, NON come stringa
FILTER(xsd:integer(?data) >= 20240101)
E per trovare i parlamentari in carica servono due pattern SPARQL opposti:
# Camera: esclude chi ha una data di fine
MINUS { ?mandato ocd:endDate ?fine }
# Senato: filtra dove la fine non è valorizzata
OPTIONAL { ?mandato osr:fine ?fine }
FILTER(!bound(?fine))
L'ibrido dei gruppi parlamentari
Il dettaglio più sorprendente: per i gruppi parlamentari il Senato riusa le classi della Camera (ocd:gruppoParlamentare, ocd:adesioneGruppo) — ma le popola con proprietà OSR (osr:gruppo, osr:inizio, osr:fine).
PREFIX osr: <http://dati.senato.it/osr/>
PREFIX ocd: <http://dati.camera.it/ocd/>
?senatore ocd:aderisce ?adesione . # classe Camera
?adesione osr:gruppo ?gruppo ; # proprietà Senato!
osr:inizio ?inizio . # proprietà Senato!
?gruppo a ocd:gruppoParlamentare . # di nuovo classe Camera
Lo stesso vale per i mandati: le classi ocd:mandatoCamera e ocd:mandatoSenato vivono entrambe nel namespace della Camera, anche quella del Senato. Senza una mappa esplicita di queste eccezioni, qualsiasi tentativo di scrivere una query «generica» fallisce.
E la documentazione?
Per la Camera esiste una documentazione di ontologia ragionevolmente completa. Per il Senato no: l'OSR non ha una documentazione ufficiale esplicita paragonabile. Abbiamo dovuto ricostruire il modello per reverse engineering, partendo dalle query d'esempio ufficiali e verificando empiricamente quali proprietà esistono. Alcune entità (interventi, documenti) restano parzialmente documentate.
Come si risolve: normalizzare, non «unire»
La lezione è netta: le due ontologie sono coordinate ma non identiche, quindi non puoi trattarle con lo stesso codice. La strategia che funziona:
- Query builder separati per istituzione. Ogni Camera ha il suo modulo che conosce i suoi nomi di proprietà, formati e pattern.
- Configurazione centralizzata delle differenze. Cognome, legislatura, date e operatori «in carica» vivono in una mappa per-istituzione, non sparsi nel codice.
- Layer di normalizzazione verso il grafo. Prima di entrare nel knowledge graph, i dati vengono mappati su un modello unico con relazioni tipizzate e provenienza — così l'agente AI interroga un grafo coerente, non due dialetti SPARQL.
È esattamente ciò che fa Open·Parlamento: trasformare fonti che, da sole, non sono interrogabili in modo affidabile in un grafo unico, citando sempre l'originale.
FAQ
Cos'è un'ontologia nei dati pubblici?
È un vocabolario formale (in RDF) che definisce le entità di un dominio e le relazioni tra loro: per il Parlamento, classi come «parlamentare», «mandato», «gruppo», «atto» e proprietà come «aderisce a» o «presenta». Permette di pubblicare dati interrogabili via SPARQL invece che in semplici tabelle.
Perché Camera e Senato non hanno un'ontologia unica?
Sono istituzioni autonome che hanno digitalizzato i propri dati in tempi e modi diversi. Il risultato sono due ontologie (OCD e OSR) che si ispirano a standard comuni (FOAF) e in parte si riusano a vicenda, ma divergono nei dettagli pratici di proprietà, formati e namespace.
Si possono comunque unire in un unico grafo?
Sì, ma serve un layer di normalizzazione: query builder separati per leggere ciascuna fonte e una mappatura verso un modello unico prima di scrivere nel knowledge graph. È quello che abbiamo costruito per Open·Parlamento.
Costruiamo agenti AI che rispondono sui dati reali — citando la fonte, non inventandola. Vedi come funziona Open·Parlamento e i progetti open source, oppure parla con noi del tuo knowledge graph.
Articoli correlati
- Come ho messo Costituzione e codici italiani in un knowledge graphCostituzione e sette codici (penale, civile, procedura, strada, consumo, assicurazioni): ~6.445 articoli ingeriti uno per uno, con identificatori ELI e 86.672 relazioni di modifica autoritative da Normattiva. Ecco metodo, numeri e limiti reali.
- Ho scaricato il diritto UE e l’ho messo nel grafo della legge italianaDal bulk dump dell’Ufficio Pubblicazioni UE (56.292 atti) ho estratto e collegato migliaia di norme europee — regolamenti, direttive, decisioni — al grafo della legge italiana, con CELEX ed ELI. Ecco metodo, numeri reali e cosa manca ancora.
- Open data in Italia: aperti sulla carta, inusabili nella praticaI dati pubblici italiani sono «aperti» per legge ma spesso tenuti malissimo: portali datati, endpoint che rispondono vuoti, certificati rotti, link spuntati, progetti civici abbandonati. Un’analisi documentata, fonte per fonte, da chi li ha dovuti integrare davvero.