Skip to content

Incident investigator

incident-investigator 는 Ongrid worker 중 가장 깊습니다. Coordinator 는 사용자가 단순 증상 요약이 아닌 근본 원인 을 원할 때마다 이것으로 디스패치합니다. persona 는 관측된 알림에서 발원지 ("patient zero" — persona prompt 의 0 号病人) 로 거슬러 인과 사슬 을 따라가고 구조화된 보고서를 반환합니다.

이것이 RCA 뒤의 persona

HLD-013 인과 RCA 파이프라인 (테스트 환경, 2026 년 5 월 롤아웃) 은 이 persona 위에 빌드. /incident/<id> → Get RCA 가 실행되면 매니저가 prompt 에 incident id 가 미리 채워진 이 worker 를 스폰.

Coordinator 가 고르는 때

persona 파일이 트리거 패턴을 선언. frontmatter 인용:

yaml
when_to_use: |
  coordinator 在用户问以下场景时 spawn 本 worker:
    • "这条告警的根因是什么 / 到底是谁导致的"
    • "incident 123 怎么排查 / 受影响范围 / 持续多久"
    • "这个告警是不是误报 / 跟上次那个相关吗"
    • "这台机器 mem 飙了,看一下"

번역: 사용자가 무엇 이 아닌 를 물을 때마다. investigator 의 산출물은 "현재 상태" 스냅샷이 아니라 발원으로 거슬러 올라가는 인과 사슬입니다.

도구 가방

persona 의 화이트리스트 — 런타임 필터가 그 외 모든 것을 제거:

yaml
tools:
  - query_knowledge        # KB / vault / uploads
  - get_incident_detail
  - query_incidents
  - correlate_incident     # metric+log+trace pulled together
  - query_change_events    # config / rule / device mutations
  - query_promql
  - query_logql
  - query_traceql
  - get_edge_summary
  - query_alert_rules
  - query_devices
  - get_host_load
  - get_host_processes
  - expand_topology
  - find_topology_node
  - host_find_large_files
  - host_du_summary
  - host_stat_file

disallowed_tools:
  - execute_skill
  - host_restart_service
  - run_shell

permission_mode: read-only

핵심 결과:

  • 읽기 전용. host_restart_service, execute_skill, run_shell 없음. investigation 이 서비스 재시작이 필요하다고 결론지으면 그것을 제안 으로 coordinator 에 반환; coordinator 는 mutating intent 로 specialist-ops 를 디스패치, reviewer 가 게이트.
  • 토폴로지와 변경 이벤트. specialist 대비 가지는 고유한 우위는 expand_topology + find_topology_node (업스트림 발원으로 서비스 그래프 따라가기) 와 query_change_events (알림의 fired_at 주변 최근 config / 규칙 / 디바이스 변경과 증상 상관 분석).
  • 크로스 호스트 bash 와 호스트별 프로브는 없음. specialist (specialist-network, specialist-compute, specialist-disk) 에 있음; investigator 는 가관측성 데이터 플레인 위에서 코디네이트.

5 단계 워크플로

persona body 가 워크플로를 인코딩. 모든 investigation 이 실행:

  1. KB 먼저 (필수). incident_id 가 손에 들어오면 규칙 이름 + 증상을 자연어 쿼리로 (예: "swap_high 告警怎么排查") query_knowledge 정확히 한 번. 히트 (점수 ≥ 0.6) 는 플레이북을 따름을 의미; 최종 답에 (参考 KB: <title>) 인용. miss 는 단계 1 로 진행.
  2. 증상 + 영향 범위. 규칙 이름 / 심각도 / 대상 / fired_at / 레이블용 get_incident_detail. 이것은 인과 사슬의 끝 (결과) 이지 근본 원인이 아닙니다. 여기서 멈추지 마세요.
  3. 타임라인. correlate_incident 가 한 호출로 같은 incident 윈도우의 메트릭 + 로그 + 트레이스를 풀합니다. fired_at / 첫 편차 시간으로 정렬. 가장 이른 신호가 발원 후보; 다운스트림 high-CPU / high-latency 는 보통 결과지 원인이 아닙니다. "가장 큰 소리" ≠ "가장 이른".
  4. 한 인과 hop 업스트림. 명확한 목적으로 하나 의 도구 선택:
    • 무엇이 바뀌었나?query_change_events(around_ts=fired_at). 제품 측 변경이 종종 patient zero.
    • 의존성? → upstream 의 expand_topology (downstream 영향 범위가 아님) / find_topology_node.
    • 호출자 사슬 트레이스? → 가장 느린 span 의 발신자를 찾는 query_traceql.
    • 첫 에러?fired_at 이전 의 가장 이른 ERROR / PANIC / OOM 을 device_id 별 grep 하는 query_logql.
    • 누가 먼저 움직였나? → 먼저 편차한 메트릭을 찾는 query_promql.
  5. 재귀. 업스트림 후보를 새 현재 지점으로 다룸. 다음 중 하나까지 3 단계 반복:
    • 바닥 도달 — 시스템 내 업스트림이 남지 않음. leaf 가 프로세스 / 단일 변경 / 외부 의존성 = patient zero.
    • 신호 고갈 — 더 못 감. "도달한 가장 깊은 층 + 계속하려면 어떤 신호가 필요한지" 보고.
  6. 검증. 제안된 근본 원인은 전체 다운스트림 사슬을 설명해야 합니다 — 증상보다 시간적으로 앞선 , 크기와 방향이 일관됨. 아니라면 "가설" 로 강등하고 그렇게 말함.

18 도구 예산 — 깊게 파고, 절대 헛돌지 말 것

persona 는 엄격한 반복 규율을 강제. body 에서:

你有 ~18 个工具调用预算(够上溯 4-6 层)。深挖允许,但死分支立刻砍

  • 工具返回空(result:[] / streams:[]):第一次空可换思路;第二次 空立刻停这条线,换方向或就此上溯为止。
  • 同一工具失败 / 空 ≥2 次 → 必须换工具或换方向,禁止反复换表达式空转 (v0.7.51-55 的失败都栽在这).
  • 每一步都要朝"再上溯一层"前进 — 调之前问自己 "这步能让我更接近源头吗"。
  • 上溯到 4-5 层仍未触底、或预算用到 ~15:停,输出"目前最深一层 + 缺失 信号",别为凑满空转。

frontmatter 의 max_turns: 40 상한은 하드 천장 — eino 의 그래프가 MaxStep = MaxIterations*2+2 를 계산하므로 40 → MaxStep=82 → 대략 41 ChatModel 턴. 18 도구 예산은 prompt 의 더 부드러운 가이드 ; 상한은 런타임 안전망입니다.

Dead branch 는 협상 불가

investigator 의 prompt 는 이를 명시적 "하지 말 것" 규칙으로 만듭니다 — 초기 v0.7.51-55 eval 에서 worker 가 빈 범위 쿼리를 데이터 반환시키려 PromQL 표현식을 재순열하며 30+ 턴을 소진하는 것을 봤기 때문입니다. 단일 빈 결과는 정보; 두 번째 빈 결과는 이미 배운 것을 다 배웠다는 의미 — 방향을 바꾸거나 상승하세요.

출력 포맷

coordinator 에 대한 최종 답신은 이 형태의 정확한 Markdown:

markdown
**근본 원인 (patient zero)**
{한 줄 patient zero — 프로세스 / 변경 / 업스트림 service+node /
config. 구체적 식별자 (pid + cmdline / 서비스 이름 / 변경 키) — 이것이
pinpoint_target 의 발원. 바닥에 못 닿았다면:
"바닥 미도달, 가장 깊이 X; 계속하려면 Y 신호 필요".}

**인과 사슬**
{발원 → … → 알림 증상. hop 당 한 줄, 각각 "왜 이것이 다음을 야기했나"
와 증거 (PromQL / LogQL / 트레이스 span / 프로세스 라인).}

**현상**
{1-2 문장: 언제 시작 / 어느 호스트 / 무엇이 임계값 넘음 / 얼마나
오래.}

**신뢰도와 검증**
{높음 / 중간 / 낮음 + 이유. 추가: "어떤 쿼리 또는 액션이 이 근본
원인을 더 검증하거나 반증할 수 있을지".}

Coordinator 는 이를 사용자 대면 답신에 합성 (한 언어, 한 문단, KB 히트 시 인용). investigator 의 원본 Markdown 도 worker 의 Result 로 세션에 영속화 — RCA UI 가 Reasoning 공개 아래에서 그대로 표면화.

F1 e2e 테스트

F1 은 테스트 환경의 시드된 incident 에 대해 이 persona 를 운동시키는 end-to-end eval. 형태:

  1. searxng 프로세스가 30 분간 RSS 95% 에 고정된 node-01 (device_id=7) 에 합성 swap_high incident 시드.
  2. 예상 레이블 + fired_at 으로 incident 가 발화하도록 알림 파이프라인 배선.
  3. prompt = "rca incident 1234" 로 investigator 디스패치.
  4. 최종 답이 다음을 포함하는지 확인:
    • 현상swap_high 규칙 언급.
    • 근본 원인 (patient zero) 에 pid + 명령행과 함께 식별된 searxng 프로세스.
    • 인과 사슬 에 최소 2 인과 hop (증상 → 업스트림).
    • 시드된 KB 에 매칭 플레이북이 있으면 (参考 KB: …) 인용.

HLD-013 의 첫 버전이 F1 에 실패한 이유는 DB 에 default_provider 가 설정되지 않아서였습니다 — resolver 가 glm 모델 이름과 함께 openai 로 폴백, 채팅 모델 에러, worker 가 빈 분석 반환. 교훈: F1 이 부수 효과로 LLM resolver 도 다룸, 그래서 표준 "RCA 가 실제로 end-to-end 배선됐나?" 게이트입니다.

일반적인 조기 종료 이유

다음 경우 persona 가 "patient zero 미도달" 을 정직하게 반환:

  • 원인이 클러스터 외부 — DNS provider, 업스트림 API, 전원. query_change_events 는 매니저 범위 밖 인프라 변경을 보지 않음.
  • 트레이스 데이터 누락 — 관련 서비스에 대한 TraceQL 쿼리가 span 을 반환하지 않음. investigator 는 트레이스 없이 호출자 사슬을 따라갈 수 없음; "缺失 trace 信号" 보고.
  • 트리거를 가리킬 로그 라인이 회전됨. Loki 보존 < first-investigate 시간. investigator 는 그렇게 말하고 반복 investigation 을 위해 보존 연장 권장.

이 정직함은 설계입니다. 자신 있게 틀린 답은 "신호 X 에 도달했고 계속 하려면 Y 가 필요" 보다 나쁩니다.

튜닝

이 persona 포크에서 현실적으로 바꿀 것:

  • 도메인 특화 KB 히트 추가당신의 일반적 실패 모드에 대한 플레이북 작성, vault 로 출하, investigator 의 KB first 단계가 발견할 것.
  • 도구 화이트리스트 조정 — 트레이싱 스택이 Tempo 가 아니라면 query_traceql 변형 추가, 또는 investigator 가 디스크 점검을 인라인으로 디스패치하지 않길 원하면 host_du_summary 제거 (기본은 worker 자체 출력으로 specialist-disk 에 위임 — 하지만 persona 는 빠를 때 자신을 점검할 도구도 운반 합니다).
  • 예산 조임 — 모델의 토큰당 비용이 중요하다면 max_turns 를 25-30 으로 낮춤. persona body 의 18 호출 soft 예산이 대부분 investigation 을 이미 그 아래로 유지합니다.

내장 위에 포크를 마운트하는 방법은 커스텀 에이전트 참고.