Agente IA che redige un'analisi del terreno in MilX

Tutorial 15 di 17 · Esperto · 60 min

Date a un agente IA un’area e una missione e ricevete un file .milxlyz con ostacoli, vie di approccio, terreno chiave e osservazione già disegnati — una prima bozza che poi verificate e rifinite in map.army.

L’agente fa esattamente ciò che fa l’analisi del terreno manuale, nello stesso ordine OAKOC. Seguite prima quel tutorial: potete verificare la bozza dell’agente solo se sapete come appare una buona analisi.

Cosa vi serve

  • Un agente IA in grado di eseguire strumenti e scrivere file — per esempio Claude Code, oppure un agente costruito su un’API di IA.
  • Python 3 per lo scrittore di file qui sotto e l’accesso ai dati del terreno della vostra area (vedi il passo 3).
  • L’esempio terrain-analysis-example.milxlyz come modello per l’agente.
  • Un servizio di IA approvato dalla vostra organizzazione per i dati coinvolti.
Suggerimento: Non inviate mai informazioni classificate o personali a un servizio di IA pubblico. Posizioni, missioni ed elenchi di unità lasciano la vostra organizzazione nel momento in cui li inviate. Usate un servizio approvato e locale (on-premise) dove le vostre norme lo richiedono.

Come funziona l’agente

Un documento MilX contiene layer con simboli e grafiche tattiche, più i metadati.

Un modello linguistico non vede il terreno. Se gli chiedete un’analisi del terreno a memoria, inventa fiumi e creste plausibili. Una bozza accurata richiede quindi tre componenti:

  1. Strumenti di dati che recuperano fatti reali sul terreno dell’area: altimetria (per trovare i pendii ripidi), fiumi, boschi, zone edificate, strade e ponti.
  2. Il modello, che applica le regole OAKOC a questi fatti e decide cosa disegnare.
  3. Uno scrittore che trasforma le decisioni in un file MilX® valido — scritto dal codice, non digitato dal modello, così il formato è sempre corretto.

map.army entra in gioco solo alla fine: caricate il file finito e lo verificate lì.

Passo 1: insegnare il formato all’agente

Un layer MilX è un XML, compresso come Layer.milxly dentro un .milxlyz. Ogni grafica è un codice simbolo MIL-STD-2525C con i suoi modificatori di testo, più un elenco di punti. Date all’agente il file di esempio e queste regole nelle sue istruzioni:

  • Ogni codice simbolo ha esattamente 15 caratteri. Il 2° carattere è l’atteggiamento (F amico, H ostile), il 4° lo stato d’impiego (P presente, A previsto).
  • I punti sono in WGS84: X è la longitudine, Y la latitudine.
  • Le grafiche multipunto hanno un ordine dei punti: un asse di avanzata richiede prima la punta, poi l’inizio, poi un punto dietro la punta che definisce la larghezza della freccia.
  • I valori degli attributi sono convalidati da MSS®. Un valore errato — 60 dove servono tre cifre — fa sparire il simbolo. Lasciate che l’agente usi solo il modificatore di testo T, a meno che non ne verifichiate altri.

Il quadro completo è in IA con map.army: generare e analizzare file MilX e Formato di file MilX — Guida al formato di scambio map.army.

Passo 2: dargli un vocabolario di simboli fisso

Non lasciate che il modello scelga i simboli liberamente. Dategli questa tabella e ditegli di non usare altro:

Elemento OAKOCSimbolo (MIL-STD-2525C)CodicePunti
Terreno fortemente ristretto (NO-GO)Obstacle Restricted AreaGFMPOGR--------area, 3 o più
Fiume, burrone, terrapienoObstacle LineGFMPOGL--------linea, 2 o più
Via di approccio nemicaAxis of Advance, Ground (hostile)GHGPOLAG-------punta, inizio, larghezza
Terreno chiavePoint Of InterestGFGPGPRI-------1
Posto di osservazioneObservation Post / OutpostGFGPDPO--------1
Dove una via di approccio si restringeNamed Area Of InterestGFGPSAN--------area, 3 o più

Ogni codice proviene dall’elenco dei simboli MIL-STD-2525C. Il testo T dice perché: pendii NO-GO oltre il 45 %, K1 ponte La Punt.

Passo 3: fornirgli dati reali del terreno

Date all’agente strumenti che restituiscono fatti, non mappe. Fonti aperte comuni:

  • Altimetria — un modello digitale di elevazione come Copernicus DEM o il modello del vostro servizio topografico nazionale. Lo strumento calcola le classi di pendenza dell’area: per esempio GO sotto il 30 %, SLOW-GO 30–45 %, NO-GO sopra il 45 % per i veicoli cingolati. Impostate le soglie per i vostri veicoli.
  • Acqua, bosco, zone edificate, strade, ponti — OpenStreetMap tramite l’API Overpass, oppure i vostri dati topografici nazionali.

Poi istruite l’agente a parole semplici:

Area di interesse: ovest 9.84, sud 46.54, est 10.03, nord 46.66 (WGS84).
Missione: difendere la valle contro un nemico che avanza da nord-est.
1. Chiamare lo strumento di altimetria e quello dei dati cartografici per l'area.
2. Contrassegnare le aree di pendio NO-GO e gli ostacoli lineari (fiumi) in base ai dati.
3. Ricavare le vie di approccio nemiche tra gli ostacoli,
   abbastanza larghe per una compagnia meccanizzata.
4. Contrassegnare il terreno chiave (ponti, nodi stradali, alture dominanti) e un
   posto di osservazione per ogni via di approccio; una NAI dove ogni via si restringe.
5. Restituire le grafiche come elenco per lo scrittore. Usare solo la tabella
   di simboli fornita. Indicare un motivo in T per ogni grafica.

Passo 4: scrivere il file con il codice

Barra del Gestore dei layer di map.army sotto 'Local MilX Layers', con l'icona Carica MilX cerchiata

L’agente passa il suo elenco a un piccolo scrittore, che controlla ogni grafica prima di scrivere qualsiasi cosa. Questo scrittore ha prodotto il file di esempio:

import io, re, zipfile
from xml.sax.saxutils import escape

SIDC = re.compile(r"^[SG][FHNU][A-Z][PA][A-Z-]{11}$")

def check(sidc, points, bbox):
    if not SIDC.match(sidc):
        raise ValueError(f"not a 15-character 2525C code: {sidc}")
    need = 2 if sidc[4:7] == "OGL" else 3 if sidc[4:6] in ("OL", "OG", "SA") else 1
    if len(points) < need:
        raise ValueError(f"{sidc}: needs at least {need} points")
    west, south, east, north = bbox
    for lon, lat in points:
        if not (west <= lon <= east and south <= lat <= north):
            raise ValueError(f"{sidc}: {lon},{lat} is outside the area")

def graphic(sidc, points, attributes):
    symbol = f'<Symbol ID="{sidc}">' + "".join(
        f'<Attribute ID="{k}">{escape(v)}</Attribute>' for k, v in attributes.items()
    ) + "</Symbol>"
    pts = "".join(f"<Point><X>{x:.6f}</X><Y>{y:.6f}</Y></Point>" for x, y in points)
    return (f"<MilXGraphic><MssStringXML>{escape(symbol)}</MssStringXML>"
            f"<PointList>{pts}</PointList></MilXGraphic>")

def write_layer(path, name, graphics, bbox):
    for g in graphics:
        check(g[0], g[1], bbox)
    xml = ('<?xml version="1.0" encoding="UTF-8" standalone="no"?>'
           '<MilXDocument_Layer xmlns="http://gs-soft.com/MilX/V3.1" '
           'xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">'
           "<MssLibraryVersionTag>2025.02.20</MssLibraryVersionTag>"
           f"<MilXLayer><Name>{escape(name)}</Name><LayerType>Normal</LayerType>"
           "<GraphicList>" + "".join(graphic(*g) for g in graphics) + "</GraphicList>"
           "<CoordSystemType>WGS84</CoordSystemType><ViewScale>0.1</ViewScale>"
           "<SymbolSize>1</SymbolSize></MilXLayer></MilXDocument_Layer>")
    buffer = io.BytesIO()
    with zipfile.ZipFile(buffer, "w", zipfile.ZIP_DEFLATED) as z:
        z.writestr("Layer.milxly", xml)
    with open(path, "wb") as f:
        f.write(buffer.getvalue())

write_layer("terrain-analysis.milxlyz", "Terrain analysis (AI draft)", [
    ("GFMPOGL--------", [(9.885, 46.552), (9.925, 46.578), (10.0, 46.625)], {"T": "Inn"}),
    ("GHGPOLAG-------", [(9.89, 46.562), (10.01, 46.64), (9.90, 46.574)], {"T": "AA 1"}),
    ("GFGPGPRI-------", [(9.928, 46.582)], {"T": "K1 bridge La Punt"}),
], bbox=(9.84, 46.54, 10.03, 46.66))

Caricate il risultato con Carica MilX nel Gestore dei layer, oppure pubblicatelo su un server web e apritelo con un link ?layer=.

Suggerimento: Un .milxlyz è un file ZIP. Scrivetelo in modalità binaria e tenetelo lontano da strumenti che convertono i fine riga — un solo byte convertito lo rende illeggibile.

Passo 5: verificare la bozza prima di fidarsene

Il file si carica anche quando l’analisi è sbagliata. Verificatelo sulla mappa, possibilmente nella vista 3D:

  • Ogni area NO-GO si trova davvero su terreno ripido o sull’acqua, e non manca nessun varco tra di esse?
  • Ogni via di approccio corre tra gli ostacoli, nella direzione giusta, con la punta sull’obiettivo?
  • Ogni punto di terreno chiave si trova sul ponte, sul nodo stradale o sull’altura indicati dal suo testo?
  • Correggete in map.army ciò che è sbagliato, aggiungete ciò che i dati non possono sapere — il meteo, l’equipaggiamento del nemico — e salvate il layer come vostro.

L’agente vi risparmia il disegno, non il giudizio. L’analisi è pronta quando una persona l’ha verificata.

Prossimo tutorial

Proseguite con Scambio NVG con sistemi C2 per consegnare l’analisi finita ad altri sistemi. Riferimenti: IA con map.army: generare e analizzare file MilX, Importare layer MilX, vettoriali e immagine in map.army, Caricare un layer MilX tramite parametro URL in map.army.

Ultimo aggiornamento: