Skip to content

토폴로지

토폴로지는 "edge-prod-04 호스트의 incident" 를 "payments 와 search 와 email 을 다운시키는 incident" 로 바꾸는 그래프 입니다. 없으면 LLM 은 단일 발화 시리즈에 대해서만 추론할 수 있습니다.

ADR-025

현재 토폴로지 BaseTool (expand_topology, find_topology_node) 은 2026-05-18 에 안착. 그 전에 LLM 은 flat 디바이스 리스트만 가졌고 관계를 워크할 방법이 없었습니다; "X 에 의존하는 것" 은 운영자가 이미 답을 알아야 했습니다.

데이터 모델

네 테이블, 모두 MySQL 에:

TableHolds
topology_nodes노드당 한 행. type (device / service / cluster / ...), name, 자유 형식 props_json 가짐.
topology_node_types허용된 node.type 값의 폐쇄 셋.
topology_relationstype 을 가진 방향 엣지 src_node_id -> dst_node_id.
topology_relation_types엣지 타입의 폐쇄 셋, 각각 semantics 필드 (hard_dep / runtime_dep / traffic / annotation / observation) 로 태그.

semantics 태그가 핵심 아이디어. hard_dep 으로 태그된 엣지는 실패를 전파 (src 가 죽으면 dst 가 영향); annotation 으로 태그된 엣지는 그렇지 않음. 영향 범위 워크가 이를 사용해 필터링.

internal/manager/biz/topology/ 참고.

데이터 출처

세 소스, 계층화:

  1. Span 에서 자동 — Tempo 의 service_graph 프로세서가 routes_to semantics 태그와 함께 service_a -> service_b 엣지를 배출. 매니저가 sync 틱에 이를 topology_relations 에 미러링.
  2. Edge 에서 자동 — 등록된 모든 edge 가 type=device 노드가 됨; 노드 id 는 host_devices.node_id 컬럼에 back-link 되므로 expand_topology(device_id=X) 가 해결됨.
  3. 수동 — 운영자가 SPA 의 /topology 페이지로 type=service / type=cluster 노드와 엣지를 추가. 주소 지정하고 싶지만 직접 관측되지 않는 노드 (관리형 데이터베이스, 서드파티 API) 에 사용.

도구

expand_topology

노드에서 외부로 워크하여 도달 가능한 모든 노드와 어떻게 도달했는지 반환. 기본 BFS 깊이 2, 상한 5. 기본 방향 both (영향 범위는 대칭 — 무엇이 이걸 깨뜨릴 수 있는지 AND 이게 무엇을 깨뜨리는지).

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

또는 디바이스 id 에서 시작:

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

도구가 device_id → device.node_id 를 자동 해석. only_propagating=true (기본) 는 hard_dep / runtime_dep / traffic 엣지만 워크; false 로 뒤집으면 observation / annotation 엣지 포함 ("X 와 관련된 모든 것 보여" 케이스에 유용).

반환된 히트는 LLM 이 영향에 대해 추론하는 데 필요한 경로 메타데이터를 운반:

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

Flat 리스트 (이웃별 중첩 구조 없음) 는 의도적 — JSON 을 prompt 에 임베드하기 저렴하게 유지. expand_topology_basetool.go 참고.

find_topology_node

"사람이 준 이름이 있다, node_id 를 줘" 사전 단계. Prompt 가 이름으로 서비스 / 호스트를 언급할 때마다 persona 는 expand_topology 전에 이걸 실행:

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

둘 다 ScopeManager BaseTool 로 등록 (edge_id 인자 없음) — 토폴로지 DB 는 매니저 측에 산다.

실무에서의 영향 범위 워크

Investigator persona 의 prompt 는 "발화 서비스를 식별한 후 무엇이 또 영향 받는지 보려면 expand_topology 를 호출하라" 는 명시적 지시 포함. 이것이 보고서의 related_alerts 와 "业务影响 / Business impact" 섹션이 채워지는 방법 — 에이전트가 발화 디바이스에서 위/아래로 그래프를 워크하고 그 노드들에서 같은 윈도우에 발화한 다른 incident 를 크로스 체크.

관련 코드 경로:

  1. correlate_incident 가 메트릭 + 로그 + 트레이스 요약과 incident 의 device_id 반환.
  2. expand_topology { device_id, direction: both, depth: 2 } 가 도달 가능 셋 반환.
  3. Pass-2 추출이 worker 의 내러티브를 읽고 pinpointed_target (zero patient) + related_alerts (캐스케이드) 를 풀.

같이 보기

  • RCA — 이 도구들을 사용하는 investigator persona.
  • 기능expand_topology 가 BaseTool 가방과 기능 레지스트리 (inventory_bridge) 양쪽에 어떻게 등록되는지.
  • 개념Edge / Device / Node 어휘.