Skip to content

Topologie

La topologie est le graphe qui transforme « un incident sur le host edge-prod-04 » en « un incident qui met à terre payments, search et email ». Sans elle, le LLM ne peut raisonner que sur la série unique en feu.

ADR-025

Les BaseTools de topologie actuels (expand_topology, find_topology_node) ont atterri le 2026-05-18. Avant ça, le LLM avait une liste plate de devices et aucune façon de parcourir les relations ; « qu'est-ce qui dépend de X » nécessitait que l'opérateur sache déjà la réponse.

Le modèle de données

Quatre tables, toutes en MySQL :

TableContient
topology_nodesUne ligne par nœud. A un type (device / service / cluster / ...), un name et un props_json libre.
topology_node_typesL'ensemble fermé de valeurs node.type autorisées.
topology_relationsArête dirigée src_node_id -> dst_node_id avec un type.
topology_relation_typesEnsemble fermé de types d'arêtes, chacun tagué d'un champ semantics (hard_dep / runtime_dep / traffic / annotation / observation).

Le tag semantics est l'idée clé. Une arête tagguée hard_dep propage la défaillance (si src meurt, dst est affecté) ; une arête tagguée annotation non. La marche de blast-radius s'en sert pour filtrer.

Voir internal/manager/biz/topology/.

D'où viennent les données

Trois sources, en couches :

  1. Auto depuis les spans — le processeur service_graph de Tempo émet des arêtes service_a -> service_b avec un tag de sémantique routes_to. Le manager les miroir dans topology_relations sur un tick de sync.
  2. Auto depuis les edges — chaque edge enregistré devient un nœud type=device ; l'id de nœud est back-linké vers la colonne host_devices.node_id pour que expand_topology(device_id=X) se résolve à travers.
  3. Manuel — les opérateurs ajoutent des nœuds type=service / type=cluster et des arêtes via la page /topology de la SPA. Utilisé pour les nœuds que vous voulez adresser mais qui ne sont pas directement observés (une base de données managée, une API tierce).

Outils

expand_topology

Marche vers l'extérieur depuis un nœud, renvoie chaque nœud atteignable plus comment il a été atteint. Profondeur BFS par défaut 2, plafond 5. Direction par défaut both (le blast radius est symétrique — ce qui pourrait casser ceci, ET ce que ceci casse).

json
{
  "node_id": 142,
  "depth": 2,
  "only_propagating": true,
  "direction": "downstream"
}

Ou, quand vous partez d'un id de device :

json
{ "device_id": 17, "depth": 3 }

L'outil résout device_id → device.node_id automatiquement. only_propagating=true (défaut) ne parcourt que les arêtes hard_dep / runtime_dep / traffic ; passez à false pour inclure les arêtes observation / annotation (utile pour les cas « montre-moi tout ce qui est lié à X »).

Les hits retournés portent les métadonnées de chemin dont le LLM a besoin pour raisonner sur l'impact :

json
{
  "center":  { "node_id": 142, "node_name": "payments-api", "node_type": "service", "hops": 0, "propagates_failure": false },
  "max_hops": 2,
  "reachable_count": 7,
  "reachable": [
    { "node_id": 71, "node_name": "edge-prod-04", "node_type": "device", "hops": 1,
      "relation_type": "deployed_on", "semantics_tag": "runtime_dep", "reached_via": "downstream",
      "propagates_failure": true,
      "via_node_id": 142, "via_node_name": "payments-api" }
  ]
}

La liste plate (pas de struct imbriquée par voisin) est intentionnelle — garde le JSON bon marché à embarquer dans le prompt. Voir expand_topology_basetool.go.

find_topology_node

L'étape préalable « j'ai un nom donné par un humain, donne-moi un node_id ». La persona exécute ceci avant expand_topology chaque fois que le prompt mentionne un service / host par nom :

text
User: "what does loki-write depend on?"
Agent:
  → find_topology_node{ name: "loki-write" }
    ← { node_id: 219, node_type: "service", name: "loki-write" }
  → expand_topology{ node_id: 219, direction: "upstream" }
    ← { reachable_count: 4, ... }

Les deux sont enregistrés comme BaseTools ScopeManager (pas d'argument edge_id) — la DB de topologie vit côté manager.

Marche de blast-radius en pratique

Le prompt de la persona investigator inclut un « après avoir identifié le service en feu, appelle expand_topology pour voir ce qui d'autre est affecté » explicite. C'est ainsi que le related_alerts du rapport et la section « 业务影响 / Business impact » se peuplent — l'agent parcourt le graphe depuis le device en feu vers le haut / le bas et cross-check quels autres incidents sont partis dans la même fenêtre sur ces nœuds.

Le chemin de code pertinent :

  1. correlate_incident renvoie des résumés métriques + logs + traces plus le device_id de l'incident.
  2. expand_topology { device_id, direction: both, depth: 2 } renvoie le set atteignable.
  3. L'extraction Pass-2 lit la narrative du worker et tire pinpointed_target (le patient zéro) + related_alerts (la cascade).

Voir aussi

  • RCA — la persona investigator qui utilise ces outils.
  • Skills — comment expand_topology est enregistré à la fois dans le sac de BaseTools et le registre de skills (inventory_bridge).
  • Concepts — le vocabulaire Edge / Device / Node.