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 인용:
when_to_use: |
coordinator 在用户问以下场景时 spawn 本 worker:
• "这条告警的根因是什么 / 到底是谁导致的"
• "incident 123 怎么排查 / 受影响范围 / 持续多久"
• "这个告警是不是误报 / 跟上次那个相关吗"
• "这台机器 mem 飙了,看一下"번역: 사용자가 무엇 이 아닌 왜 를 물을 때마다. investigator 의 산출물은 "현재 상태" 스냅샷이 아니라 발원으로 거슬러 올라가는 인과 사슬입니다.
도구 가방
persona 의 화이트리스트 — 런타임 필터가 그 외 모든 것을 제거:
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 이 실행:
- KB 먼저 (필수).
incident_id가 손에 들어오면 규칙 이름 + 증상을 자연어 쿼리로 (예: "swap_high 告警怎么排查")query_knowledge정확히 한 번. 히트 (점수 ≥ 0.6) 는 플레이북을 따름을 의미; 최종 답에(参考 KB: <title>)인용. miss 는 단계 1 로 진행. - 증상 + 영향 범위. 규칙 이름 / 심각도 / 대상 /
fired_at/ 레이블용get_incident_detail. 이것은 인과 사슬의 끝 (결과) 이지 근본 원인이 아닙니다. 여기서 멈추지 마세요. - 타임라인.
correlate_incident가 한 호출로 같은 incident 윈도우의 메트릭 + 로그 + 트레이스를 풀합니다.fired_at/ 첫 편차 시간으로 정렬. 가장 이른 신호가 발원 후보; 다운스트림 high-CPU / high-latency 는 보통 결과지 원인이 아닙니다. "가장 큰 소리" ≠ "가장 이른". - 한 인과 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.
- 무엇이 바뀌었나? →
- 재귀. 업스트림 후보를 새 현재 지점으로 다룸. 다음 중 하나까지 3 단계 반복:
- 바닥 도달 — 시스템 내 업스트림이 남지 않음. leaf 가 프로세스 / 단일 변경 / 외부 의존성 = patient zero.
- 신호 고갈 — 더 못 감. "도달한 가장 깊은 층 + 계속하려면 어떤 신호가 필요한지" 보고.
- 검증. 제안된 근본 원인은 전체 다운스트림 사슬을 설명해야 합니다 — 증상보다 시간적으로 앞선 , 크기와 방향이 일관됨. 아니라면 "가설" 로 강등하고 그렇게 말함.
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:
**근본 원인 (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. 형태:
searxng프로세스가 30 분간 RSS 95% 에 고정된node-01(device_id=7) 에 합성swap_highincident 시드.- 예상 레이블 +
fired_at으로 incident 가 발화하도록 알림 파이프라인 배선. prompt = "rca incident 1234"로 investigator 디스패치.- 최종 답이 다음을 포함하는지 확인:
현상에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 을 이미 그 아래로 유지합니다.
내장 위에 포크를 마운트하는 방법은 커스텀 에이전트 참고.