En 2018, j’ai élaboré un modèle de réseau afin de déterminer où investir mon temps au sein de la communauté technologique de l’Iowa. Ce modèle a fini par compter environ 10 000 éléments : entreprises, organisations, personnes, villes, connexions. J’ai utilisé la centralité par vecteur propre pour mettre en évidence les nœuds auxquels je n’étais pas connecté, mais qui présentaient une forte connectivité ailleurs. Cela a influencé des décisions concrètes : j’ai rejoint le conseil d’administration de TAI, j’ai découvert des communautés dont j’ignorais l’existence et j’ai cartographié les différences de densité entre Des Moines et les écosystèmes côtiers.

Ce modèle m’a marqué. Au fil des années passées chez Brale, les graphes de relations orientés par la force reviennent sans cesse : ils mettent en correspondance les émetteurs, les actifs et les infrastructures, et relient les opérateurs de programmes aux blockchains sur lesquelles ils fonctionnent. À chaque fois, quelqu’un réinvente le langage visuel. Que signifie une couleur ? Que représente une ligne épaisse ? Quelle forme distingue une entreprise d’une personne ou d’un événement ? Ces décisions sont prises à chaque nouveau projet. La personne suivante qui ouvre le graphe doit tout décomposer avant de pouvoir en comprendre le contenu.

L’année dernière, le CSF (Commons Stablecoin Format) a normalisé la manière dont nous représentons les flux de fonds. Il suffit de coller la spécification dans un modèle de langage de grande envergure (LLM), de demander un flux de fonds «stablecoin », et le résultat respecte systématiquement le format. Je souhaitais obtenir le même résultat pour les graphes de relations. J’ai donc rédigé le Graphing Standard Format (GSF), une petite grammaire qui définit comment le type détermine la forme, comment le poids détermine la taille, et comment les niveaux de densité contrôlent les informations divulguées.

Voici mon réseau, représenté au format GSF :

densité
GSF v0.5.2

Les cercles représentent des personnes. Les rectangles arrondis représentent des organisations. Les triangles représentent des événements – distincts des entreprises qui les organisent. Les losanges représentent des lieux. Les hexagones représentent des concepts. Les pastilles représentent des systèmes. Cliquez sur n’importe quel nœud pour afficher sa fiche de profil. Basculez en mode « Medium » pour voir les couleurs. Vous n’avez pas eu à prendre ces décisions. C’est GSF qui s’en est chargé.

Voici une vidéo présentant l’utilisation de GSF pour la première fois. Le résultat est plutôt réussi !

GSF et CSF

CSF GSF
Résultat Diagrammes de séquence Mermaid Graphiques de relations D3
Réponses Comment la valeur passe de A à B, dans l’ordre Ce qui existe et comment cela est relié
Nature Temporel, ordonné par étapes Structurel, non temporel
Niveaux Léger / Moyen / Lourd Léger / Moyen / Lourd

Les deux implémentent les mêmes primitives de la couche de valeur : ValueType, TransferType, Exchange. La seule perte lors du passage de CSF à GSF est l'ordre de séquence, car les graphes sont non temporels.

La norme

GSF définit les règles de visualisation – et non la visualisation elle-même. Son utilisation implique que vous définissiez ce qu’il faut afficher et que le format se charge de la manière de l’afficher. La base de référence reste cohérente d’un projet à l’autre.

Trois points à retenir :

  • GSF est l’ensemble de règles. Il n’est jamais visualisé.
  • Un ensemble de données est une {view, nodes, links} instance conforme au GSF. C’est ce qui est rendu.
  • Un moteur de rendu utilise les règles ainsi qu’un ensemble de données pour générer l’image.

Quatre primitives. Tout ce dont un moteur de rendu a besoin :

  1. Relation – un lien entre exactement deux entités. Les liens créent le graphe.
  2. Type – le classificateur qualitatif. Il détermine la forme et la couleur.
  3. Variables – l’ensemble des détails. Contient tout ce que le type ne contient pas.
  4. Poids – la grandeur quantitative. Il détermine la taille et la largeur.

La règle d’encodage : valeur vs valeurs. La valeur quantitative unique (un nombre, véhiculé par weight) détermine la taille et la largeur. Les valeurs qualitatives (catégorie, statut, libellé) déterminent la forme, la couleur, le regroupement et ce qui s’affiche au survol.

Un choix de conception qui mérite d’être souligné : les types de relations sont des chaînes ouvertes. Il n’y a pas de liste fermée. Un ensemble de données définit les types dont il a besoin – mon graphique ci-dessus utilise founder, cofounder, spinout, et operates, dont aucun ne figure dans la spécification. Le rendu s’est bien passé. GSF définit l’encodage (comment les types se transforment en formes et en couleurs), pas le vocabulaire (quels types vous êtes autorisé à utiliser).

Densité

Même cadran que pour le CSF. Niveau de détail et de couleur révélé par le moteur de rendu :

  • Léger – noir et blanc. La forme code le type, le style de ligne code la classe de relation (continue = valeur, en pointillés = données, en pointillés doubles = dérivée), l’épaisseur code l’amplitude, la pointe de flèche code la direction. Pas de couleur. Prêt à l’impression.
  • Moyen – ajoute de la couleur sous forme de superposition, une légende et des variables au survol.
  • Intens – l’enregistrement complet. Toutes les variables, les points d’extrémité de transfert, les possibilités d’extension.

Une seule règle : le mode « Léger » doit être lisible en noir et blanc. La couleur n’est jamais le seul signal.

Le format

Un lien doit source, destination, et type. Tout le reste est facultatif :

{
  "format": "gsf",
  "version": "0.5.2",
  "renderer": "d3-force",
  "view": { "level": "light", "hops": 1, "focus": ["Person A"] },
  "links": [
    { "source": "Person A", "destination": "Person B", "type": "message" }
  ]
}

Pour les graphes de couche de valeur, les objets d’extrémité portent value_type et transfer_type de chaque côté. Lorsqu’ils diffèrent, cela signale un échange – et via identifie l’échangeur :

{
  "format": "gsf",
  "version": "0.5.2",
  "renderer": "d3-force",
  "view": { "level": "heavy", "hops": 1, "focus": ["Brale"] },
  "nodes": [
    { "id": "Sender", "type": "org" },
    { "id": "Brale", "type": "org", "variables": { "sub_type": "exchange" } },
    { "id": "Recipient Wallet", "type": "system", "variables": { "sub_type": "wallet" } }
  ],
  "links": [
    {
      "source": { "id": "Sender", "value_type": "USD", "transfer_type": "wire" },
      "destination": { "id": "Recipient Wallet", "value_type": "USDC", "transfer_type": "solana" },
      "type": "transfers_via",
      "via": "Brale",
      "weight": 1000,
      "variables": { "exchange": "USD -> USDC", "rate": 1.0 }
    }
  ]
}

Utilisation

Collez le fichier gsf-0.5.2.json dans un LLM et demandez-lui de convertir le matériel source en un ensemble de données GSF. Il respecte systématiquement le format, tout comme le CSF. Le llm_instructions bloc de la spécification est conçu pour être directement exploité par une machine. Consultez le dépôt GSF pour obtenir la dernière version.

La norme est open source : github.com/benmilne-com/standards/gsf. Créez une branche, utilisez-la, contribuez-y.

La structure est libre.