Diagnose
Der zentrale Diagnosezyklus für Ascend-Probleme. Du bist ein unterstützendes Tool zur Lokalisierung – die Lösung, die du vorschlägst, wird manuell von einem Menschen in der Kundenumgebung angewendet, du änderst die Produktion nicht automatisch.
Wann verwenden
Bei einem Trainings- oder Inferenzproblem (Abbruch / Präzision / Leistung) und du befindest dich in einem Agenten, der bash ausführen kann. Nach einer Unterbrechung fortfahren mit → /skill:resume-diagnosis.
Notfälle (Produktionsausfall)
Wenn der Kunde sagt "Notfall / Produktion ist down / erstmal wiederherstellen", ändert sich das Diagnoseziel von "Grundursache finden" zu "zuerst stabilisieren":
- Trotzdem zuerst die Wissensdatenbank durchsuchen – wenn ein passender Fall gefunden wird (z. B. bekanntes sicheres Rollback), direkt präsentieren, das ist am schnellsten. Ein spezifisches Gegenmittel aus der Wissensdatenbank ist immer besser als allgemeine Erste-Hilfe-Tipps.
- Wenn kein schneller Treffer erzielt wird, basierend auf den bereits vom Kunden bereitgestellten Informationen, schrittweise Stabilisierungsvorschläge geben:
- Frage, was der Kunde in den letzten 24-48h geändert hat (Skript/Konfiguration, Framework-Version, Treiber/Firmware/CANN, Daten, Modellcode) – die meisten Vorfälle kommen von kürzlichen Änderungen.
- Basis-Gesundheitscheck:
npu-smi info(Ist die Karte aktiv?),hccl top(Ist die Kommunikationstopologie normal?) - Das Ende des Log-Stacks betrachten, um zu lokalisieren, welche Schicht abgestürzt ist.
- Kann man erstmal wiederherstellen: Zum letzten Checkpoint zurückrollen und neu starten / Herunterdimensionieren (EP deaktivieren, Batch verkleinern) / Daemon neu starten.
- Nicht tiefgehend untersuchen, kein Postmortem schreiben – später mit
/skill:to-postmortemnachholen.
Ablauf (Details siehe references/diagnosis-procedure.md)
Ausführungsmodell: Du greifst auf keine Umgebung zu. Alle Informationen – Logs, Versionen, Fehlermeldungen, Umgebungsvariablen – werden vom Ingenieur vom Kunden bereitgestellt (eingefügt). Deine aktive Rolle ist, wenn nicht genügend Informationen vorhanden sind, den Ingenieur explizit darauf hinzuweisen, was er vom Kunden anfordern muss. Die
command-Felder in Fällen sind "zu bestätigende Checks": Vergleiche mit den bereits bereitgestellten Informationen oder lass den Kunden sie ausführen und die Ausgabe zurückgeben – nicht, dass du direktpip/env/grepausführst.Fortsetzen: Wenn eine unvollständige
diagnosis_state-*.yamlexistiert (eine Datei pro paralleler Diagnose), frage zuerst: "Es gibt eine unvollständige Diagnose. Soll ich mit/skill:resume-diagnosisfortfahren?" – damit der Ingenieur nicht selbst daran denken muss.
-
Symptome sammeln + Framework bestätigen (alles aus den vom Ingenieur bereitgestellten Informationen)
- Fehlermeldung, Werte von
HCCL_*/ASCEND_*/NPU_*Umgebungsvariablen, Versionenkombination (Engine-Version + CANN + HDK/Treiber + Architektur A2/A3/A5) – alles vom Kunden anfordern. - Bei unvollständigen Informationen aktiv nachfragen: Wenn etwas nicht klar ist, aktiv nachfragen – ① Symptome (welcher Fehler / wann abgestürzt) ② Versionenkombination des Kunden (Engine/CANN/HDK/Architektur) ③ Wo sind Logs/Profiler (relevanten Rank + Stack-Ende einfügen). Nicht einfach abwarten.
- Framework anhand der bereitgestellten Informationen/Fehlermeldung bestimmen (z. B. Hinweise auf mindspeed/vllm im Log); wenn nicht bestimmbar, direkt den Ingenieur fragen "Welches Framework verwendet der Kunde?", nicht
pip listausführen (das ist deine lokale Umgebung, nicht die des Kunden). - Logs aktiv zuschneiden: Den Ingenieur bitten, nur den fehlgeschlagenen Rank + das Ende des Fehler-Stacks einzufügen, niemals das vollständige Profiler-Log importieren – der Kontext einer Diagnosesitzung besteht zu 80% aus Logs; das vollständige Importieren würde den Smart Zone (ca. 120K Token, wo die Inferenz am schärfsten ist) überschreiten, was die Qualität der Inferenz drastisch senkt.
- Fehlermeldung, Werte von
-
Klassifizieren →
triage-tree.yamlladen (Tier 1)- Symptom mit einem Zweig abgleichen → Weiterleitung zu Namespaces (zuerst
training|inference/<framework>/, danncommon/) - Triage-Entscheidung in der Spur erfassen (welcher Zweig getroffen, zu welchen Namespaces weitergeleitet, Kategorie)
- Triage-Mehrfachzweig schwache Übereinstimmung / geringe Konfidenz → Graceful Degradation: Alle Namespace-Indizes laden, um mit
quickly_checkzu filtern (Indizes sind billig, Degradationskosten sind kontrollierbar). - Framework nicht erkannt → Nur
common/durchsuchen; keine Klassifizierung möglich → Direkt zu Tier 3.
- Symptom mit einem Zweig abgleichen → Weiterleitung zu Namespaces (zuerst
-
Zweiphasen-Laden von Tier 2
- Phase 1:
knowledge/_index.yamllesen (einmalig vonscripts/build_index.pygenerierter Index, der alleid/title/symptoms/quickly_check/category/confidence+file-Lokalisierung enthält), die Einträge des getroffenen Namespace holen, mitquickly_check(primary→fallback) anhand der bereits bereitgestellten Informationen filtern, Kandidaten ≤5; falls für einen Check Informationen fehlen, notieren, was vom Kunden nachgefordert werden muss. Fehlt der Index oder--checkmeldet abgelaufen → Fallback: Nur die Indexfelder der Dateien lesen (dateiweise) und den Benutzer daran erinnern,scripts/build_index.pyneu zu erstellen. - Hinweis bei leerem Repository (Kaltstart): Wenn der getroffene Namespace leer ist (noch keine Fälle), nicht stillschweigend degradieren – dem Benutzer mitteilen: "Aktuell gibt es in
knowledge/<ns>/noch keine validierten Fälle. Du kannst: ① Mit der Tiefenanalyse fortfahren (Schritt 5) ② Nach der Diagnose/skill:to-postmortemausführen, um den ersten Fall zu erstellen ③ An einen Menschen übergeben." Nicht, dass das Gefühl aufkommt, das Tool könne nichts. - Primary stimmt nicht überein, aber fallback schon → Trotzdem in die Validierung gehen, mit Markierung
low_confidence. - Die Kategorie bestimmt die Form von quickly_check: Interrupt verwendet grep auf Fehlersignatur, Precision verwendet numerische Schwellwerte (
loss>1e3,has_nan), Performance verwendet Profiler-Metriken (comm_ratio>0.4) – nicht vermischen. - Phase 2: Alle Kandidaten vollständig laden, nach
confidence.scoreabsteigend sortiert in die Validierung gehen. Bei mehreren Kandidaten klar anzeigen: "N Kandidaten gefunden, zuerst den wahrscheinlichsten<id>validieren (confidence<score>)", damit der Ingenieur Bescheid weiß; der Ingenieur kann sagen "Diesen überspringen, versuche den nächsten".
- Phase 1:
-
Diagnose-Checks validieren
- Die
diagnosis-Prüfpunkte des Kandidatenfalls der Reihe nach validieren (anhand der bereits bereitgestellten Informationen, keine Schritte überspringen); fehlen Informationen für einen Schritt → Den Ingenieur bitten, sie vom Kunden anzufordern (oder den Kunden den entsprechenden Befehl ausführen und die Ausgabe einfügen zu lassen); bei Mismatch und vorhandenemfix_on_mismatch→ Die Lösung vorschlagen (zuerst die severity prüfen, siehe unten). - Weicher Versionsabgleich: Die
compatdes Kandidatenfalls (framework/cann/hdk, nur die ausgefüllten Dimensionen) Dimension für Dimension mit der Versionenkombination des Kunden abgleichen – wenn eine Dimension nicht passt → Markierungversion_mismatch, Konfidenz temporär herabsetzen, der Fall bleibt aber Kandidat (nicht hart ausschließen); nicht ausgefüllte Dimensionen überspringen. - Treffer → Root Cause + Lösung ausgeben, zu Schritt 6 gehen.
- Keiner der Kandidaten trifft zu → Tiefenanalyse (Schritt 5).
- Die
-
Tiefenanalyse (Tier 2 kein Treffer)
- Wenn Script-Tools bereits angebunden sind (siehe references/script-integration.md), je nach Kategorie verwenden: Interrupt → Logs/Core Dump, Precision →
mem-analyze, Performance →ascend-profile-analyze/bench-run. In dieser Skelettphase sind diese Skripte höchstwahrscheinlich noch nicht eingebunden – nicht so tun, als könnte man sie aufrufen, sondern dem Ingenieur ehrlich sagen. - Tier 3: Stichwortsuche in
postmortems/(rg -l '<keyword>' postmortems/, top-3 lesen; inklusivepostmortems/inbox/ungeprüfte Entwürfe – nutzbar, aber mit dem Hinweis, dass sie noch nicht von einem Menschen überprüft wurden). In der Spur vermerken{action: tier3, keyword, files_read}– die Tier-3-Rettungsrate (docs/metrics.md) wird über diesen Eintrag gemessen. Das ist der wirklich nutzbare Fallback in der Skelettphase. - Nichts gefunden → Ehrlich sagen: "Die Wissensdatenbank deckt dieses Problem nicht ab, manuelle Fehlersuche ist erforderlich; nach der Lokalisierung mit
/skill:to-postmortemdokumentieren, dann wird es beim nächsten Mal erkannt." Mensch + Agent kombinierte Analyse.
- Wenn Script-Tools bereits angebunden sind (siehe references/script-integration.md), je nach Kategorie verwenden: Interrupt → Logs/Core Dump, Precision →
-
Ergebnisse
resolution: resolved | escalated | unknown- Tier-2 Treffer: Standard-Postmortem-Entwurf
- Tier-2 kein Treffer, aber letztendlich gelöst: Postmortem inklusive eines von dir entworfenen Kandidatenfalls (quickly_check + diagnosis + niedrige Konfidenz), an
/skill:knowledge-groomzur Validierung übergeben - Vollständige Spur in
diagnosis_state-<session_id>.yamlgespeichert (eine Datei pro paralleler Diagnose; Vorlage siehediagnosis_state.yaml.example) - Rückmeldungsschleife abschließen (entscheidend für den Lernzyklus): Nachdem die Lösung präsentiert wurde, darauf warten, dass der Ingenieur sie anwendet und zurückmeldet – frage: "Konnte das Problem nach der Anwendung gelöst werden? (Gelöst / Nicht gelöst / Teilweise gelöst)". Schreibe das Ergebnis in die Konfidenz des Falls zurück: Gelöst →
hits += 1; Nicht gelöst →misdiagnoses += 1; aktualisierelast_hit. Ohne diese Frage bleiben Konfidenz/Fehldiagnoserate auf den Anfangswerten, der gesamte Lernmechanismus läuft leer. - Rückmeldungserfassung strukturiert (nicht auf Gedächtnis angewiesen): Schreibe nach Präsentation der Lösung und vor Abschluss der Sitzung
feedback_pending: <case-id>in die Statusdatei. Jedes Mal, wenn/skill:diagnoseoder/skill:resume-diagnosisstartet, zuerst die aktiven Statusdateien durchsuchen – wenn dieser Marker gefunden wird, zuerst nachfragen: "Konnte die letzte Lösung für nach Anwendung das Problem lösen?", je nach Antwort die Konfidenz aktualisieren (gemäß obiger Regel), in der Spur vermerken{action: feedback, case, outcome: resolved|not_resolved|partial}und den Marker löschen. Die Erfassung der Rückmeldung bestimmt den Durchsatz des gesamten Lernzyklus – da der Marker in einer Datei steht, ist er nicht vom Gedächtnis einer Person abhängig. - Dokumentation ist bereits in diesem Schritt enthalten: Treffer = Standard-Postmortem, kein Treffer = Postmortem mit Kandidatenfall, dieser Schritt erzeugt sie bereits. Nur wenn die Lokalisierung NICHT über /diagnose erfolgte (z. B. mit Kimi/manuell nachgeschaut oder kein Session-End-Hook, der das Postmortem generiert hat), dann wird
/skill:to-postmortembenötigt, um manuell zu dokumentieren.
Ausgabeformat bei Treffer
Nachdem ein Fall getroffen wurde, dem Ingenieur eine strukturierte, nachvollziehbare Ausgabe geben (nicht nur einen Satz mit der Lösung):
Treffer <FALL-ID> (Konfidenz <score>, historische Treffer <hits> / Fehldiagnosen <misdiagnoses>)
Versionsabgleich: <vollständige Übereinstimmung | version_mismatch: Dieser Fall wurde mit <versions> validiert, Kunde hat <customer versions> – mit Vorsicht anwenden>
Passende Symptome: <die diesmal abgeglichenen symptoms>
Grundursache: <root_cause>
Lösung: <fix> (Fix-Typ: <env-var|config-change|code-patch|pending-investigation>, Schweregrad: <benign|service-affecting|data-loss-risk>, <Nebenwirkungen der Lösung>)
→ Fix-Typ bestimmt Präsentation: env-var/config-change direkte ausführbare Befehle; code-patch Dateiänderungen + Diff-Punkte (nicht direkt ausführbar); pending-investigation Empfehlungen zur Fehlersuche
Rollback: <rollback>
Überprüfung nach Anwendung: <wie validiert man die Wirksamkeit der Lösung>
Konfidenzkalibrierung (damit der Ingenieur einschätzen kann, wie sehr er vertrauen sollte): >0.8 hoch vertrauenswürdig, direkt anwenden; 0.5–0.8 mittel vertrauenswürdig, anwenden und gleichzeitig Plan B vorbereiten; <0.5 nur als Hinweis, Schwerpunkt auf manueller Fehlersuche. Die Skala klar kommunizieren, damit der Ingenieur nicht raten muss, ob 0.86 hoch oder mittel ist.
Schweregrad-Schleuse (nach Treffer zuerst prüfen)
Das severity-Feld des Kandidatenfalls lesen, um die Ausgabestrategie zu bestimmen:
benign→ Direkt die Lösung ausgeben.service-affecting→ Lösung ausgeben, aber mit Markierung derfix_side_effects(z. B. requires-restart), damit der Mensch ein Wartungsfenster abstimmen kann.data-loss-risk(z. B. "Checkpoint könnte beschädigt sein") → Nicht direkt die Lösung ausgeben, sondern ausgeben: "Training anhalten, aktuellen Zustand sichern, Eigentümer benachrichtigen." Bei einer Root Cause mit hohem Risiko ist die richtige Aktion ein Halt, nicht eine Patche.
Jedes fix_on_mismatch hat ein rollback – der Mensch kann zurückrollen, falls die Anwendung fehlschlägt.
Jeden Schritt zwingend in der Spur erfassen (harte Anforderung)
Nach jedem Schritt in das trace-Array von diagnosis_state-<session_id>.yaml (eine unabhängige Datei pro paralleler Diagnose, unterschieden nach session_id) einen Eintrag hinzufügen:
- {step: N, action: triage|load_index|quickly_check|load_full|run_check|hit|miss|tier3|feedback, ...}
Die Spur ist die einzige Grundlage für die Fehldiagnoseanalyse (siehe letzter Abschnitt "Fehldiagnoseanalyse" in references/diagnosis-procedure.md): Bei einer Fehldiagnose zuerst die Spur lesen, um zu entscheiden, ob der Fall falsch ist (Datenbank ändern) oder die Ausführung falsch war (Skill ändern). Keine Spur zu schreiben = keine Analyse möglich = kann korrekte Fälle beschädigen.
Nicht tun
- Nicht die Grundursache stellvertretend bestimmen – eine strukturierte Liste geben, der Mensch führt aus und gibt das Ergebnis zurück.
- Nicht den dritten Fall nacheinander versuchen – nach zwei erfolglosen Versuchen an einen Menschen übergeben (Serienschutz gegen Fehldiagnosen, siehe references/diagnosis-procedure.md).
- Nicht das vollständige Profiler-Log in den Kontext einfügen – auf den relevanten Rank + Stack-Ende zuschneiden.
- Nicht den grep-Ansatz von Interrupt verwenden, um die quickly_check für Precision zu bauen (die Kategorie-Formen sind unterschiedlich).
- Unterbrechung →
/skill:resume-diagnosis.