Vai al contenuto principale

Informazioni

OpenData AI è un orchestratore di agenti che interroga in parallelo i principali cataloghi italiani ed europei di dati aperti e produce una sintesi narrativa con le risorse trovate.

Cosa fa

Una sola domanda in linguaggio naturale viene smistata in parallelo a tre specialisti: un agente CKAN per i portali open data (dati.gov.it e i portali municipali / regionali), un agente SDMX 2.1 per le statistiche ufficiali (ISTAT, e — opzionalmente — Eurostat e OCSE), e un agente di sintesi che fonde le risposte in una narrativa unica. Le risorse geografiche vengono convertite in GeoJSON e disegnate su OpenStreetMap.

Come usarlo

  • Chat — interfaccia conversazionale. Fai una domanda (“popolazione di Milano per età”, “qualità dell'aria nelle città italiane”) e ricevi un testo di sintesi più la lista dei dataset coinvolti, con anteprima del contenuto quando possibile (CSV, JSON, GeoJSON, KML, PDF).
  • Mappa — variante geografica. La query è biasata verso risorse cartografiche (Shapefile, GeoJSON, KML, WMS); i layer compatibili appaiono come overlay accendibili sulla mappa OSM.

Durante l'elaborazione vedi lo stato in tempo reale degli specialisti (“Interrogo ISTAT…”, “CKAN ha risposto”, “Sintesi in corso…”) e gli heartbeat con i secondi trascorsi sulle chiamate lunghe.

Fonti dati

  • CKAN — qualsiasi portale CKAN-compatibile. Default: dati.gov.it. Altri portali supportati: data.gov.uk, data.gov, open.canada.ca, data.gov.au.
  • ISTAT — endpoint SDMX 2.1 di esploradati.istat.it.
  • Eurostat e OCSE — opzionali, da abilitare via configurazione lato backend.
  • OpenStreetMap — geocoding (Nominatim), routing (OSRM) e rendering Leaflet per i layer della pagina mappa.

Per sviluppatori e integratori

OpenData AI espone due superfici programmabili:

REST

Endpoint autenticati tramite Clerk JWT. I principali:

  • POST /datasets/search — sincrono, ritorna {text, resources}.
  • POST /datasets/search/stream — NDJSON con eventi di stato durante l'elaborazione.
  • POST /datasets/classify — classificazione di un dataset rispetto a una tassonomia, con cache 24h.
  • GET /datasets/proxy?url=… — proxy server-side per scaricare risorse dai portali senza problemi CORS.

A2A (Agent-to-Agent)

Il backend pubblica una AgentCard secondo il protocollo A2A. Discovery su /.well-known/agent-card.json (SDK 1.0, oppure /.well-known/agent.json come alias legacy 0.3), JSON-RPC su /a2a/. Tre skill esposte:

  • search_open_data — fan-out multi-fonte come in chat.
  • find_geo_resources — variante geografica.
  • classify_dataset — classificatore di tassonomia.

Vincoli da rispettare

  • messageId è obbligatorio: il SDK valida il payload come pydantic strict.
  • L'header A2A-Version deve coincidere col metodo: 1.0SendMessage, 0.3 message/send. In alternativa puoi omettere l'header: il server lo deduce dal nome del metodo.
  • La skill si seleziona via message.metadata.skill (default search_open_data).

SDK 1.0 — SendMessage

PascalCase, role come enum protobuf:

curl -sX POST http://localhost:18000/a2a/ \
  -H 'Content-Type: application/json' \
  -H 'A2A-Version: 1.0' \
  -d '{
    "jsonrpc":"2.0","id":"1","method":"SendMessage",
    "params":{"message":{
      "messageId":"m-1",
      "role":"ROLE_USER",
      "parts":[{"text":"qualità aria a Milano"}],
      "metadata":{"skill":"search_open_data"}
    }}
  }'

SDK 0.3 (compat) — message/send

slash-case, role lowercase, kind: text esplicito nei parts:

curl -sX POST http://localhost:18000/a2a/ \
  -H 'Content-Type: application/json' \
  -H 'A2A-Version: 0.3' \
  -d '{
    "jsonrpc":"2.0","id":"1","method":"message/send",
    "params":{"message":{
      "messageId":"m-2",
      "role":"user",
      "parts":[{"kind":"text","text":"qualità aria a Milano"}],
      "metadata":{"skill":"search_open_data"}
    }}
  }'

Shape della risposta

result.task.status.state = completed / TASK_STATE_COMPLETED e una lista di artifacts: il primo part è la sintesi narrativa testuale, il secondo è un JSON strutturato {text, resources} con la stessa shape di POST /datasets/search.

In produzione gli endpoint A2A sono autenticati come il resto dell'API: aggiungi Authorization: Bearer <clerk_jwt> all'header.

Stato del progetto

Sperimentale. Il backend, i server MCP e l'interfaccia web sono pubblicati con licenza open su GitHub: agent-engineering-studio/opendata-ai. Le risposte dell'agente dipendono da modelli LLM esterni (Claude o un modello locale via Ollama) e possono contenere errori — verifica sempre i dati consultando la fonte indicata nelle risorse.