Un agent IA qui rédige une analyse du terrain MilX

Tutoriel 15 sur 17 · Expert · 60 min

Donnez à un agent IA une zone et une mission, et recevez un fichier .milxlyz avec obstacles, axes d’approche, terrain clé et observation déjà dessinés — une première ébauche que vous contrôlez et terminez dans map.army.

L’agent fait exactement ce que fait l’analyse du terrain manuelle, dans le même ordre OAKOC. Suivez d’abord ce tutoriel : vous ne pouvez relire l’ébauche de l’agent que si vous savez à quoi ressemble une bonne analyse.

Ce qu’il vous faut

  • Un agent IA capable d’exécuter des outils et d’écrire des fichiers — par exemple Claude Code, ou un agent que vous construisez sur une API d’IA.
  • Python 3 pour le programme d’écriture ci-dessous, et un accès à des données de terrain pour votre zone (voir l’étape 3).
  • L’exemple terrain-analysis-example.milxlyz comme modèle pour l’agent.
  • Un service d’IA que votre organisation approuve pour les données concernées.
Astuce: N’envoyez jamais d’informations classifiées ou personnelles à un service d’IA public. Positions, missions et listes d’unités quittent votre organisation dès que vous les envoyez. Utilisez un service approuvé, sur site, là où vos règles l’exigent.

Comment l’agent fonctionne

Un document MilX contient des layers avec symboles et graphiques tactiques, plus des métadonnées.

Un modèle de langage ne voit pas le terrain. Si on lui demande une analyse du terrain de mémoire, il invente des rivières et des crêtes plausibles. Une ébauche exacte demande donc trois éléments :

  1. Des outils de données qui récupèrent de vrais faits sur le terrain de la zone : altitude (pour trouver les pentes raides), cours d’eau, forêts, zones bâties, routes et ponts.
  2. Le modèle, qui applique les règles OAKOC à ces faits et décide ce qu’il faut dessiner.
  3. Un programme d’écriture qui transforme les décisions en fichier MilX® valide — écrit par du code, non saisi par le modèle, pour que le format soit toujours correct.

map.army n’intervient qu’à la fin : vous y chargez le fichier terminé et vous le relisez.

Étape 1 : enseigner le format à l’agent

Un layer MilX est du XML, zippé sous le nom Layer.milxly dans un .milxlyz. Chaque graphique est un code de symbole MIL-STD-2525C avec ses modificateurs de texte, plus une liste de points. Donnez à l’agent le fichier d’exemple et ces règles dans ses instructions :

  • Chaque code de symbole compte exactement 15 caractères. Le 2e caractère est l’affiliation (F ami, H hostile), le 4e le statut (P présent, A prévu).
  • Les points sont en WGS84 : X est la longitude, Y la latitude.
  • Les graphiques multipoints ont un ordre de points : un axe d’attaque prend d’abord la pointe, puis le départ, puis un point derrière la pointe qui fixe la largeur de la tête de flèche.
  • Les valeurs d’attribut sont validées par le MSS®. Une valeur erronée — 60 là où trois chiffres sont requis — fait disparaître le symbole. Laissez l’agent n’utiliser que le modificateur de texte T, sauf si vous vérifiez les autres.

Le contexte complet se trouve dans IA et map.army : générer et analyser des fichiers MilX et Format de fichier MilX — Guide du format d’échange map.army.

Étape 2 : lui donner un vocabulaire de symboles fixe

Ne laissez pas le modèle choisir librement les symboles. Donnez-lui ce tableau et dites-lui de n’utiliser rien d’autre :

Élément OAKOCSymbole (MIL-STD-2525C)CodePoints
Terrain fortement restreint (NO-GO)Obstacle Restricted AreaGFMPOGR--------zone, 3 ou plus
Cours d’eau, ravin, remblaiObstacle LineGFMPOGL--------ligne, 2 ou plus
Axe d’approche ennemiAxis of Advance, Ground (hostile)GHGPOLAG-------pointe, départ, largeur
Terrain cléPoint Of InterestGFGPGPRI-------1
Poste d’observationObservation Post / OutpostGFGPDPO--------1
Là où un axe se resserreNamed Area Of InterestGFGPSAN--------zone, 3 ou plus

Chaque code provient de la liste des symboles MIL-STD-2525C. Le texte T dit pourquoi : Pentes NO-GO de plus de 45 %, K1 pont de La Punt.

Étape 3 : l’alimenter en données de terrain réelles

Donnez à l’agent des outils qui renvoient des faits, pas des cartes. Sources ouvertes courantes :

  • Altitude — un modèle numérique d’élévation comme Copernicus DEM ou celui de votre service topographique national. L’outil calcule des classes de pente pour la zone : par exemple GO en dessous de 30 %, SLOW-GO de 30 à 45 %, NO-GO au-dessus de 45 % pour des véhicules chenillés. Fixez les seuils pour vos véhicules.
  • Eau, forêt, zones bâties, routes, ponts — OpenStreetMap via l’API Overpass, ou vos données topographiques nationales.

Donnez ensuite vos instructions à l’agent en termes simples :

Zone d'intérêt : ouest 9.84, sud 46.54, est 10.03, nord 46.66 (WGS84).
Mission : défendre la vallée contre un ennemi qui avance depuis le nord-est.
1. Appelle l'outil d'altitude et l'outil de données cartographiques pour la zone.
2. Marque les zones de pente NO-GO et les obstacles linéaires (cours d'eau)
   d'après les données.
3. Déduis les axes d'approche ennemis entre les obstacles,
   assez larges pour une compagnie mécanisée.
4. Marque le terrain clé (ponts, carrefours, hauteurs dominantes) et un
   poste d'observation par axe ; une NAI là où chaque axe se resserre.
5. Renvoie les graphiques sous forme de liste pour le programme d'écriture.
   N'utilise que le tableau de symboles fourni. Donne une raison dans T
   pour chaque graphique.

Étape 4 : écrire le fichier avec du code

Barre d'outils du gestionnaire des layers de map.army sous « Layers MilX locaux », icône Charger MilX entourée

L’agent transmet sa liste à un petit programme d’écriture, qui contrôle chaque graphique avant d’écrire quoi que ce soit. Ce programme a produit le fichier d’exemple :

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))

Chargez le résultat avec Charger MilX dans le gestionnaire des layers, ou publiez-le sur un serveur web et ouvrez-le avec un lien ?layer=.

Astuce: Un .milxlyz est un fichier ZIP. Écrivez-le en mode binaire et tenez-le à l’écart des outils qui convertissent les fins de ligne — un seul octet converti le rend illisible.

Étape 5 : contrôler l’ébauche avant de lui faire confiance

Le fichier se charge même quand l’analyse est fausse. Relisez-le sur la carte, idéalement en vue 3D :

  • Chaque zone NO-GO se trouve-t-elle vraiment sur un terrain raide ou sur l’eau, et ne manque-t-il aucun passage entre elles ?
  • Chaque axe d’approche passe-t-il entre les obstacles, dans la bonne direction, la pointe sur l’objectif ?
  • Chaque point de terrain clé est-il sur le pont, le carrefour ou la hauteur que son texte nomme ?
  • Corrigez dans map.army ce qui est faux, ajoutez ce que les données ne peuvent pas savoir — la météo, l’équipement de l’ennemi — et enregistrez le layer comme le vôtre.

L’agent vous épargne le dessin, pas le jugement. L’analyse est prête quand une personne l’a contrôlée.

Tutoriel suivant

Continuez avec Échange NVG avec les C2 pour transmettre l’analyse terminée à d’autres systèmes. Référence : IA et map.army : générer et analyser des fichiers MilX, Importer un calque MilX, vectoriel ou image, Charger un calque MilX via un paramètre URL dans map.army.

Dernière mise à jour: