Diagnostiquer
Cycle de diagnostic de base pour les problèmes Ascend. Vous êtes un outil d'assistance au diagnostic – les corrections que vous proposez sont des suggestions, qui doivent être appliquées manuellement par l'utilisateur à son environnement ; vous ne modifiez pas la production automatiquement.
Quand l'utiliser
Quand un problème d'entraînement ou d'inférence survient (interruption / précision / performance) et que vous êtes dans un agent capable d'exécuter bash. Si vous êtes interrompu(e) → /skill:resume-diagnosis.
Urgences (interruption de production)
Quand le client dit « urgence / production en panne / revenir à un état stable d'abord », l'objectif du diagnostic passe de « trouver la cause racine » à « stabiliser d'abord » :
- Consultez d'abord la base de connaissances – s'il y a un cas correspondant (par exemple un rollback de sécurité connu), donnez-le directement, c'est le plus rapide. Les solutions spécifiques de la base de connaissances sont toujours meilleures qu'un premier secours générique.
- S'il n'y a pas de correspondance rapide, selon les informations déjà fournies par le client, donnezlui étape par étape des conseils pour stabiliser :
- Demandez au client ce qui a été modifié dans les dernières 24-48h (scripts/configuration, version du framework, driver/firmware/CANN, données, code du modèle) – la majorité des incidents proviennent de modifications récentes
- Vérifications de base de l'état de santé :
npu-smi info(la carte est-elle vivante ?),hccl top(la topologie de communication est-elle normale ?) - Regardez la fin de la pile de logs pour identifier où l'erreur s'est produite.
- Peut-on revenir à un état stable d'abord : rollback au dernier checkpoint et redémarrage / réduction de la configuration (désactiver EP, réduire le batch) / redémarrer le daemon
- Ne pas mener d'enquête approfondie, ne pas rédiger de post-mortem – faites-le après avec
/skill:to-postmortem.
Processus (Cycle principal, voir détails dans references/diagnosis-procedure.md)
Modèle d'exécution : Vous n'accédez à aucun environnement. Toutes les informations – logs, versions, erreurs, variables d'environnement – sont fournies par l'ingénieur (collées ici). Votre rôle actif est quand les informations sont insuffisantes, d'indiquer clairement à l'ingénieur ce qu'il faut demander au client. Les
commanddans un cas sont des « vérifications à confirmer » : comparez avec les informations déjà fournies, ou demandez au client d'exécuter la commande et de coller le résultat – vous n'exécutez pas directementpip/env/grep.Reprise : Si un fichier
diagnosis_state-*.yamlexiste (un fichier par diagnostic concurrent), demandez d'abord « Il y a un diagnostic non terminé, voulez-vous continuer avec/skill:resume-diagnosis? » – ne forcez pas l'ingénieur à se souvenir de reprendre.
-
Recueillir les symptômes + confirmer le framework (tout à partir des informations fournies par l'ingénieur)
- Message d'erreur, valeurs des variables d'environnement
HCCL_*/ASCEND_*/NPU_*, combinaison de versions (version du moteur + CANN + HDK/driver + architecture A2/A3/A5) – tout doit être demandé au client - Si les informations sont incomplètes, demandez activement : si ce n'est pas clair, demandez – ① symptôme (quelle erreur / quand ça s'est arrêté) ② combinaison de versions du client (moteur/CANN/HDK/architecture) ③ où sont les logs/ profileur (collez le rang concerné + la fin de la pile). N'attendez pas passivement.
- Déterminez le framework à partir des informations / erreurs fournies (mots-clés comme mindspeed/vllm dans les logs) ; si vous ne pouvez pas déterminer, demandez directement à l'ingénieur « quel framework le client utilise », n'exécutez pas
pip list(c'est votre environnement local, sans rapport avec le client). - Taillez activement les logs : demandez à l'ingénieur de ne coller que le rang en échec + la fin de la pile d'erreurs, ne jamais coller l'intégralité du profileur – le contexte d'une session de diagnostic est constitué à 80% de logs, et le coller en entier ferait sortir de la zone intelligente (~120K tokens, le raisonnement le plus affûté), ce qui ferait chuter la qualité du raisonnement.
- Message d'erreur, valeurs des variables d'environnement
-
Classifier → Charger
triage-tree.yaml(Niveau 1)- La branche de symptômes correspondante → routez vers un namespace (d'abord
training|inference/<framework>/, puiscommon/) - Enregistrez la décision de triage dans la trace (quelle branche a été choisie, vers quels namespace routés, catégorie)
- Correspondance faible / confiance basse dans le triage multi-branche → dégradation élégante : chargez tous les index des namespace et laissez
quickly_checkfiltrer (l'index est bon marché, le coût de la dégradation est contrôlable). - Framework non détecté → cherchez seulement dans
common/; impossible à classifier → allez directement au Niveau 3.
- La branche de symptômes correspondante → routez vers un namespace (d'abord
-
Chargement en deux phases du Niveau 2
- Phase 1 : Lisez
knowledge/_index.yaml(index unique généré parscripts/build_index.py, contenant tous lesid/title/symptoms/quickly_check/category/confidence+filepour localiser le fichier), prenez les entrées du namespace concerné, utilisezquickly_check(primaire → fallback) en comparant avec les informations déjà fournies pour filtrer et garder ≤5 candidates. Si une vérification manque d'information, notez ce qu'il faut demander au client. Si l'index est manquant ou--checkindique qu'il est obsolète → solution de repli : lisez fichier par fichier seulement les champs de l'index ci-dessus, et rappelez de lancerscripts/build_index.pypour le reconstruire. - Indication de base vide (démarrage à froid) : si le namespace concerné est vide (pas encore de cas), ne dégradez pas en silence – dites à l'utilisateur « Le dossier
knowledge/<ns>/ne contient pas encore de cas validé. Vous pouvez : ① continuer l'enquête approfondie (étape 5) ② après le diagnostic, lancer/skill:to-postmortempour créer le premier cas ③ passer à une analyse humaine ». Ne laissez pas l'impression que « ce truc ne sait rien faire ». - Si le primaire ne correspond pas mais le fallback correspond → allez quand même en vérification, marquez
low_confidence. - La catégorie détermine la forme de
quickly_check: interruption utilisez grep sur la signature d'erreur, précision utilisez des seuils numériques (loss>1e3,has_nan), performance utilisez des métriques du profileur (comm_ratio>0.4) – ne mélangez pas. - Phase 2 : Chargez complètement les candidates, triez par
confidence.scoredécroissant pour la vérification. S'il y a plusieurs candidates, indiquez-le clairement : « Trouvé N candidates, vérifions d'abord la plus probable<id>(confiance<score>) », pour que l'ingénieur soit au courant ; l'ingénieur peut dire « saute celle-ci, essaie la suivante ».
- Phase 1 : Lisez
-
Vérifier les vérifications de diagnostic
- Vérifiez séquentiellement les éléments de
diagnosisdu cas candidat (en comparant avec les informations déjà fournies, ne sautez pas d'étape) ; si une étape manque d'information → demandez à l'ingénieur de la demander au client (ou faites-lui exécuter la commande et coller le résultat) ; en cas de non-correspondance avecfix_on_mismatch→ proposez la correction (regardez d'abord la sévérité, voir ci-dessous). - Correspondance souple des versions : comparez les dimensions remplies du champ
compat(framework/cann/hdk, seulement les dimensions remplies) du cas candidat avec la combinaison de versions du client, dimension par dimension – si une dimension ne correspond pas → marquezversion_mismatch, réduisez temporairement la confiance, le cas reste candidat (ne l'excluez pas définitivement) ; ignorez les dimensions non renseignées. - En cas de correspondance → sortez la cause racine et la correction, passez à l'étape 6.
- Si aucune candidate ne correspond → enquête approfondie (étape 5).
- Vérifiez séquentiellement les éléments de
-
Enquête approfondie (Niveau 2 sans correspondance)
- Si l'outil Script est intégré (voir references/script-integration.md), selon la catégorie : interruption→logs/core dump, précision→
mem-analyze, performance→ascend-profile-analyze/bench-run. Actuellement, à ce stade squelettique, ces scripts ne sont probablement pas intégrés – ne faites pas semblant de pouvoir les appeler, dites-le honnêtement à l'ingénieur. - Recherche par mots-clés dans le Niveau 3
postmortems/(rg -l '<mot-clé>' postmortems/, lisez des extraits des 3 premiers ; inclut les brouillons non relus danspostmortems/inbox/– utilisables mais marquez « non revu humainement »). La trace enregistre{action: tier3, keyword, files_read}– la métrique de taux de sauvetage du Niveau 3 (docs/metrics.md) se base sur cette statistique. C'est la seule solution de repli réellement utilisable à ce stade squelettique. - Rien trouvé → dites honnêtement « La base de connaissances ne couvre pas ce problème, une enquête manuelle est nécessaire ; une fois le problème localisé, utilisez
/skill:to-postmortempour le capitaliser, et la prochaine fois il sera reconnu ». Analyse conjointe humain + agent.
- Si l'outil Script est intégré (voir references/script-integration.md), selon la catégorie : interruption→logs/core dump, précision→
-
Production
resolution: resolved | escalated | unknown- Niveau 2 trouvé : brouillon de post-mortem standard.
- Niveau 2 non trouvé mais résolu finalement : post-mortem incluant un cas candidat que vous rédigez (quickly_check + diagnosis + confiance basse), à soumettre à
/skill:knowledge-groompour validation. - Trace complète conservée avec
diagnosis_state-<session_id>.yaml(un fichier par diagnostic concurrent ; modèle dansdiagnosis_state.yaml.example). - Boucle de rétroaction sur le résultat (boucle d'apprentissage essentielle) : après avoir donné la correction, attendez que l'ingénieur l'applique et revienne avec le résultat – demandez « La correction a-t-elle résolu le problème ? (Résolu / Non résolu / Partiellement résolu) ». Le résultat met à jour la confiance du cas : résolu →
hits += 1; non résolu →misdiagnoses += 1, mettez à jourlast_hit. Si vous ne demandez pas cette étape, la confiance et le taux d'erreur de diagnostic restent aux valeurs initiales, et tout le mécanisme d'apprentissage tourne à vide. - Capture structurée du feedback (pas de mémoire) : après avoir donné la correction et avant de clore la session, écrivez
feedback_pending: <case-id>dans le fichier d'état. Chaque fois que/skill:diagnoseou/skill:resume-diagnosisest lancé, vérifiez d'abord les fichiers d'état actifs – si ce marqueur est trouvé, demandez d'abord « La correction du cas a-t-elle résolu le problème après application ? », puis mettez à jour la confiance selon la réponse (règle ci-dessus), enregistrez dans la trace{action: feedback, case, outcome: resolved|not_resolved|partial}, et effacez le marqueur. La capture du feedback est le goulot d'étranglement de tout le cycle d'apprentissage – le marqueur est dans un fichier, cela ne dépend donc de la mémoire de personne. - La capitalisation est déjà incluse dans cette étape : correspondance = post-mortem standard, non-correspondance = post-mortem avec cas candidat, cette étape l'a déjà généré. Ce n'est que lorsque le diagnostic n'a pas été fait via /diagnose (par exemple, vérification manuelle via Kimi, ou si le hook de fin de session n'a pas été configuré et que le post-mortem n'a pas été généré), qu'il faut utiliser
/skill:to-postmortempour capitaliser manuellement.
Format de sortie en cas de correspondance
Quand un cas est trouvé, donnez à l'ingénieur une sortie structureée et traçable (ne vous contentez pas de donner une correction d'une ligne) :
Cas trouvé <CASE-ID> (confiance <score>, historique <hits> hits / <misdiagnoses> erreurs de diagnostic)
Correspondance de version : <correspondance exacte | version_mismatch : ce cas a été validé sur <versions>, le client a <customer versions> – à utiliser avec prudence>
Symptômes correspondants : <symptoms trouvés dans ce tour>
Cause racine : <root_cause>
Correction : <fix> (fix_type: <env-var|config-change|code-patch|pending-investigation>, severity: <benign|service-affecting|data-loss-risk>, <fix_side_effects>)
→ fix_type détermine la présentation : env-var/config-change donnez directement la commande exécutable ; code-patch donnez le fichier modifié + les points clés du diff (non exécutable directement) ; pending-investigation donnez des suggestions d'enquête.
Rollback : <rollback>
Vérification après application : <comment vérifier que la correction est effective>
Calibrage de la confiance (pour que l'ingénieur sache à quel point se fier) : >0.8 haute confiance, appliquez directement ; 0.5–0.8 confiance moyenne, appliquez tout en préparant un plan B ; <0.5 simple suggestion, concentrez-vous sur l'enquête manuelle. Expliquez l'échelle, ne laissez pas l'ingénieur deviner si 0,86 est élevé ou moyen.
Barrière de sévérité (à lire après avoir trouvé un cas)
Lisez le champ severity du cas candidat pour décider de la stratégie de sortie :
benign→ donnez directement la correction.service-affecting→ donnez la correction, mais marquezfix_side_effects(ex. requires-restart), pour que la personne coordonne la fenêtre.data-loss-risk(ex. « le checkpoint pourrait être corrompu ») → ne donnez pas la correction directement, sortez « Arrêtez l'entraînement, conservez l'état, prévenez le propriétaire ». La bonne action pour une cause racine à haut risque est de stopper, pas de patcher.
Chaque fix_on_mismatch est accompagné de rollback – pour que l'utilisateur puisse revenir en arrière en cas d'échec d'application.
Chaque étape doit écrire une trace (exigence stricte)
Après chaque étape, ajoutez une entrée au tableau trace de diagnosis_state-<session_id>.yaml (un fichier indépendant par diagnostic concurrent, différencié par session_id) :
- {step: N, action: triage|load_index|quickly_check|load_full|run_check|hit|miss|tier3|feedback, ...}
La trace est la seule base pour l'attribution des erreurs de diagnostic (voir la section « Attribution des erreurs de diagnostic » à la fin de references/diagnosis-procedure.md) : en cas d'erreur, lisez d'abord la trace pour déterminer s'il s'agit d'une erreur de cas (à corriger dans la base) ou d'une erreur d'exécution (à corriger dans la compétence). Ne pas écrire de trace = impossible d'attribuer la cause = risque de corriger un cas correct.
À ne pas faire
- Ne décidez pas de la cause racine à la place de l'utilisateur – donnez une liste structurée, la personne exécute et colle le résultat.
- N'essayez pas un troisième cas consécutif – deux échecs, et transférez à un humain (protection en série contre les erreurs de diagnostic, voir references/diagnosis-procedure.md).
- Ne chargez pas l'intégralité du profileur dans le contexte – taillez jusqu'au rang concerné + la fin de la pile.
- N'utilisez pas l'approche grep de l'interruption pour construire le quickly_check de la précision (les formes de catégorie sont différentes).
- En cas d'interruption →
/skill:resume-diagnosis.