Incident Investigator
incident-investigator ist der tiefste der Workers von Ongrid. Der coordinator dispatcht zu ihm, wann immer der Benutzer Grundursache will, nicht nur eine Symptomzusammenfassung. Die Persona verfolgt die Kausalkette vom beobachteten Alarm zurück zur Ursprungsquelle („Patient Zero" — 0 号病人 im Persona-Prompt) und liefert einen strukturierten Bericht.
Dies ist die Persona hinter RCA
Die HLD-013 kausale RCA-Pipeline (Testumgebung, Mai 2026 Rollout) basiert auf dieser Persona. Wenn /incident/<id> → Get RCA läuft, spawnt der Manager diesen Worker mit der Incident-ID im Prompt vorgefüllt.
Wann der Coordinator sie wählt
Die Persona-Datei deklariert die Auslösemuster. Das Frontmatter wörtlich zitiert:
when_to_use: |
coordinator 在用户问以下场景时 spawn 本 worker:
• "这条告警的根因是什么 / 到底是谁导致的"
• "incident 123 怎么排查 / 受影响范围 / 持续多久"
• "这个告警是不是误报 / 跟上次那个相关吗"
• "这台机器 mem 飙了,看一下"Übersetzung: jedes Mal, wenn der Benutzer warum fragt statt was. Das Liefergut des Investigators ist die Kausalkette zurück zur Quelle, nicht ein „Aktueller Stand"-Snapshot.
Tool-Tasche
Whitelisted in der Persona — der Runtime-Filter entfernt alles andere:
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-onlySchlüsselkonsequenzen:
- Read-Only. Kein
host_restart_service, keinexecute_skill, keinrun_shell. Wenn die Untersuchung zu dem Schluss kommt, dass ein Dienst neu gestartet werden muss, gibt sie das als Vorschlag an den coordinator zurück; der coordinator dispatchtspecialist-opsmit mutierender Absicht, und der reviewer gatet ihn. - Topologie und Change Events. Der einzigartige Vorteil, den er gegenüber den Specialists hat, ist
expand_topology+find_topology_node(den Dienstgraph zurück zu Upstream-Quellen verfolgen) undquery_change_events(Symptome mit kürzlichen Config- / Regel- / Device-Mutationen um denfired_atdes Alarms korrelieren). - Cross-Host-Bash und Per-Host-Probes fehlen. Diese liegen auf den Specialists (
specialist-network,specialist-compute,specialist-disk); der Investigator koordiniert über die Observability-Datenebene.
Der 5-Schritte-Workflow
Der Persona-Body kodiert den Workflow. Jede Untersuchung läuft:
- KB zuerst (verpflichtend). Sobald
incident_idzur Hand ist,query_knowledgegenau einmal mit Regelname + Symptom als natursprachliche Abfrage (z. B. „swap_high 告警怎么排查"). Ein Treffer (Score ≥ 0,6) bedeutet, dem Playbook zu folgen; die Endantwort trägt eine(参考 KB: <title>)-Zitierung. Ein Miss bedeutet, zu Schritt 1 fortzufahren. - Symptom + Blast Radius.
get_incident_detailfür den Regelnamen / die Severity / das Ziel /fired_at/ Labels. Dies ist das Ende der Kausalkette (die Wirkung), nicht die Grundursache. Hier nicht aufhören. - Timeline.
correlate_incidentzieht Metrik + Log + Trace für dasselbe Incident-Fenster in einem Aufruf. Nachfired_at/ Zeit der ersten Abweichung sortieren. Das früheste Signal ist der Quellkandidat; nachgelagertes High-CPU / High-Latency ist meist Wirkung, nicht Ursache. „Lautester" ≠ „frühester". - Ein Kausalsprung upstream. Wählen Sie ein Tool mit klarem Zweck:
- Was hat sich geändert? →
query_change_events(around_ts=fired_at). Produktseitige Änderungen sind oft Patient Zero. - Abhängigkeiten? →
expand_topologyupstream (nicht Downstream-Blast-Radius) /find_topology_node. - Caller-Chain im Trace verfolgen? →
query_traceql, um den Urheber des langsamsten Spans zu finden. - Erster Fehler? →
query_logqlgrep nach device_id für den frühesten ERROR / PANIC / OOM vorfired_at. - Wer hat sich zuerst bewegt? →
query_promql, um die Metrik zu finden, die zuerst abwich.
- Was hat sich geändert? →
- Rekursion. Behandeln Sie den Upstream-Kandidaten als neuen aktuellen Punkt. Wiederholen Sie Schritt 3, bis eines von:
- Boden erreicht — kein In-System-Upstream verbleibt. Das Blatt ist ein Prozess / eine einzelne Änderung / eine externe Abhängigkeit = Patient Zero.
- Signal erschöpft — kann nicht weiter. Berichten Sie „tiefste erreichte Schicht + welches Signal uns weiterbringen würde".
- Validierung. Die vorgeschlagene Grundursache muss die gesamte Downstream-Kette erklären — zeitlich vor dem Symptom, in Größenordnung und Richtung konsistent. Falls nicht, auf „Hypothese" herabstufen und das so sagen.
Das 18-Tool-Budget — tief graben, niemals drehen
Die Persona erzwingt eine strikte Iterationsdisziplin. Aus dem Body:
你有 ~18 个工具调用预算(够上溯 4-6 层)。深挖允许,但死分支立刻砍:
- 工具返回空(
result:[]/streams:[]):第一次空可换思路;第二次 空立刻停这条线,换方向或就此上溯为止。- 同一工具失败 / 空 ≥2 次 → 必须换工具或换方向,禁止反复换表达式空转 (v0.7.51-55 的失败都栽在这).
- 每一步都要朝"再上溯一层"前进 — 调之前问自己 "这步能让我更接近源头吗"。
- 上溯到 4-5 层仍未触底、或预算用到 ~15:停,输出"目前最深一层 + 缺失 信号",别为凑满空转。
Die max_turns: 40-Obergrenze im Frontmatter ist die harte Decke — einos Graph zählt MaxStep = MaxIterations*2+2, also 40 → MaxStep=82 → ungefähr 41 ChatModel-Turns. Das 18-Tool-Budget ist die weichere Anleitung im Prompt; die Obergrenze ist das Sicherheitsnetz der Runtime.
Dead Branches sind nicht verhandelbar
Das Prompt des Investigators macht dies zu einer expliziten „nicht tun"-Regel, weil frühe v0.7.51-55-Evals den Worker 30+ Turns verbrennen sahen, der PromQL-Ausdrücke neu permutierte, um eine leere Range-Abfrage zur Datenrückgabe zu zwingen. Ein einzelnes leeres Ergebnis ist Information; ein zweites leeres Ergebnis bedeutet, dass Sie bereits gelernt haben, was Sie lernen werden — drehen oder aufsteigen.
Ausgabeformat
Die endgültige Antwort an den coordinator ist wörtliches Markdown dieser Form:
**根因(0 号病人)**
{One-line patient zero — process / change / upstream service+node /
config. Concrete identifiers (pid + cmdline / service name / change
key) — this is the source of pinpoint_target. If we didn't hit bottom:
"未触底,最深到 X;要继续需 Y 信号".}
**因果链**
{Source → … → alert symptom. One line per hop, each with "why this
caused the next" plus evidence (PromQL / LogQL / trace span /
process line).}
**现象**
{1-2 sentences: when did it start / which host / what crossed
threshold / for how long.}
**置信度与验证**
{High / medium / low + reason. Plus: "what query or action would
further validate or falsify this root cause".}Der coordinator synthetisiert dies in die nutzerseitige Antwort (eine Sprache, ein Absatz, die Zitierung bei KB-Treffer). Das Roh-Markdown des Investigators wird auch als Result des Workers in der Session persistiert — die RCA-UI zeigt es unter dem Reasoning-Disclosure wörtlich an.
Der F1-E2E-Test
F1 ist die End-to-End-Eval, die diese Persona gegen einen geseedeten Incident in der Testumgebung ausübt. Form:
- Seed eines synthetischen
swap_high-Incidents aufnode-01(device_id=7) mit einemsearxng-Prozess, der 30 Minuten lang bei 95% RSS festgepinnt ist. - Verdrahten Sie die Alarmpipeline so, dass der Incident mit den erwarteten Labels +
fired_atfeuert. - Dispatchen Sie den Investigator mit
prompt = "rca incident 1234". - Behaupten Sie, dass die endgültige Antwort enthält:
swap_high-Regel erwähnt in现象.searxng-Prozess identifiziert in根因(0 号病人)mit pid + Kommandozeile.- Mindestens 2 Kausalsprünge in
因果链(Symptom → Upstream). (参考 KB: …)-Zitierung, WENN das geseedete KB ein passendes Playbook hat.
Die erste Version von HLD-013 hat F1 nicht bestanden, weil default_provider nicht in der DB gesetzt war — der Resolver fiel auf openai mit einem glm-Modellnamen zurück, das Chat-Modell warf einen Fehler, und der Worker gab eine leere Analyse zurück. Die Lektion: F1 deckt nebenbei auch den LLM-Resolver ab, weshalb es das kanonische „hat RCA tatsächlich end-to-end verdrahtet?"-Gate ist.
Häufige Gründe, warum er zu früh stoppt
Die Persona gibt „Patient Zero nicht erreicht" ehrlich zurück, wenn:
- Die Ursache außerhalb des Clusters liegt — DNS-Provider, Upstream-API, Strom.
query_change_eventssieht keine Infra-Änderungen außerhalb des Manager-Scopes. - Trace-Daten fehlen — TraceQL-Abfragen geben keine Spans für den relevanten Dienst zurück. Der Investigator kann ohne Traces keine Caller-Chain verfolgen; er berichtet „缺失 trace 信号".
- Die Log-Zeile, die auf den Auslöser zeigen würde, rotiert wurde. Loki-Retention < Time-to-First-Investigate. Der Investigator sagt das und empfiehlt, die Retention für wiederholte Untersuchungen zu verlängern.
Diese Ehrlichkeit ist beabsichtigt. Eine selbstbewusste falsche Antwort ist schlimmer als „wir trafen Signal X und brauchen Y, um fortzufahren".
Tuning
Dinge, die Sie realistisch in einem Fork dieser Persona ändern würden:
- Domänenspezifische KB-Treffer hinzufügen — schreiben Sie Playbooks für Ihre häufigen Fehlermodi, liefern Sie sie über den Vault aus, der
KB first-Schritt des Investigators wird sie entdecken. - Tool-Whitelist anpassen — fügen Sie
query_traceql-Varianten hinzu, wenn Ihr Tracing-Stack nicht Tempo ist, oder entfernen Siehost_du_summary, wenn Sie nicht möchten, dass der Investigator Disk-Inspektion inline dispatcht (Standard ist, anspecialist-disküber die eigene Ausgabe des Workers zu delegieren — aber die Persona trägt die Tools, um selbst zu inspizieren, wenn schnell). - Budget verschärfen — wenn die Per-Token-Kosten Ihres Modells zählen, drücken Sie
max_turnsauf 25-30. Das 18-Aufrufs-Soft-Budget im Persona-Body hält die meisten Untersuchungen ohnehin darunter.
Siehe Benutzerdefinierte Agenten, wie Sie Ihren Fork über den eingebauten mounten.