-----------------------------------

Acquista i software ArcGIS tramite Studio A&T srl, rivenditore autorizzato dei prodotti Esri.

I migliori software GIS, il miglior supporto tecnico!

I migliori software GIS, il miglior supporto tecnico!
Azienda operante nel settore GIS dal 2001, specializzata nell’utilizzo della tecnologia ArcGIS e aderente ai programmi Esri Italia Business Network ed Esri Partner Network

-----------------------------------



Visualizzazione post con etichetta arcgis. Mostra tutti i post
Visualizzazione post con etichetta arcgis. Mostra tutti i post

venerdì 9 ottobre 2026

Agentic Planning vs Deterministic Execution: architetture AI affidabili con Azure Durable Functions, DAG e GeoAgent

Quando l'intelligenza pianifica, ma non controlla l'esecuzione

Per molto tempo abbiamo progettato gli agenti AI secondo un modello relativamente semplice: un Large Language Model interpreta una richiesta, seleziona uno strumento, ne osserva il risultato e decide cosa fare successivamente.

Il modello funziona bene per task brevi. Diventa però progressivamente meno efficiente quando deve coordinare decine di strumenti, elaborare grandi volumi di dati, gestire retry, attendere eventi esterni e garantire che operazioni già completate non vengano ripetute accidentalmente.

Con Dynamic Workflows for Azure Functions Hosted Skills, annunciato da Microsoft l'8 ottobre 2026, emerge un'architettura differente: l'LLM genera un piano strutturato, mentre un runtime durevole e deterministico si occupa della sua esecuzione.

La distinzione è fondamentale. Il modello non diventa improvvisamente affidabile perché produce JSON anziché testo. È il sistema che interpreta quel JSON a dover imporre vincoli, autorizzazioni, dipendenze e garanzie operative.

Principio architetturale: un LLM può proporre una sequenza di azioni, ma non dovrebbe essere l'autorità finale che decide se quelle azioni sono consentite, sicure o già state eseguite.

1. Il problema del reasoning loop tradizionale

Consideriamo un agente che deve analizzare un evento meteorologico, interrogare servizi GIS, produrre una mappa di rischio e inviare una notifica.

User / Event
    |
    v
   LLM
    |
    +-- Tool: read rainfall
    |       |
    |       v
    |      LLM
    |
    +-- Tool: read terrain
    |       |
    |       v
    |      LLM
    |
    +-- Tool: run spatial analysis
    |       |
    |       v
    |      LLM
    |
    +-- Tool: generate map
    |       |
    |       v
    |      LLM
    |
    +-- Tool: publish result
            |
            v
           LLM

Ogni operazione comporta un nuovo passaggio attraverso il modello. Se gli strumenti restituiscono dati voluminosi, il contesto si riempie di risultati intermedi che il modello potrebbe non aver bisogno di interpretare direttamente.

Il problema non è soltanto economico. È anche architetturale:

  • Latenza: le chiamate al modello possono serializzare operazioni indipendenti.
  • Context pollution: risultati intermedi e log possono occupare una parte significativa della context window.
  • Recovery: un crash durante un'operazione lunga richiede meccanismi di ripresa espliciti.
  • Retry: ripetere un tool può duplicare effetti esterni.
  • Audit: ricostruire perché un'azione sia stata eseguita può diventare difficile.
  • Security: il contenuto restituito da un tool può influenzare impropriamente le decisioni successive dell'agente.

Un reasoning loop è appropriato quando ogni risultato richiede una nuova decisione semantica. Non è necessariamente la scelta migliore quando le operazioni sono note, verificabili e largamente indipendenti.

2. L'architettura emergente: Plan, Validate, Execute, Verify

La nuova separazione delle responsabilità può essere rappresentata così:

                 USER / EVENT
                      |
                      v
              +---------------+
              |  LLM PLANNER  |
              +---------------+
                      |
                 Proposed DAG
                      |
                      v
              +---------------+
              | DAG VALIDATOR |
              | Policy Engine |
              +---------------+
                      |
                Approved Plan
                      |
                      v
              +---------------+
              | DURABLE ENGINE|
              +---------------+
                /     |     \
               v      v      v
           Tool A   Tool B   Tool C
               \      |      /
                \     |     /
                 v    v    v
                AGGREGATION
                      |
                      v
                VERIFICATION
                      |
                      v
                FINAL RESULT

Il passaggio più importante è quello fra planner e runtime.

Il piano generato dal modello deve essere considerato un input non attendibile, anche quando il modello appartiene a un provider affidabile. La validazione non può essere una semplice verifica della sintassi JSON: deve includere controlli strutturali, semantici, autorizzativi e di consumo delle risorse.

Microsoft applica questo paradigma nella preview Dynamic Workflows di Azure Functions Hosted Skills. Il runtime utilizza Durable Functions per eseguire il piano senza riportare continuamente i risultati intermedi nel reasoning loop dell'LLM.

È importante distinguere la funzionalità specifica Microsoft, attualmente in preview e basata su tool Python, da un'implementazione equivalente realizzata autonomamente in C# e .NET con Durable Functions.

3. Il DAG come contratto eseguibile

Un Directed Acyclic Graph è un grafo diretto senza cicli. Ogni nodo rappresenta un'operazione; ogni arco rappresenta una dipendenza.

Consideriamo un piano per valutare il rischio associato a precipitazioni intense:

         ReadRainfall
              |
              +----------------+
              |                |
              v                v
        LoadTerrain      LoadAssets
              |                |
              v                |
        ComputeRunoff          |
              |                |
              +--------+-------+
                       |
                       v
                IntersectRisk
                       |
                       v
                 GenerateMap
                       |
                       v
                PublishResult

Il DAG esplicita immediatamente il parallelismo possibile: LoadTerrain e LoadAssets possono partire quando ReadRainfall è completato, se le rispettive operazioni non dipendono l'una dall'altra.

In un sistema reale conviene spingersi oltre, rendendo indipendenti tutte le acquisizioni che non richiedono il risultato delle precipitazioni.

Un contratto JSON minimale

{
  "schemaVersion": "1.0",
  "workflowId": "rainfall-risk-20261009",
  "nodes": [
    {
      "id": "rainfall",
      "tool": "gis.readRainfall",
      "dependsOn": []
    },
    {
      "id": "terrain",
      "tool": "gis.loadTerrain",
      "dependsOn": []
    },
    {
      "id": "assets",
      "tool": "gis.loadAssets",
      "dependsOn": []
    },
    {
      "id": "risk",
      "tool": "gis.computeRisk",
      "dependsOn": [
        "rainfall",
        "terrain",
        "assets"
      ]
    },
    {
      "id": "map",
      "tool": "gis.generateMap",
      "dependsOn": ["risk"]
    }
  ]
}

Questo JSON è una rappresentazione concettuale del nostro contratto applicativo, non lo schema ufficiale della preview Microsoft.

Un contratto production-grade dovrebbe inoltre includere versione del piano, input tipizzati, riferimenti agli output, classificazione dei tool, limiti di esecuzione e policy di autorizzazione. Gli argomenti non devono poter contenere endpoint arbitrari o istruzioni eseguibili non previste.

4. DAG validation: il vero confine di sicurezza

La validazione di un piano prodotto da un LLM deve essere eseguita prima che il workflow venga avviato.

I controlli minimi comprendono:

  • Identificatori univoci dei nodi.
  • Assenza di dipendenze inesistenti.
  • Assenza di cicli.
  • Limiti su numero di nodi, profondità e fan-out.
  • Tool presenti in una allowlist server-side.
  • Compatibilità tra input e output dei tool.
  • Autorizzazioni coerenti con utente, tenant e risorsa.
  • Limiti su costo, durata e concorrenza.
  • Approvazioni esplicite per operazioni con effetti esterni sensibili.

Validazione strutturale in C#

public sealed record WorkflowNode(
    string Id,
    string Tool,
    string[] DependsOn);

public sealed record WorkflowPlan(
    string SchemaVersion,
    WorkflowNode[] Nodes);

public static class DagValidator
{
    private static readonly HashSet<string> AllowedTools =
        new(StringComparer.Ordinal)
        {
            "gis.readRainfall",
            "gis.loadTerrain",
            "gis.loadAssets",
            "gis.computeRisk",
            "gis.generateMap"
        };

    public static void Validate(WorkflowPlan plan)
    {
        ArgumentNullException.ThrowIfNull(plan);

        if (plan.SchemaVersion != "1.0")
            throw new InvalidOperationException(
                "Unsupported schema version.");

        if (plan.Nodes is null ||
            plan.Nodes.Length is < 1 or > 50)
            throw new InvalidOperationException(
                "Invalid workflow size.");

        var nodes = new Dictionary<string, WorkflowNode>(
            StringComparer.Ordinal);

        foreach (var node in plan.Nodes)
        {
            if (string.IsNullOrWhiteSpace(node.Id) ||
                !nodes.TryAdd(node.Id, node))
                throw new InvalidOperationException(
                    "Invalid or duplicate node ID.");

            if (!AllowedTools.Contains(node.Tool))
                throw new InvalidOperationException(
                    $"Tool not allowed: {node.Tool}");
        }

        var indegree = nodes.Keys.ToDictionary(
            id => id,
            _ => 0,
            StringComparer.Ordinal);

        var children = nodes.Keys.ToDictionary(
            id => id,
            _ => new List<string>(),
            StringComparer.Ordinal);

        foreach (var node in nodes.Values)
        {
            var dependencies = node.DependsOn ??
                throw new InvalidOperationException(
                    "Dependencies cannot be null.");

            foreach (var dependency in dependencies.Distinct())
            {
                if (!nodes.ContainsKey(dependency))
                    throw new InvalidOperationException(
                        $"Unknown dependency: {dependency}");

                indegree[node.Id]++;
                children[dependency].Add(node.Id);
            }
        }

        var ready = new Queue<string>(
            indegree
                .Where(x => x.Value == 0)
                .Select(x => x.Key));

        var visited = 0;

        while (ready.Count > 0)
        {
            var id = ready.Dequeue();
            visited++;

            foreach (var child in children[id])
            {
                if (--indegree[child] == 0)
                    ready.Enqueue(child);
            }
        }

        if (visited != nodes.Count)
            throw new InvalidOperationException(
                "Workflow contains a cycle.");
    }
}

L'algoritmo utilizza una variante del topological sorting di Kahn. La complessità è O(V + E), dove V rappresenta i nodi ed E le dipendenze.

Questo codice valida soltanto la struttura e una allowlist di base. Non rappresenta un security validator completo. In produzione servono anche controllo degli argomenti, autorizzazione contestuale, compatibilità dei tipi, quote e validazione della provenienza del piano.

Un ulteriore accorgimento consiste nel calcolare un hash canonico del piano validato, registrando insieme ad esso identità del richiedente, versione delle policy e identificativo dell'esecuzione. Il runtime dovrebbe eseguire esattamente quel piano immutabile, evitando modifiche successive alla validazione.

5. Durable Functions: perché l'orchestrazione deve essere deterministica

Azure Durable Functions utilizza una forma di event sourcing per ricostruire lo stato delle orchestrazioni.

Quando un'orchestrazione riprende dopo un evento, il runtime può rieseguire il codice dell'orchestratore dall'inizio, recuperando dalla history i risultati delle attività già completate.

Questo meccanismo prende il nome di replay.

Execution history
       |
       +-- ActivityScheduled(A)
       +-- ActivityCompleted(A)
       +-- ActivityScheduled(B)
       +-- ActivityCompleted(B)
       |
       v
  Orchestrator Replay
       |
       +-- A: result from history
       +-- B: result from history
       +-- C: schedule new activity

Il codice dell'orchestratore deve quindi essere deterministico. Non dovrebbe effettuare direttamente chiamate HTTP, interrogazioni SQL, operazioni GIS o letture dell'orologio di sistema.

Le operazioni con effetti esterni appartengono alle Activity Functions.

Esempio di orchestrazione C# con .NET isolated worker

using Microsoft.Azure.Functions.Worker;
using Microsoft.DurableTask;

public static class GeoWorkflow
{
    [Function(nameof(RunGeoWorkflow))]
    public static async Task<string> RunGeoWorkflow(
        [OrchestrationTrigger]
        TaskOrchestrationContext context)
    {
        var rainfallTask =
            context.CallActivityAsync<string>(
                "ReadRainfall");

        var terrainTask =
            context.CallActivityAsync<string>(
                "LoadTerrain");

        var assetsTask =
            context.CallActivityAsync<string>(
                "LoadAssets");

        await Task.WhenAll(
            rainfallTask,
            terrainTask,
            assetsTask);

        var input = new RiskInput(
            rainfallTask.Result,
            terrainTask.Result,
            assetsTask.Result);

        var risk =
            await context.CallActivityAsync<string>(
                "ComputeRisk",
                input);

        return await context.CallActivityAsync<string>(
            "GenerateMap",
            risk);
    }
}

public sealed record RiskInput(
    string RainfallUri,
    string TerrainUri,
    string AssetsUri);

Questo è un esempio di orchestrazione statica. Non è ancora un interprete dinamico di DAG: serve a mostrare il modello Durable Functions e il parallelismo fan-out/fan-in.

Le tre Activity iniziali restituiscono riferimenti a dati persistenti, non interi raster o dataset serializzati nella history dell'orchestrazione.

Per interpretare DAG generati dinamicamente è preferibile utilizzare un executor generico che riceva un piano validato, identifichi i nodi pronti e li programmi attraverso un catalogo di Activity consentite.

6. Un DAG executor dinamico: la differenza fra scheduling e reasoning

Il runtime non deve chiedere all'LLM quale nodo eseguire dopo ogni completamento. Deve applicare una regola deterministica:

Ready(node) =
    AllDependenciesCompleted(node)
    AND PolicyAllows(node)
    AND ResourcesAvailable(node)

Un possibile algoritmo è:

completed = {}
pending = allNodes

while pending is not empty:

    ready = nodes where:
        every dependency is completed

    if ready is empty:
        fail invalid workflow

    execute ready nodes concurrently
    await completion

    persist outputs
    mark nodes completed
    remove nodes from pending

Questo pseudocodice illustra l'idea, ma in produzione richiede alcuni raffinamenti importanti.

Prima di tutto, i nodi devono essere ordinati stabilmente per evitare divergenze durante il replay. Inoltre la concorrenza deve essere limitata, gli errori devono essere gestiti per nodo e il risultato di ogni Activity deve essere registrato con un identificatore stabile.

Un semplice Task.WhenAll() su tutti i nodi pronti può produrre fan-out eccessivo. In un workflow geografico, cinquanta richieste simultanee a un servizio ArcGIS possono saturare il servizio, esaurire risorse o produrre throttling.

È quindi utile distinguere tre livelli di concorrenza:

  • Workflow concurrency: quante orchestrazioni possono essere attive.
  • Node concurrency: quanti nodi dello stesso DAG possono essere eseguiti contemporaneamente.
  • Resource concurrency: quante operazioni possono utilizzare uno specifico servizio, database o pool di worker.

Il terzo livello è particolarmente importante: limitare il fan-out di una singola orchestrazione non impedisce a cento orchestrazioni concorrenti di sovraccaricare lo stesso servizio.

7. Idempotenza: at-least-once non significa exactly-once

Uno dei problemi più pericolosi dei workflow distribuiti è la ripetizione delle operazioni.

Durable Functions può rieseguire un'Activity quando si verifica un errore o quando il completamento dell'attività non è stato registrato correttamente.

Supponiamo che un'Activity esegua:

POST /arcgis/rest/services/Analysis/GPServer/SubmitJob

Il servizio remoto riceve la richiesta e avvia il job. Subito dopo, il worker Azure Functions si interrompe prima di registrare il risultato.

Al riavvio, il runtime può ripetere l'Activity.

Il risultato potrebbe essere:

First attempt  --> ArcGIS Job 1001
Worker crash
Second attempt --> ArcGIS Job 1002

Il sistema ha prodotto due elaborazioni per una sola richiesta logica.

Il retry è quindi corretto dal punto di vista dell'infrastruttura, ma non necessariamente dal punto di vista del business.

La soluzione: Operation Ledger e Idempotency Key

Ogni operazione con effetti esterni dovrebbe avere una chiave stabile:

IdempotencyKey =
    WorkflowId + ":" + NodeId

Una tabella SQL può mantenere lo stato dell'operazione:

CREATE TABLE WorkflowOperations
(
    OperationKey NVARCHAR(200) NOT NULL
        PRIMARY KEY,

    State NVARCHAR(30) NOT NULL,

    ExternalJobId NVARCHAR(200) NULL,

    ResultUri NVARCHAR(2000) NULL,

    UpdatedAt DATETIMEOFFSET NOT NULL
);

Il pattern operativo diventa:

1. Reserve OperationKey atomically
2. Check previous execution state
3. Submit or reconcile external job
4. Persist ExternalJobId
5. Poll external job
6. Persist ResultUri
7. Mark operation Completed

È fondamentale riconoscere che il ledger, da solo, non garantisce exactly-once.

Esiste infatti una finestra critica fra l'invio della richiesta al sistema esterno e il salvataggio dell'ExternalJobId. Se il processo si interrompe in quel punto, il database locale non sa se l'operazione remota sia stata accettata.

Per eliminare questa ambiguità serve un meccanismo di riconciliazione: una chiave di idempotenza supportata dal servizio remoto, un identificatore applicativo ricercabile oppure un adapter che possa individuare un job già creato.

Se l'API esterna non supporta alcuna forma di deduplicazione o riconciliazione, la garanzia di exactly-once non può essere ottenuta semplicemente aggiungendo retry e una tabella SQL.

8. Retry, timeout, circuit breaker e compensazione

Un workflow distribuito affidabile deve distinguere gli errori transitori da quelli permanenti.

Un HTTP 429 o 503 può giustificare un retry con backoff. Un errore di autorizzazione, un input GIS non valido o un piano che viola una policy non dovrebbe invece essere ripetuto automaticamente.

Per gli errori transitori è possibile utilizzare le retry policy delle Activity Durable Functions.

Per operazioni che modificano sistemi esterni è inoltre utile introdurre una logica di compensazione.

Consideriamo:

CreateAnalysisJob
        |
        v
PublishFeatureLayer
        |
        v
UpdateWebMap
        |
        v
NotifyUsers

Se UpdateWebMap fallisce dopo la pubblicazione del layer, il sistema potrebbe dover eliminare il layer temporaneo o ripristinare la configurazione precedente.

Questo modello è vicino al pattern Saga: ogni azione può avere un'azione compensativa, ma la compensazione non equivale necessariamente a un rollback transazionale perfetto.

Per un workflow geografico occorre inoltre distinguere:

  • Risultati temporanei, eliminabili automaticamente.
  • Risultati pubblicati, che richiedono autorizzazioni specifiche per la rimozione.
  • Modifiche a dati autorevoli, che possono richiedere approvazione umana.
  • Notifiche già inviate, che non possono essere semplicemente annullate.

La progettazione delle compensazioni deve essere parte del catalogo dei tool, non una decisione improvvisata dall'LLM dopo un errore.

9. Isolamento dei sub-agent: un agente specializzato non è un processo fidato

Un workflow può delegare attività a sub-agent specializzati.

Per esempio:

GeoCoordinator
      |
      +-- RainfallAgent
      |
      +-- TerrainAgent
      |
      +-- InfrastructureAgent
      |
      +-- RiskVerificationAgent

Il vantaggio è la specializzazione. Il rischio è l'ampliamento della superficie di attacco.

Un sub-agent non dovrebbe ereditare automaticamente l'intera cronologia del coordinatore, tutte le sue credenziali o la capacità di invocare qualsiasi tool.

Nella preview Microsoft Dynamic Workflows, le invocazioni dei sub-agent utilizzano sessioni isolate e stateless, con istruzioni, modelli, strumenti e timeout propri. Non ricevono automaticamente la conversation history o la sandbox del coordinatore.

Questo è un buon punto di partenza, ma non sostituisce l'isolamento infrastrutturale.

Capability-based execution

Ogni sub-agent dovrebbe ricevere soltanto le capability necessarie.

RainfallAgent
    READ rainfall observations
    READ station metadata
    NO write access
    NO publishing permissions

TerrainAgent
    READ elevation datasets
    EXECUTE terrain analysis
    NO access to notifications

PublisherAgent
    READ approved outputs
    PUBLISH to approved folders
    NO arbitrary service access

Il controllo deve essere imposto dal gateway dei tool e dalle identità utilizzate verso i servizi, non soltanto da istruzioni testuali come "non pubblicare dati".

In Azure, Managed Identity, Azure RBAC, Key Vault e isolamento di rete possono contribuire a questo modello, purché le identità siano effettivamente separate secondo i confini di autorizzazione richiesti.

10. Context engineering: la memoria dell'agente non è lo stato del workflow

Un altro errore frequente consiste nell'utilizzare la conversation history come archivio dello stato operativo.

La memoria del modello è utile per mantenere obiettivi, vincoli e informazioni semantiche. Non dovrebbe essere la fonte autorevole per determinare se un job è completato, quale output è stato pubblicato o quali autorizzazioni sono state concesse.

Propongo di separare quattro livelli:

+----------------------------------+
| Semantic Context                 |
| Goal, assumptions, constraints   |
+----------------------------------+
| Execution State                  |
| Node status, retries, timestamps |
+----------------------------------+
| Artifact Store                   |
| Raster, JSON, logs, results      |
+----------------------------------+
| Audit & Authorization            |
| Identity, approvals, provenance  |
+----------------------------------+

Il modello dovrebbe ricevere soltanto il contesto necessario per decidere il piano e, alla fine, interpretare i risultati.

Gli output voluminosi dovrebbero essere conservati in storage e rappresentati attraverso riferimenti immutabili o versionati, accompagnati da metadata come checksum, schema, sistema di riferimento e provenienza.

Questo evita che raster, grandi FeatureSet, log o migliaia di record GIS vengano inseriti nella context window senza alcun beneficio.

11. GeoAgent: un laboratorio architetturale con ArcGIS e Azure

Immaginiamo di voler realizzare un agente che risponda alla richiesta:

Analizza le precipitazioni delle ultime 24 ore, individua le aree potenzialmente critiche e produci una mappa delle infrastrutture esposte.

Il modello non dovrebbe generare direttamente una mappa di rischio basandosi soltanto sul testo. Deve selezionare strumenti GIS deterministici, ciascuno con input, output e limiti ben definiti.

Pipeline proposta

Weather / Rainfall API
          |
          v
   Observation Validation
          |
          v
   Spatial Interpolation
      IDW / Spline
          |
          v
   Rainfall Raster
          |
          +------------------+
          |                  |
          v                  v
    Terrain Data       Asset Inventory
          |                  |
          +---------+--------+
                    |
                    v
             Spatial Analysis
                    |
                    v
             Exposure Overlay
                    |
                    v
             Result Validation
                    |
                    v
             ArcGIS Publishing
                    |
                    v
               WebMap / App

Una possibile implementazione utilizza:

  • C#/.NET: API di ingresso, validazione, orchestrazione e integrazione enterprise.
  • Azure Durable Functions: scheduling durevole, retry e recovery.
  • Azure SQL: operation ledger, metadata, policy e audit applicativo.
  • Azure Blob Storage: artifact store per input e output voluminosi.
  • ArcGIS Enterprise: geoprocessing, analisi raster, feature service e pubblicazione.
  • LLM: interpretazione della richiesta, costruzione del piano e sintesi finale.

È importante non confondere l'interpolazione delle precipitazioni con una simulazione idrologica o idraulica completa.

IDW e Spline producono superfici interpolate a partire dalle osservazioni. Per modellare runoff, propagazione delle piene o dinamiche fisiche occorrono modelli e dati aggiuntivi, opportunamente calibrati e validati.

Inoltre l'eventuale esecuzione di Spatial Analyst richiede di verificare disponibilità delle capability e licenze nella versione e nell'ambiente ArcGIS effettivamente distribuiti.

12. Un adapter ArcGIS robusto deve conoscere il ciclo di vita dei job

Un adapter per un servizio ArcGIS Geoprocessing asincrono non dovrebbe limitarsi a invocare SubmitJob e attendere indefinitamente.

Deve modellare esplicitamente gli stati del job remoto:

NotSubmitted
      |
      v
  Submitted
      |
      v
   Executing
      |
      +----> Succeeded
      |
      +----> Failed
      |
      +----> Cancelled
      |
      +----> TimedOut

La gestione deve distinguere lo stato del job ArcGIS dallo stato dell'Activity Azure Functions.

Un job ArcGIS può continuare a essere eseguito anche quando il worker che lo ha avviato non è più disponibile. Per questo è preferibile salvare l'identificatore del job e utilizzare un meccanismo di polling o riconciliazione durevole.

Per processi molto lunghi, il pattern può diventare:

Submit GP Job
     |
     v
Persist Job ID
     |
     v
Durable Timer
     |
     v
Check GP Status
     |
     +-- Running --> Durable Timer
     |
     +-- Success --> Fetch Results
     |
     +-- Failure --> Error Policy

Il polling non dovrebbe occupare un thread o una Function instance per tutta la durata del job.

Per i servizi GIS occorre inoltre definire timeout, frequenza di polling, politiche di cancellazione e comportamento in caso di perdita temporanea della connettività.

13. Observability: misurare il workflow, non soltanto i token

Un sistema agentico enterprise dovrebbe essere osservabile su più livelli.

Il livello LLM deve registrare modello, versione, token, latenza, versione del prompt e identificativo del piano generato.

Il livello workflow deve registrare durata dei nodi, retry, timeout, dipendenze, errori e stato complessivo.

Il livello GIS deve registrare servizio utilizzato, identificativo del job, tempi di elaborazione, parametri analitici, dataset e riferimenti agli output.

Una struttura di correlazione può essere:

TraceId
   |
   +-- PlanningSpan
   |
   +-- ValidationSpan
   |
   +-- WorkflowInstanceId
          |
          +-- Node: rainfall
          +-- Node: terrain
          +-- Node: risk
          +-- Node: publishing
                    |
                    +-- ArcGIS JobId

OpenTelemetry e Application Insights possono contribuire a questa osservabilità, ma occorre propagare esplicitamente gli identificatori di correlazione fra sistemi.

Il replay delle orchestrazioni richiede inoltre attenzione: log prodotti ingenuamente durante il replay possono essere duplicati. Dove disponibile, conviene utilizzare il replay-safe logger fornito dal runtime Durable Functions.

Metriche che misurerei

  • Planning latency e planning token cost.
  • Percentuale di piani rifiutati dal validator.
  • Numero di nodi e profondità media del DAG.
  • Parallelismo effettivo rispetto a quello teorico.
  • Retry per tool e per servizio esterno.
  • Numero di job remoti riconciliati dopo failure.
  • Workflow completion rate.
  • Tempo medio e percentile P95/P99 per nodo.
  • Costo per workflow completato.
  • Accuratezza e validità dei risultati GIS.

Una riduzione dei token non rappresenta automaticamente un miglioramento del sistema se aumentano i workflow falliti o diminuisce la qualità del risultato.

14. Sicurezza: il piano generato dall'LLM è una superficie di attacco

Un piano apparentemente valido può essere pericoloso anche senza contenere codice eseguibile.

Consideriamo alcuni scenari:

  • Tool escalation: il modello seleziona un tool di pubblicazione quando l'utente ha richiesto soltanto un'analisi.
  • Data exfiltration: un parametro contiene un endpoint esterno non autorizzato.
  • Resource exhaustion: il piano richiede centinaia di analisi raster molto costose.
  • Cross-tenant access: un nodo tenta di utilizzare dati appartenenti a un altro tenant.
  • Prompt injection: un dataset o documento esterno influenza il planner inducendolo a inserire operazioni non richieste.
  • Approval spoofing: un output intermedio dichiara falsamente che l'utente ha autorizzato un'azione.

Le contromisure devono essere applicate fuori dal modello:

Untrusted User / Tool Data
             |
             v
        LLM Planner
             |
             v
        Schema Validator
             |
             v
        Policy Decision
             |
             v
       Approval Gateway
             |
             v
        Tool Dispatcher
             |
             v
     Authorized Execution

Un'approvazione dovrebbe essere un evento autenticato e correlato a una specifica operazione, non una proprietà booleana modificabile dal modello.

Il tool dispatcher dovrebbe risolvere le credenziali dal contesto server-side, evitando che il piano possa scegliere liberamente identità, segreti o endpoint.

15. Benchmark Microsoft: cosa dimostrano realmente i numeri

Nel proprio annuncio, Microsoft ha confrontato un normale reasoning loop con Dynamic Workflows su un benchmark sintetico di analisi di dieci servizi.

I risultati riportati sono:

MetricaReasoning loopDynamic Workflow
Token utilizzati99.0976.781
Latenza247,1 s12,7 s
Riduzione token—93,1%
Riduzione latenza—95,1%

I numeri sono notevoli, ma vanno interpretati correttamente. Il benchmark riguarda un task specifico, strutturato e adatto alla parallelizzazione. Non significa che qualsiasi workflow agentico possa ottenere automaticamente riduzioni equivalenti.

Il vantaggio dipende soprattutto da tre fattori:

  • Le attività indipendenti possono essere eseguite in parallelo.
  • Gli output intermedi non devono attraversare continuamente il modello.
  • Il numero di round-trip LLM viene drasticamente ridotto.

Un workflow che richiede decisioni semantiche dopo ogni passaggio potrebbe invece beneficiare meno di questo modello.

16. Il trade-off: meno autonomia durante l'esecuzione, più affidabilità

Separare pianificazione ed esecuzione introduce anche un limite.

Un DAG statico non può adattarsi arbitrariamente a qualsiasi informazione inattesa. Se un risultato intermedio richiede una nuova strategia, il workflow deve prevedere una decisione condizionale oppure una fase esplicita di replanning.

Per questo considero particolarmente interessante un modello ibrido:

LLM Planning
      |
      v
Validated DAG
      |
      v
Deterministic Execution
      |
      +-- Expected Result
      |       |
      |       v
      |   Continue DAG
      |
      +-- Unexpected Result
              |
              v
        Controlled Replan
              |
              v
        New Validation
              |
              v
        Resume Execution

Il replanning deve essere limitato e tracciato. Ogni nuovo piano deve essere nuovamente validato, e il sistema deve conoscere quali operazioni precedenti siano già state completate.

Non dovrebbe essere possibile aggirare un rifiuto del validator semplicemente generando ripetutamente nuovi piani.

17. Verso una nuova architettura: il GeoAgent come compilatore di workflow geografici

La prospettiva più interessante è considerare l'LLM non come il motore di esecuzione, ma come un compilatore semantico.

L'utente esprime un obiettivo in linguaggio naturale. Il modello lo traduce in una rappresentazione intermedia tipizzata. Il sistema valida questa rappresentazione, la ottimizza e la esegue utilizzando strumenti GIS affidabili.

Natural Language Goal
          |
          v
      LLM Planner
          |
          v
    GeoWorkflow IR
          |
          v
   Semantic Validation
          |
          v
   Optimization Passes
          |
          v
    Execution Plan
          |
          v
 Durable GIS Runtime
          |
          v
 Verified GeoArtifacts

Questa analogia con un compilatore è particolarmente potente.

La rappresentazione intermedia potrebbe contenere informazioni tipizzate come:

  • Sistema di riferimento spaziale.
  • Tipo geometrico.
  • Risoluzione raster.
  • Unità di misura.
  • Estensione geografica.
  • Dipendenze tra dataset.
  • Requisiti di licenza e capability GIS.
  • Classificazione dei dati.
  • Stima del costo computazionale.

Il validator potrebbe rifiutare un'operazione che combina raster con sistemi di riferimento incompatibili, utilizza unità di misura non coerenti oppure richiede capability non disponibili.

Un optimizer potrebbe invece individuare acquisizioni parallelizzabili, eliminare elaborazioni duplicate, riutilizzare risultati già presenti nello storage o selezionare differenti backend di elaborazione.

È importante distinguere ciò che è già disponibile da ciò che rappresenta una possibile evoluzione progettuale: questa GeoWorkflow IR è una proposta architetturale, non un prodotto Esri o Microsoft attualmente disponibile con tale nome.

18. Oltre il DAG: workflow gerarchici, feedback loop e sistemi autonomi

Il DAG è ideale per rappresentare dipendenze acicliche. Non descrive però naturalmente sistemi che devono reagire indefinitamente a nuovi eventi.

Un sistema di monitoraggio territoriale continuo può richiedere cicli di osservazione, analisi, verifica e aggiornamento.

La soluzione non è introdurre cicli arbitrari dentro un DAG non controllato, ma comporre workflow durevoli di durata limitata attraverso eventi, sub-orchestrazioni e nuove istanze.

Observation Event
       |
       v
Analysis Workflow
       |
       v
Verification
       |
       +-- No Change --> Archive
       |
       +-- Relevant Change
                  |
                  v
             New Event
                  |
                  v
          Follow-up Workflow

In questo modo ogni esecuzione rimane identificabile, verificabile e soggetta a quote, mentre il sistema complessivo può funzionare continuamente.

È una distinzione importante per il futuro degli agenti persistenti: persistenza della responsabilità non significa esecuzione illimitata di un singolo processo o di una singola conversazione LLM.

19. Checklist di produzione

Prima di portare in produzione un'architettura agentic workflow, verificherei almeno questi aspetti:

  • Il piano viene validato prima dell'esecuzione.
  • Ogni tool è registrato in un catalogo server-side.
  • Gli input sono tipizzati e soggetti a limiti.
  • Le autorizzazioni vengono verificate sul backend.
  • Le operazioni con effetti esterni hanno idempotency key e riconciliazione.
  • Gli orchestratori rispettano i vincoli di determinismo del replay.
  • I job remoti possono essere recuperati dopo un crash.
  • Gli output voluminosi sono esternalizzati dalla history.
  • I sub-agent hanno capability limitate.
  • Le approvazioni sono eventi autenticati.
  • Il parallelismo è limitato anche a livello di risorsa condivisa.
  • Le modifiche ai workflow già attivi sono gestite con versioning.
  • Gli audit log sono protetti da modifiche non autorizzate.
  • Le metriche misurano correttezza, costo e affidabilità, non soltanto latenza.
  • Esistono test di fault injection per crash, timeout, duplicazioni e retry.

20. Conclusione: l'LLM non deve diventare il transaction manager

Dynamic Workflows rappresenta un passaggio significativo nell'evoluzione delle architetture agentiche.

Non perché renda i modelli più intelligenti, ma perché riconosce esplicitamente che intelligenza, autorizzazione ed esecuzione affidabile sono problemi differenti.

Il modello interpreta obiettivi ambigui e propone piani. Il validator controlla che quei piani siano ammissibili. Il workflow engine esegue le attività rispettando dipendenze, retry e checkpoint. I tool applicano le operazioni reali attraverso API e identità autorizzate.

Nel mondo GIS questa separazione è ancora più importante: un LLM può scegliere quali analisi geospaziali effettuare, ma la correttezza geometrica, statistica e fisica deve rimanere responsabilità di algoritmi, dati e procedure verificabili.

La prossima generazione di GeoAgent potrebbe quindi non essere un chatbot con accesso a qualche geoprocessing tool, ma un vero sistema capace di compilare richieste territoriali in workflow geografici tipizzati, verificabili, riproducibili e osservabili.

La direzione è chiara: l'LLM definisce l'intenzione, il piano diventa un contratto e il runtime garantisce l'esecuzione. L'autonomia utile nasce quando il ragionamento probabilistico incontra un'infrastruttura deterministica.

Riferimenti tecnici

martedì 6 ottobre 2026

ArcGIS Crime Analysis 6.0: dalla mappa dei reati alla Spatio-Temporal Intelligence

Una mappa dei reati non è Crime Analysis.

Visualizzare migliaia di incidenti come punti su una mappa può essere utile, ma il vero problema analitico è molto più profondo: capire se ciò che osserviamo rappresenta un pattern statisticamente significativo, come evolve nel tempo, quanto rapidamente decade il rischio attorno a un evento, se un intervento ha realmente modificato il fenomeno e, soprattutto, quanta incertezza esiste nei dati che stiamo analizzando.

Con Crime Analysis 6.0, rilasciato a settembre 2026, Esri ha aggiornato in modo significativo la propria soluzione per ArcGIS Pro. La nuova release supporta ArcGIS Pro 3.7, introduce un nuovo add-in e due strumenti particolarmente interessanti: Aoristic Analysis e Weighted Displacement Difference.

Ma questi strumenti diventano ancora più interessanti se li inseriamo in un quadro più ampio:

Crime Mapping
      ↓
Spatial Statistics
      ↓
Spatio-Temporal Analysis
      ↓
Crime Pattern Detection
      ↓
Uncertainty Modelling
      ↓
Vector + Graph Representation
      ↓
GeoAI / Agentic Spatial Intelligence

In questo deep dive vediamo quindi Crime Analysis non semplicemente come una toolbar di ArcGIS Pro, ma come il punto di ingresso verso una moderna architettura di spatial intelligence.

1. Il dato criminale è un evento spazio-temporale

Il modello più semplice rappresenta un incidente come:

CrimeEvent = (x, y, t)

dove x,y identificano la posizione e t il tempo.

Nella realtà un evento è molto più ricco:

CrimeEvent =
{
    Geometry,
    OccurFrom,
    OccurTo,
    CrimeType,
    ModusOperandi,
    Target,
    Context,
    Relationships
}

Già qui emerge un problema fondamentale: spesso t non è conosciuto.

Un furto in abitazione può essere scoperto alle 18:00, mentre il proprietario ha lasciato casa alle 08:00. L'unica informazione corretta è quindi:

08:00 ≤ t ≤ 18:00

Attribuire arbitrariamente il crimine alle 08:00, alle 13:00 o alle 18:00 introduce informazione che il dato originale non contiene.

Ed è esattamente qui che entra in gioco una delle novità più interessanti di Crime Analysis 6.0.

2. Aoristic Analysis: modellare il tempo che non conosciamo

L'Aoristic Analysis affronta gli eventi per i quali conosciamo un intervallo temporale ma non l'istante esatto.

Supponiamo che un evento possa essere avvenuto in quattro intervalli temporali:

10:00
11:00
12:00
13:00

In assenza di altra informazione, ciascun intervallo riceve peso:

P(t) = 1 / 4 = 0.25

Più generalmente, per un evento i compatibile con n intervalli:

w(i,t) = 1 / n

quando il time bucket t appartiene alla finestra temporale dell'evento, e zero altrimenti.

Aggregando molti eventi otteniamo:

A(t) = Σ w(i,t)

che rappresenta il peso aoristico complessivo associato a quel periodo.

La differenza concettuale è importante: non stiamo inventando l'orario più probabile del singolo evento. Stiamo propagando esplicitamente la sua incertezza temporale.

3. Implementarlo in C#

Il principio può essere riprodotto facilmente in .NET. Immaginiamo un modello minimale:

public sealed record CrimeIncident(
    long Id,
    DateTime OccurFrom,
    DateTime OccurTo,
    string CrimeType);

Possiamo calcolare quanto un evento contribuisce a un determinato bucket temporale:

static double AoristicWeight(
    DateTime occurFrom,
    DateTime occurTo,
    DateTime bucketFrom,
    DateTime bucketTo)
{
    if (occurTo <= occurFrom)
        return 0;

    var from = occurFrom > bucketFrom
        ? occurFrom
        : bucketFrom;

    var to = occurTo < bucketTo
        ? occurTo
        : bucketTo;

    if (to <= from)
        return 0;

    return (to - from).TotalSeconds /
           (occurTo - occurFrom).TotalSeconds;
}

Questa variante utilizza la frazione effettiva di sovrapposizione dell'intervallo, rendendo esplicito ciò che normalmente viene nascosto dietro una semplice classificazione temporale.

In un add-in ArcGIS Pro potremmo quindi leggere le feature con ArcGIS Pro SDK, estrarre OccurFrom e OccurTo, costruire i bucket e produrre una tabella o una feature class derivata.

Il punto interessante non è riscrivere uno strumento che ArcGIS possiede già. È capire il modello matematico per poterlo integrare in pipeline analitiche più complesse.

4. Kernel Density non significa Hot Spot Analysis

Una delle confusioni più comuni nella spatial analysis è interpretare qualsiasi superficie con zone rosse come un hot spot statisticamente significativo.

Kernel Density Estimation (KDE) costruisce una superficie continua distribuendo attorno agli eventi una funzione kernel. In forma semplificata:

f̂(x) = 1/(nh²) Σ K((x-Xᵢ)/h)

dove h è il bandwidth.

Aumentando il search radius si ottiene una superficie più liscia e generalizzata; riducendolo emergono strutture locali più dettagliate.

Il risultato rimane però una stima di densità, non automaticamente una prova di significatività statistica.

high density ≠ statistically significant hot spot

5. Getis-Ord Gi*: quando il clustering diventa statistico

Per individuare cluster statisticamente significativi ArcGIS Pro mette a disposizione, tra gli altri strumenti, Optimized Hot Spot Analysis, basato sulla statistica Getis-Ord Gi*.

Concettualmente non ci interessa soltanto sapere se una feature ha un valore elevato. Vogliamo sapere se essa è circondata da valori elevati in misura difficilmente compatibile con una distribuzione casuale.

Il risultato comprende:

Gi* z-score
p-value
confidence bin

Questa distinzione dovrebbe essere alla base di qualsiasi sistema serio di crime intelligence:

Visualization
    ≠
Density estimation
    ≠
Spatial clustering
    ≠
Statistical evidence

6. DBSCAN, HDBSCAN e clustering spazio-temporale

Non tutti i pattern hanno forma regolare.

Density-based Clustering in ArcGIS Pro consente di identificare cluster immersi nel rumore utilizzando algoritmi come DBSCAN, HDBSCAN e OPTICS.

Questa proprietà è particolarmente interessante nel crime analysis perché un pattern può essere molto evidente per tre settimane e scomparire completamente nel mese successivo.

Una distanza puramente spaziale:

d(i,j) = √((xᵢ-xⱼ)² + (yᵢ-yⱼ)²)

non cattura questa dinamica.

Possiamo concettualmente introdurre una distanza spazio-temporale:

D(i,j) = αDspace(i,j) + βDtime(i,j)

con scale opportunamente normalizzate.

7. Repeat e Near-Repeat: il rischio non è statico

Uno dei concetti più potenti della crime geography è la repeat/near-repeat victimization.

Dopo un evento, il luogo colpito e le aree vicine possono presentare per un periodo limitato un rischio maggiore di eventi analoghi. Tale influenza tende a diminuire sia con la distanza sia con il tempo.

Crime Analysis contiene strumenti dedicati per classificare eventi come originator, repeat e near-repeat utilizzando bande spaziali e temporali.

Possiamo rappresentare concettualmente il decadimento come:

R(d,t) = R₀ · e-λd · e-μt

dove:

d = distanza dall'incidente
t = tempo trascorso
λ = decadimento spaziale
μ = decadimento temporale

Non è quindi una superficie di rischio permanente.

È una superficie che decade continuamente nello spazio e nel tempo.

8. Prediction Zones: attenzione alla parola "prediction"

Crime Analysis può generare Prediction Zones a partire dai pattern repeat/near-repeat.

È però importante capire cosa significa "prediction".

Non significa:

qui avverrà il prossimo crimine

Significa piuttosto:

date le regolarità spazio-temporali
osservate nel dataset,
quest'area presenta un rischio relativo
più elevato nel breve periodo.

È una differenza enorme, sia statisticamente sia eticamente.

9. Space-Time Cube: quando la mappa 2D non basta più

Un altro salto concettuale consiste nel trattare lo spazio e il tempo come un'unica struttura analitica.

Lo Space-Time Cube suddivide i dati in bin spaziali e temporali:

             TIME
              ↑
              │  ▢
              │  ▢ ▢
              │  ▢ ▢
              │  ▢ ▢ ▢
              │
              └────────────→ SPACE

Emerging Hot Spot Analysis permette di osservare non solo dove sono presenti cluster, ma come essi evolvono nel tempo.

La domanda non è più:

Dove sono gli hot spot?

ma:

Dove stanno nascendo?
Quali persistono?
Quali si stanno intensificando?
Quali stanno scomparendo?

Questa è già spatio-temporal intelligence.

10. Crime series e comportamento spaziale

Crime Analysis include workflow per ordinare cronologicamente gli eventi appartenenti a una serie e rappresentarne le connessioni.

Questo consente di studiare concetti classici del geographic profiling, come la distinzione tra comportamento marauder e commuter.

La sequenza:

P1 → P2 → P3 → P4 → P5

diventa quindi molto più di una polilinea.

Possiamo analizzare:

distance(Pn, Pn+1)
bearing(Pn, Pn+1)
Δt(Pn, Pn+1)
velocity
dispersion
directional persistence

e cercare cambiamenti nella struttura della serie.

11. Weighted Displacement Difference: l'intervento ha funzionato?

Crime Analysis 6.0 introduce anche Weighted Displacement Difference.

Qui la domanda cambia completamente.

Non vogliamo più soltanto descrivere il fenomeno. Vogliamo valutare un intervento.

Response Area
      +
Response Displacement Zone

Control Area
      +
Control Displacement Zone

        ↓

Before vs After
        ↓
Weighted Displacement Difference

La statistica confronta il cambiamento degli incidenti nell'area interessata dall'intervento con quello osservato in un'area di controllo e considera anche le aree circostanti per verificare se il fenomeno sia stato semplicemente spostato.

Questo è un passaggio metodologico importantissimo:

Crime ↓ nell'area A

non implica necessariamente:

Intervento efficace

perché potrebbe essersi verificato:

A ↓
B ↑

ovvero displacement.

12. Da Crime Analysis a un Crime Graph

Fin qui abbiamo considerato principalmente geometrie, attributi e tempo.

Ma un'indagine contiene naturalmente anche relazioni.

Person ── called ── Person
   │                   │
 visited             owns
   │                   │
   ▼                   ▼
Place ── near ── CrimeEvent
                       │
                    similar
                       │
                       ▼
                  CrimeEvent

Crime Analysis contiene già strumenti investigativi per lavorare con call links, settori delle celle telefoniche e corrispondenze spazio-temporali.

La naturale evoluzione architetturale è quindi rappresentare parte del dominio come un spatio-temporal knowledge graph.

13. Il passo successivo: Crime Event Embeddings

Ed è qui che possiamo andare oltre gli strumenti standard.

Un incidente non deve necessariamente essere confrontato con un altro soltanto attraverso la distanza geografica.

Possiamo costruire una rappresentazione multidimensionale:

E = [
    spatial features,
    temporal features,
    modus operandi,
    target characteristics,
    environmental context,
    semantic description,
    graph relationships
]

e trasformarla in un vettore:

z = f(E) ∈ Rⁿ

A quel punto due incidenti possono essere confrontati attraverso una funzione di similarità che combina più domini:

D(i,j) = αDspace + βDtime + γDsemantic + δDMO + εDgraph

La query investigativa cambia radicalmente.

Da:

Find incidents within 500 meters.

a:

Find incidents that are:

geographically compatible
AND temporally compatible
AND behaviorally similar
AND semantically similar
AND connected through relevant entities.

Questo è il punto d'incontro tra GIS, vector search e graph analytics.

14. Un'architettura GeoAI

Una possibile architettura enterprise potrebbe diventare:

                ArcGIS Pro
                    │
             Crime Analysis
                    │
          Spatial Statistics
                    │
             ArcGIS Enterprise
                    │
        ┌───────────┴───────────┐
        │                       │
 Spatial Features         Operational Data
        │                       │
        └───────────┬───────────┘
                    │
               Azure SQL
                    │
       ┌────────────┼────────────┐
       │            │            │
   relational     vector       graph
     data         index      relationships
       │            │            │
       └────────────┼────────────┘
                    │
             Retrieval Layer
                    │
                 GeoAgent
                    │
             ArcGIS Pro / Web

Il GeoAgent potrebbe ricevere una richiesta come:

Analyze residential burglaries from the last six weeks.

Identify statistically significant spatial clusters,
test for repeat/near-repeat behavior,
compare modus-operandi similarity,
and explain which evidence supports each candidate series.

15. L'LLM non deve fare statistica al posto del GIS

Questo è forse il punto architetturale più importante.

Non costruirei un sistema nel quale chiediamo direttamente a un Large Language Model:

Where will the next crime occur?

Un LLM non dovrebbe sostituire Getis-Ord Gi*, KDE, DBSCAN, Space-Time Cube o un modello statistico validato.

Dovrebbe invece funzionare come orchestratore analitico:

User
  │
  ▼
GeoAgent
  │
  ├──► ArcGIS Spatial Statistics
  │
  ├──► Space-Time Analysis
  │
  ├──► Vector Search
  │
  ├──► Graph Query
  │
  └──► Operational Database
          │
          ▼
      Evidence
          │
          ▼
   LLM explanation

In altre parole:

LLM ≠ analytical truth

LLM = reasoning + orchestration + explanation

mentre il risultato quantitativo deve continuare a provenire da strumenti deterministici, modelli statistici o algoritmi esplicitamente validati.

16. Explainability prima della prediction

Un sistema di crime intelligence dovrebbe poter rispondere non soltanto:

Risk = HIGH

ma anche:

WHY?

• 7 recent related incidents
• statistically significant Gi* cluster
• 5 incidents inside the near-repeat temporal window
• high spatial proximity
• strong modus-operandi similarity
• pattern intensifying over the last 3 weeks

La spiegabilità non è un accessorio dell'AI.

In domini ad alto impatto è parte dell'architettura.

17. Il problema più difficile: i dati non sono la realtà

Esiste infine un limite che nessun algoritmo può eliminare automaticamente.

Un database criminale non rappresenta necessariamente:

all crimes that happened

ma più precisamente qualcosa di simile a:

events reported
+
events detected
+
events recorded
+
events classified
+
effects of enforcement activity

Questa distinzione è fondamentale.

Una maggiore concentrazione di osservazioni in una zona può derivare da un maggior numero di eventi, ma può anche essere influenzata da maggiore presenza operativa, differenti livelli di denuncia, procedure amministrative o qualità diversa del dato.

Se utilizziamo questi dati senza comprenderne il processo generativo, rischiamo di creare un feedback loop:

more observations
      ↓
higher estimated risk
      ↓
more attention
      ↓
more detected events
      ↓
even higher estimated risk

La precisione matematica del modello non elimina il bias del processo che ha prodotto i dati.

18. Dal GIS descrittivo alla Spatial Intelligence

Crime Analysis 6.0 mostra bene quanto il GIS moderno si stia allontanando dalla semplice rappresentazione cartografica.

Il percorso ormai è:

Where did it happen?
        ↓
Where is it concentrated?
        ↓
Is the concentration statistically significant?
        ↓
How is the pattern evolving?
        ↓
How does risk decay in space and time?
        ↓
Are apparently separate events related?
        ↓
Did an intervention change the pattern?
        ↓
What evidence supports the conclusion?

E il prossimo passo potrebbe essere:

Can an intelligent spatial agent
autonomously assemble the right analyses,
test competing hypotheses,
retrieve supporting evidence
and explain its conclusions?

Conclusione

Crime Analysis 6.0 è interessante non tanto perché aggiunge nuovi pulsanti ad ArcGIS Pro, ma perché rende evidente una trasformazione più ampia.

La geografia del crimine sta diventando sempre più una disciplina spazio-temporale, probabilistica e relazionale.

Aoristic Analysis ci ricorda che anche il tempo può essere incerto. Repeat/Near-Repeat Analysis introduce il decadimento spazio-temporale del rischio. Space-Time Cube permette di osservare l'evoluzione dei cluster. Weighted Displacement Difference porta l'analisi verso la valutazione degli interventi.

Embeddings, vector search, graph analytics e GeoAI possono costituire il livello successivo, purché non sostituiscano la statistica con un modello linguistico.

Il GIS del futuro non dovrà semplicemente mostrare dove si trova qualcosa.

Dovrà essere in grado di spiegare:

what happened
where
when
how it is connected
how certain we are
how the pattern is changing
and which evidence supports the hypothesis.

È in quel momento che una mappa smette di essere soltanto una rappresentazione dello spazio e diventa un vero sistema di Spatial Intelligence.

giovedì 1 ottobre 2026

AI Agent e ArcGIS: un nuovo pattern per migrare applicazioni legacy

Il problema più difficile nella modernizzazione di un'applicazione legacy non è necessariamente convertire il codice.

È capire che cosa l'applicazione faccia realmente.

Il 30 settembre 2026 Esri ha pubblicato Rethinking Application Migrations, mostrando un approccio particolarmente interessante alla modernizzazione di applicazioni basate su ArcGIS Maps SDK for JavaScript.

Il caso utilizzato è il Building Viewer, migrato da uno stack basato su Dojo e Grunt verso:

  • Vite;
  • TypeScript;
  • @arcgis/core;
  • ArcGIS Maps SDK for JavaScript Components;
  • tooling moderno basato su @arcgis/create.

La motivazione immediata è tecnologica: con l'evoluzione del Maps SDK for JavaScript e la progressiva transizione dai tradizionali widget ai componenti nel percorso con ArcGIS Maps SDK for JavaScript 5.x e la transizione ormai esplicita dai tradizionali widget ai Web Components, alcune applicazioni richiederanno qualcosa di più profondo di un aggiornamento delle dipendenze.

Ma l'aspetto più interessante dell'esperimento Esri non è lo stack di destinazione.

È il processo di migrazione.

Legacy Application
        |
        v
Static Code Inspection
        +
Runtime Exploration
        |
        v
Behavioral Discovery
        |
        v
Verified PRD
        |
        v
Modern Application Generation
        |
        v
Runtime / Visual Validation
        |
        v
Architecture & Code Review

In altre parole:

non chiedere all'AI di tradurre il vecchio codice. Chiedile prima di ricostruire il contratto comportamentale dell'applicazione.

Ed è una differenza architetturale enorme.

Refactoring e re-platforming non sono la stessa cosa

Esri fa una distinzione importante.

Se dobbiamo semplicemente aggiornare una normale applicazione ArcGIS:

ArcGIS Maps SDK 5.x
        |
        +-- aggiornare a una release 5.x più recente
        +-- adeguare eventuali API cambiate o deprecate
        +-- aggiornare componenti e dipendenze
        |
        v
same application architecture

un aggiornamento incrementale può essere perfettamente ragionevole.

Il problema cambia quando contemporaneamente cambiano:

  • SDK;
  • framework;
  • build system;
  • architettura UI;
  • component model;
  • dependency model;
  • development patterns.

Nel caso Building Viewer il salto era sostanzialmente:

Dojo
Grunt
legacy ArcGIS widgets
legacy application patterns
        |
        v
Vite
TypeScript
ArcGIS Components
modern Maps SDK patterns

In un caso di questo tipo, trascinare progressivamente il vecchio software attraverso una lunga sequenza di upgrade può essere meno conveniente che ricostruire l'applicazione partendo dai requisiti verificati.

Questo introduce una distinzione fondamentale:

CODE MIGRATION
    legacy implementation
          |
          v
    transformed implementation


BEHAVIORAL MIGRATION
    observable behavior
          |
          v
    formal specification
          |
          v
    new implementation

Nel secondo caso il vecchio codice non è più il progetto della nuova applicazione.

Diventa una delle fonti di evidenza utilizzate per ricostruirne le specifiche.

Il legacy diventa un sistema da osservare

Tradizionalmente, quando dobbiamo migrare un'applicazione, iniziamo dal repository:

repository
   |
   +-- source
   +-- dependencies
   +-- configuration
   +-- build
   +-- documentation

Ma un'applicazione reale contiene conoscenza che non è necessariamente evidente dal codice.

Per esempio:

source code
configuration
runtime state
external services
ArcGIS Portal items
WebMap / WebScene
user interaction
browser behavior
CSS / layout
historical workarounds

Il comportamento effettivo dell'applicazione è quindi qualcosa di più simile a:

Application Behavior =
    Code
  + Configuration
  + Runtime
  + Data
  + External Services
  + UI State
  + User Interaction

Ed è qui che entra in gioco il coding agent.

Nel workflow Esri l'agente non deve limitarsi a leggere JavaScript e TypeScript.

Deve eseguire realmente l'applicazione.

Browser automation come strumento di reverse engineering

Esri utilizza un browser integrato e Playwright per esplorare l'applicazione legacy.

L'agente deve:

  • avviare l'applicazione;
  • navigarne le funzionalità;
  • attivare controlli e workflow;
  • osservare gli stati della UI;
  • verificare il comportamento della mappa;
  • catturare screenshot;
  • correlare quello che osserva con il sorgente;
  • individuare risorse ArcGIS e configurazioni esterne.

Gli screenshot diventano quindi qualcosa di molto più importante della semplice documentazione.

Diventano evidence artifacts.

Requirement
    |
    +-- source evidence
    +-- runtime evidence
    +-- screenshot evidence
    +-- configuration evidence

Il PRD risultante non descrive soltanto ciò che il codice sembra voler fare.

Descrive ciò che l'applicazione effettivamente fa.

Il PRD come Behavioral Contract

Prima di generare qualsiasi nuova applicazione, Esri fa produrre all'agente un vero Product Requirements Document.

Il prompt impone una regola particolarmente importante: documentare il comportamento esistente senza proporre subito nuove tecnologie, redesign, miglioramenti o nuove architetture.

Inoltre l'agente deve distinguere chiaramente ciò che è stato verificato da ciò che è soltanto dedotto oppure non determinabile.

Questo trasforma il PRD in qualcosa che, dal punto di vista architetturale, possiamo definire:

Behavioral Contract

tra:

legacy implementation
        |
        v
       PRD
        |
        v
new implementation

Il nuovo sistema non deve necessariamente replicare l'implementazione.

Deve soddisfare il contratto comportamentale.

Verified, Assumption, Unknown

Una delle scelte più intelligenti è evitare che l'LLM presenti ogni deduzione come un fatto.

Nel PRD reale del Building Viewer Esri distingue categorie quali:

Verified
Specified correction
Assumption
Unknown

Questa distinzione è estremamente importante nell'uso professionale degli agenti.

Un modello potrebbe facilmente trasformare:

inference

in:

requirement

e successivamente trasformare quel requisito inventato in codice perfettamente funzionante.

Il risultato sarebbe tecnicamente corretto ma funzionalmente sbagliato.

La provenance dell'informazione deve quindi diventare parte della specifica.

Una possibile estensione enterprise potrebbe essere:

Requirement R-042

Behavior:
Selecting floor 2 filters the building.

Evidence:
[x] Source inspection
[x] Runtime verification
[x] Screenshot
[x] ArcGIS service query

Confidence:
VERIFIED

Dependencies:
WebScene: ...
Layer: ...
Field: BldgLevel

Validation:
Playwright test BV-FLOOR-002

A questo punto il PRD comincia ad assomigliare più a una specifica eseguibile che a un normale documento di progetto.

Il Data & Configuration Inventory è fondamentale nel GIS

Qui il caso ArcGIS diventa particolarmente interessante.

Un'applicazione GIS raramente è contenuta interamente nel repository.

Una parte importante dell'architettura può vivere dentro:

ArcGIS Online / Enterprise
        |
        +-- WebMap
        +-- WebScene
        +-- FeatureLayer
        +-- SceneLayer
        +-- ElevationLayer
        +-- Portal Items
        +-- Renderers
        +-- Popups
        +-- Expressions
        +-- Service Configuration

Per questo Esri chiede esplicitamente all'agente di costruire un Data & Configuration Inventory.

Nel PRD del Building Viewer vengono inventariati elementi quali:

  • Portal;
  • WebScene ID;
  • URL REST;
  • spatial reference;
  • elevation source;
  • SceneServer;
  • FeatureServer;
  • layer ID;
  • visibility;
  • definition expression;
  • configurazioni applicative;
  • risorse esterne.

Il documento arriva quindi a ricostruire relazioni funzionali come:

UI floor
   |
   v
level_id
   |
   v
FeatureLayer filter

oppure:

UI floor
   |
   v
BldgLevel
   |
   v
BuildingSceneLayer filtering

Questa è una lezione importante per qualsiasi migrazione GIS:

il repository Git non coincide con il sistema.

Il sistema reale è piuttosto:

Git repository
      +
Portal configuration
      +
WebMap / WebScene JSON
      +
REST services
      +
external data
      +
runtime behavior

Un agente che analizzi soltanto il repository vede quindi soltanto una parte dell'architettura.

Dal PRD alla nuova applicazione

Solo dopo questa fase Esri passa alla generazione.

La nuova applicazione viene creata utilizzando @arcgis/create con Vite e uno stack moderno, mantenendola separata dal progetto originale.

Legacy App
     |
     | discovery
     v
   PRD
     |
     | generation
     v
Clean Project
     |
     v
Modern SDK

Questo riduce un problema tipico delle migrazioni automatiche: la legacy contamination.

Se chiedessimo semplicemente:

convert this Dojo application to modern TypeScript

il modello potrebbe produrre:

legacy architecture
      +
TypeScript syntax
      +
modern build

ottenendo un'applicazione apparentemente moderna, ma concettualmente ancora legacy.

Widget thinking vs Component thinking

Questo problema è particolarmente evidente nel Maps SDK.

Un agente può facilmente ricadere nei pattern che ha già visto più spesso, per esempio:

  • vecchi widget;
  • classi legacy;
  • codice custom che reinventa funzionalità già presenti nei nuovi componenti;
  • pattern di inizializzazione appartenenti a versioni precedenti dell'SDK.

Esri non ha risolto il problema continuando ad allungare il prompt della singola conversazione.

Ha modificato le istruzioni persistenti del repository.

Ed è probabilmente una delle parti più interessanti dell'intero esperimento.

.github/copilot-instructions.md come Architecture Policy

Nel repository Building Viewer è presente:

.github/copilot-instructions.md

In altri ambienti lo stesso concetto può essere rappresentato da:

AGENTS.md

Il file contiene conoscenza persistente relativa al progetto.

Non:

"correggi questo componente"

ma:

"questo è il modo corretto di sviluppare in questo repository"

Le istruzioni possono stabilire, per esempio:

  • quali versioni di @arcgis/core e @arcgis/map-components utilizzare;
  • quali pattern non devono più essere introdotti;
  • quando preferire i Map Components;
  • come validare il codice;
  • quali requisiti di sicurezza rispettare.

Quindi:

Prompt
    = task context

copilot-instructions.md
    = architectural context

È una distinzione fondamentale.

Architecture as Instructions

Da un punto di vista enterprise, possiamo spingere questo concetto molto più avanti.

Un repository potrebbe contenere:

AGENTS.md

architecture/
    principles.md
    security.md
    arcgis-patterns.md
    testing.md
    observability.md

con regole come:

DO use ArcGIS Components

DO NOT use deprecated widgets

DO NOT place secrets in browser code

DO validate browser console

DO execute type checking

DO verify against screenshots

DO inspect ArcGIS service metadata

DO keep changes scoped

L'agente non riceve quindi soltanto una richiesta.

Riceve una policy architetturale versionata insieme al codice.

Possiamo quasi considerarla:

Architecture Policy as Code

Correggere l'agente, non soltanto il codice

Questo cambia anche il modo di lavorare quando l'AI commette ripetutamente lo stesso errore.

Workflow ingenuo:

Agent generates wrong pattern
        |
        v
developer fixes prompt
        |
        v
agent generates another wrong pattern
        |
        v
developer fixes prompt again

Workflow più maturo:

Agent generates wrong pattern
        |
        v
identify systemic misconception
        |
        v
update AGENTS.md / copilot-instructions
        |
        v
future generations inherit correction

In pratica il feedback non modifica soltanto l'output.

Modifica il sistema che produce gli output successivi.

Questo assomiglia molto più alla gestione di una engineering organization che al normale prompting.

Visual validation non significa semplicemente pixel comparison

Dopo la generazione Esri confronta vecchia e nuova applicazione utilizzando browser e screenshot.

Ma in una GIS application la validazione visuale deve essere interpretata con attenzione.

Una schermata apparentemente identica può nascondere differenze sostanziali:

camera position
zoom
layer visibility
definitionExpression
renderer
popup behavior
hitTest
floor filtering
WebScene state
service errors
console errors

Per questo una pipeline realmente robusta dovrebbe combinare:

Visual Validation
        +
Functional Validation
        +
GIS State Validation
        +
Network Validation
        +
Console Validation

Per esempio:

Playwright
   |
   +-- click Floor 2
   +-- capture screenshot
   +-- inspect visible controls
   +-- verify selected state
   +-- inspect browser console
   +-- inspect failed requests
   +-- verify expected layer filter

Qui l'AI agent non sostituisce i test.

Può diventare il coordinatore dei diversi strumenti di verifica.

Una possibile pipeline CI/CD

Il pattern mostrato da Esri può essere ulteriormente industrializzato.

                    LEGACY APPLICATION
                           |
                           v
                +--------------------+
                | Discovery Agent    |
                +--------------------+
                  |       |       |
                  v       v       v
                Code   Browser   ArcGIS REST
                  \       |       /
                   \      |      /
                    v     v     v
                 VERIFIED PRD
                       |
                       v
               Architecture Rules
                       |
                       v
                Generation Agent
                       |
                       v
                  New Application
                       |
          +------------+------------+
          |            |            |
          v            v            v
       Build        Playwright    Security
       Typecheck     Tests         Checks
          |            |            |
          +------------+------------+
                       |
                       v
                Visual Regression
                       |
                       v
                Human Review Gate
                       |
                       v
                    Deploy

A questo punto non stiamo più parlando semplicemente di Copilot.

Stiamo parlando di una agentic application-modernization pipeline.

Il ruolo della sicurezza

Il file di istruzioni utilizzato da Esri contiene anche indicazioni esplicite sulla sicurezza.

Un punto fondamentale per le applicazioni JavaScript è il seguente: una API key utilizzata dal browser è necessariamente disponibile al client.

Inserirla in una build-time environment variable può evitare di commetterla direttamente nel repository, ma non trasforma il bundle JavaScript in un secret store.

OAuth client secret, credenziali applicative e token confidenziali devono invece rimanere fuori da:

  • browser;
  • bundle;
  • log;
  • commit;
  • prompt e contesto dell'assistente.

Questo diventa ancora più importante con gli agenti.

Un discovery agent potrebbe infatti avere accesso contemporaneamente a:

repository
environment
browser
network
configuration
logs
Portal

Il modello di sicurezza dovrebbe quindi ragionare esplicitamente su:

Agent permissions
      |
      +-- filesystem scope
      +-- repository scope
      +-- browser scope
      +-- network scope
      +-- credentials
      +-- Portal privileges
      +-- command execution

Il principio dovrebbe essere sempre:

least privilege
+
isolated environment
+
auditable actions
+
human approval for sensitive operations

Attenzione: il PRD può diventare il nuovo single point of failure

Il workflow è potente, ma introduce anche un rischio interessante.

Legacy
   |
   v
PRD
   |
   v
New Application

Un errore nel PRD può propagarsi direttamente nella nuova implementazione.

Il problema quindi si sposta:

prima:
"il codice generato è corretto?"

dopo:
"la specifica generata è corretta?"

È probabilmente comunque un miglioramento, perché una specifica è più semplice da revisionare rispetto a migliaia di righe di codice.

Ma il PRD deve essere trattato come un artefatto critico:

PRD
 |
 +-- machine generated
 +-- evidence linked
 +-- human reviewed
 +-- version controlled
 +-- test traceable

Requirement → Evidence → Test

L'evoluzione naturale del pattern Esri potrebbe essere la completa tracciabilità:

Requirement
    |
    v
Evidence
    |
    v
Generated implementation
    |
    v
Automated test

Per esempio:

REQ-GIS-017

"When floor 3 is selected,
only floor 3 content is visible."

        |
        +-- source evidence
        +-- runtime screenshot
        +-- service configuration
        |
        v
Playwright test
        |
        v
ArcGIS runtime assertion

Avremmo quindi una vera catena:

Legacy behavior
      |
      v
Evidence
      |
      v
Requirement
      |
      v
Implementation
      |
      v
Test
      |
      v
Validation

Ed è probabilmente qui che l'agentic software engineering diventa realmente interessante per applicazioni enterprise.

Non è solo un pattern ArcGIS

Sebbene Esri lo mostri sul Building Viewer, il modello è molto più generale.

Potrebbe funzionare altrettanto bene per:

  • ASP.NET WebForms → Blazor;
  • AngularJS → Angular;
  • jQuery → React;
  • ArcGIS JavaScript legacy → ArcGIS Components;
  • old Java application → modern services;
  • desktop client → web application.

La condizione fondamentale è che il sistema legacy sia ancora sufficientemente eseguibile da poter essere osservato.

In questo caso il runtime stesso diventa una forma di documentazione.

Dal source-driven development all'evidence-driven modernization

È forse questo il cambiamento concettuale più interessante.

Tradizionalmente:

Source Code
     |
     v
Migration

Con questo modello:

             Source Code
                  |
Runtime ----------+
                  |
Configuration ----+
                  |
External Data ----+
                  |
Screenshots ------+
                  |
                  v
               Evidence
                  |
                  v
          Behavioral Model
                  |
                  v
             New System

La migrazione diventa quindi evidence-driven.

E questo può essere particolarmente efficace nei sistemi con dieci o quindici anni di storia, dove il codice racconta soltanto una parte della verità.

Una conseguenza interessante per ArcGIS Enterprise

Nel mondo ArcGIS questo approccio potrebbe diventare ancora più potente.

Un discovery agent specializzato potrebbe interrogare automaticamente:

Portal REST API
ArcGIS Server REST
WebMap JSON
WebScene JSON
FeatureServer
MapServer
SceneServer
ImageServer

e costruire un dependency graph:

Application
    |
    +-- WebMap
    |     |
    |     +-- FeatureLayer
    |     +-- MapImageLayer
    |
    +-- WebScene
    |     |
    |     +-- SceneLayer
    |     +-- ElevationLayer
    |
    +-- OAuth Application
    |
    +-- External API

A quel punto il PRD potrebbe essere affiancato da una vera:

GIS Application Dependency Graph

utilizzabile non soltanto per la migrazione, ma anche per:

  • impact analysis;
  • security assessment;
  • dependency auditing;
  • upgrade planning;
  • disaster recovery;
  • documentazione automatica;
  • individuazione di servizi legacy.

La lezione architetturale

L'aspetto più interessante di Rethinking Application Migrations non è il fatto che Esri abbia usato GitHub Copilot o uno specifico frontier model.

Il workflow è in larga misura indipendente dal modello.

Contano soprattutto:

  • contesto;
  • istruzioni;
  • strumenti;
  • evidenze;
  • validazione.

La vera innovazione è il cambio di astrazione:

"convert this code"

diventa:

"understand this system"
        |
        v
"prove what you understood"
        |
        v
"formalize its behavior"
        |
        v
"rebuild it with modern primitives"
        |
        v
"prove that the new system behaves correctly"

Ed è una differenza enorme.

Il coding agent smette di essere soltanto un generatore di codice.

Diventa contemporaneamente:

reverse engineer
requirements analyst
browser operator
developer
tester
architecture assistant

mentre l'architect mantiene la responsabilità delle decisioni, delle policy e dei criteri di accettazione.

Conclusione

Il pattern mostrato da Esri può essere riassunto così:

Legacy App
   |
   v
Runtime Discovery
   |
   v
Evidence Collection
   |
   v
Verified Behavioral PRD
   |
   v
Architecture Instructions
   |
   v
Clean Reimplementation
   |
   v
Visual + Functional Validation
   |
   v
Human Review

Non è semplicemente un modo più veloce di riscrivere una vecchia applicazione.

È un possibile modello per la modernizzazione agentica del software.

E per il mondo GIS è particolarmente interessante, perché una ArcGIS application non è quasi mai soltanto il suo codice: è codice, configurazione, Portal items, servizi REST, dati, WebMap, WebScene e comportamento runtime.

La vera domanda per un coding agent, quindi, non dovrebbe più essere:

“Riesci a convertire questa applicazione?”

ma:

“Riesci prima a dimostrare di aver capito esattamente che cosa questa applicazione fa?”

Solo dopo ha senso lasciargli scrivere quella nuova.


Fonte principale:
Esri — Rethinking Application Migrations, 30 settembre 2026
https://www.esri.com/arcgis-blog/products/js-api-arcgis/geoai/rethinking-application-migrations

Building Viewer — PRD:
https://github.com/Esri/building-viewer/blob/main/prd/PRD.md

Repository instructions:
https://github.com/Esri/building-viewer/blob/main/.github/copilot-instructions.md

martedì 29 settembre 2026

Embedding nel GIS: quando una posizione geografica diventa un vettore

Negli ultimi anni il concetto di embedding è diventato centrale nel mondo dell'intelligenza artificiale. Nei Large Language Model una frase, un documento o un concetto vengono trasformati in un vettore numerico che ne rappresenta, in modo distribuito, il significato.

Lo stesso paradigma sta entrando nel GIS.

Una posizione geografica, un quartiere, una cella territoriale, un'immagine satellitare o una feature GIS possono essere rappresentati non soltanto attraverso coordinate, geometrie e attributi, ma attraverso un vettore ad alta dimensionalità appreso da un modello.

Il risultato è un cambiamento concettuale importante:

da "dove si trova questa feature?" e "quali attributi possiede?" a "che tipo di luogo rappresenta e quali altri luoghi le assomigliano?"

ArcGIS sta integrando questo paradigma direttamente nei propri workflow GeoAI. Gli USA Geodemographic Embeddings 2026 ne sono un esempio particolarmente interessante: migliaia di variabili demografiche, socioeconomiche, abitative e ambientali vengono trasformate in un vettore compatto di 256 dimensioni per ogni area geografica.

Ma il concetto va molto oltre quel dataset specifico. Gli embedding possono diventare una nuova primitiva dell'informazione geografica, insieme a geometria, attributi, topologia e coordinate.

1. Un embedding è prima di tutto algebra lineare

Formalmente possiamo descrivere un encoder come una funzione:

f : X → R^d

dove X rappresenta lo spazio originale dei dati e R^d uno spazio vettoriale di dimensione d.

Un oggetto complesso:

x ∈ X

viene trasformato in:

e = f(x)

e = [e₀, e₁, e₂, ..., e₍d-1₎]

Il vettore e viene chiamato embedding.

Nel caso di un modello linguistico:

"spatial database for urban analysis"
                │
                ▼
             Encoder
                │
                ▼
[0.18, -0.42, 0.71, ..., -0.09]

Nel caso GIS potremmo invece avere:

Location / Area / Raster / Feature
                │
                ▼
       Geospatial Encoder
                │
                ▼
[0.31, 0.08, -0.67, ..., 0.22]

La caratteristica fondamentale è che le singole componenti del vettore normalmente non hanno un significato interpretabile isolatamente.

Non possiamo quindi dire:

embedding[17] = reddito
embedding[42] = densità
embedding[103] = urbanizzazione

Il significato è distribuito nell'intero spazio latente.

È il pattern complessivo delle componenti a rappresentare il fenomeno.

2. Coordinate ed embedding non sono la stessa cosa

Nel GIS siamo già abituati a rappresentare un punto attraverso numeri:

P = (x, y)

oppure:

P = (longitude, latitude)

Ma queste coordinate descrivono esclusivamente la posizione geometrica.

Un location embedding risponde a una domanda differente.

Coordinate:
45.46, 9.19

Embedding:
[0.31, -0.12, 0.77, ..., -0.22]

Le coordinate dicono:

Dove si trova questo luogo?

L'embedding cerca invece di codificare:

Che tipo di luogo è?

A seconda del modello utilizzato, il vettore può rappresentare informazioni relative a:

  • urbanizzazione;
  • demografia;
  • uso del suolo;
  • morfologia urbana;
  • vegetazione;
  • infrastrutture;
  • caratteristiche ambientali;
  • immagini satellitari;
  • POI;
  • mobilità;
  • testi associati alla feature;
  • relazioni spaziali con altre entità.

Quindi:

geometry ≠ embedding

Sono due rappresentazioni complementari dello stesso oggetto geografico.

3. Due spazi differenti: geographic space ed embedding space

Questa distinzione porta a uno dei concetti più interessanti del GeoAI.

Nel normale spazio geografico possiamo avere:

A ●--------------------------------● B
              500 km

La distanza viene calcolata utilizzando coordinate, sistemi di riferimento e metriche spaziali.

Nello spazio degli embedding, gli stessi oggetti potrebbero invece essere:

A ●----● B

perché, nonostante siano geograficamente lontani, presentano caratteristiche estremamente simili.

Oppure due aree fisicamente vicine:

Geographic space

A ●---● B

Embedding space

A ●-------------------------------● B

potrebbero risultare molto differenti dal punto di vista socioeconomico, urbanistico o ambientale.

Possiamo quindi distinguere due funzioni:

SpatialDistance(A, B)

e:

EmbeddingDistance(E(A), E(B))

La prima misura una relazione nello spazio geografico. La seconda misura una relazione nello spazio latente appreso dal modello.

4. La cosine similarity

Uno dei modi più comuni per confrontare embedding è la cosine similarity.

Dati due vettori A e B:

               A · B
cos(A,B) = -----------------
             ||A|| ||B||

Il prodotto scalare è:

A · B = Σ AᵢBᵢ

mentre la norma euclidea è:

||A|| = √Σ Aᵢ²

La cosine similarity misura essenzialmente l'angolo fra due vettori.

Se i vettori normalizzati puntano nella stessa direzione:

similarity → 1

sono molto simili secondo lo spazio semantico costruito dal modello.

Attenzione però a un errore interpretativo frequente:

una cosine similarity di 0.90 non significa che due luoghi siano "uguali al 90%".

È una misura geometrica nello spazio degli embedding, il cui significato dipende dal modello, dal training e dalla distribuzione dei dati.

5. Calcolare la similarity con NumPy

Il calcolo è estremamente semplice.

import numpy as np

a = np.array([0.21, 0.74, -0.32, 0.61], dtype=np.float32)
b = np.array([0.19, 0.70, -0.29, 0.58], dtype=np.float32)

similarity = np.dot(a, b) / (
    np.linalg.norm(a) *
    np.linalg.norm(b)
)

print(similarity)

Dietro una parte importante della cosiddetta "semantic search" c'è quindi algebra lineare relativamente semplice.

La parte complessa non è il confronto fra i vettori.

La vera complessità consiste nel costruire uno spazio vettoriale nel quale la distanza abbia un significato utile per il dominio applicativo.

6. Che cosa possiamo trasformare in embedding nel GIS?

Praticamente qualsiasi sorgente informativa associata allo spazio.

                         GIS Feature
                              │
          ┌───────────────────┼───────────────────┐
          │                   │                   │
          ▼                   ▼                   ▼
       Geometry             Imagery           Attributes
          │                   │                   │
          ▼                   ▼                   ▼
    Geo Encoder          Vision Encoder      Tabular/Text
          │                   │                   │
          └───────────────────┼───────────────────┘
                              │
                              ▼
                         Embedding
                     [e₀ ... eₙ]

Location embeddings

Rappresentano il contesto associato a una posizione geografica.

Image embeddings

Un modello visuale o geospatial foundation model trasforma chip di immagini satellitari o aeree in vettori.

Text embeddings

Descrizioni, metadata, documenti, toponimi e altri campi testuali collegati a feature GIS possono essere trasformati in vettori semantici.

Geodemographic embeddings

Comprimono centinaia o migliaia di indicatori territoriali in una rappresentazione numerica compatta.

Multimodal embeddings

È probabilmente la direzione più interessante:

Satellite imagery ──► Vision encoder ──────┐
                                           │
Demography ─────────► Tabular encoder ─────┤
                                           │
POI ─────────────────► POI encoder ────────┼──► PLACE EMBEDDING
                                           │
Text ────────────────► Text encoder ───────┤
                                           │
Road network ────────► Graph encoder ──────┘

Il risultato sarebbe una sorta di fingerprint digitale del luogo.

7. Gli USA Geodemographic Embeddings di Esri

Un'implementazione concreta di questo paradigma è rappresentata dagli USA Geodemographic Embeddings 2026 disponibili nell'ecosistema ArcGIS.

Gli embedding vengono costruiti attraverso il Geodemographic Foundation Model (GDFM) di Esri.

Il modello utilizza quattro grandi viste informative.

Dataset Informazione Variabili
Age & Race Census Struttura demografica e variazioni nel tempo 2.049
American Community Survey Istruzione, lavoro, reddito, commuting, household 1.617
Housing & Household Housing units, occupancy, tenure, composizione familiare 1.521
Environment Temperatura, precipitazioni, land cover e indicatori fisici 113

Parliamo quindi di oltre 5.000 variabili originarie.

Dopo preprocessing, pulizia, imputazione e scaling, queste informazioni vengono elaborate da un'architettura multiview autoencoder.

8. Multiview autoencoder: come nasce il vettore

Un autoencoder classico contiene due parti:

Input
  │
  ▼
Encoder
  │
  ▼
Latent representation
  │
  ▼
Decoder
  │
  ▼
Reconstructed input

L'obiettivo del training è ricostruire il più fedelmente possibile l'input dopo averlo compresso attraverso uno spazio latente più piccolo.

Nel modello geodemografico Esri il concetto viene esteso utilizzando viste informative differenti:

Census ─────────► Encoder 1 ──┐
                              │
ACS ────────────► Encoder 2 ──┤
                              │
Housing ────────► Encoder 3 ──┼──► Latent vector
                              │      256 dimensions
Environment ────► Encoder 4 ──┘
                                      │
                    ┌─────────────────┼─────────────────┐
                    ▼                 ▼                 ▼
                 Decoder          Decoder           Decoder
                    │                 │                 │
                    ▼                 ▼                 ▼
              reconstruct         reconstruct       reconstruct

Il modello viene addestrato minimizzando l'errore di ricostruzione delle differenti viste.

Il vettore latente finale ha:

D = 256

dimensioni.

Un intero territorio viene quindi trasformato da migliaia di variabili esplicite a:

E(location) ∈ R²⁵⁶

senza che ciascuna dimensione debba corrispondere direttamente a una singola variabile originale.

9. H3 come unità spaziale

Gli USA Geodemographic Embeddings vengono distribuiti utilizzando celle Uber H3 resolution 7.

Concettualmente:

territory
    │
    ▼
H3 tessellation
    │
    ├── hex 1 ──► embedding[256]
    ├── hex 2 ──► embedding[256]
    ├── hex 3 ──► embedding[256]
    │
    └── ...

Questa scelta è importante perché l'embedding diventa associato a un'unità spaziale uniforme e interrogabile come una normale feature GIS.

10. ArcGIS Pro: gli embedding diventano un tipo di informazione GIS

ArcGIS Pro dispone oggi di un toolset dedicato alla Embeddings Based Analysis.

Tra gli strumenti principali troviamo:

  • Generate Embeddings Using AI Models;
  • Find Similar Features Using Embeddings;
  • Merge Embeddings;
  • Extract Embeddings To Fields.

Questo è rilevante architetturalmente.

L'embedding non viene più considerato soltanto un artefatto interno a una pipeline di machine learning, ma diventa un elemento persistente del dataset GIS.

11. Come ArcGIS memorizza realmente un embedding

ArcGIS Pro persiste gli embedding in un campo geodatabase di tipo BLOB chiamato normalmente Embedding.

La rappresentazione è particolarmente interessante per uno sviluppatore.

Ogni componente viene serializzata come:

IEEE-754 32-bit floating point
little-endian

Il payload è costituito semplicemente dalla sequenza dei valori:

[e₀][e₁][e₂]...[e₍D-1₎]

senza header, delimitatori o metadata aggiuntivi.

Ogni componente occupa:

4 bytes

perciò:

payload_size = D × 4

Per un embedding da 256 dimensioni:

256 × 4 = 1024 bytes

ovvero circa 1 KB per feature, senza considerare l'overhead del database.

12. Leggere direttamente il BLOB con Python

import arcpy
import numpy as np

feature_class = r"C:\GIS\Data.gdb\Embeddings"
dimension = 256

with arcpy.da.SearchCursor(
    feature_class,
    ["OBJECTID", "Embedding"]
) as cursor:

    for object_id, blob in cursor:

        if blob is None:
            continue

        expected_size = dimension * 4

        if len(blob) != expected_size:
            raise ValueError(
                f"Embedding non valido per OID {object_id}: "
                f"{len(blob)} bytes invece di {expected_size}"
            )

        vector = np.frombuffer(
            blob,
            dtype="<f4"
        )

        print(object_id, vector.shape)

Il dtype:

<f4

significa:

  • < = little-endian;
  • f = floating point;
  • 4 = quattro byte.

13. Scrivere un embedding in una Feature Class

È possibile effettuare anche l'operazione opposta.

import arcpy
import numpy as np

embedding = np.array(
    [0.12, -0.98, 1.42, 0.33],
    dtype="<f4"
)

embedding_bytes = np.asarray(
    embedding,
    dtype="<f4",
    order="C"
).tobytes()

with arcpy.da.InsertCursor(
    feature_class_path,
    ["SHAPE@", "Name", "Embedding"]
) as cursor:

    cursor.insertRow([
        geometry,
        "Sample Feature",
        embedding_bytes
    ])

Questo apre una possibilità interessante: gli embedding non devono necessariamente essere generati da ArcGIS.

Possiamo produrli attraverso un modello esterno, serializzarli nel formato previsto e inserirli in una feature class per utilizzarli nei workflow GIS.

14. Base64 e Feature Service

Quando il BLOB deve transitare attraverso un canale testuale, ad esempio JSON o REST, il payload binario viene normalmente rappresentato attraverso Base64.

Float32[]
   │
   ▼
binary payload
   │
   ▼
Base64
   │
   ▼
JSON / REST

La rappresentazione logica del vettore non cambia.

15. Similarity Search in ArcGIS Pro

Supponiamo di voler trovare negli Stati Uniti aree con caratteristiche analoghe a una determinata zona universitaria.

Il workflow concettuale è:

Query polygon
      │
      ▼
intersect embedding cells
      │
      ▼
E₁, E₂, ..., Eₙ
      │
      ▼
mean embedding
      │
      ▼
       Q
      │
      ▼
cosine similarity
      │
      ▼
all embeddings
      │
      ▼
SIMILARITY ≥ threshold
      │
      ▼
output Feature Class

Se la query interessa più feature, ArcGIS costruisce un unico query embedding attraverso la media:

        1
Q = -------- Σ Eᵢ
        n

Il vettore risultante viene quindi confrontato con gli embedding dello spazio di ricerca utilizzando la cosine similarity.

16. ArcPy: Find Similar Features Using Embeddings

L'operazione può essere automatizzata direttamente in Python:

import arcpy

embedding_features = (
    r"C:\GIS\GeoAI.gdb\LocationEmbeddings"
)

query_features = (
    r"C:\GIS\GeoAI.gdb\QueryArea"
)

output_features = (
    r"C:\GIS\GeoAI.gdb\SimilarAreas"
)

threshold = 0.85

arcpy.geoai.FindSimilarFeaturesUsingEmbeddings(
    embedding_features,
    query_features,
    output_features,
    threshold
)

Il risultato è una nuova feature class contenente le feature che superano la soglia di similarità.

Questa query:

Find areas similar to this area

è profondamente diversa da:

Find areas within 50 km

oppure:

population > 100000
AND income BETWEEN ...
AND age BETWEEN ...
AND ...

Nel primo caso non stiamo definendo manualmente le caratteristiche che rendono due aree simili.

Utilizziamo invece la struttura dello spazio latente appresa dal modello.

17. Implementare la stessa ricerca senza il tool ArcGIS

Possiamo riprodurre il concetto direttamente con NumPy.

import numpy as np

# N feature × D dimensioni
embeddings = np.asarray(embeddings, dtype=np.float32)

# D dimensioni
query = np.asarray(query, dtype=np.float32)

# normalizzazione
embeddings_norm = embeddings / np.linalg.norm(
    embeddings,
    axis=1,
    keepdims=True
)

query_norm = query / np.linalg.norm(query)

# similarity di tutte le feature in una singola operazione matriciale
scores = embeddings_norm @ query_norm

threshold = 0.85

matching_indices = np.where(
    scores >= threshold
)[0]

for index in matching_indices:
    print(index, scores[index])

Questa riga:

scores = embeddings_norm @ query_norm

è particolarmente significativa.

Con una singola moltiplicazione matrice-vettore otteniamo la similarità fra la query e tutte le feature.

18. Il problema della scala: brute force e ANN

Su qualche migliaio di feature un confronto esaustivo è perfettamente gestibile.

Se però abbiamo:

10 milioni di feature
×
768 dimensioni

la ricerca lineare diventa più costosa.

È qui che entrano in gioco gli algoritmi di Approximate Nearest Neighbor, o ANN.

Tra le strutture più utilizzate troviamo:

  • HNSW;
  • IVF;
  • IVF-PQ;
  • product quantization;
  • graph-based vector indexes.

Il concetto è analogo a ciò che da decenni facciamo nei database spaziali.

GIS

Geometry
   │
   ▼
Spatial Index
R-tree / grid / other
   │
   ▼
candidate pruning
   │
   ▼
exact geometry operation

nel mondo vettoriale:

Embedding
   │
   ▼
Vector Index
HNSW / IVF / ...
   │
   ▼
candidate pruning
   │
   ▼
vector similarity

19. Spatial Index + Vector Index

La combinazione delle due tecnologie è probabilmente una delle architetture GIS più interessanti dei prossimi anni.

Feature
   │
   ├── Geometry
   │      │
   │      └── Spatial Index
   │
   ├── Attributes
   │      │
   │      └── B-tree / column index
   │
   └── Embedding
          │
          └── Vector Index

La stessa entità può essere interrogata secondo tre dimensioni differenti:

  • dove si trova;
  • quali proprietà possiede;
  • a cosa assomiglia.

20. La query GIS del futuro

Una query concettuale potrebbe diventare:

SELECT *
FROM Places
WHERE ST_Distance(
        Geometry,
        @SearchPoint
      ) < 50000
ORDER BY VectorDistance(
        Embedding,
        @QueryEmbedding
      )
LIMIT 20;

Prima applichiamo un vincolo geografico:

entro 50 km

e successivamente ordiniamo i candidati in base alla similarità semantica:

più simili al luogo di riferimento

Spatial query e vector search non sono quindi tecnologie concorrenti.

Risolvono dimensioni differenti dello stesso problema.

21. Aggregare gli embedding nello spazio

Un problema molto GIS riguarda il cambio di scala.

Supponiamo di avere embedding a livello H3 ma di voler effettuare un'analisi a livello di contea:

H3 embeddings
     │
     ▼
spatial overlay
     │
     ▼
County
     │
     ▼
aggregated embedding

ArcGIS Pro mette a disposizione Merge Embeddings.

Quando le sorgenti sono poligonali, l'aggregazione considera l'area di sovrapposizione con il poligono target.

In termini concettuali:

                 Σ wᵢ Eᵢ
E_target = -----------------------
                    Σ wᵢ

dove il peso può dipendere dall'area di overlap.

Questo introduce un problema affascinante:

che cosa significa aggregare semanticamente lo spazio?

Nella statistica tradizionale sappiamo aggregare popolazione, reddito, superficie o densità.

Con gli embedding stiamo aggregando invece rappresentazioni latenti apprese.

22. Merge Embeddings con ArcPy

import arcpy

target_features = r"C:\GIS\Data.gdb\Counties"

embedding_features = (
    r"C:\GIS\Data.gdb\H3_Embeddings"
)

output = (
    r"C:\GIS\Data.gdb\CountyEmbeddings"
)

arcpy.geoai.MergeEmbeddings(
    target_features,
    embedding_features,
    output
)

23. Da BLOB a variabili esplicative

Molti algoritmi tradizionali di machine learning si aspettano una matrice tabulare:

X =
[
  [x₁₁, x₁₂, ..., x₁d],
  [x₂₁, x₂₂, ..., x₂d],
  ...
]

Per questo ArcGIS permette di estrarre le componenti dell'embedding dal BLOB creando campi come:

emb_0
emb_1
emb_2
...
emb_255

Il dataset diventa quindi:

OBJECTID
SHAPE
Population
Income
...
emb_0
emb_1
...
emb_255

e può essere utilizzato come input di modelli di regressione, classificazione, clustering o AutoML.

24. Embedding come feature engineering automatizzato

Tradizionalmente un data scientist GIS potrebbe costruire manualmente decine o centinaia di variabili:

population_density
median_income
road_density
distance_to_station
green_area_percentage
building_density
average_age
employment_rate
...

Questa attività viene chiamata feature engineering.

Un embedding può essere visto, con le dovute cautele, come una forma di:

learned feature engineering.

Il modello apprende automaticamente una rappresentazione compatta delle relazioni presenti nei dati.

Questo non significa che gli attributi originali diventino inutili.

Al contrario, una delle strategie più potenti consiste nel combinare:

domain variables
      +
spatial variables
      +
embedding dimensions
      │
      ▼
ML model

25. Un embedding non è una spiegazione

Questa distinzione è fondamentale.

Se un modello utilizza:

median_income = 42,000

la variabile è interpretabile.

Se utilizza:

emb_147 = -0.2738

quel numero, da solo, normalmente non ha alcun significato leggibile.

Gli embedding introducono quindi un trade-off:

feature engineering manuale
        │
        ├── maggiore interpretabilità
        └── maggiore lavoro

embedding
        │
        ├── rappresentazione ricca
        ├── maggiore riusabilità
        └── minore interpretabilità diretta

26. Image embeddings e Earth Observation

Il concetto diventa ancora più potente nel remote sensing.

Invece di classificare immediatamente un'immagine:

Satellite image
      │
      ▼
Classifier
      │
      ▼
urban / forest / water / ...

possiamo produrre prima una rappresentazione generale:

Satellite image
      │
      ▼
Foundation model
      │
      ▼
Embedding
      │
      ├── similarity search
      ├── clustering
      ├── anomaly detection
      ├── classification
      ├── segmentation
      └── downstream fine tuning

Questo è uno dei motivi per cui i geospatial foundation model sono così interessanti.

La rappresentazione può essere riutilizzata in task differenti senza ricominciare ogni volta dal dato grezzo.

27. Location embeddings con ArcGIS API for Python

L'ArcGIS API for Python espone anche una classe Embeddings nel modulo arcgis.learn.

Fra i tipi supportati troviamo:

image
text
location

Concettualmente:

from arcgis.learn import Embeddings

model = Embeddings(
    dataset_type="location"
)

result = model.get(
    input_path,
    return_embeddings=True
)

Per i location embedding la documentazione ArcGIS API for Python indica come backbone predefinito una variante di SatCLIP addestrata su Sentinel-2.

Qui il concetto è differente dal geodemographic embedding.

Non stiamo comprimendo migliaia di variabili Census, ma stiamo costruendo una rappresentazione geografica utilizzando un modello addestrato a catturare struttura e contesto spaziale.

28. "Embedding GIS" non identifica quindi una sola tecnologia

È importante evitare di utilizzare il termine embedding come se identificasse un'unica rappresentazione universale.

Possiamo avere:

Text embedding
Image embedding
Location embedding
Geodemographic embedding
POI embedding
Network embedding
Trajectory embedding
Graph embedding
Multimodal embedding

Due vettori della stessa dimensione prodotti da modelli differenti non appartengono necessariamente allo stesso spazio semantico e non sono automaticamente confrontabili.

Se:

E₁(x) ∈ R²⁵⁶
E₂(x) ∈ R²⁵⁶

non significa:

cos(E₁(x), E₂(y))

abbia un significato valido.

La compatibilità dipende dallo spazio latente costruito durante il training.

29. Model versioning diventa data governance

Da sviluppatore questo porta immediatamente a un problema architetturale.

Se memorizziamo embedding persistentemente, dobbiamo sapere quale modello li ha generati.

Un dataset production-ready dovrebbe quindi conservare informazioni come:

Embedding
EmbeddingModel
EmbeddingModelVersion
EmbeddingDimension
EmbeddingGeneratedAt
EmbeddingSourceVersion

Perché:

model v1 embedding
        ≠
model v2 embedding

anche quando la dimensione è identica.

Aggiornare un modello può richiedere il ricalcolo dell'intero indice vettoriale.

30. Un esempio C#

La cosine similarity non richiede necessariamente Python.

Una semplice implementazione C# potrebbe essere:

static float CosineSimilarity(
    ReadOnlySpan<float> a,
    ReadOnlySpan<float> b)
{
    if (a.Length != b.Length)
        throw new ArgumentException(
            "Vectors must have the same dimension.");

    double dot = 0;
    double normA = 0;
    double normB = 0;

    for (int i = 0; i < a.Length; i++)
    {
        dot += a[i] * b[i];
        normA += a[i] * a[i];
        normB += b[i] * b[i];
    }

    if (normA == 0 || normB == 0)
        return 0;

    return (float)(
        dot /
        (Math.Sqrt(normA) * Math.Sqrt(normB))
    );
}

Un'applicazione .NET potrebbe quindi leggere gli embedding provenienti da ArcGIS, da un database vettoriale o da un modello AI ed effettuare direttamente ranking e filtering.

31. Decodificare il formato Float32 ArcGIS in C#

Dal momento che il BLOB ArcGIS contiene float32 little-endian contigui, il concetto lato .NET è:

static float[] DecodeEmbedding(
    byte[] bytes,
    int expectedDimension)
{
    if (bytes.Length != expectedDimension * sizeof(float))
        throw new InvalidOperationException(
            "Unexpected embedding payload size.");

    var result = new float[expectedDimension];

    for (int i = 0; i < expectedDimension; i++)
    {
        result[i] = BitConverter.ToSingle(
            bytes,
            i * sizeof(float)
        );
    }

    return result;
}

Su una piattaforma little-endian come l'architettura Windows/x64 normalmente utilizzata da ArcGIS Pro, il mapping è diretto; in codice interoperabile è comunque opportuno trattare esplicitamente l'endianness prevista dal formato.

32. Vector database e GIS

Un database vettoriale memorizza oggetti del tipo:

ID
metadata
embedding

Un database GIS tradizionale memorizza:

ID
geometry
attributes

L'evoluzione naturale è:

ID
geometry
attributes
embedding

con:

spatial index
+
attribute indexes
+
vector index

Questo modello rende possibili query ibride estremamente potenti.

33. Hybrid Spatial-Vector Search

Consideriamo una richiesta:

Trova entro 30 km da questa posizione aree che assomigliano a questo distretto commerciale.

La pipeline potrebbe essere:

                         Query
                           │
             ┌─────────────┴─────────────┐
             │                           │
             ▼                           ▼
       Geographic filter           Query embedding
             │                           │
             ▼                           ▼
       Spatial Index               Vector Index
             │                           │
             └─────────────┬─────────────┘
                           ▼
                    Candidate set
                           │
                           ▼
                    similarity rank
                           │
                           ▼
                        Results

Questo tipo di ricerca combina contemporaneamente:

  • geografia;
  • semantica;
  • attributi;
  • AI.

34. GeoRAG: Retrieval Augmented Generation geografico

Il passaggio successivo è collegare questo sistema a un LLM.

In un normale RAG:

User question
     │
     ▼
Text embedding
     │
     ▼
Vector search
     │
     ▼
Documents
     │
     ▼
LLM

In un possibile GeoRAG:

User
 │
 │ "Trova aree industriali simili a questa
 │  entro 50 km e spiegami le differenze"
 │
 ▼
LLM / Agent
 │
 ├────────► intent extraction
 │
 ├────────► spatial query
 │
 ├────────► vector similarity
 │
 ├────────► feature attributes
 │
 ├────────► imagery embeddings
 │
 └────────► external/context data
                │
                ▼
          ArcGIS / Spatial DB
                │
                ▼
           Feature collection
                │
                ▼
               LLM
                │
                ▼
      explanation + map results

L'LLM non deve inventare il risultato geografico.

Il GIS rimane il motore deterministico per geometria, coordinate, overlay, network analysis e spatial constraints.

Il motore vettoriale aggiunge invece il retrieval semantico.

L'LLM orchestra e interpreta i risultati.

35. Geometry, semantics e language reasoning

Possiamo vedere l'architettura come tre livelli.

┌────────────────────────────────────┐
│        LANGUAGE / REASONING        │
│              LLM                   │
├────────────────────────────────────┤
│        SEMANTIC RETRIEVAL          │
│ Embeddings / Vector Search / ANN   │
├────────────────────────────────────┤
│         SPATIAL COMPUTATION        │
│ Geometry / Topology / CRS / GIS    │
└────────────────────────────────────┘

Ognuno risolve un problema differente.

Il GIS calcola.

Gli embedding rappresentano e recuperano similarità.

L'LLM ragiona sull'intento e costruisce una risposta comprensibile.

36. Embedding e Tobler's First Law

Nel GIS è quasi inevitabile collegare questo argomento alla nota prima legge della geografia di Waldo Tobler:

Things that are near tend to be more related than things that are far apart.

Gli embedding introducono però una nuova dimensione.

Due fenomeni possono essere:

far in geographic space
but
near in embedding space

La prossimità geografica rimane fondamentale, ma non è più l'unico concetto di vicinanza disponibile.

Possiamo parlare di:

  • prossimità geografica;
  • prossimità topologica;
  • prossimità temporale;
  • prossimità semantica.

37. Attenzione alla spatial autocorrelation

Gli embedding geografici introducono anche problemi statistici specifici.

Se il training set viene suddiviso casualmente:

80% train
20% test

feature geograficamente vicine possono finire nei due insiemi.

A causa della spatial autocorrelation, questo può produrre valutazioni eccessivamente ottimistiche.

In molti problemi GeoAI è preferibile valutare anche strategie come:

  • spatial block cross-validation;
  • geographic holdout;
  • leave-one-region-out;
  • temporal-spatial split.

Un embedding sofisticato non elimina le regole fondamentali della statistica spaziale.

38. Similarità non significa causalità

Un altro punto essenziale:

embedding similarity
        ≠
causal relationship

Due territori possono avere embedding simili perché condividono numerosi pattern statistici senza che esista alcuna relazione causale diretta.

Gli embedding sono eccellenti strumenti per:

  • retrieval;
  • clustering;
  • feature enrichment;
  • anomaly detection;
  • candidate generation;
  • prediction.

Non costituiscono automaticamente una spiegazione causale.

39. Distribution shift

Un modello di embedding apprende dalla distribuzione osservata durante il training.

Se viene applicato a:

  • un'altra nazione;
  • un altro periodo storico;
  • sensori differenti;
  • urbanizzazioni radicalmente differenti;
  • dati con diversa qualità;

potrebbe verificarsi distribution shift.

Questo è particolarmente importante in ambito geospaziale, dove le distribuzioni cambiano nello spazio e nel tempo.

40. Un embedding USA non è automaticamente un embedding europeo

Gli USA Geodemographic Embeddings sono stati progettati utilizzando dataset e geografie statunitensi.

Il principio è generale, ma il modello non deve essere interpretato come rappresentazione universale di qualsiasi territorio.

Per costruire un equivalente europeo o italiano sarebbe necessario definire un insieme coerente di sorgenti, ad esempio:

ISTAT
Copernicus
Sentinel
OpenStreetMap
land cover
meteorological data
mobility
POI
cadastral/urban information
socioeconomic indicators
...

e addestrare una rappresentazione coerente con il dominio geografico di interesse.

41. Un possibile "Italian Place Embedding"

Immaginiamo, puramente a livello architetturale:

ISTAT ──────────────────────┐
                            │
Sentinel / Copernicus ──────┤
                            │
OpenStreetMap ───────────────┤
                            ├──► Multi-view encoder
POI ────────────────────────┤
                            │
Mobility ───────────────────┤
                            │
Climate / Environment ──────┘
                                   │
                                   ▼
                             PLACE VECTOR
                                 R^d

Ogni cella territoriale italiana avrebbe una rappresentazione numerica general-purpose.

A quel punto potremmo eseguire query come:

Quali aree italiane presentano un profilo urbano, infrastrutturale e socioeconomico simile a questo quartiere?

senza costruire manualmente decine di filtri.

42. Verso il "place foundation model"

Il passo successivo rispetto al semplice embedding è un modello capace di comprendere in maniera multimodale il concetto di luogo.

                 PLACE FOUNDATION MODEL

       ┌──────────────┬──────────────┬──────────────┐
       │              │              │              │
       ▼              ▼              ▼              ▼
    Imagery        Geometry       Network         Text
       │              │              │              │
       └──────────────┼──────────────┼──────────────┘
                      │
                      ▼
              Shared latent space
                      │
       ┌──────────────┼──────────────┐
       ▼              ▼              ▼
   Retrieval      Prediction      Reasoning

In prospettiva potremmo non avere soltanto:

text → vector

ma:

place → vector

e magari:

text ↔ place ↔ image

all'interno di uno spazio multimodale condiviso.

43. Dal GIS basato sugli attributi al GIS basato sulle rappresentazioni

Per decenni una feature GIS è stata concettualmente:

Feature =
Geometry
+
Attributes

Con il GeoAI possiamo iniziare a pensare:

Feature =
Geometry
+
Attributes
+
Learned Representation

Il cambiamento può sembrare piccolo, ma è architetturalmente profondo.

La geometria rappresenta dove.

Gli attributi rappresentano ciò che sappiamo esplicitamente.

L'embedding rappresenta una sintesi latente di ciò che il modello ha appreso.

44. Gli embedding non sostituiranno il GIS classico

Gli embedding non eliminano:

  • buffer;
  • overlay;
  • spatial join;
  • network analysis;
  • coordinate systems;
  • geocoding;
  • topologia;
  • spatial statistics.

Se devo sapere se due poligoni si intersecano:

ST_Intersects(A, B)

rimane la soluzione corretta.

Non avrebbe senso chiedere a un embedding di approssimare un predicato geometrico deterministico.

Ma se la domanda è:

quali territori presentano un contesto simile a questo?

allora entriamo esattamente nel dominio degli embedding.

45. La vera evoluzione è l'integrazione

Il GIS futuro probabilmente non sarà:

GIS
oppure
AI

ma:

             GIS PLATFORM

Geometry ─────── Spatial Engine
                     │
Attributes ───── Data Engine
                     │
Embeddings ───── Vector Engine
                     │
Models ───────── GeoAI Engine
                     │
LLM ──────────── Agent / Reasoning
                     │
                     ▼
              Geographic Intelligence

Ed è probabilmente qui che il concetto di GeoAI diventa realmente interessante per chi sviluppa sistemi GIS.

Conclusioni

Gli embedding stanno introducendo nel GIS un nuovo modo di rappresentare l'informazione geografica.

Non descrivono semplicemente dove si trova un oggetto e non sostituiscono gli attributi tradizionali.

Costruiscono invece uno spazio latente nel quale luoghi, immagini e feature possono essere confrontati in funzione delle caratteristiche apprese da un modello.

La distinzione fondamentale è:

Geographic distance
        ≠
Semantic distance

e le due possono essere utilizzate contemporaneamente.

Spatial Index
     +
Vector Index
     +
GIS Attributes
     +
Foundation Models
     +
LLM / Agents

aprono la strada a sistemi capaci non soltanto di rispondere:

Dove si trova?

ma anche:

A quali luoghi assomiglia?

e, in prospettiva:

Quali caratteristiche rendono questo luogo simile ad altri, quali differenze sono geograficamente rilevanti e come posso utilizzarle per prendere una decisione?

Per chi lavora nel GIS questo è probabilmente uno dei passaggi più interessanti dell'attuale evoluzione GeoAI: la feature geografica non è più soltanto una geometria con attributi. Può diventare una rappresentazione appresa.


Riferimenti tecnici

  • Esri — Concepts of USA Geodemographic Embeddings
  • Esri — Use the USA Geodemographic Embeddings
  • ArcGIS Pro — Embeddings Based Analysis toolset
  • ArcGIS Pro — Find Similar Features Using Embeddings
  • ArcGIS Pro — How Find Similar Features Using Embeddings works
  • ArcGIS Pro — Merge Embeddings
  • ArcGIS Pro — Embeddings in BLOB fields
  • ArcGIS API for Python — arcgis.learn.Embeddings

Nota: gli USA Geodemographic Embeddings 2026 citati nell'articolo sono un modello/dataset specifico dell'ecosistema ArcGIS e, al momento della stesura, Esri li indica come Beta. Gli esempi architetturali relativi a place embeddings, GeoRAG e sistemi multimodali descrivono invece pattern generali e possibili evoluzioni tecnologiche, non uno specifico prodotto ArcGIS.