Skip to content

Topologia

Topologia é o grafo que converte "um incidente no host edge-prod-04" em "um incidente que derruba payments e search e email". Sem ele o LLM só consegue raciocinar sobre a única série disparando.

ADR-025

Os BaseTools de topologia atuais (expand_topology, find_topology_node) entraram em 2026-05-18. Antes disso, o LLM tinha uma lista plana de devices e nenhuma forma de percorrer relações; "o que depende de X" exigia que o operador já soubesse a resposta.

O modelo de dados

Quatro tabelas, todas no MySQL:

TabelaMantém
topology_nodesUma linha por nó. Tem um type (device / service / cluster / ...), um name, e um props_json free-form.
topology_node_typesO conjunto fechado de valores permitidos de node.type.
topology_relationsAresta direcionada src_node_id -> dst_node_id com um type.
topology_relation_typesConjunto fechado de tipos de aresta, cada um marcado com um campo semantics (hard_dep / runtime_dep / traffic / annotation / observation).

A tag semantics é a ideia-chave. Uma aresta marcada hard_dep propaga falha (se src morre, dst é afetado); uma marcada annotation não. O walk de blast-radius usa isso para filtrar.

Veja internal/manager/biz/topology/.

De onde os dados vêm

Três fontes, em camadas:

  1. Auto de spans — o processor service_graph do Tempo emite arestas service_a -> service_b com a tag de semântica routes_to. O manager espelha essas para topology_relations em um tick de sync.
  2. Auto de edges — todo edge registrado vira um nó type=device; o id do nó é back-linkado à coluna host_devices.node_id para que expand_topology(device_id=X) resolva.
  3. Manual — operadores adicionam nós type=service / type=cluster e arestas pela página /topology do SPA. Usado para nós que você quer endereçar mas que não são diretamente observados (um banco gerenciado, uma API de terceiro).

Tools

expand_topology

Percorra para fora a partir de um nó, retorne todo nó alcançável mais como foi alcançado. BFS padrão depth 2, cap 5. Direção padrão both (o blast radius é simétrico — o que pode quebrar isso, E o que isso quebra).

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

Ou, quando você parte de um device id:

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

A tool resolve device_id → device.node_id automaticamente. only_propagating=true (padrão) percorre só arestas hard_dep / runtime_dep / traffic; vire para false para incluir arestas de observation / annotation (útil para casos "mostre-me tudo relacionado a X").

Hits retornados carregam os metadados de path que o LLM precisa para raciocinar sobre impacto:

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" }
  ]
}

A lista plana (sem struct aninhada por vizinho) é intencional — mantém o JSON barato para embutir no prompt. Veja expand_topology_basetool.go.

find_topology_node

O pre-step "tenho um nome humano, me dê um node_id". A persona roda isso antes de expand_topology sempre que o prompt menciona um serviço / host por nome:

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, ... }

Ambos são registrados como BaseTools ScopeManager (sem argumento edge_id) — o DB de topologia vive do lado manager.

Walk de blast-radius na prática

O prompt da persona investigator inclui um "depois que você identifica o serviço disparando, chame expand_topology para ver o que mais está afetado". É assim que o related_alerts do report e a seção "业务影响 / Business impact" são populados — o agent percorre o grafo do device disparando para cima / para baixo e checa cruzado quais outros incidentes dispararam na mesma janela nesses nós.

O caminho de código relevante:

  1. correlate_incident retorna sumários de metric + log + trace mais o device_id do incidente.
  2. expand_topology { device_id, direction: both, depth: 2 } retorna o conjunto alcançável.
  3. Extração Pass-2 lê a narrativa do worker e puxa pinpointed_target (o paciente zero) + related_alerts (a cascata).

Veja também

  • RCA — a persona investigator que usa essas tools.
  • Skills — como expand_topology é registrado tanto na BaseTool bag quanto no skill registry (inventory_bridge).
  • Conceitos — o vocabulário Edge / Device / Node.